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): // Do not use this example. // It's just here for showing were global and internal functions are placed. // DEFINE GLOBAL VARIABLES HERE // PREPARE GLOBAL FUNCTIONS HERE function funGlobalExample(vValue) { // CODE HERE return vValue; } var objPoScript; objPoScript = ({ beforeChannelMessage: function (message, channel, html) { // PREPARE INTERNAL FUNCTIONS HERE function funInternalExample(vValue) { // CODE HERE return vValue; } } }); Here's how to use one: Code (JavaScript): var vInput = "áéíóú"; var vNewValue = funSpecialCharEscape(vInput); print(vNewValue); // 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): // SPECIAL CHARACTER ESCAPE v1.04 // ******** ******** ******** function funSpecialCharEscape(vString) { var x, vSpecialChar = "àáāäâăåąçčèéëêěėēęìíïîķñòóöôõōśşùúüûūůý", vNormalChar = "aaaaaaaacceeeeeeeeiiiiknoooooossuuuuuuv"; for (x = 0; x < vSpecialChar.length; x++) { vString = vString.replace(new RegExp(vSpecialChar.charAt(x), "g"), vNormalChar.charAt(x)); } return String(vString); } --- 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): // REMOVE NON-CHARACTERS v1.01 // ******** ******** ******** function funRemoveNonChar(vString) { var x, y, vAllowedChar = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ", vOutput= ""; vString = String(vString); for (x = 0; x < vString.length; x++) { for (y = 0; y < vAllowedChar.length; y++) { if (vString.charAt(x) === vAllowedChar.charAt(y)) { vOutput = vOutput + vAllowedChar.charAt(y); } } } return vOutput; } Spoiler: RegExp Version of Remove Non-Characters Code (JavaScript): // REMOVE NON-CHARACTERS // ******** ******** ******** function funRemoveNonChar(vString) { return vString.replace(/[^a-zA-Z0-9 ]/g, ""); } --- 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): // DEEP COPY OBJECT ENTRY // ******** ******** ******** function funDeepCopyObject(vObject) { return JSON.parse(JSON.stringify(vObject)); } --- 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): // SECOND TO YOUTUBE DURATION // ******** ******** ******** function funSecondToYouTubeDuration(vNumber) { vNumber = parseInt(vNumber, 10); var vSecs, vMins, vHours, vResult; vSecs = vNumber % 60; vMins = Math.floor(vNumber / 60) % 60; vHours = Math.floor(vNumber / 3600); if (vSecs > 9) { vResult = ":" + vSecs; } else { vResult = ":0" + vSecs; } if (vHours > 0) { if (vMins > 9) { vResult = vHours + ":" + vMins + vResult; } else { vResult = vHours + ":0" + vMins + vResult; } } else { vResult = vMins + vResult; } return String(vResult); } --- Random Number Generator Generates a random number between the minimum and maximum range. Works both negative and positive ranges. Code (JavaScript): // RANDOM NUMBER GENERATOR // ******** ******** ******** function funRng(vMin, vMax) { return Math.floor(Math.random() * (1 + parseInt(vMax, 10) - parseInt(vMin, 10))) + parseInt(vMin, 10); } --- 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): // HTML ESCAPE // ******** ******** ******** function funHtmlEscape(vString) { return String(vString.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">")); } --- 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): // RANDOM PO ELEMENT // ******** ******** ******** // Tested objects: sys.pokemon, sys.move, sys.item, sys.nature, sys.ability, sys.gender function toolRandomPoElement(obj) { var x = 0, elementArray = []; while ((["Missingno", undefined, ""].indexOf(obj(x)) === -1) || (x < 1)) { elementArray[x] = obj(x); x++; } return elementArray[Math.floor(Math.random() * elementArray.length)]; } 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: Spoiler: Test Version with Eval Code (JavaScript): // RANDOM PO ELEMENT // Tested objects: sys.pokemon, sys.move, sys.item, sys.nature, sys.ability, sys.gender function funRandomPoElement(vObject) { var x, vElementArray = [], vZero = 0; if (typeof vObject === "string") { vObject = eval(vObject); } for (x = 0; x < 1000; x++) { if ((["Missingno", undefined, ""].indexOf(vObject(x)) !== -1) && (x > 1)) { break; } vElementArray[x] = vObject(x); } return vElementArray[Math.floor((Math.random() * vElementArray.length) + vZero)]; } --- 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): // TIME STRING TO VALUE // ******** ******** ******** function funTimeStringToValue(vString) { var vDate = new Date(), vHour = vDate.getHours(), vMinute = vDate.getMinutes(), vSecond = vDate.getSeconds(); if (vHour < 10) { vHour = String("0" + vHour); } else { vHour = String(vHour); } if (vMinute < 10) { vMinute = String("0" + vMinute); } else { vMinute = String(vMinute); } if (vSecond < 10) { vSecond = String("0" + vSecond); } else { vSecond = String(vSecond); } return vString.replace(/hh/i, vHour).replace(/mm/i, vMinute).replace(/ss/i, vSecond); } --- 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): // PO COMMAND TIME CONVERT // ******** ******** ******** function funPoCommandTimeConvert(vInput) { if (vInput === undefined) { return "1 day"; } try { // GET SECONDS var vParts = vInput.split(" "); var vSeconds = 0; for (var x = 0; x < vParts.length; x++) { var vCountType = (vParts[x][vParts[x].length - 1]).toLowerCase(); var vSecondsMultiply = 60; if (vCountType == "s") { vSecondsMultiply = 1; } else if (vCountType == "m") { vSecondsMultiply = 60; } else if (vCountType == "h") { vSecondsMultiply = 60*60; } else if (vCountType == "d") { vSecondsMultiply = 24*60*60; } else if (vCountType == "w") { vSecondsMultiply = 7*24*60*60; } vSeconds = vSeconds + vSecondsMultiply * parseInt(vParts[x], 10); } // GET TIME STRING var vSplit = []; var vActualNumber; var vDateType = [[7*24*60*60, "week"], [24*60*60, "day"], [60*60, "hour"], [60, "minute"], [1, "second"]]; for (var vJunctionArrayNum = 0; vJunctionArrayNum < 5; ++vJunctionArrayNum) { vActualNumber = parseInt(vSeconds / vDateType[vJunctionArrayNum][0], 10); if (vActualNumber > 0) { vSplit.push((vActualNumber + " " + vDateType[vJunctionArrayNum][1] + (vActualNumber > 1 ? "s" : ""))); vSeconds = vSeconds - vActualNumber * vDateType[vJunctionArrayNum][0]; if (vSplit.length >= 2) { break; } } } return vSplit.join(", "); } catch (e) { return "1 day"; } } ~ 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): /*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.