Posted: Tue Dec 05, 2017 1:47 pm
PuppetMaster Login Script
Edit: Version 1.6. This version is slightly faster. NS can receive 25 requests every 30 seconds. Previous versions left a gap of 1.2 seconds between NS acknowledging a request, and sending the next one. As there is a short delay between sending request, and receiving acknowledgement, 25 requests were taking over 30 seconds. This version keeps an array of timestamps that the requests were received by NS. This allows request 26 to be sent exactly 30 seconds after request 1, request 27 to be sent exactly 30 seconds after request 2 etc.
Edit: Now on version 1.4. This one displays the region your puppet is in, and a count of any unread notices, TGs, RMB posts, and unanswered issues. It also puts your WA nation at the top of the screen (handy if you forgot where you left your WA!), followed by nations in the Rejected Realms (handy to see if your puppets got booted out of a region).
Edit: I've updated the code to version 1.2. This new version can (theoretically) be used for unlimited puppets. Login requests are suitably spaced apart to keep [v] satisfied!
The original version 1.0 was limited to a maximum of 25 puppets, and sent all requests at once. I've kept the original code in a spoiler in case anyone cares from an educational point of view.
What
Use this code to log in to a list of your puppets with the push of one button. Handy to stop them CTEing!
How
On your PC or laptop, open a text editor, like Notepad. Copy the code (below) into the editor.
Put your own email address in the code (place indicated by all the asterisks).
Put your own Nation names and passwords in the code (place indicated by all the asterisks).
REMEMBER: If you share your computer, then potentially someone else will have access to these passwords.
Save the file as “PuppetLogin.html”
Check the filename. If it saved as “PuppetLogin.html.txt” or similar, rename it to “PuppetLogin.html”.
When you open the file again, it should get opened in your browser by default. You should see a black page with “Wolfram & Hart” written across the top.
When you click the button, the code should send login requests to NS. NS then sends a response back. The code associated with the response gets displayed on your webpage.
Why
Yes, I know there's already code out there that you can download. But I don't like downloading things, and I like to know how things work. So I wrote code that needs no downloading, and is filled with explanatory comments.
HTML can be written in a simple text editor, and JavaScript can be embedded directly in HTML. Both will be recognised by your browser without the need for any other software or downloads. So they're what I used.
This is the first time I've properly tried to code HTML and JavaScript, so I've added comments at practically every line of code, explaining what it does. That also means users know exactly what they are getting.
Feedback
If you use this script, please drop [nation]Wolfram & Hart[/nation] a telegram. It would be interesting to know how widely this was used (if at all!). Any suggestions for improvements and enhancements are welcome.
Edit: Version 1.6. This version is slightly faster. NS can receive 25 requests every 30 seconds. Previous versions left a gap of 1.2 seconds between NS acknowledging a request, and sending the next one. As there is a short delay between sending request, and receiving acknowledgement, 25 requests were taking over 30 seconds. This version keeps an array of timestamps that the requests were received by NS. This allows request 26 to be sent exactly 30 seconds after request 1, request 27 to be sent exactly 30 seconds after request 2 etc.
Edit: Now on version 1.4. This one displays the region your puppet is in, and a count of any unread notices, TGs, RMB posts, and unanswered issues. It also puts your WA nation at the top of the screen (handy if you forgot where you left your WA!), followed by nations in the Rejected Realms (handy to see if your puppets got booted out of a region).
Edit: I've updated the code to version 1.2. This new version can (theoretically) be used for unlimited puppets. Login requests are suitably spaced apart to keep [v] satisfied!
The original version 1.0 was limited to a maximum of 25 puppets, and sent all requests at once. I've kept the original code in a spoiler in case anyone cares from an educational point of view.
What
Use this code to log in to a list of your puppets with the push of one button. Handy to stop them CTEing!
How
On your PC or laptop, open a text editor, like Notepad. Copy the code (below) into the editor.
Put your own email address in the code (place indicated by all the asterisks).
Put your own Nation names and passwords in the code (place indicated by all the asterisks).
REMEMBER: If you share your computer, then potentially someone else will have access to these passwords.
Save the file as “PuppetLogin.html”
Check the filename. If it saved as “PuppetLogin.html.txt” or similar, rename it to “PuppetLogin.html”.
When you open the file again, it should get opened in your browser by default. You should see a black page with “Wolfram & Hart” written across the top.
When you click the button, the code should send login requests to NS. NS then sends a response back. The code associated with the response gets displayed on your webpage.
Why
Yes, I know there's already code out there that you can download. But I don't like downloading things, and I like to know how things work. So I wrote code that needs no downloading, and is filled with explanatory comments.
HTML can be written in a simple text editor, and JavaScript can be embedded directly in HTML. Both will be recognised by your browser without the need for any other software or downloads. So they're what I used.
This is the first time I've properly tried to code HTML and JavaScript, so I've added comments at practically every line of code, explaining what it does. That also means users know exactly what they are getting.
Feedback
If you use this script, please drop [nation]Wolfram & Hart[/nation] a telegram. It would be interesting to know how widely this was used (if at all!). Any suggestions for improvements and enhancements are welcome.
- Code: Select all
<!DOCTYPE html>
<!-- Wolfram & Hart PuppetMaster v1.6
Version | Date | Name | Comment
1.0 | 04 Dec 2017 | Wolfram & Hart | Created
1.2 | 16 Dec 2017 | Wolfram & Hart | Changes following Roavin's advice:
| | | Put nation / password pairs into an array.
| | | Included 'setTimeout()' in fGetXml function to leave suitable gap between logins.
| | | Other minor changes.
1.4 | 12 Feb 2018 | Wolfram & Hart | NS query now returns the WA status, region, and number of unread issues, TGs etc
| | | Output is now to a table instead of paragraph.
| | | WA nation is listed first, followed by nations in the Rejected Realms
1.6 | 20 Aug 2018 | Wolfram & Hart | Added 'fSetNextRequest()' to improve efficiency of request times
| | |
This code is not warranted in any way. Use at your own risk.
Use and modify this code as suits.
Make sure you comply with the NationStates API rules.
See: https://www.nationstates.net/pages/api.html
Feedback: If you use this script, please drop [nation]Wolfram & Hart[/nation] a telegram.
It would be interesting to know how widely this was used (if at all!)
Any suggestions for improvements and enhancements are welcome.
-->
<head>
<title>W&H PuppetMaster</title>
<style>
body {background-color: black;}
div {
text-align: center;
color: white;
font-family: times;
}
table,th,td {
border : 1px solid white;
border-collapse: collapse;
}
th,td {
padding: 5px;
}
</style>
</head>
<body>
<div>
<h1><span style="font-size:120%;">W</span>OLFRAM <span style="color:red; font-size:120%;">&</span> <span style="font-size:120%;">H</span>ART</h1>
<h3>PuppetMaster</h3>
<br>
<button type="button" onclick="fMain()">View Puppets</button>
<p id="err"></p>
<table id="msg" align=center></table>
</div>
<!-- This is the JavaScript that will be run when the button is pressed -->
<script>
/* **********************CHANGE THIS TO USE YOUR OWN EMAIL ADDRESS********************** */
/* NationStates require a 'UserAgent', so you can be contacted if something goes wrong */
var strUserAgent = "myname@email.com";
/* ************************************************************************************* */
/* ***************CHANGE THIS ARRAY TO INCLUDE YOUR NATIONS AND PASSWORDS*************** */
var aobjNtns = [
{nation:"Nation 1", password:"Password1"},
{nation:"Nation 2", password:"Password2"},
{nation:"Nation 3", password:"Password3"},
{nation:"Last Nation", password:"LastPassword"}
];
/* ************************************************************************************* */
/* Tell NS the format of the password. This code uses the unencrypted text password.
(The one you type into the NationStates website). NS allows you to use an encrypted
password instead. See this page for more details:
https://www.nationstates.net/pages/api.html#nationapi-privateshards
*/
var strPasswordType = "X-Password";
/* Set variables to record the nations processed. This will update the html. */
var strErr;
var strWA;
var strTRR;
var strMsg;
var strHdr = "<tr><th>Nation</th><th>Region</th><th>Notices</th><th>Telegrams</th><th>RMB</th><th>Issues</th></tr>";
var intNtn = 0;
/* NS can receive 25 requests in 30 seconds. Recording the times that NS receives the requests
enables us to send the latest request exactly 30 seconds after NS received the 25th-ago request.
*/
var adteTime = [];
/* The fMain function:
Initialises the adteTime array with values from 'now' to 24 seconds in the future.
Resets the 'msg' table to being blank.
Tells the code to login the first nation in the list.
*/
function fMain() {
var dteNow = new Date().getTime();
var i;
for (i = 0; i < 24; i++) {
adteTime[i] = dteNow + (i + 1) * 1200;
}
strErr = "";
strWA = "";
strTRR = "";
strMsg = "";
document.getElementById("err").innerHTML = strErr;
document.getElementById("msg").innerHTML = strMsg;
fGetXml();
}
/* fGetXml checks if there is another nation to be processed, then requests the XML from NS */
function fGetXml() {
if (intNtn < aobjNtns.length) {
var strNtn = aobjNtns[intNtn].nation.replace(" ", "_"); // get the nation name & password from the list
var strPassword = aobjNtns[intNtn].password;
intNtn = intNtn + 1;
var objXhttp = new XMLHttpRequest(); // Create an object to send the details to NS
objXhttp.onreadystatechange = function() {
if (objXhttp.readyState == 2) {
fSetNextRequest();
} else if (objXhttp.readyState == 4) {
if (objXhttp.status == 200) {
fProcessXml(this);
} else {
if (objXhttp.status == 403) {
strErr = strNtn + ": Forbidden (incorrect password?)<br>" + strErr;
} else if (objXhttp.status == 404) {
strErr = strNtn + ": Not Found (nation CTEd / misspelled / doesn't exist?)<br>" + strErr;
} else if (objXhttp.status == 429) {
strErr = strNtn + ": Too Many Requests. Processing stopped<br>" + strErr;
} else {
strErr = strNtn + ": Error " + objXhttp.status + "<br>" + strErr;
};
document.getElementById("err").innerHTML = strErr;
};
};
};
objXhttp.open("GET", "https://www.nationstates.net/cgi-bin/api.cgi?nation=" + strNtn + "&q=wa+name+region+unread", true);
objXhttp.setRequestHeader(strPasswordType, strPassword);
objXhttp.setRequestHeader("User-Agent", strUserAgent);
objXhttp.send();
};
}
/* fSetNextRequest adds an entry to the end of adteTime, set for 30 seconds from now.
It then looks at the entry recorded for the 25th-ago request, to set up when the next request should go.
*/
function fSetNextRequest() {
var intDly;
var dteNow = new Date().getTime();
adteTime.push(dteNow + 30000);
intDly = adteTime.shift() - dteNow;
if (intDly < 0) { intDly = 1; };
setTimeout(function(){ fGetXml() }, intDly);
}
/* fProcess reads in the XML data. It puts any WA nation to the top of the output,
followed by any nations in the Rejected Realms, followed by all other nations.
*/
function fProcessXml(objXhttp) {
var objXML = objXhttp.responseXML;
var strNtn = objXML.getElementsByTagName("NAME")[0].childNodes[0].nodeValue;
var strRgn = objXML.getElementsByTagName("REGION")[0].childNodes[0].nodeValue;
var strNtc = objXML.getElementsByTagName("NOTICES")[0].childNodes[0].nodeValue;
if (strNtc == "0") { strNtc = ""; };
var strTGs = objXML.getElementsByTagName("TELEGRAMS")[0].childNodes[0].nodeValue;
if (strTGs == "0") { strTGs = ""; };
var strRMB = objXML.getElementsByTagName("RMB")[0].childNodes[0].nodeValue;
if (strRMB == "0") { strRMB = ""; };
var strIss = objXML.getElementsByTagName("ISSUES")[0].childNodes[0].nodeValue;
if (strIss == "0") { strIss = ""; };
var strTmp = strRgn + "</th><th>" + strNtc +
"</th><th>" + strTGs + "</th><th>" + strRMB + "</th><th>" + strIss + "</th></tr>"
if (objXML.getElementsByTagName("UNSTATUS")[0].childNodes[0].nodeValue != "Non-member") {
strWA = strWA + "<tr style='color:red;'><th>WA Member: " + strNtn + "</th><th>" + strTmp;
} else if (strRgn == "the Rejected Realms") {
strTRR = strTRR + "<tr><th>" + strNtn + "</th><th style='color:red;'>" + strTmp;
} else {
strMsg = strMsg + "<tr><th>" + strNtn + "</th><th>" + strTmp;
};
document.getElementById("msg").innerHTML = strHdr + strWA + strTRR + strMsg;
}
</script>
</body>
</html>