Function Snippets

Discussion in 'Server and Client Scripting' started by Nightfall Alicorn, Mar 20, 2015.

  1. Nightfall Alicorn

    Nightfall Alicorn Left Pokémon Online, most likely not coming back.

    Joined:
    Oct 15, 2013
    Messages:
    491
    Likes Received:
    171
    PO Trainer Name:
    Nightmare Moon
    Function Snippets

    ~ Introduction ~
    Hey, everyone.

    After a bit of time, specially with my script evolving, I thought I make a thread were everyone can contribute and discuss function improvements. If anyone is interested in contributing please read the last section of this post. Hope this thread helps everyone who codes on PO.

    ~ How to Use ~
    Functions can be placed in two areas of the script. Global or internal. Global can be called just about anywhere below the script once declared above. Internal however can only be called below and inside the parent of an outer function only.

    This should help give an idea how to place the functions:
    Code (JavaScript):
    1. // Do not use this example.
    2. // It's just here for showing were global and internal functions are placed.
    3.  
    4. // DEFINE GLOBAL VARIABLES HERE
    5.  
    6. // PREPARE GLOBAL FUNCTIONS HERE
    7. function funGlobalExample(vValue) {
    8.     // CODE HERE
    9.     return vValue;
    10. }
    11.  
    12. var objPoScript;
    13. objPoScript = ({
    14.     beforeChannelMessage: function (message, channel, html) {
    15.         // PREPARE INTERNAL FUNCTIONS HERE
    16.         function funInternalExample(vValue) {
    17.             // CODE HERE
    18.             return vValue;
    19.         }
    20.     }
    21. });
    Here's how to use one:
    Code (JavaScript):
    1. var vInput = "áéíóú";
    2. var vNewValue = funSpecialCharEscape(vInput);
    3. print(vNewValue);
    4. // PRINTS aeiou
    If this doesn't help. Try researching JavaScript at W3Schools site.

    ~ Functions ~
    Here are a list of functions I've provided.

    Escape Special Characters
    Converts all special letters in a string (áéíóú) to normal letters (aeiou). Of course, I don't think it includes all special letters at the moment but new ones will be added when found.
    Code (JavaScript):
    1. // SPECIAL CHARACTER ESCAPE v1.04
    2. // ******** ******** ********
    3. function funSpecialCharEscape(vString) {
    4.     var x,
    5.         vSpecialChar = "àáāäâăåąçčèéëêěėēęìíïîķñòóöôõōśşùúüûūůý",
    6.         vNormalChar = "aaaaaaaacceeeeeeeeiiiiknoooooossuuuuuuv";
    7.     for (x = 0; x < vSpecialChar.length; x++) {
    8.         vString = vString.replace(new RegExp(vSpecialChar.charAt(x), "g"), vNormalChar.charAt(x));
    9.     }
    10.     return String(vString);
    11. }
    ---

    Remove Non-Characters
    This removes characters that do not exist in the vAllowedChar string variable. Handy if you do not want symbols or any of those special letters like áéíóú in your strings. There is a short version that involves RegExp but JSLint doesn't like it due to reason "Insecure '^'." which can be ignored if you have ". and [^...] in /RegExp/: true". It's provided underneath this code if you wanna use it instead.
    Code (JavaScript):
    1. // REMOVE NON-CHARACTERS v1.01
    2. // ******** ******** ********
    3. function funRemoveNonChar(vString) {
    4.     var x, y,
    5.         vAllowedChar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ",
    6.         vOutput= "";
    7.     vString = String(vString);
    8.     for (x = 0; x < vString.length; x++) {
    9.         for (y = 0; y < vAllowedChar.length; y++) {
    10.             if (vString.charAt(x) === vAllowedChar.charAt(y)) {
    11.                 vOutput = vOutput + vAllowedChar.charAt(y);
    12.             }
    13.         }
    14.     }
    15.     return vOutput;
    16. }
    Code (JavaScript):
    1. // REMOVE NON-CHARACTERS
    2. // ******** ******** ********
    3. function funRemoveNonChar(vString) {
    4.     return vString.replace(/[^a-zA-Z0-9 ]/g, "");
    5. }

    ---

    Deep Copy the Value of a JavaScript Object into a Variable
    This allows you to get the value of an object and store into a variable without it being treated as a link to the object, if ever the variable gets modified.
    Code (JavaScript):
    1. // DEEP COPY OBJECT ENTRY
    2. // ******** ******** ********
    3. function funDeepCopyObject(vObject) {
    4.     return JSON.parse(JSON.stringify(vObject));
    5. }
    ---

    Convert Seconds to YouTube Time Format
    This converts the number of overall seconds into the same time format that is used on YouTube. (Examples: 1 to 0:01, 61 to 1:01, 3601 to 1:00:01.) As you can see, the hour is auto added when needed.
    Code (JavaScript):
    1. // SECOND TO YOUTUBE DURATION
    2. // ******** ******** ********
    3. function funSecondToYouTubeDuration(vNumber) {
    4.     vNumber = parseInt(vNumber, 10);
    5.     var vSecs, vMins, vHours, vResult;
    6.     vSecs = vNumber % 60;
    7.     vMins = Math.floor(vNumber / 60) % 60;
    8.     vHours = Math.floor(vNumber / 3600);
    9.     if (vSecs > 9) {
    10.         vResult = ":" +  vSecs;
    11.     } else {
    12.         vResult = ":0" + vSecs;
    13.     }
    14.     if (vHours > 0) {
    15.         if (vMins > 9) {
    16.             vResult = vHours + ":" + vMins + vResult;
    17.         } else {
    18.             vResult = vHours + ":0" + vMins + vResult;
    19.         }
    20.     } else {
    21.         vResult = vMins + vResult;
    22.     }
    23.     return String(vResult);
    24. }
    ---

    Random Number Generator
    Generates a random number between the minimum and maximum range. Works both negative and positive ranges.
    Code (JavaScript):
    1. // RANDOM NUMBER GENERATOR
    2. // ******** ******** ********
    3. function funRng(vMin, vMax) {
    4.     return Math.floor(Math.random() * (1 + parseInt(vMax, 10) - parseInt(vMin, 10))) + parseInt(vMin, 10);
    5. }
    ---

    HTML Escape
    This is a shortened version of Crystal Moogle's HTML Escape function from her client script. This allows you to show HTML actual text without it being formatted like it seen in a HTML viewer. Original function can be found here.
    Code (JavaScript):
    1. // HTML ESCAPE
    2. // ******** ******** ********
    3. function funHtmlEscape(vString) {
    4.     return String(vString.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;"));
    5. }
    ---

    Random PO Element
    It allows you to return a random Pokemon object type's value from the built-in data in the Pokemon Online client. Meaning new moves added on client updates are auto added so you don't have to write the list. The value types are listed in the comments at the top of the code. Note the open and closing brackets aren't needed at end of the objects. The original versoin can be found here.
    Code (JavaScript):
    1. // RANDOM PO ELEMENT
    2. // ******** ******** ********
    3. // Tested objects: sys.pokemon, sys.move, sys.item, sys.nature, sys.ability, sys.gender
    4. function toolRandomPoElement(obj) {
    5.     var x = 0, elementArray = [];
    6.     while ((["Missingno", undefined, ""].indexOf(obj(x)) === -1) || (x < 1)) {
    7.         elementArray[x] = obj(x);
    8.         x++;
    9.     }
    10.     return elementArray[Math.floor(Math.random() * elementArray.length)];
    11. }
    12.  
    If you wanna input test an object by command data. Here's the debug version that eval string input I used when testing. Be careful, I think eval can cause security issues if not used correctly:
    Code (JavaScript):
    1. // RANDOM PO ELEMENT
    2. // Tested objects: sys.pokemon, sys.move, sys.item, sys.nature, sys.ability, sys.gender
    3. function funRandomPoElement(vObject) {
    4.     var x, vElementArray = [], vZero = 0;
    5.     if (typeof vObject === "string") {
    6.         vObject = eval(vObject);
    7.     }
    8.     for (x = 0; x < 1000; x++) {
    9.         if ((["Missingno", undefined, ""].indexOf(vObject(x)) !== -1) && (x > 1)) {
    10.             break;
    11.         }
    12.         vElementArray[x] = vObject(x);
    13.     }
    14.     return vElementArray[Math.floor((Math.random() * vElementArray.length) + vZero)];
    15. }

    ---

    Time String To Value
    An easy to use function that prints the actual hours, minutes and seconds. By changing hh, mm and ss string tags into double digit string format numbers. Works on first occurrence of each tag only. You can place the values either way round. Example: "hh:mm abc ss ss" could print "01:00 abc 59 ss". So as you can see, you can display the digits anyway you like regardless of string content.
    Code (JavaScript):
    1. // TIME STRING TO VALUE
    2. // ******** ******** ********
    3. function funTimeStringToValue(vString) {
    4.     var vDate = new Date(), vHour = vDate.getHours(), vMinute = vDate.getMinutes(), vSecond = vDate.getSeconds();
    5.     if (vHour < 10) {
    6.         vHour = String("0" + vHour);
    7.     } else {
    8.         vHour = String(vHour);
    9.     }
    10.     if (vMinute < 10) {
    11.         vMinute  = String("0" + vMinute);
    12.     } else {
    13.         vMinute = String(vMinute);
    14.     }
    15.     if (vSecond < 10) {
    16.         vSecond  = String("0" + vSecond);
    17.     } else {
    18.         vSecond = String(vSecond);
    19.     }
    20.     return vString.replace(/hh/i, vHour).replace(/mm/i, vMinute).replace(/ss/i, vSecond);
    21. }
    ---

    Po Command Time Convert
    This function converts the same time input values, that you use for Pokemon Online's channel mutes and bans, to their actual text output. Examples: "59m" returns "59 minutes" and "61m" returns "1 hour, 1 minute".

    This code was extracted and partly rewritten from the actual Pokemon Online's source code for their server scripts. They can be found here:
    https://github.com/po-devs/po-server-goodies/blob/master/scripts/utilities.js#L159
    https://github.com/po-devs/po-server-goodies/blob/master/scripts/utilities.js#L175
    Code (JavaScript):
    1. // PO COMMAND TIME CONVERT
    2. // ******** ******** ********
    3. function funPoCommandTimeConvert(vInput) {
    4.     if (vInput === undefined) {
    5.         return "1 day";
    6.     }
    7.     try {
    8.         // GET SECONDS
    9.         var vParts = vInput.split(" ");
    10.         var vSeconds = 0;
    11.         for (var x = 0; x < vParts.length; x++) {
    12.             var vCountType = (vParts[x][vParts[x].length - 1]).toLowerCase();
    13.             var vSecondsMultiply = 60;
    14.             if (vCountType == "s") { vSecondsMultiply = 1; }
    15.             else if (vCountType == "m") { vSecondsMultiply = 60; }
    16.             else if (vCountType == "h") { vSecondsMultiply = 60*60; }
    17.             else if (vCountType == "d") { vSecondsMultiply = 24*60*60; }
    18.             else if (vCountType == "w") { vSecondsMultiply = 7*24*60*60; }
    19.             vSeconds = vSeconds + vSecondsMultiply * parseInt(vParts[x], 10);
    20.         }
    21.         // GET TIME STRING
    22.         var vSplit = [];
    23.         var vActualNumber;
    24.         var vDateType = [[7*24*60*60, "week"], [24*60*60, "day"], [60*60, "hour"], [60, "minute"], [1, "second"]];
    25.         for (var vJunctionArrayNum = 0; vJunctionArrayNum < 5; ++vJunctionArrayNum) {
    26.             vActualNumber = parseInt(vSeconds / vDateType[vJunctionArrayNum][0], 10);
    27.             if (vActualNumber > 0) {
    28.                 vSplit.push((vActualNumber + " " + vDateType[vJunctionArrayNum][1] + (vActualNumber > 1 ? "s" : "")));
    29.                 vSeconds = vSeconds - vActualNumber * vDateType[vJunctionArrayNum][0];
    30.                 if (vSplit.length >= 2) {
    31.                     break;
    32.                 }
    33.             }
    34.         }
    35.         return vSplit.join(", ");
    36.     } catch (e) {
    37.         return "1 day";
    38.     }
    39. }
    ~ Questions & Answers ~
    Q: What is a function and what is it used for?
    A: Basically, a function, is a block of code that can be used multiple times without having to write a large amount of repetitive code when it can be re-used as a function. It simply receives information, processes it and sends it back modified. Like using an orange fruit on a juicer and you get orange juice in return. Saves you having to buy 50 juicers when you can re-use the first one.

    Q: I'm getting an error on JSLint saying: "Move 'var' declarations to the top of the function." What shall I do?
    A: This is common for me when I had var set in a for loop. (Example: for (var x = 0;...)) The code does indeed work but JSLint frowns upon it. So you have to declare var x; just above the for loop. Just to note: JSLint stops verifying the rest of the script from this error. Also there's no directive I'm aware of to prevent the error.

    Q: Why do you prefix all the functions with "fun" and variables with "v"?
    A: It's just a error proof coding method I use. One time I had a problem coding and it was all because the variable was actually a built-in function without me knowing. Never know when new built-in functions are added and prevents having to change them in future. Also for functions, it makes it easily to select a function in Notepad++ without needing to scroll for absolute name when suggested list shows all the "fun" entries at once.

    ~ Contributing ~
    Of course. If you anyone wants to contribute. It's recommended to use JSLint site, a tool to help verify clean and error free code. There is also JSHint site but not as powerful. I personally use pointy brackets differently but I've posted my functions here the standard way.

    The following JSLint Directive, from the JSLint site, I've set so far are:
    • ++ and --: true
      This is the exact same as using "x++" instead of "x = x + 1;", also "x--" instead of "x = x - 1;", but it is a shortened way of doing it. So I've allowed this since it's often used in for loops.
    • missing 'use strict' pragma: true
      At the moment. I've not used this and I've not seen it in any PO scripts at the moment so I've allowed it to be ignored.
    Copy and paste this at the top of the script to allow JSLint to use those directive when it verifies the code without needing to manually set them.
    Code (JavaScript):
    1. /*jslint plusplus: true, sloppy: true */
    When contributing please make sure it's a function that anyone can use for their script. It be pointless posting something here and others can't use it. Try focus the code being fast and short to run same time. Finally give an explanation on what it does and what it can be used for.
     
    Last edited: Jun 26, 2015
    Strudels likes this.