Guest User

kf2autochat.js

a guest
Jun 7th, 2017
170
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. // ==UserScript==
  2. // @name        KF2 Chat Script
  3. // @namespace   https://github.com/wookiefriseur/KF2AutoAnnouncer
  4. // @description KF2 webinterface chat Automation
  5. // @include     */ServerAdmin/current/chat*
  6. // @match       */ServerAdmin/current/chat*
  7. // @version     0.9d
  8. // @grant       none
  9. // ==/UserScript==
  10.  
  11. /*
  12.    Right now all variables have to be changed here in the source code because I couldn't come up
  13.    with an easy and user friendly way to save settings in the Tampermonkey sandbox.
  14.    Variable changes on the page have an effect and changing textarea changes the message, but
  15.    none of the settings are being saved in between browser refreshes. The browser doesn't use refresh
  16.    to post (and not implemented: read) messages but XMLHTTPRequests instead. Though when you submit
  17.    a message by hand from say textfield it will transmit a form and reload the page, resetting to default.
  18. */
  19.  
  20. // Vars to make your welcome message easier to edit, server_ip and server_port are used for url-comparison check
  21. var server_name = 'KF2 SERVER';
  22. var server_ip = 'LOCALHOST';
  23. var server_port = 7777;
  24. var chatbot_user = '[ChatBot]'; // enter AutoChat nickname name so its messages can be ignored by the script (case sensitive)
  25. // Default message. Can be changed in textarea on page, but is not saved because I'm dumb. Change it here to save it.
  26. var auto_message = '[Welcome on '+server_name+'], enter !help for a cmd list; Server Info on: gametracker.com/server_info/'+server_ip+':'+server_port+'/';
  27.  
  28.  
  29. // Vars that are used during init or some function calls, careful with changes (don't set times too low or delete vars)
  30. var auto_interval = 600; // Repeat message every x seconds
  31. var jan_delay = 3; // Cooldown inbetween the messages, if multiple entered (I had to use freeze/sleep to make it work, makes UI unresponsive while processing)
  32. var autosend_state = 'checked=true'; // Automessage, default on (in case the browser gets reloaded while admin is afk)
  33. var autorespond_state = 'checked=true'; // Autoresponder, default on
  34. // URL string that has to be matched for the script to activate changes. That's for preventing it from being active on incompatible subdirectories.
  35. var target_url = 'http://'+server_ip+':'+server_port+'/ServerAdmin/current/chat#chatlog';
  36.  
  37. // Chat response messages that can be called, when commands are detected, like !help
  38. // List public commands with and without arguments.. can be just put into an array in the future
  39. var mapvote_time = 60;
  40. var cmd_help = [
  41.     "[Cmds are case sensitive, try again if it doesn't work]",
  42.     "!time, !status, !dice <sides>, !dostuff <target>",
  43.     "SC, FP, !iz, !ip, !slap <target>"];
  44. // List of admin cmds, a check needs to be implemented to test if the user is logged in as admin or the name is in the admin list
  45. var cmd_adm_help = ["Admin Commands(!admin):", "!switchmap, !setmap KF-Map, !restartmap", "!setdiff,  !setmessage, !kick !setpw"];
  46. var cmd_mapchange = "Majority of currently " +getGameDetails()[1]+" Players must type !mapchange to switch to a random map"; // mapchange info
  47. var cmd_mapvote = ["Mapvoting initiated. Vote ends after "+mapvote_time+" seconds.", "Example: !mapvote kf-burningparis to vote"];
  48. var cmd_insult_player = [
  49.     "Nob off, you tosspot!",
  50.     "My granny shoots better than you!",
  51.     "Smeghead!",
  52.     "At least look like you're trying.",
  53.     "God almighty, you're a waste of space!",
  54.     "Wayne Rooney's smarter than you!",
  55.     "Don't be sodding stupid!",
  56.     "What a plonker!",
  57.     "You daft wanker!",
  58.     "Oh, get on with it! Plod!",
  59.     "Who do you think you are? Bleedin' action man?",
  60.     "I've met smarter donkeys than you lot!",
  61.     "Please! Join their side!",
  62.     "You muppet!",
  63.     "Bloody frog would be more use than you!"];
  64. var cmd_insult_zed = [
  65.     "Ha, call yourself a bloody zombie?",
  66.     "Wankers!",
  67.     "Reminds me of a bunch of pikies!",
  68.     "You're pathetic, like a bunch of bloody Millwall fans!",
  69.     "You're all fur-coat, no knickers, bitches!",
  70.     "Soft as shite!",
  71.     "It's like shooting fish in a barrel!",
  72.     "Bloody hell! You stink!",
  73.     "Try harder, ya smelly bastards!",
  74.     "At least try, you mutant bastards!",
  75.     "Oooh! Thats just nasty!",
  76.     "You're too soft to be a zombie!",
  77.     "I could kill you losers all night long!",
  78.     "Come on! Ya' want some, ya' poncies?!",
  79.     "It's like Croydon on a Friday night!",
  80.     "Dickless zombie scum!",
  81.     "You couldn't scare my mum!",
  82.     "Die, you useless clot sucker!",
  83.     "I've seen scarier schoolgirls than you lot!",
  84.     "I've seen scarier five-year-olds! Ha ha ha ha!"];
  85. var cmd_sc_spotted = [
  86.     "Mind where you're waving that, pal!",
  87.     "Please tell me that's not a chainsaw he's carrying.",
  88.     "A chainsaw? You have got to be kidding me, pal.",
  89.     "God, chainsaw massacre time!"];
  90. var cmd_fp_spotted = [
  91.     "Geez, that's a big one.",
  92.     "Oh, crap. Don't let that big bugger near me!",
  93.     "Bloody hell, what's he got on his arms?",
  94.     "God, he's all lit up!"];
  95. var cmd_objects = [
  96.     "a chair", "a fish", "a dildo", "a Clot leg", "an old shoe", "used toilet paper",
  97.     "a pan", "a bloat head", "a rubber chicken", "stinking socks", "a magic wand",
  98.     "a rubber ducky", "a tooth brush", "clean underwear", "drum sticks", "chicken wings",
  99.     "a Zweihander", "a Clot", "a Slasher", "a Cyst", "a Siren", "a Crawler", "a Gorefast",
  100.     "a Stalker", "a Husk", "a Scrake", "a Bloat", "a Fleshpound", "Hans Volter", "a twig",
  101.     "the Trader Pod", "Constable Briar", "Lt. Masterson", "Rev. Alberts", "Ana", "Donovan",
  102.     "Tanaka", "Mr Foster", "Dj Scully", "Tom", "Anton", "the Zerker", "the Commando",
  103.     "the Medic", "the Support", "the Firebug", "the Demo", "the Gunslinger","the Sharpshooter",
  104.     "the Martial Artist", "the S.W.A.T.", "a Krovel", "a Pulverizer", "a Nailgun",
  105.     "an Eviscerator", "the holy hand grenade", "an AR", "a scalpel", "a pistol", "an SMG", "a shotgun",
  106.     "a Boomstick", "a flamethrower", "a Katana", "a door", "some cake", "crayons", "a club",
  107.     "a rotten egg", "a police car", "a volcano", "a kitten", "a rocket", "an RPG", "butter",
  108.     "an elbow", "a cannon", "the Dude", "pubic hair", "a giant cactus", "a poisonous frog",
  109.     "an evil donkey", "a CASIO fx-991ES calculator", "an office desk", "a vacuum cleaner salesman",
  110.     "a Joint", "a confused snake", "a pool cue", "a rock", "a turkey", "a mean cat", "a dead parrot",
  111.     "a nice boat", "a HORZINE employee", "the Patriarch", "furniture", "an owl", "Dosh", "loadsamoney",
  112.     "Harry Enfield", "soap on a roap", "a beautiful Bloat", "a feisty Fleshpound", "a seductive Stalker",
  113.     "a cocky clot", "a sad Scrake", "a happy Husk", "an albino Crawler", "a silent Siren", "a Cowboy hat",
  114.     "the Spanish Inquisition", "a pair of pants", "a KEVLAR vest"
  115. ];
  116. var cmd_actions = [
  117.     "hugs", "pokes", "kicks", "hits", "nods at", "looks at", "laughs at", "waves at", "welds",
  118.     "eats", "shouts at", "runs towards", "runs away from", "jumps on", "escapes from", "unwelds",
  119.     "chases", "uses", "hangs", "yells at", "bangs", "scratches", "talks to", "whispers to",
  120.     "visits", "questions", "accepts", "admires", "agrees with", "analyzes", "apologizes to",
  121.     "applauds", "appreciates", "asks", "avoids", "dresses", "bans", "bathes", "washes", "battles",
  122.     "fights", "becomes", "turns into", "cleans", "breaks", "blows", "brushes", "burns", "shoots",
  123.     "wakes", "calls", "cares about", "carries", "catches", "charges at", "challenges", "cheers at",
  124.     "checks out", "chokes on", "chews on", "threatens", "licks", "rages", "ignores", "cowers in fear from",
  125.     "kites", "unrages", "annoys", "combs the hair of", "damages", "destroys", "blows up", "drags",
  126.     "drowns", "points at", "knows", "does", "disarms", "discovers", "disagrees with", "cuts", "wins",
  127.     "examines", "expects", "flees from", "buys", "faces", "forces", "grins at", "hides", "hides from",
  128.     "greets", "hammers", "holds", "misses", "hunts", "hypnotizes", "hears", "harasses", "imagines", "injures",
  129.     "wets", "interrupts", "invites", "jails", "joins", "jokes about", "juggles", "kills", "kisses", "knocks out",
  130.     "lies to", "locks", "owns", "measures", "marries", "moans at", "motivates", "encourages", "mourns", "mugs",
  131.     "robs", "murders", "nails", "needs", "wants", "obeys", "offends", "opens", "orders", "paints", "smokes",
  132.     "sits on", "persuades", "peels", "photographs", "takes a picture of", "peeps at", "stalks", "pinches",
  133.     "pleases", "pleasures", "plays with", "praises", "prefers", "protects", "punishes", "punches", "purchases",
  134.     "pushes", "irradiates", "remembers", "repairs", "touches", "rubs", "rushes", "sleeps on", "screws", "sells",
  135.     "scares", "saves", "scorches", "sees", "shaves", "sings about", "slays", "smiles at", "sneaks towards",
  136.     "sneaks away from", "hides behind", "spots", "stares at", "stimulates", "strikes", "sucks", "swings at",
  137.     "talks to", "teases", "tames", "targets", "taps", "tastes", "tempts", "terrifies", "thanks", "tickles",
  138.     "tips", "trades with", "transforms into", "turns into", "tricks", "teleports into", "tries", "sniffs", "spares",
  139.     "soothes", "squeezes", "brushes", "suspects", "is suspicious of", "understands", "undresses", "upgrades", "upsets",
  140.     "visits", "vexes", "waits for", "warns", "watches", "wears", "wastes", "zooms in on", "whistles at", "flirts with",
  141.     "wonders about", "works with", "writes a letter to", "does", "draws"    
  142. ];
  143.  
  144. var cmd_adj = [
  145.     "angrily", "carefully", "eagerly", "fast", "patiently", "quickly", "quietly", "downstairs", "upstairs", "dearly",
  146.     "accidentally", "fataly", "intentionally", "purposely", "sometimes", "always", "... not!", "often", "rarely",
  147.     "absentmindedly", "adventurously", "anxiously", "awkwardly", "badly", "bashfully", "beautifully", "blindly",
  148.     "boldly", "busily", "bravely", "cheerfully", "curiously", "courageously", "cautiously", "defiantly", "deeply",
  149.     "deliberately", "delightfully", "doubtfully", "elegantly", "easily", "excitedly", "enthusiastically", "energetically",
  150.     "furiously", "gently", "innocently", "intensely", "instantly", "joyfully", "jovially", "keenly", "knowingly",
  151.     "lovingly", "lazily", "mortally", "madly", "merrily", "monthly", "daily", "weekly", "majestically", "nervously",
  152.     "overconfidently", "optimistically", "painfully", "politely", "rapidly", "rudely", "readily", "reluctantly", "inappropriately",
  153.     "repeatedly", "sadly", "scarcely", "scarily", "sedately", "selfishly", "seriously", "sheepishly", "silently", "unseemingly",
  154.     "tenderly", "terribly", "thoughtfully", "tightly", "triumphantly", "slowly", "sleepily", "stealthily", "sweetly",
  155.     "unexpectedly", "unnecessarily", "upliftingly", "upside-down", "uselessly", "valiantly", "viciously", "violently",
  156.     "victoriously", "voluntarily", "warmly", "weakly", "wildly", "worriedly", "wonderfully", "yawningly", "yearly", "youthfully",
  157.     "like a true hero", "like a boss", "because why not", "once in a while", "like one of your French girls", "in an orderly manner"
  158. ];
  159.  
  160. // and so on...
  161.  
  162. // Images for message status indicators (15x15)
  163. var img_checked = 'data:image/gif;base64,R0lGODlhDwAPAIABADP/MwAAACH5BAEKAAEALAAAAAAPAA8AQAIejI9pAMsKD2voxVsTdZtPDIai1EFftZ1ooypTOSYFADs=';
  164. var img_tocheck = 'data:image/gif;base64,R0lGODlhDwAPALMCAISEhP///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFCgACACwAAAAADwAPAAAEMFDISSsFWIRtBc4bd3kgB0wfqQXk2bpo+lYf3HU1LefXnv0nmadFtM14umDmxhREAAAh+QQFCgACACwIAAEABgAGAAAEDxBIQeUUVgQMdNjeR31fBAAh+QQFCgACACwKAAMABAAJAAAEDxAIOYG9WGgRuu9cJwVCBAAh+QQFCgACACwIAAgABgAGAAAEEFAIQIGsIIRJ9bbeJniSEAEAIfkEBQoAAgAsAwAKAAkABAAABA4QiBAEkJLWm7XlE/VJEQAh+QQFCgACACwBAAgABgAGAAAEDzDIIMSkVgoA7OYVB4ZcBAAh+QQFCgACACwBAAMABAAJAAAEDlAEAYKVNl/Bgf8g0FERACH5BAUKAAIALAEAAQAGAAYAAAQPUMhAJw0CiAv6Dp2XhVIEADs=';
  165. var img_ignored = 'data:image/gif;base64,R0lGODlhDwAPAIABAOMmJv///yH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEKAAEALAAAAAAPAA8AAAIjjI9poMcLXoqSzngrVta2QG0fKH6hxGFe5pQk+rYwVI3zaBQAOw==';
  166. var img_executed = 'data:image/gif;base64,R0lGODlhDwAPAIABAP//AAAAACH5BAEKAAEALAAAAAAPAA8AQAIljI8ZANjH4FsysYsV3m7SakQhqJQlp4nSpH7h03pia7H0dWZIAQA7';
  167.  
  168. /* -------------------|
  169. ----- Functions ------|
  170. ---------------------*/
  171.  
  172. /*
  173. ----- GET, COMPARE STUFF, AND OTHER HELPERS -----
  174. */
  175.  
  176. // Helper to check if a variable is empty or undefined
  177. // Obj => Bool
  178. function isDefined(object) {
  179.     return (typeof object !== 'undefined' && object !== null && object !== '');    
  180. }
  181.  
  182. // Compare two URL Strings that aren't empty, split them at anchor / div marker '#' by default
  183. // String x String => Boolean
  184. // TODO: Replace by jQuery.. or dont
  185. function cmpUrl(haystack, needle) {
  186.     needle = needle.split('#');
  187.     //    if (typeof haystack == 'undefined' || typeof needle == 'undefined' || haystack.includes(needle[0]) === false  || haystack === ''  || needle === '') {
  188.     if ( !isDefined(haystack) || !isDefined(needle[0]) || !(haystack.includes(needle[0])) ) {
  189.         return false;
  190.     } else {
  191.         return true;
  192.     }
  193. }
  194.  
  195. // Help function to construct jQuery element searches
  196. // String x String => Obj
  197. function getNodeObj(type_name, object_name) {
  198.     var obj_array = [];
  199.     if (!isDefined(type_name) || !isDefined(object_name) ) {
  200.         return false;
  201.     } else {
  202.         return $('['+type_name+'="'+object_name+'"]');
  203.     }
  204. }
  205.  
  206.  
  207. // Calls url-compare function to check if the directory is supported by the script
  208. // You can remove the check, but remember to call the html constructors (addAutoChatDiv, shoveOffYouTosser, addInfoDiv)
  209. // In Firefox the alert appears as a popup message even though the site has an interface for it,  remove if it gets too annoying.
  210. // NULL => Proc
  211. function checkUrl() {
  212.     if (cmpUrl(target_url, location.pathname)) {
  213.         addAutoChatDiv();
  214.         setTimeout(shoveOffYouTosser(), 500);
  215.         setTimeout(addInfoDiv(), 500);
  216.         setTimeout(addStatusDiv(), 500);
  217.     } else {
  218.         self.alert("Target subdirectory:\n" + target_url + "\n\nAutoChat will be inactive until you enter the target dir.");
  219.     }
  220. }
  221.  
  222. // Sleep function, in case a timeout is not the right tool
  223. // But don't use it in loops that you want to complete, because the break leaves not just this one but any loop it is executed it
  224. // Int => SLEEP
  225. function breakLoop(seconds){
  226.     biggestnumberintheworld = 999999999;
  227.     var timestamp = new Date().getTime();
  228.     for (i = 0; i <= biggestnumberintheworld; i++) {
  229.         if ((new Date().getTime() - timestamp) > seconds * 1000) {
  230.             break;
  231.         }
  232.     }
  233. }
  234.  
  235. // Help function to recursively add delay to each to be looped element
  236. // Int x Int x Int x Proc => Proc
  237. function waitForIt(index, n_times, delay, cmd) {
  238.     // Break condition
  239.     if (index >= n_times){
  240.         return;
  241.     } else {
  242.         // Execute and increment
  243.         cmd(index);
  244.         index++;
  245.     }
  246.     // Steps taken, next run
  247.     breakLoop(delay);
  248.     waitForIt(index, n_times, delay, cmd);
  249. }
  250.  
  251. // Picks a random key from an array and returns its value
  252. // Array => Witchcraft => String
  253. function getRandomItem(array) {
  254.     if (!isDefined(array) || typeof array !== 'object') {
  255.         return false;
  256.     }
  257.     var ary_size = array.length;
  258.     var ary_index = Math.floor(Math.random()*ary_size);
  259.     var ary_item = array[ary_index];
  260.  
  261.     return array[ary_index];
  262. }
  263.  
  264. // Rolls an n sided dice and returns the result
  265. // Num => Num
  266. function rollDice(sides) {
  267.     (!isDefined(sides) || typeof sides !== 'number' || sides <= 0)?(sides = 6):(false);
  268.     sides = Math.round(sides);
  269.     var output = Math.floor(Math.random()*sides)+1;
  270.     return output;
  271. }
  272.  
  273.  
  274. /*
  275. ----- READ, POST MESSAGES AND EXECUTE COMMANDS -----
  276. */
  277.  
  278.  
  279.  
  280. // Post message to chat console, splits string at semicolon + space and posts it after n seconds
  281. // String => Array => String => AJAX
  282. function postAutoMessage(auto_message) {
  283.     var auto_message_ary = auto_message.split("; ");
  284.     i = 0; // index start
  285.  
  286.     if ($('#autochat_delay').val() >= 0) {
  287.         jan_delay = $('#autochat_delay').val();
  288.     } else {
  289.         jan_delay = 2;
  290.     }
  291.  
  292.     waitForIt(i, auto_message_ary.length, jan_delay, function(i){
  293.         $.ajax({
  294.             type : 'POST',
  295.             url : pageUri + '+data',
  296.             data : {
  297.                 ajax : 1,
  298.                 message : auto_message_ary[i],
  299.                 teamsay : -1},
  300.             success : chatMessage,
  301.             error : ajaxError});
  302.     });
  303. }
  304.  
  305. // Quickpost a message, can be used by autoresponder functions, no delay, no separators
  306. // Str => Proc
  307. function postResponseMessage(message){
  308.     $.ajax({
  309.         type : 'POST',
  310.         url : pageUri + '+data',
  311.         data : {
  312.             ajax : 1,
  313.             message : message,
  314.             teamsay : -1},
  315.         success : chatMessage,
  316.         error : ajaxError});
  317. }
  318.  
  319.  
  320. function refreshGameSummary(){
  321.     $.ajax({
  322.         type: 'POST',
  323.         url: webadminPath + '/current+gamesummary',
  324.         data: {
  325.             ajax: 1},
  326.         success: newGameSummary,
  327.         error: gameSummaryAjaxError});
  328. }
  329.  
  330. // Change map command
  331. // TODO: voting algorithm before non admin users can call on that
  332. function changeMap(map) {
  333.     // would be called from inside parseMessage(input,index)
  334.     // mapchange command in current_change.js
  335. }
  336.  
  337.  
  338. // Read message and output action / answer according to it
  339. // Str x Int => Func
  340. function parseMessage(input, index) {
  341.     setTimeout(getDown('content'),2000);
  342.     var teamcolor = getNodeObj('class','teamcolor')[index].innerHTML;
  343.     var player = getPlayerName(index);
  344.     var datum = new Date();
  345.     var img = img_executed;
  346.     var stats = getWaveStatus();
  347.  
  348.  
  349.     // Asynchronous instruction handling by javascript forces me to do funny shit like this:
  350.     //  if (datum.getMilliseconds() % 2 !== 0) {
  351.     // Maybe get unix timestamp, divide by bigger number and introduce random numbers to ice the cake
  352.     //       console.log("Will be parsed in a few");
  353.     //      getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img_tocheck+'" />';
  354.     //       return false;
  355.     //  }
  356.  
  357.     if ((!isDefined(input) || !$('#autorespond_chckbox')[0].checked) || (teamcolor.includes('base64') && !teamcolor.includes(img_tocheck))) {
  358.         console.log("Already parsed, no message or autoresponder not active");
  359.         return false;
  360.     }
  361.  
  362.     if (input == "!time") {
  363.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  364.         var answer_date = Date().split(' ');
  365.         var answer_time = "[" + chatbot_user+" time] " + answer_date[4] + " " + answer_date[5];
  366.         postResponseMessage(answer_time);
  367.  
  368.     } else if (input == "hey "+chatbot_user) {
  369.         postResponseMessage("leave me alone, " + player);
  370.     } else if (input.split(' ')[0] == "!dice") {
  371.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  372.         (!isDefined(input.split('!dice ')[1]))?(sides = 6):(sides = input.split('!dice ')[1]);
  373.         result = rollDice(parseInt(sides));
  374.         (result == sides && parseInt(sides) >= 6)?(crit = ". Lucky bastard!"):(crit = "");
  375.         postResponseMessage(player + " rolls a " + result + crit);
  376.     } else if (input == "!help") {
  377.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  378.         for (i = 0, max = cmd_help.length; i < max; i++) {
  379.             setTimeout(postResponseMessage(cmd_help[i]),1000*i);
  380.         }
  381.     } else if (input == "!motd") {
  382.         var tmp = ($('#autochat_txtbox').val()).split("; ");
  383.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  384.         for (i = 0, max = tmp.length; i < max; i++) {
  385.             setTimeout(postResponseMessage(tmp[i]),1000*i);
  386.         }
  387.     } else if (input == "!status") {
  388.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  389.         postResponseMessage("[Wave "+stats[0]+"] ["+stats[3] + "/" + stats[4] + " Players] ["+stats[1] + "/" + stats[2] + " Zeds]" );
  390.     } else if (input == "SC") {
  391.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  392.         postResponseMessage(player + ": " + getRandomItem(cmd_sc_spotted));
  393.     } else if (input == "FP") {
  394.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  395.         postResponseMessage(player + ": " + getRandomItem(cmd_fp_spotted));
  396.     } else if (input == "!ip") {
  397.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  398.         postResponseMessage(player + ": " + getRandomItem(cmd_insult_player));
  399.     } else if (input == "!iz") {
  400.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  401.         postResponseMessage(player + ": " + getRandomItem(cmd_insult_zed));
  402.     } else if (input.split(' ')[0] == "!slap") {
  403.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  404.         (!isDefined(input.split('!slap ')[1]))?(target = "everybody"):(target = input.split('!slap ')[1]);
  405.         postResponseMessage(player + " slaps " + target + " with " + getRandomItem(cmd_objects));
  406.     } else if (input.split(' ')[0] == "!dostuff") {
  407.         getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  408.         (!isDefined(input.split('!dostuff ')[1]))?(target = getRandomItem(cmd_objects)):(target = input.split('!dostuff ')[1]);
  409.         postResponseMessage(player + " " + getRandomItem(cmd_actions) + " " + target + ", " + getRandomItem(cmd_adj) + ".");
  410.  
  411.     } else {
  412.         console.log("Msg detected, not a command: " + input);
  413.         img = img_checked;
  414.     }
  415.  
  416.     getNodeObj('class', 'teamcolor')[index].innerHTML = '<img src="'+img+'" />';
  417. }
  418.  
  419.  
  420.  
  421. /*
  422. ----- OTHER FUNCTIONS / NOT YET USED OR NO CATEGORY ------
  423. */
  424.  
  425. // List all messages currently visible in the chat log window
  426. // NULL => Array
  427. // ToDo: Timestamps, ids and stuff (only temp timestamps and ids possible without api access)
  428. function getAllMessages() {
  429.     var cm_ary_ind = [];
  430.     var messages_ary = [];
  431.  
  432.     cm_ary_ind[0] = getNodeObj("class", "chatmessage").length - 1;
  433.     cm_ary_ind[1] = getNodeObj("class", "chatmessage")[0].children.length - 1;
  434.     for (var row_i = 0; row_i <= cm_ary_ind[0]; row_i++) {
  435.         messages_ary[row_i] = [];
  436.         for (var col_i = 0; col_i <= cm_ary_ind[1]; col_i++) {
  437.             if (col_i === 0) {
  438.                 // ID as Placeholder
  439.                 messages_ary[row_i][col_i] = 'msg_[' + row_i + col_i + ']';
  440.             } else if (col_i == 1) {
  441.                 // Player Name
  442.                 messages_ary[row_i][col_i] = jackTheStripper(getPlayerName(row_i));
  443.             } else if (col_i == 2) {
  444.                 // Message text
  445.                 messages_ary[row_i][col_i] = jackTheStripper(getPlayerMessage(row_i));
  446.             } else {
  447.                 // Default for who knows what situation
  448.                 messages_ary[row_i][col_i] = '---';
  449.             }
  450.         }
  451.     }
  452.     return messages_ary;
  453. }
  454.  
  455.  
  456. // Get user name belonging to chatmessage index
  457. // Int -> String
  458. function getPlayerName(index) {
  459.     return getNodeObj('class', 'chatmessage')[index].children[1].innerHTML;
  460. }
  461.  
  462. // Get message text belonging to chatmessage index
  463. // Int => String
  464. function getPlayerMessage(index) {
  465.     return getNodeObj('class', 'chatmessage')[index].children[2].innerHTML;
  466. }
  467.  
  468. // Get number of players from game status info as [Current, Max]
  469. // NULL => Array(Int,Int)
  470. function getNumPlayers() {
  471.     var inner_html = getNodeObj('class', 'gs_players')[1].innerHTML;
  472.     var output = inner_html.split('/');
  473.     return output;
  474. }
  475.  
  476. // Get wave and number of zeds from game status info as [Current, Max]
  477. // NULL => Array(Int,Int,Int,Int,Int)
  478. function getWaveStatus() {
  479.     var output = [];
  480.     output[0] = ((getNodeObj('class', 'gs_wave')[0].innerHTML).split(' '))[1]; //wave
  481.     tmp_wave = (getNodeObj('class', 'gs_wave')[1].innerHTML).split('/');
  482.     tmp_players = (getNodeObj('class', 'gs_players')[1].innerHTML.split('/'));
  483.     output[1] = tmp_wave[0]; // zeds killed
  484.     output[2] = tmp_wave[1]; // zeds total
  485.     output[3] = tmp_players[0]; // players
  486.     output[4] = tmp_players[1]; //player max (6)
  487.     return output;
  488. }
  489.  
  490. // Alternative approach for getting game details
  491. function getGameDetails() {
  492.     var output = [
  493.         $('#gamesummary-details')[0].getElementsByTagName('dd')[0].innerHTML, // Map
  494.         $('#gamesummary-details')[0].getElementsByTagName('dd')[1].innerHTML,  // x/n players
  495.         $('#gamesummary-details')[0].getElementsByTagName('dd')[2].innerHTML  // x/n zeds
  496.     ];
  497.     return output;
  498. }
  499.  
  500.  
  501. // Strips user chat entries from possible  script breaking characters, if not already filtered by server
  502. // TODO: test Security or replace by jQuery, or just dont
  503. function jackTheStripper(input_str) {
  504.     return input_str.replace(/\\<>\'\"\{\}/g, '');
  505. }
  506.  
  507. /*
  508. ----- LAYOUT FUNCTIONS -----
  509. */
  510.  
  511. // Add controls for auto messages, +work arounds chat display
  512. // NULL => HTML
  513. // TODO: Transform all into node create / transform commands instead of string concatenation
  514. function addAutoChatDiv() {
  515.     var original_div_obj = $('#content');
  516.     var new_div_obj = $('#autochatdiv');
  517.     var autochat_div_top = '<div id="autochatdiv" style="position: absolute; top: 120px; width: 100%;">';
  518.     var autochat_checkbox = '<input id="autochat_chckbox" type="checkbox" onclick="if (!self.checked) { self.checked = true; self.value = \'on\'} else { self.checked = false; self.value = \'off\'};"' + autosend_state +'></input><label for="autochat_chckbox">Auto send messages every &nbsp;</label>';
  519.     var autorespond_checkbox = '<input id="autorespond_chckbox" type="checkbox" onclick="if (!self.checked) { self.checked = true; self.value = \'on\'} else { self.checked = false; self.value = \'off\'};"' + autorespond_state +'></input><label for="autorespond_chckbox">Autoresponder</label>';
  520.     var autochat_interval = '<input id="autochat_interval" type="number" step="30" max="54000" min="10" maxlength="5" style="width: 75px; color: blue;" value="'+auto_interval+'"></input><label for="autochat_interval">&nbsp; sec</label><br />';
  521.     var autochat_delay = 'Delay each msg for <input id="autochat_delay" type="number" max="10" min="0" maxlength="2" style="width: 30px; color: red;" value="'+jan_delay+'"></input><label for="autochat_delay">s (freezes UI+Script)</label>';
  522.     var autochat_txtbox = '<textarea id="autochat_txtbox" style="width: 90%; height: 80px; color: yellow;">'+auto_message+'</textarea>';
  523.     var original_div = original_div_obj[0].innerHTML;
  524.     var autochat_div = autochat_div_top + '<div id="autochat_left" style="width: 50%; position: absolute; left: 1px;">'
  525.     + autochat_checkbox + autochat_interval + autochat_delay+ "<br />" + autorespond_checkbox +'</div>'
  526.     + '<div id="autochat_right" style="width: 50%; position: absolute; left: 325px; top: 0px;">' + autochat_txtbox + '</div></div>';
  527.     var new_div = original_div + autochat_div;
  528.  
  529.     var maxMessages = 300; // I don't think this works, must be changed in webadmin sourcecode
  530.     replaceMe(original_div_obj[0], new_div);
  531.     $('#content')[0].style.height = "65%";
  532.     $('#content')[0].style.overflowY = "scroll";
  533.     //$('#chatlog')[0].style.overflowY = "scroll";
  534. }
  535.  
  536. // Replaces menu with info box
  537. // NULL => HTML
  538. // TODO: Transform all into node create / transform commands instead of string concatenation
  539. function addInfoDiv() {
  540.     var original_div_obj = getNodeObj('id', 'menu', '');
  541.     var currinfo_li = '<li class="no-submenu"><a href="/ServerAdmin/current/info" title="The current game status."><span>Server Info</span></a></li>';
  542.     var currgame_li = '<li class="no-submenu"><a href="/ServerAdmin/current" title="The current game status."><span>Current Game</span></a>';
  543.     var chattab_li = '<li class="no-submenu"><a href="/ServerAdmin/current/chat" title="Chat Tab"><span>Chat Tab</span></a></li>';
  544.     var changemap_li = '<li class="no-submenu"><a href="/ServerAdmin/current/change" title="Change the current map or game type."><span>Change Map</span></a></li>';
  545.     var players_li = '<li class="no-submenu"><a href="/ServerAdmin/current/players" title="Manage the players currently on the server."><span>Players</span></a></li>';
  546.     var logout_li = '<li class="no-submenu"><a href="/ServerAdmin/logout" title="Log out"><span>Log out</span></a></li>';
  547.     var infobox_div = '<h2 id="autochat_infobox">InfoBox</h2><ul class="navigation">'
  548.     +currgame_li
  549.     +currinfo_li
  550.     +chattab_li
  551.     +players_li
  552.     +changemap_li
  553.     +logout_li+'</ul>';
  554.     replaceMe(original_div_obj, infobox_div);
  555. }
  556.  
  557.  
  558. // Tries to arrange divs
  559. // yeah, ok mate
  560. function shoveOffYouTosser() {
  561.     var messages_div_obj = $('#messages');
  562.     var chat_console_h2_obj = $('#content');
  563.     if (! chat_console_h2_obj) {
  564.         alert("Error in " + arguments.callee.toString().match(/function ([^\(]+)/)[1]);
  565.         return false;
  566.     } else {
  567.         chat_console_h2_obj = chat_console_h2_obj[0].getElementsByTagName('h2')[0];
  568.     }
  569.     var footer_obj = $('#footer');
  570.     var autoupd_div_obj = $('#autoupdatechatdiv');
  571.     var autochat_txtbox_obj = $('#autochat_txtbox');
  572.     var chat_div_obj = $('#chat');
  573.  
  574.     // Top space for autochat components
  575.     messages_div_obj[0].style.height = "80px";
  576.     messages_div_obj[0].style.width = "90%";
  577.  
  578.     // Move copyright, chat input and autoupdate checkbox to bottom
  579.     footer_obj[0].style.position = 'absolute';
  580.     footer_obj[0].style.bottom = '5px';
  581.     footer_obj[0].style.width = '70%';
  582.     autoupd_div_obj[0].style.position = 'absolute';
  583.     autoupd_div_obj[0].style.bottom = '40px';
  584.     chat_div_obj[0].style.position = 'absolute';
  585.     chat_div_obj[0].style.bottom = '55px';
  586.  
  587.     // Position Textarea for auto messages
  588.     autochat_txtbox_obj[0].style.position = "absolute";
  589.     autochat_txtbox_obj[0].style.top = "0px";
  590.     //autochat_txtbox_obj.style.width = "250px";
  591.  
  592.     // Delete Chatlog header
  593.     if(chat_console_h2_obj){
  594.         chat_console_h2_obj.parentNode.removeChild(chat_console_h2_obj);
  595.     }
  596.  
  597.     setTimeout(getDown('content'),2000);
  598.  
  599.  
  600. }
  601.  
  602. // Creates status div near Logo that shows status of announcements
  603. // NULL => HTML
  604. function addStatusDiv(iterations){
  605.     var datum = new Date();
  606.     var zeit = datum.getTime() / 1000;
  607.  
  608.     if (!isDefined($('#infobox')[0])) {
  609.         var infotext = document.createElement("p");
  610.         var infoParent = document.getElementById("header");
  611.         infoParent.appendChild(infotext);
  612.         infotext.id = "infobox";
  613.         infotext.style.top = "20px";
  614.         infotext.style.left = "400px";
  615.         infotext.style.position = "absolute";
  616.     } else {
  617.  
  618.         if (! $('#autochat_chckbox')[0].checked || getNumPlayers()[0] == 0) {
  619.             (getNumPlayers()[0] == 0)?(message = "(Pause) No Players detected"):(message = "Auto Announcement Deactivated");
  620.             $('#infobox')[0].innerHTML = "<span style='color: grey;'>"+message+"<br />"
  621.             + "MotD: " + $('#autochat_chckbox')[0].checked + "&nbsp;&nbsp;Autorespond: "+$('#autorespond_chckbox')[0].checked+"<br />Message parts: " + ($('#autochat_txtbox').val()).split('; ').length + "</span>";
  622.  
  623.         } else {
  624.             $('#infobox')[0].innerHTML = "<span style='color: limegreen;'>Next announcement: ~" + ($('#autochat_interval').val() - (iterations % $('#autochat_interval').val()) ).toFixed() + "s @"+$('#autochat_delay').val()+"s Delay<br />"
  625.             + "MotD: " + $('#autochat_chckbox')[0].checked + "&nbsp;&nbsp;Autorespond: "+$('#autorespond_chckbox')[0].checked+"<br />Message parts: " + ($('#autochat_txtbox').val()).split('; ').length + "</span>";
  626.         }
  627.     }
  628.     //    console.log(($('#autochat_interval').val() - (iterations % $('#autochat_interval').val()) ).toFixed() + "s until next announcement");
  629.     //    console.log("Chckboxes: " + $('#autochat_chckbox')[0].checked + $('#autorespond_chckbox')[0].checked);
  630. }
  631.  
  632. // Function to scroll down
  633. function getDown(targetid) {
  634.     getNodeObj('id', targetid)[0].scrollTop = getNodeObj('id',targetid)[0].scrollHeight;
  635. }
  636.  
  637. // Helper for easier use of delays when replacing
  638. function replaceMe(old_obj,new_obj) {
  639.     old_obj.innerHTML = new_obj;
  640.     return new_obj;
  641. }
  642.  
  643. /*
  644. ----- CALLING AND POLLING -----
  645. */
  646.  
  647.  
  648. //waitForKeyElements ('[class="gs_players"]', commentCallbackFunction);
  649. //function commentCallbackFunction () {
  650. //    console.log("Change in player numbers detected");
  651. //}
  652.  
  653. // This function is called every 1000ms, avoid using another interval within this function
  654. // You can use conditions and breakLoop(seconds) inbetween for a sleep phase
  655. // Checkbox "Auto send messages" enables auto announcing, Checkbox "Autoresponder" enables auto answering
  656. var iterations = 0;
  657. function checkTheStuff() {
  658.     iterations++;
  659.  
  660.     addStatusDiv(iterations);
  661.     var datum = new Date();
  662.     var zeit = datum.getTime() / 1000;
  663.  
  664.     var last_message_id = getAllMessages().length -1;
  665.     var last_message = getPlayerMessage(last_message_id);
  666.     var last_teamcolor = getNodeObj('class','teamcolor')[last_message_id].innerHTML;
  667.     var last_player = getPlayerName(last_message_id);
  668.     //    console.log("Chat messages loaded: " + (last_message_id +1));
  669.  
  670.     if ( getNumPlayers()[0] > 0 && (!isDefined(autoMsgSent) || autoMsgSent == "0")  && iterations % $('#autochat_interval').val() === 0 && $('#autochat_chckbox')[0].checked) {
  671.         // breakLoop(7); // 7 sec sleep (freezes UI)
  672.         var autoMsgSent = "1";
  673.         setTimeout(postAutoMessage($('#autochat_txtbox').val()),500);
  674.         setTimeout(getDown('content'),(lat_message_id+1)*jan_delay);
  675.     } else {
  676.         var autoMsgSent = "0";    
  677.     }
  678.  
  679.     if (getNumPlayers()[0] > 0 && Math.round(zeit) % 17 == 0) {
  680.         console.log('Players detected, increased GameSummary refresh rate');
  681.         refreshGameSummary();
  682.     }
  683.  
  684.     var currWave = getWaveStatus()[0];
  685.     var restZeds = getWaveStatus()[2] - getWaveStatus()[1];
  686.     if ( restZeds < 20 && restZeds > 10 && currWave > 3 && !last_teamcolor.includes(img_ignored) && iterations % 10 == 0) {
  687.         postResponseMessage("---ZEDS WILL RAGE SOON---");
  688.         refreshGameSummary();
  689.     }
  690.  
  691.  
  692.  
  693.     // Check for double posts by same person (maybe useful later)
  694.     //    var msg_prev = [getPlayerName(last_message-1),getPlayerMessage(last_message-1)];
  695.     //    var msg_new = [getPlayerName(last_message),getPlayerMessage(last_message)];
  696.     //    console.log("Old msg: " + msg_prev + "\nNew msg: " + msg_new);
  697.     //    if (msg_new != msg_prev) {
  698.     //        var msg_chng = msg_new;
  699.     //    } else {
  700.     //        var msg_chng = [0,0];
  701.     //    }
  702.  
  703.  
  704.     // The following routines could be extended to check the whole message array (or last 5 entries or so) and add status icons
  705.     // to each message parsed / ignored. While that would allow for a check of all messages, it could cause problems
  706.     // when refreshing the page. Some kind of function for an internal todo-Queue would be better but feels unneccessary complicated
  707.     // Right now only the last message is parsed. When too many people chat it just gets ignored.. could be used to troll mapvotes
  708.     // if the troll knows the internal cooldown and keeps spamming to make the others not being parsed.. ..though that could be prevented
  709.     // by either ignoring certain messages or ignoring certain commands.. or reiterating the all_messages array just for voting
  710.     var latest_msg_parsed = "NEGATIVE";
  711.     if (last_teamcolor.includes('base64') && !last_teamcolor.includes(img_tocheck)) {
  712.         latest_msg_parsed = 'AFFIRMATIVE';
  713.     } else if (last_player == chatbot_user || !$('#autorespond_chckbox')[0].checked) {
  714.         latest_msg_parsed = 'ignored';
  715.         getNodeObj('class', 'teamcolor')[last_message_id].innerHTML = '<img src="'+img_ignored+'" />';
  716.  
  717.         // For later use, in case parsing for all messages instead of just last one is active
  718.         //    } else if (last_teamcolor.includes(img_tocheck)) {
  719.         //      
  720.         //        latest_msg_parsed = 'PENDING';
  721.         //    } else {
  722.         //        getNodeObj('class', 'teamcolor')[last_message_id].innerHTML = '<img src="'+img_tocheck+'" />';  
  723.     }
  724.     // console.log("Latest msg parsed? " + latest_msg_parsed);
  725.  
  726.  
  727.     if ( isDefined(last_message) && (!last_teamcolor.includes('base64') || (last_teamcolor.includes('base64') && last_teamcolor.includes(img_tocheck))) && last_player != chatbot_user && $('#autorespond_chckbox')[0].checked) {
  728.         console.log("New msg for testing: " + last_player + ": " + last_message);
  729.         parseMessage(last_message,last_message_id);
  730.         setTimeout(getDown('content'),5000);
  731.     }
  732. }
  733.  
  734.  
  735. /*
  736. ----- ENTRY POINT -----
  737. */
  738.  
  739. // Check and modify current page
  740. checkUrl();
  741. // Call check script once a second
  742. setTimeout(setInterval(checkTheStuff, 1000),5000);
  743.  
  744.  
  745.  
  746. // idea for !mapchange:
  747. // if at least 50% of users type !mapchange, then the bot picks a random mapname from
  748. // <select id="map" name="map"> option-value on /current/change, then send ajax POST header
  749. // with mapchangerequest like:
  750. /*
  751. Request URL:/ServerAdmin/current/change
  752. POST Form Data
  753. gametype:KFGameContent.KFGameInfo_Survival
  754. map:KF-WestLondon2009_Prerelease
  755. mutatorGroupCount:0
  756. urlextra:?difficulty=3
  757. action:change
  758. */
  759. // (voter should get a timestamp and be identified by steamid to prevent wrong results, if the person isn't on the server anymore by the time the vote ends
  760. // the voice should be void. The  vote should be active for 60 sec after first invoking it, and have some kind of cooldown, and so on)
  761. // Same would work with !difficulty HoE (GET request for difficulty=3 and so on should suffice)
  762. // I imagine !mapvote from chat to work like this:
  763. // !mapvote KF-SmurfBrothel, !mapvote KF-Paris, !mapvote KF-Paris => switching to KF-Paris
  764.  
  765.  
  766.  
  767. /*
  768. ----- BORROWED CODE THAT HELPED ME AND MIGHT COME IN HANDY LATER :) -----
  769. */
  770.  
  771.  
  772.  
  773. /*--- waitForKeyElements():  A utility function, for Greasemonkey scripts,
  774.     that detects and handles AJAXed content.
  775.     Usage example:
  776.         waitForKeyElements (
  777.             "div.comments"
  778.             , commentCallbackFunction
  779.         );
  780.         //--- Page-specific function to do what we want when the node is found.
  781.         function commentCallbackFunction (jNode) {
  782.             jNode.text ("This comment changed by waitForKeyElements().");
  783.         }
  784.     IMPORTANT: This function requires your script to have loaded jQuery.
  785.  
  786.  
  787.     SOURCE: https://gist.github.com/BrockA/2625891
  788. */
  789. //function waitForKeyElements (
  790. //selectorTxt,    /* Required: The jQuery selector string that
  791. //                        specifies the desired element(s).
  792. //                    */
  793. // actionFunction, /* Required: The code to run when elements are
  794. //                        found. It is passed a jNode to the matched
  795. //                        element.
  796. //                    */
  797. // bWaitOnce,      /* Optional: If false, will continue to scan for
  798. //                        new elements even after the first match is
  799. //                        found.
  800. //                    */
  801. // iframeSelector  /* Optional: If set, identifies the iframe to
  802. //                        search.
  803. //                    */
  804. //) {
  805. //    var targetNodes, btargetsFound;
  806. //
  807. //    if (typeof iframeSelector == "undefined")
  808. //        targetNodes     = $(selectorTxt);
  809. //    else
  810. //        targetNodes     = $(iframeSelector).contents ()
  811. //        .find (selectorTxt);
  812. //
  813. //    if (targetNodes  &&  targetNodes.length > 0) {
  814. //        btargetsFound   = true;
  815. //        /*--- Found target node(s).  Go through each and act if they
  816. //            are new.
  817. //        */
  818. //        targetNodes.each ( function () {
  819. //            var jThis        = $(this);
  820. //            var alreadyFound = jThis.data ('alreadyFound')  ||  false;
  821. //
  822. //            if (!alreadyFound) {
  823. //                //--- Call the payload function.
  824. //                var cancelFound     = actionFunction (jThis);
  825. //                if (cancelFound)
  826. //                    btargetsFound   = false;
  827. //                else
  828. //                  jThis.data ('alreadyFound', true);
  829. //            }
  830. //        } );
  831. //    }
  832. //    else {
  833. //        btargetsFound   = false;
  834. //    }
  835. //
  836. //    //--- Get the timer-control variable for this selector.
  837. //    var controlObj      = waitForKeyElements.controlObj  ||  {};
  838. //    var controlKey      = selectorTxt.replace (/[^\w]/g, "_");
  839. //    var timeControl     = controlObj [controlKey];
  840. //
  841. //    //--- Now set or clear the timer as appropriate.
  842. //    if (btargetsFound  &&  bWaitOnce  &&  timeControl) {
  843. //        //--- The only condition where we need to clear the timer.
  844. //        clearInterval (timeControl);
  845. //        delete controlObj [controlKey]
  846. //    }
  847. //    else {
  848. //        //--- Set a timer, if needed.
  849. //        if ( ! timeControl) {
  850. //            timeControl = setInterval ( function () {
  851. //                waitForKeyElements (    selectorTxt,
  852. //                                    actionFunction,
  853. //                                    bWaitOnce,
  854. //                                    iframeSelector
  855. //                                   );
  856. //            },
  857. //                                       300
  858. //                                      );
  859. //            controlObj [controlKey] = timeControl;
  860. //        }
  861. //    }
  862. //    waitForKeyElements.controlObj   = controlObj;
  863. //}
  864.  
  865. /* AJAX EVENT LISTENER
  866. Just c/p this onto your page or include it in a .js file or whatever. This will create an object called s_ajaxListener.
  867. Whenever an AJAX GET or POST request is made, s_ajaxListener.callback() is called, and the following properties are available:
  868.  
  869. s_ajaxListener.method : The ajax method used.
  870. This should be either GET or POST.
  871. NOTE: the value may not always be uppercase, it depends on how the specific request was coded.
  872.  
  873. s_ajaxListener.url : The url of the requested script (including query string, if any) (urlencoded).
  874. I have noticed, depending on how the data is sent and from which browser/framework,
  875. for example this value could end up being as " " or "+" or "%20".
  876.  
  877. s_ajaxListener.data : the data sent, if any
  878. ex: foo=bar&a=b (same 'issue' as .url with it being url-encoded)
  879.  
  880. NOTES:
  881. I have tested this in (as of this posted date): Current Safari, Current Chrome, Current FireFox, IE8, IE8 (IE7 Compatible).
  882. It doesn't currently work with IE6 because IE6 uses an ActiveX object, while virtually everything else uses XMLHttpRequest.
  883. Under each of the browsers I tested above, this works with AJAX requests from a generic object, and also from the jquery and prototype frameworks.
  884. I know there are other frameworks out there, but IMO these 2 are the major ones. I might possibly QA MooTools, but other than that, I'm fine with only testing those.
  885.  
  886. SOURCE: http://stackoverflow.com/questions/3596583/javascript-detect-an-ajax-event/3597640#3597640
  887. */
  888. //var s_ajaxListener = new Object();
  889. //s_ajaxListener.tempOpen = XMLHttpRequest.prototype.open;
  890. //s_ajaxListener.tempSend = XMLHttpRequest.prototype.send;
  891. //s_ajaxListener.callback = function () {
  892. // this.method :the ajax method used
  893. // this.url    :the url of the requested script (including query string, if any) (urlencoded)
  894. // this.data   :the data sent, if any ex: foo=bar&x=b (urlencoded)
  895. //};
  896.  
  897. //XMLHttpRequest.prototype.open = function(x,y) {
  898. //    if (!x) x='';
  899. //    if (!y) y='';
  900. //    s_ajaxListener.tempOpen.apply(this, arguments);
  901. //    s_ajaxListener.method = x;  
  902. //    s_ajaxListener.url = y;
  903. //    if (x.toLowerCase() == 'get') {
  904. //        s_ajaxListener.data = y.split('?');
  905. //        s_ajaxListener.data = s_ajaxListener.data[1];
  906. //    }
  907. //};
  908.  
  909. //XMLHttpRequest.prototype.send = function(x,y) {
  910. //    if (!x) x='';
  911. //    if (!y) y='';
  912. //    s_ajaxListener.tempSend.apply(this, arguments);
  913. //    if(s_ajaxListener.method.toLowerCase() == 'post' && !s_ajaxListener.url.includes('gamesummary'))s_ajaxListener.data = x;
  914. //    s_ajaxListener.callback(checkTheStuff());
  915. //};
Add Comment
Please, Sign In to add comment