Source code
// ==UserScript==
// @name Neopets - Coconut Shy Auto-Player
// @author none
// @description Automatically plays 20 rounds Coconut Shy.
// @grant GM.xmlHttpRequest
// @grant GM_xmlhttpRequest
// @match https://www.neopets.com/halloween/coconutshy.phtml
// @namespace you
// @version 1.0.0
// @downloadURL https://www.scriptneo.com/scripts/download.php?id=31
// @updateURL https://www.scriptneo.com/scripts/download.php?id=31
// ==/UserScript==
(function() {
function numberWithCommas(number) {
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
function getItem(key, defaultValue) {
var value = localStorage.getItem(key);
if (value != null) {
if (typeof value === "string") {
try {
return JSON.parse(value);
} catch (error) {}
}
return value;
}
return defaultValue;
}
function parseUrl(url) {
var parsedUrl = {
href: "",
name: "",
parameters: {}
};
if (url) {
var queryString;
if (typeof url === "string") {
queryString = url;
parsedUrl.href = url;
} else {
if (url.pathname) parsedUrl.name = url.pathname.match(/\/(.*)$/)[1].toLowerCase();
queryString = url.search;
parsedUrl.href = url.href;
}
for (var match, regex = /([^\&\=\?]+)\=([^\&]*)/g; match = regex.exec(queryString);) {
parsedUrl.parameters[match[1]] = match[2];
}
}
return parsedUrl;
}
function setItem(key, value) {
if (value == null || value === undefined) {
localStorage.removeItem(key);
} else {
if (typeof value !== "number" && typeof value !== "string") {
value = JSON.stringify(value);
}
localStorage.setItem(key, value);
}
}
if (typeof $ === "undefined") $ = unsafeWindow.$;
if (typeof GM_xmlhttpRequest === "undefined") GM_xmlhttpRequest = GM.xmlHttpRequest;
var swfObjectMatch = ($(".content script:contains(SWFObject):first").html() || "").match(/swfobject\(['"]([^\?]*)/i);
$(".content img[src*='/halloween/coconutshy']").after('<table cellpadding="0" cellspacing="0" id="coconutShy" style="margin: 0 auto; text-align: center;"><tr><td style="width: 500px;"><br><b>-Coconut Shy Auto-Player-</b></td></tr><tr><td><br><br><table cellpadding="0" cellspacing="0" style="margin: 0 auto;"><tr><td><b>Auto-start:</b></td><td style="padding-left: 16px;"><input id="coconutShyAutoStart" style="margin: 0;" type="checkbox"></td></tr></table><br></td></tr><tr><td><br><input id="coconutShyStartStop" type="button"><br><br><br></td></tr><tr><td><h2 style="margin-bottom: 32px;"></h2><b>-Prizes-</b><br><br><div style="height: 500px; overflow-x: auto; width: 500px;"><table style="margin: 0 auto; text-align: center;"></table></div><br><br></td></tr></table>').nextAll(":not(center, " + (swfObjectMatch ? "" : "p, ") + "table)").remove();
var autoStart = getItem("coconutShy.autoStart") || false;
var coconutShyAutoStartCheckbox = $("#coconutShyAutoStart").prop("checked", autoStart);
var throwCountDisplay = $("#coconutShy > tbody > tr:nth-child(2)");
var isAutoPlaying = autoStart;
var prizeDisplayTable = $("#coconutShy > tbody > tr:nth-child(4) > td > div > table");
var prizeDisplayContainer = $("#coconutShy > tbody > tr:nth-child(4)").hide();
var startStopButton = $("#coconutShyStartStop");
var statusDisplay = $("#coconutShy > tbody > tr:nth-child(4) > td > h2");
var throwTimeout;
function playCoconutShy() {
var throwNumber = 0;
var delayMin = 1000;
var delayMax = 3000;
function handleThrow(response) {
if (response && response.responseText) {
var parsedResponse = parseUrl(response.responseText).parameters;
throwNumber++;
if (parsedResponse.success = parseInt(parsedResponse.success)) {
var displayContent = [numberWithCommas(parseInt(parsedResponse.points.replace(/\,/g, ""))) + " NP"];
if (parsedResponse.success == 4) {
function fetchPrizeInfo(response) {
if (response && response.responseText) {
var prizeMatch = response.responseText.match(/<br[^>]*>\s*<b[^>]*>\s*(.*?)\s*<\/b>/i);
if (prizeMatch) displayContent.push(prizeMatch[1]);
}
if ((parsedResponse.error || "").match(/avatar/i)) displayContent.push("Avatar");
prizeDisplayTable[0].insertRow(0).innerHTML = "<td>" + throwNumber + ". " + displayContent.join(", ") + "</td>";
if (isAutoPlaying) {
statusDisplay.html("Waiting for throw " + (throwNumber + 1) + " of 20...");
throwTimeout = setTimeout(throwCoconut, Math.round(Math.random() * (delayMax - delayMin)) + delayMin);
}
}
GM_xmlhttpRequest({
headers: {
Referer: swfObjectMatch[1]
},
method: "GET",
onabort: fetchPrizeInfo,
onerror: fetchPrizeInfo,
onload: fetchPrizeInfo,
ontimeout: fetchPrizeInfo,
timeout: 10000,
url: location.origin + "/halloween/coconutshy_item.phtml?obj_id=" + parsedResponse.prize_id
});
} else {
prizeDisplayTable[0].insertRow(0).innerHTML = "<td>" + throwNumber + ". " + displayContent.join(", ") + "</td>";
statusDisplay.html("Waiting for throw " + (throwNumber + 1) + " of 20...");
throwTimeout = setTimeout(throwCoconut, Math.round(Math.random() * (delayMax - delayMin)) + delayMin);
}
} else {
handleThrow(); // Retry
}
} else {
statusDisplay.html("Error throwing! Waiting for throw " + (throwNumber + 1) + " of 20...");
throwTimeout = setTimeout(throwCoconut, Math.round(Math.random() * (delayMax - delayMin)) + delayMin);
}
}
function throwCoconut() {
GM_xmlhttpRequest({
headers: {
Referer: swfObjectMatch[1]
},
method: "GET",
onabort: handleThrow,
onerror: handleThrow,
onload: handleThrow,
ontimeout: handleThrow,
timeout: 10000,
url: location.origin + "/halloween/process_cocoshy.phtml?coconut=3&r=" + Math.round(Math.random() * 9999999)
});
statusDisplay.html("Throwing " + (throwNumber + 1) + " of 20");
}
statusDisplay.html("Initializing...");
throwCoconut();
}
function stopPlaying() {
isAutoPlaying = false;
if (throwTimeout) {
clearTimeout(throwTimeout);
throwTimeout = null;
}
throwCountDisplay.show();
startStopButton.val("Start");
statusDisplay.hide().html("");
}
if (!swfObjectMatch) startStopButton.next("br").remove();
document.getElementById(coconutShyAutoStartCheckbox.attr("id")).addEventListener("change", function() {
setItem("coconutShy.autoStart", (autoStart = coconutShyAutoStartCheckbox.prop("checked")) || null);
});
document.getElementById(startStopButton.attr("id")).addEventListener("click", function() {
if ((isAutoPlaying = !isAutoPlaying) && swfObjectMatch) {
throwCountDisplay.hide();
prizeDisplayTable.html("");
prizeDisplayContainer.show();
startStopButton.val("Stop");
statusDisplay.show();
playCoconutShy();
} else {
stopPlaying();
}
});
if (isAutoPlaying && swfObjectMatch) {
throwCountDisplay.hide();
prizeDisplayContainer.show();
startStopButton.val("Stop");
playCoconutShy();
} else {
startStopButton.val("Start");
}
})();