NATION

PASSWORD

Script: "Reliant" + HTML Script Legality Discussion

Bug reports, general help, ideas for improvements, and questions about how things are meant to work.

Advertisement

Remove ads

User avatar
Frattastan IV
Envoy
 
Posts: 225
Founded: Sep 02, 2018
Ex-Nation

Postby Frattastan IV » Fri May 27, 2022 2:36 am

Did admin manage to reproduce the observed rulebreaking behaviour? (a separate question from establishing what's responsible for causing it in the code)
Rejected Realms Army, High Commander

Draganisia wrote:Also it seems the next war could be NPO fighting directly against Pacifica.

User avatar
Roavin
Admin
 
Posts: 1777
Founded: Apr 07, 2016
Democratic Socialists

Postby Roavin » Fri May 27, 2022 2:36 am

I'm currently at the office so I can't go into much detail here (will be doing that later), but I'm very confused by this ruling. I've written close to 50 kilobytes worth of GHRs on this topic, explaining all my hypotheses and findings, and even had a 45-minute screenshare session back in April with a very receptive and interested site admin to show these findings. The running hypothesis that I showed in that screenshare was that operating Reliant+Breeze at the same time could lead to violations (rather than Reliant being at any fault on its own), and I broke it down so much that verifying the hypothesis was nearly as simple as a Ctrl+F in server logs. I also, in my subsequent GHR, took apart the possible intersections between Reliant and Breeze, explaining which could lead to simultaneous non-idempotent requests that could give a gameplay advantage, and not finding any (I could have missed a case, but ... which one??)

So now it's 3 months WA ban for three people. The hypothesis that I so meticulously set out and just needed essentially a Ctrl+F to verify (or disprove) remains unanswered as well, and ... well, honestly, given all the info I piped in and the lack of info coming back out, this looks and feels like "we stopped investigating, we're just gonna WA-ban three people and call it a day". I don't want to think that, but it's very hard not to.
Helpful Resources: One Stop Rules Shop | API documentation | NS Coders Discord
About me: Longest serving Prime Minister in TSP | Former First Warden of TGW | aka Curious Observations

Feel free to TG me, but not about moderation matters.

User avatar
Sedgistan
Site Director
 
Posts: 35471
Founded: Oct 20, 2006
Anarchy

Postby Sedgistan » Fri May 27, 2022 2:59 am

Frattastan IV wrote:Did admin manage to reproduce the observed rulebreaking behaviour? (a separate question from establishing what's responsible for causing it in the code)

Not to my knowledge.

Roavin wrote:I'm currently at the office so I can't go into much detail here (will be doing that later), but I'm very confused by this ruling. I've written close to 50 kilobytes worth of GHRs on this topic, explaining all my hypotheses and findings, and even had a 45-minute screenshare session back in April with a very receptive and interested site admin to show these findings. The running hypothesis that I showed in that screenshare was that operating Reliant+Breeze at the same time could lead to violations (rather than Reliant being at any fault on its own), and I broke it down so much that verifying the hypothesis was nearly as simple as a Ctrl+F in server logs. I also, in my subsequent GHR, took apart the possible intersections between Reliant and Breeze, explaining which could lead to simultaneous non-idempotent requests that could give a gameplay advantage, and not finding any (I could have missed a case, but ... which one??)

I understand that Eluvatar did spend some time early on working with you to try to determine what had caused the illegal behaviour - but that's not the role of the Admins (it is a script author's responsibility to ensure their script functions legally). The exact aspect of the script(s) that caused the violation isn't particularly relevant to the Moderation question of handling rules violations by players. I would have liked to know the answer, but that's more from personal curiosity and because that would help to avoid similar problems in the future.

It could be that it was interaction between Reliant and Breeze that caused the illegal behaviour - I cannot say, and nor is it my place (or the staff's place) to say whether that's the case or not. We have recognised this possibility in removing the blanket ban on use of Reliant.

If you're asking for examples of the illegal behaviour, the majority of that comes in the form of server logs, which I'm not going to reformat for the sake of publishing (sorry; I've also spent a significant amount of my own time on the Reliant case and trying to get us to a resolution on it, and there's only so much more I'll put into it). I don't mind posting the publicly observable national happenings that were cited in the original GHR report:

2/14/2022, 5:48:22 PM MST: Emnietom endorsed Lunaflower-2.
2/14/2022, 5:48:22 PM MST: Emnietom endorsed Nivilons.
2/14/2022, 5:48:22 PM MST: Emnietom endorsed Imperial Sword.
2/14/2022, 5:48:22 PM MST: Emnietom endorsed Zequinha do Abacaxi.
2/14/2022, 5:48:22 PM MST: Emnietom endorsed Expansivian Onionist Revolutionary Force.
2/14/2022, 5:48:22 PM MST: Emnietom endorsed Little Mermraider.

2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Venicos Fiancee.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed The Airforce Guy.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed The Toukaian Night Bomber Squadron.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Scorchy Boi 1.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Tablerepublic.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Giraffe Liberator.

Roavin wrote:So now it's 3 months WA ban for three people. The hypothesis that I so meticulously set out and just needed essentially a Ctrl+F to verify (or disprove) remains unanswered as well, and ... well, honestly, given all the info I piped in and the lack of info coming back out, this looks and feels like "we stopped investigating, we're just gonna WA-ban three people and call it a day". I don't want to think that, but it's very hard not to.

Absolutely, we stopped investigating the actual script itself; Eluvatar has not been available to spend more time on it, but as per the above it's not really relevant to what Moderators are here to handle - which is the rules violations that resulted from that script.

User avatar
Roavin
Admin
 
Posts: 1777
Founded: Apr 07, 2016
Democratic Socialists

Postby Roavin » Fri May 27, 2022 3:07 am

Fast endorsements on their own aren't rule-breaking to my knowledge, but it's doing them simultaneously that would break the rules, and also it's worth noting that the three players in question are those Reliant users that had the fastest connection to NationStates. 5 endorsements in a second can be done with an endo every 200 milliseconds, and people like Luca, GK, and Altmoras certainly can get TTFB-times of 100ms or below. And in fact, Reliant meticulously makes sure that these endorsements are done sequentially, while doing it manually (by pre-opening and ctrl+tabbing) works just as quick (if more tediously) and in that case can actually cause simultaneous requests (though in that case not rule-breaking).

So, where is this rule-breaking?
Last edited by Roavin on Fri May 27, 2022 3:26 am, edited 3 times in total.
Helpful Resources: One Stop Rules Shop | API documentation | NS Coders Discord
About me: Longest serving Prime Minister in TSP | Former First Warden of TGW | aka Curious Observations

Feel free to TG me, but not about moderation matters.

User avatar
Roavin
Admin
 
Posts: 1777
Founded: Apr 07, 2016
Democratic Socialists

Postby Roavin » Fri May 27, 2022 3:11 am

For reference, I just did this on my work computer (which you can confirm based on my IP), on which I have no NS tools installed, from my connection in Germany which is significantly slower than coming from the USA or Canada. There's a burst of 5 endos a second in there - the most I could hope for with actual Reliant use with my connection would be 4 if I'm really lucky.

Code: Select all
27.5.2022, 12:10:54 MESZ: Kutumal XVI endorsed Pomerania-Wolgast.
27.5.2022, 12:10:54 MESZ: Kutumal XVI endorsed Karl Maldens Nose.
27.5.2022, 12:10:53 MESZ: Kutumal XVI endorsed Youttlesover.
27.5.2022, 12:10:53 MESZ: Kutumal XVI endorsed EAF1.
27.5.2022, 12:10:53 MESZ: Kutumal XVI endorsed Asuka-Soryu.
27.5.2022, 12:10:53 MESZ: Kutumal XVI endorsed Commubirb.
27.5.2022, 12:10:52 MESZ: Kutumal XVI endorsed Rogue Lawnmower.
27.5.2022, 12:10:52 MESZ: Kutumal XVI endorsed 1st Marine Assault Corps.
27.5.2022, 12:10:52 MESZ: Kutumal XVI endorsed Wednesday Addams.
27.5.2022, 12:10:52 MESZ: Kutumal XVI endorsed BHpuppet 2.
27.5.2022, 12:10:52 MESZ: Kutumal XVI endorsed Decreeism.
27.5.2022, 12:10:51 MESZ: Kutumal XVI endorsed Nagaramariningrad.
27.5.2022, 12:10:51 MESZ: Kutumal XVI endorsed La Hellhole.
Last edited by Roavin on Fri May 27, 2022 3:22 am, edited 2 times in total.
Helpful Resources: One Stop Rules Shop | API documentation | NS Coders Discord
About me: Longest serving Prime Minister in TSP | Former First Warden of TGW | aka Curious Observations

Feel free to TG me, but not about moderation matters.

User avatar
Refuge Isle
Technical Moderator
 
Posts: 1875
Founded: Dec 14, 2018
Left-wing Utopia

Postby Refuge Isle » Fri May 27, 2022 3:26 am

Sedgistan wrote:2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Venicos Fiancee.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed The Airforce Guy.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed The Toukaian Night Bomber Squadron.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Scorchy Boi 1.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Tablerepublic.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Giraffe Liberator.


This loses all credibility of this investigation to me. I have a 1.5Gb/s connection and live 100km from Vancouver. I'm regularly able to create happenings logs of moves or other actions within the same second, using containers which admin has previously likened to native browsers' private sessions, or even vanilla Firefox itself. This has been the case for years, including prepping in TBH where I posted logs of 4-7 WA apps a second, moving thousands of nations to tic-tacs during 2020's South Pacific raid, even the day I started defending, where Sweeze complained that I was moving nations too quickly, but most likely the servers took a dump during those move requests, just as the site did as I was trying to write this post.

My primary concern is now, since you have selected the three fastest chasers on NS, or more specifically three users with some of the fastest connections to NS on the site, that you are looking at logs without context and feeling that they are not possible to generate through any other means than illegal activity. My concern is that when or if I ever return to chasing, simply chasing fast is going to be viewed with suspicion. Because I can tell you now, there's no shortage of logs of me getting 0s chases with Breeze, which is a relatively uncontroversial script these days.

User avatar
Roavin
Admin
 
Posts: 1777
Founded: Apr 07, 2016
Democratic Socialists

Postby Roavin » Fri May 27, 2022 3:36 am

Sorry if I'm a bit spammy - but sedge, you implied that you had access to the server logs.

First, the default access log format for Apache doesn't include the %D format specifier, which (if I'm reading the documentation right) is the only one that could be used for detecting actual simultaneous requests based on Apache logs. Is %D included to actually see that these are simultaneous requests? Note that %T as a format specifier would not work here, since it's only accurate down to the nearest second and we're dealing with multiple requests a second.

Second, my third-to-last GHR broke it down to essentially a ctrl-F in the offending server logs to verify/disprove the Reliant+Breeze-hypothesis, which really should take less than half a minute. Have you checked that?
Last edited by Roavin on Fri May 27, 2022 3:37 am, edited 1 time in total.
Helpful Resources: One Stop Rules Shop | API documentation | NS Coders Discord
About me: Longest serving Prime Minister in TSP | Former First Warden of TGW | aka Curious Observations

Feel free to TG me, but not about moderation matters.

User avatar
Wymondham
Chargé d'Affaires
 
Posts: 401
Founded: Apr 03, 2017
Libertarian Police State

Postby Wymondham » Fri May 27, 2022 4:06 am

I just want to note that, around 20 minutes ago, GCR Delegate North East Somerset achieved 6 endorsements in a second with no scripts at all and no containers; despite living over 4,500 miles from vancouver with an internet speed of 18.4Mb/s download and 5.4Mb/s upload.

Image

You do not even need to live 100km from Vancouver or have 1.5Gb/s internet to manage 6 endorsements in a second, so it's not even as if Luca's endorsement rate is unique to even a small group of people, I have managed 4 endorsements in a second myself in the past without scripts. Would the moderation team therefore be able to explain how achieving 6 endorsements in a second can therefore be taken as an indication of rulebreaking activity when it can easily be achieved with no scripts by someone with a poor internet connection living over 4,500 miles away from the server?

If the moderation team would like more examples of this being possible with no scripts, crap ping and abysmal internet, I'm more than happy to try and find some more.
Last edited by Wymondham on Fri May 27, 2022 4:08 am, edited 1 time in total.
Doer of the things and the stuffs.
That British dude who does the charity fundraiser.

User avatar
Quebecshire
Ambassador
 
Posts: 1912
Founded: Mar 17, 2017
Democratic Socialists

Postby Quebecshire » Fri May 27, 2022 8:56 am

I’ve avoided commenting in this thread since the investigation began, mainly because Roavin could articulate my thoughts and concerns in a much more qualified manner. With this finally being ruled on, though, there’s a few things I’m inclined to say.

It is good that we’ve seen some level of a conclusion here. As one of the people being investigated, I’m both relieved personally and concerned more broadly. I understand that it is not admin’s responsibility to ensure script legality for the developers, but this has gone on for three months and now three players in good standing have been given substantial punishment.

As others have posted it seems to me, as an outsider to investigation, that these players were potentially punished as a result of their faster internet connections and possibly even geographic proximity to the NationStates servers. This solution feels, based on Sedge’s posts, that it was thrown together quickly in the absence of what could have been more useful and extensive administrative investigation.

After more three months of stress and concern, I feel we are owed more of an explanation as to what went wrong and what we can do to avoid anything like this in the future. In particular, I really think admin should answer the question of Roavin’s Reliant+Breeze theory and attempt to either confirm or deny it. I can’t put into words how much sincere and dedicated effort Roavin has put into trying to figure out this issue on his own time, and he actively collaborated with admin on it has been previously mentioned.

I understand that the moderator portion of staff is probably equally concerned with how this all played out, and that’s valid. It seems the main problems with the investigation were certainly not the result of anything they did or didn’t do. But overall, this entire ordeal, which lasted over a quarter of a year and has given punishments of another quarter of a year to some, has led to serious issues of disconnect between the staff and player base.
PATRIOT OF THE LEAGUE REDEEMER OF CONCORD
Defender Moralist | Consul of the LDF | Warden-Lieutenant Emeritus | Commended
Benevolent Thomas wrote:I founded a defender organization out of my dislike of invaders, what invading represents, and my desire to see them suffer.
Pergamon wrote:I must say, you are truly what they deserve.

User avatar
Sedgistan
Site Director
 
Posts: 35471
Founded: Oct 20, 2006
Anarchy

Postby Sedgistan » Fri May 27, 2022 9:54 am

I will see if I can get an Admin to comment on more technical matters, but I'm not making any promises - it's taken us three months to get to this point.

In case it's not clear, this whole situation has been frustrating for staff as well, both mods and admins. We are considering what can be done to avoid a repeat.

User avatar
The Chariot
Bureaucrat
 
Posts: 61
Founded: Jan 16, 2019
Ex-Nation

Postby The Chariot » Fri May 27, 2022 12:25 pm

Roavin wrote:For reference, I just did this on my work computer (which you can confirm based on my IP), on which I have no NS tools installed, from my connection in Germany which is significantly slower than coming from the USA or Canada. There's a burst of 5 endos a second in there - the most I could hope for with actual Reliant use with my connection would be 4 if I'm really lucky.

Thought I'd give it a go as well and I managed to consistently reproduce 6 endos in 1 second with no tools. The original inquiry was laughably justified, and it is even more ridiculous anybody could think a simple low pageload endo run (I do not have low pageloads, unlike GK, Luca, and Alt) would be at all an indicator of illegal behavior, let alone actual illegal behavior.
Code: Select all
5/27/2022, 3:07:36 PM EDT: The Chariot endorsed The Kock.
5/27/2022, 3:07:06 PM EDT: The Chariot endorsed Kyary Pamyu Pamyu.
5/27/2022, 3:07:06 PM EDT: The Chariot endorsed Steak Paul.
5/27/2022, 3:07:06 PM EDT: The Chariot endorsed Nababa Republic.
5/27/2022, 3:07:06 PM EDT: The Chariot endorsed Counterfeit Kyrusia Puppet.
5/27/2022, 3:07:06 PM EDT: The Chariot endorsed New Astrian Outpost 8.
5/27/2022, 3:07:06 PM EDT: The Chariot endorsed Metal Gear Solid.
5/27/2022, 3:07:06 PM EDT: The Chariot endorsed Malicious Rigel.
5/27/2022, 3:07:05 PM EDT: The Chariot endorsed Myuri.
5/27/2022, 3:06:25 PM EDT: The Chariot withdrew its endorsement from NaganoLegend.

Code: Select all
5/27/2022, 3:05:59 PM EDT: The Chariot withdrew its endorsement from Myuri.
5/27/2022, 3:05:06 PM EDT: The Chariot endorsed NaganoLegend.
5/27/2022, 3:05:05 PM EDT: The Chariot endorsed Kyary Pamyu Pamyu.
5/27/2022, 3:05:05 PM EDT: The Chariot endorsed Traditional Japan.
5/27/2022, 3:05:05 PM EDT: The Chariot endorsed Steak Paul.
5/27/2022, 3:05:05 PM EDT: The Chariot endorsed Nababa Republic.
5/27/2022, 3:05:05 PM EDT: The Chariot endorsed Interimian XIX.
5/27/2022, 3:05:05 PM EDT: The Chariot endorsed Counterfeit Kyrusia Puppet.
5/27/2022, 3:05:05 PM EDT: The Chariot endorsed Metal Gear Solid.
5/27/2022, 3:05:05 PM EDT: The Chariot endorsed New Astrian Outpost 8.
5/27/2022, 3:05:04 PM EDT: The Chariot endorsed The Kock.
5/27/2022, 3:05:04 PM EDT: The Chariot endorsed Malicious Rigel.
5/27/2022, 3:05:04 PM EDT: The Chariot endorsed Myuri.
5/27/2022, 3:05:00 PM EDT: The Chariot withdrew its endorsement from NaganoLegend.

There's eight whole "simultaneous" endos for you!
Code: Select all
5/27/2022, 3:04:33 PM EDT: The Chariot withdrew its endorsement from Myuri.
5/27/2022, 3:04:06 PM EDT: The Chariot endorsed NaganoLegend.
5/27/2022, 3:04:06 PM EDT: The Chariot endorsed Kyary Pamyu Pamyu.
5/27/2022, 3:04:06 PM EDT: The Chariot endorsed Traditional Japan.
5/27/2022, 3:04:05 PM EDT: The Chariot endorsed Steak Paul.
5/27/2022, 3:04:05 PM EDT: The Chariot endorsed Nababa Republic.
5/27/2022, 3:04:05 PM EDT: The Chariot endorsed Counterfeit Kyrusia Puppet.
5/27/2022, 3:04:05 PM EDT: The Chariot endorsed Interimian XIX.
5/27/2022, 3:04:05 PM EDT: The Chariot endorsed Metal Gear Solid.
5/27/2022, 3:04:05 PM EDT: The Chariot endorsed The Kock.
5/27/2022, 3:04:04 PM EDT: The Chariot endorsed New Astrian Outpost 8.
5/27/2022, 3:04:04 PM EDT: The Chariot endorsed Malicious Rigel.
5/27/2022, 3:04:04 PM EDT: The Chariot endorsed Myuri.
5/27/2022, 3:03:57 PM EDT: The Chariot withdrew its endorsement from Malicious Rigel.
Each has been provided with preceding and subsequent national happenings to prove that this pheonomenon can be reproduced (and trumped!) in a small sample size by anyone whose chrome shortcut savviness is even moderate. I live 5200km away from Vancouver and have 200mb/s parallel internet. I imagine any of our fine canadian friends could easily trump this feat were they so inclined with nothing but their keyboards and mice.
Last edited by The Chariot on Fri May 27, 2022 1:11 pm, edited 3 times in total.
@waste#9808
Supreme Command of Lily| Steven of 3 Guys
"I wish when I quit i had stayed gone, Steve makes me regret ever coming back." - Salem
"he shit postsbut hes the best at what he does... and thats raiding and shitposting at the same time while ignoring opsec" - Matthew
"[Steven] is the only upstanding person in this organization" - Liliarchy
“@waste waste” - Haku

Join the Horsemen of the Apocalypse

User avatar
Syberis
Diplomat
 
Posts: 689
Founded: Jan 21, 2016
Iron Fist Consumerists

Postby Syberis » Fri May 27, 2022 3:00 pm

Sedgistan wrote:I will see if I can get an Admin to comment on more technical matters, but I'm not making any promises - it's taken us three months to get to this point.

In case it's not clear, this whole situation has been frustrating for staff as well, both mods and admins. We are considering what can be done to avoid a repeat.


Three months of discussion and drafting and what everyone gets is a team response fundamentally dismissive to people trying to help find a solution so it doesn't happen again, if not actively hostile, with "evidence" mathematically off by so many significant figures that it's effortlessly rendered nonsensical by a significant portion of the playerbase via independent study in a matter of hours. Heck, nobody needed to actually test it as your margin of error is just a fast typing speed, not even a fast "pressing the same 2-3 buttons over again manually" speed. It's rendered questionable by napkin math.

Do the server logs offer additional precision? If so, and if it apparently took three months to come up with this discussion why is the team's response the following?

If you're asking for examples of the illegal behaviour, the majority of that comes in the form of server logs, which I'm not going to reformat for the sake of publishing (sorry; I've also spent a significant amount of my own time on the Reliant case and trying to get us to a resolution on it, and there's only so much more I'll put into it)


The fact that putting together server logs wouldn't actually take all that long when the timescale of the wait was three months is enough, but also anyone during the drafting process should have seen this approach as dismissive and borderline insulting to players. This whole thing reads like it was written because people saw that offsite frustration was building and something was thrown together with minimal discussion. Almost a "Yeah, 3 months WA ban sounds good, just ship" level of discussion. The team response here is less on par with the initial Predator post and more on par with the Texasa situation.

Keep in mind I'm not saying evidence is needed, but if you're going to whip it out as an example, make sure it's actually, you know, evidence. It being frustrating to moderation and admin isn't enough when the day of this announcement has been the most team engagement forumside during the whole debacle and it seems to be directly in opposition to prior stated goals of community engagement and input to say things like, and I'm going to reiterate your own words directly...

In case it's not clear, this whole situation has been frustrating for staff as well, both mods and admins.


If you want to engage the community, if you want player input and involvement,if you want to make sure that there's good reporting of potential issues and good-faith approaches to resolution, then maybe situations where players go out of their way to attempt to debug, discuss, and develop their tools when unforseen issues and conflicts arise shouldn't be directly called an annoyance on the forums.
I've finally found what I was looking for
A place where I can be without remorse
Because I am a stranger who has found
An even stranger war

Zaolat wrote:WHO THE F*** IS SYBERIS

User avatar
Custadia
Attaché
 
Posts: 83
Founded: May 29, 2014
Father Knows Best State

Postby Custadia » Fri May 27, 2022 3:19 pm

Sedgistan wrote:We believe it is highly likely that those players that benefited from using Reliant in an illegal fashion could not have been unaware that they were violating the rules.

What has led you to this conclusion?

Why these three players in particular?

Which scripting rules specifically were broken?
Last edited by Custadia on Fri May 27, 2022 3:22 pm, edited 4 times in total.
AKA McChimp

User avatar
Bormiar
Ambassador
 
Posts: 1555
Founded: Mar 25, 2019
Inoffensive Centrist Democracy

Postby Bormiar » Fri May 27, 2022 3:58 pm

It sounds like they log when they receive and when they finish servicing a request with enough precision that they can tell there was simultaneity. I don't think they would call it with such certainty unless that were the case. But that's just me.

However, I still find this very confusing.

Why do you think that the players knew they were breaking the rules? Doesn't intentionally breaking scripting rules usually entail a larger punishment?

What made it so hard to investigate?

What format are the server logs in such that they can be read by a human but not posted on the forums?

I'm sure this has a decent explanation, but I can't for the life of me make sense of it all.
Last edited by Bormiar on Fri May 27, 2022 3:59 pm, edited 1 time in total.

User avatar
Roavin
Admin
 
Posts: 1777
Founded: Apr 07, 2016
Democratic Socialists

Postby Roavin » Fri May 27, 2022 5:27 pm

I've written a script that essentially contains Reliant's cross-endorsement code ported to Tampermonkey. With that script and Wireshark, I can show that Reliant's cross-feature does not violate simultaneity, but NationStates itself does.

I just performed these actions by spam-clicking with the script:
28/05/2022, 1:52:16 CEST: Kutumal XVI endorsed Ancient Republics.
28/05/2022, 1:52:14 CEST: Kutumal XVI endorsed Ghojingles.
28/05/2022, 1:52:13 CEST: Kutumal XVI endorsed Arachnostan.


If you're thinking "this is incredibly slow" - you're right, more on that later.

Here is the Wireshark trace from that same sequence of events:
19955 825.884666 192.168.2.112 104.25.62.43 HTTP2 173 HEADERS[449]: GET /page=ajax2/a=refresh/nation=kutumal_xvi
19957 825.962381 192.168.2.112 104.25.62.43 HTTP2 268 HEADERS[451]: POST /cgi-bin/endorse.cgi/script=relendo_by_roavin/userclick=1653695528329
19958 825.962415 192.168.2.112 104.25.62.43 HTTP2 440 DATA[451]
19962 826.422941 104.25.62.43 192.168.2.112 HTTP2 479 HEADERS[449]: 200 OK, DATA[449]
19963 826.422941 104.25.62.43 192.168.2.112 HTTP2 1105 DATA[449]
19965 826.425197 104.25.62.43 192.168.2.112 HTTP2 1248 DATA[449]
19966 826.425775 192.168.2.112 104.25.62.43 HTTP2 89 WINDOW_UPDATE[0]
19967 826.425918 104.25.62.43 192.168.2.112 HTTP2 95 DATA[449]
19968 826.425918 104.25.62.43 192.168.2.112 HTTP2 132 DATA[449]
19969 826.425918 104.25.62.43 192.168.2.112 HTTP2 86 DATA[449]
19970 826.425918 104.25.62.43 192.168.2.112 HTTP2 85 DATA[449] (text/html)
19974 826.512435 104.25.62.43 192.168.2.112 HTTP2 621 HEADERS[451]: 302 Found, DATA[451]
19975 826.512435 104.25.62.43 192.168.2.112 HTTP2 85 DATA[451] (text/html)
19977 826.517191 192.168.2.112 104.25.62.43 HTTP2 2313 HEADERS[453]: GET /nation=arachnostan
19981 826.714179 104.25.62.43 192.168.2.112 HTTP2 757 HEADERS[453]: 200 OK, DATA[453]
19982 826.714179 104.25.62.43 192.168.2.112 HTTP2 138 DATA[453]
19984 826.714419 104.25.62.43 192.168.2.112 HTTP2 1077 DATA[453]
19985 826.716181 104.25.62.43 192.168.2.112 HTTP2 1206 DATA[453]
19987 826.718149 104.25.62.43 192.168.2.112 HTTP2 209 DATA[453]
19988 826.728027 104.25.62.43 192.168.2.112 HTTP2 1020 DATA[453]
19992 826.763176 104.25.62.43 192.168.2.112 HTTP2 1372 DATA[453]
19995 826.763707 104.25.62.43 192.168.2.112 HTTP2 228 DATA[453]
19997 826.885678 104.25.62.43 192.168.2.112 HTTP2 763 DATA[453]
19998 826.886142 104.25.62.43 192.168.2.112 HTTP2 85 DATA[453] (text/html)
20002 827.346487 192.168.2.112 104.25.62.43 HTTP2 227 HEADERS[455]: POST /cgi-bin/endorse.cgi/script=relendo_by_roavin/userclick=1653695529713
20003 827.346524 192.168.2.112 104.25.62.43 HTTP2 439 DATA[455]
20006 827.504822 192.168.2.112 104.25.62.43 HTTP2 190 HEADERS[457]: GET /images/banners/p20.jpg
20008 827.538912 104.25.62.43 192.168.2.112 HTTP2 880 HEADERS[457]: 200 OK, DATA[457]
20019 827.540653 104.25.62.43 192.168.2.112 HTTP2 1213 DATA[457], DATA[457]
20038 827.542891 104.25.62.43 192.168.2.112 HTTP2 928 DATA[457]
20042 827.543651 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[457], DATA[457] [TCP segment of a reassembled PDU]
20059 827.545409 104.25.62.43 192.168.2.112 HTTP2 831 DATA[457]
20071 827.547160 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[457], DATA[457], DATA[457] [TCP segment of a reassembled PDU]
20077 827.547658 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[457] [TCP segment of a reassembled PDU]
20095 827.550149 104.25.62.43 192.168.2.112 HTTP2 457 DATA[457]
20113 827.552400 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[457], DATA[457], DATA[457]
20131 827.554657 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[457] [TCP segment of a reassembled PDU]
20146 827.556308 104.25.62.43 192.168.2.112 HTTP2 746 DATA[457], DATA[457], DATA[457], DATA[457] (JPEG JFIF image)
20148 827.622402 104.25.62.43 192.168.2.112 HTTP2 598 HEADERS[455]: 302 Found, DATA[455]
20149 827.622402 104.25.62.43 192.168.2.112 HTTP2 85 DATA[455] (text/html)
20151 827.626134 192.168.2.112 104.25.62.43 HTTP2 146 HEADERS[459]: GET /nation=ghojingles
20153 827.825162 104.25.62.43 192.168.2.112 HTTP2 807 HEADERS[459]: 200 OK, DATA[459]
20154 827.825162 104.25.62.43 192.168.2.112 HTTP2 138 DATA[459]
20156 827.825644 104.25.62.43 192.168.2.112 HTTP2 1079 DATA[459]
20157 827.827538 104.25.62.43 192.168.2.112 HTTP2 1218 DATA[459]
20158 827.827538 104.25.62.43 192.168.2.112 HTTP2 209 DATA[459]
20160 827.834918 104.25.62.43 192.168.2.112 HTTP2 1021 DATA[459]
20167 827.994893 104.25.62.43 192.168.2.112 HTTP2 1172 DATA[459]
20169 827.995129 104.25.62.43 192.168.2.112 HTTP2 932 DATA[459]
20170 827.995129 104.25.62.43 192.168.2.112 HTTP2 86 DATA[459]
20171 827.995129 104.25.62.43 192.168.2.112 HTTP2 85 DATA[459] (text/html)
20178 828.834576 192.168.2.112 104.25.62.43 HTTP2 2435 HEADERS[461]: POST /cgi-bin/endorse.cgi/script=relendo_by_roavin/userclick=1653695531202
20179 828.834615 192.168.2.112 104.25.62.43 HTTP2 446 DATA[461]
20183 829.066377 104.25.62.43 192.168.2.112 HTTP2 638 HEADERS[461]: 302 Found, DATA[461]
20184 829.066377 104.25.62.43 192.168.2.112 HTTP2 85 DATA[461] (text/html)
20186 829.073088 192.168.2.112 104.25.62.43 HTTP2 136 HEADERS[463]: GET /nation=ancient_republics
20188 829.272117 104.25.62.43 192.168.2.112 HTTP2 836 HEADERS[463]: 200 OK, DATA[463]
20189 829.273362 104.25.62.43 192.168.2.112 HTTP2 1071 DATA[463]
20191 829.274109 104.25.62.43 192.168.2.112 HTTP2 1207 DATA[463]
20192 829.275096 104.25.62.43 192.168.2.112 HTTP2 209 DATA[463]
20194 829.281619 104.25.62.43 192.168.2.112 HTTP2 1024 DATA[463]
20198 829.440599 104.25.62.43 192.168.2.112 HTTP2 1410 DATA[463]
20201 829.441111 104.25.62.43 192.168.2.112 HTTP2 1010 DATA[463]
20203 829.441348 104.25.62.43 192.168.2.112 HTTP2 853 DATA[463]
20204 829.441348 104.25.62.43 192.168.2.112 HTTP2 85 DATA[463] (text/html)


This is how each line of the above Wireshark trace can be interpreted
  • The second column contains a relative timestamp in seconds
  • The third and fourth column are the source and destination, respectively; 104.25.62.43 is NationStates (technically CloudFlare, for the nitpickers), while 192.168.2.112 is my computer's IP address in my home network.
  • The seventh column states what kind of HTTP2 frame is being sent. The number in [brackets] is the stream id, so basically the request - if two requests are acting simultaneously, you will see simultaneous packets with different sequence ids. The final packet for a sequence ID contains the mime-type of the data, e.g. "(text/html)".

What you can see is the following:
  • "Relendo" (which is what I called the script, Reliant+endo) initiates the endorsement with a POST to /cgi-bin/endorse.cgi
  • NationStates replies with a 302, which means "redirect", and the browser responds by automatically making a new request with the redirect location, followed possibly by even more requests to retrieve images etc.
  • NationStates also initiates a request on its own just by virtue of being on the page, in order to refresh things like notices etc. (see sequence id 449 near the beginning)
  • I was spamclicking the hell out of those buttons, and yet Relendo dutifully refused to send another request until the previous request (including its redirect) completed.

Note that Relendo or any other tool cannot prevent the redirect from going through, as there is no API in XMLHttpRequest for scripts to do so.

Inadvertently, what this also shows is that using Relendo (and therefore Reliant's cross feature) is strictly slower than what can be done manually, because manual clicks to NationStates-generated buttons don't have to abide by simultaneity like scripts do. This is accentuated due to the particularities of my geographical situation; for wholly unrelated reasons, NS is by and large pretty sluggish when coming in from Europe due to increased roundtrip times, so the penalty for me having to wait for everything to complete before doing the next click with Relendo is very obvious here. This penalty is significantly lower for individuals like GK, Luca, and Altmoras due to their proximity (much lower roundtrip latency times), which means they can easily perform multiple endorsements a second even with Relendo/Reliant (the math works like this: assuming each endo is one POST and one redirect, images are in cache or blocked (as many defenders do these days), then with a roundtrip time of under 100ms (which GK, Luca, and Altmoras all have) they can still easily get in 5 endos a second. Even in the best case, my round trip times are about 250ms, meaning I could get maybe 2 in, though normally my roundtrip times are about 600ms with occasional bursts of 250ms, which means I can get maybe one a second in using Relendo/Reliant, as seen above)

To compare and contrast with manual, I just did this by pre-opening 4 tabs, then quickly clicking the button and ctrl-tabbing to the next tab (no script even loaded):
28/05/2022, 2:14:44 CEST: Kutumal XVI endorsed Deltarios.
28/05/2022, 2:14:44 CEST: Kutumal XVI endorsed Byzant.
28/05/2022, 2:14:43 CEST: Kutumal XVI endorsed Provinces of North America.
28/05/2022, 2:14:43 CEST: Kutumal XVI endorsed The Horror Channel.


Wireshark looks like this (note all the simultaneous requests):
43042 2175.509801 192.168.2.112 104.25.62.43 HTTP2 343 HEADERS[679]: POST /cgi-bin/endorse.cgi
43043 2175.509835 192.168.2.112 104.25.62.43 HTTP2 147 DATA[679] (application/x-www-form-urlencoded)
43096 2175.933387 192.168.2.112 104.25.62.43 HTTP2 603 HEADERS[681]: POST /cgi-bin/endorse.cgi
43097 2175.933424 192.168.2.112 104.25.62.43 HTTP2 155 DATA[681] (application/x-www-form-urlencoded)
43122 2176.077925 104.25.62.43 192.168.2.112 HTTP2 669 HEADERS[679]: 302 Found, DATA[679]
43123 2176.077925 104.25.62.43 192.168.2.112 HTTP2 85 DATA[679] (text/html)
43126 2176.081302 192.168.2.112 104.25.62.43 HTTP2 236 HEADERS[683]: GET /nation=the_horror_channel
43148 2176.279161 104.25.62.43 192.168.2.112 HTTP2 836 HEADERS[683]: 200 OK, DATA[683]
43149 2176.279161 104.25.62.43 192.168.2.112 HTTP2 138 DATA[683]
43151 2176.280169 192.168.2.112 104.25.62.43 HTTP2 89 WINDOW_UPDATE[0]
43152 2176.280392 104.25.62.43 192.168.2.112 HTTP2 1077 DATA[683]
43154 2176.281641 104.25.62.43 192.168.2.112 HTTP2 1175 DATA[683]
43156 2176.282388 104.25.62.43 192.168.2.112 HTTP2 206 DATA[683]
43157 2176.290925 104.25.62.43 192.168.2.112 HTTP2 1054 DATA[683]
43169 2176.336183 192.168.2.112 104.25.62.43 HTTP2 1650 HEADERS[685]: POST /cgi-bin/endorse.cgi
43170 2176.336219 192.168.2.112 104.25.62.43 HTTP2 138 DATA[685] (application/x-www-form-urlencoded)
43212 2176.449667 104.25.62.43 192.168.2.112 HTTP2 1369 DATA[683]
43215 2176.449963 104.25.62.43 192.168.2.112 HTTP2 767 DATA[683]
43216 2176.449963 104.25.62.43 192.168.2.112 HTTP2 86 DATA[683]
43217 2176.449963 104.25.62.43 192.168.2.112 HTTP2 85 DATA[683] (text/html)
43225 2176.485000 192.168.2.112 104.25.62.43 HTTP2 186 HEADERS[687]: GET /images/banners/l1.jpg
43226 2176.493644 104.25.62.43 192.168.2.112 HTTP2 625 HEADERS[681]: 302 Found, DATA[681]
43227 2176.493644 104.25.62.43 192.168.2.112 HTTP2 85 DATA[681] (text/html)
43231 2176.503699 192.168.2.112 104.25.62.43 HTTP2 399 HEADERS[689]: GET /nation=provinces_of_north_america
43232 2176.505646 104.25.62.43 192.168.2.112 HTTP2 687 HEADERS[687]: 200 OK, DATA[687]
43245 2176.506891 104.25.62.43 192.168.2.112 HTTP2 123 DATA[687], DATA[687]
43263 2176.509145 104.25.62.43 192.168.2.112 HTTP2 928 DATA[687]
43266 2176.509640 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[687], DATA[687] [TCP segment of a reassembled PDU]
43268 2176.509920 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[687] [TCP segment of a reassembled PDU]
43287 2176.512125 104.25.62.43 192.168.2.112 HTTP2 555 DATA[687]
43306 2176.514639 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[687], DATA[687], DATA[687]
43325 2176.516891 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[687] [TCP segment of a reassembled PDU]
43326 2176.516891 104.25.62.43 192.168.2.112 HTTP2 265 DATA[687], DATA[687]
43327 2176.516891 104.25.62.43 192.168.2.112 HTTP2 85 DATA[687] (JPEG JFIF image)
43379 2176.669957 192.168.2.112 104.25.62.43 HTTP2 537 HEADERS[691]: POST /cgi-bin/endorse.cgi
43380 2176.669987 192.168.2.112 104.25.62.43 HTTP2 135 DATA[691] (application/x-www-form-urlencoded)
43389 2176.701374 104.25.62.43 192.168.2.112 HTTP2 804 HEADERS[689]: 200 OK, DATA[689]
43390 2176.701877 104.25.62.43 192.168.2.112 HTTP2 1074 DATA[689]
43392 2176.703132 104.25.62.43 192.168.2.112 HTTP2 1179 DATA[689]
43393 2176.706284 104.25.62.43 192.168.2.112 HTTP2 280 DATA[689]
43396 2176.711797 104.25.62.43 192.168.2.112 HTTP2 1018 DATA[689]
43407 2176.748698 192.168.2.112 104.25.62.43 HTTP2 1724 HEADERS[693]: GET /images/ns-inhouse-skyscraper_1.png
43430 2176.773134 104.25.62.43 192.168.2.112 HTTP2 928 HEADERS[693]: 200 OK, DATA[693]
43441 2176.774385 104.25.62.43 192.168.2.112 HTTP2 253 DATA[693], DATA[693], DATA[693]
43442 2176.774385 104.25.62.43 192.168.2.112 HTTP2 85 DATA[693] (PNG)
43468 2176.913879 104.25.62.43 192.168.2.112 HTTP2 596 HEADERS[685]: 302 Found, DATA[685]
43469 2176.913879 104.25.62.43 192.168.2.112 HTTP2 85 DATA[685] (text/html)
43471 2176.916791 192.168.2.112 104.25.62.43 HTTP2 163 HEADERS[695]: GET /nation=deltarios
43473 2176.920869 104.25.62.43 192.168.2.112 HTTP2 626 HEADERS[691]: 302 Found, DATA[691]
43474 2176.920869 104.25.62.43 192.168.2.112 HTTP2 85 DATA[691] (text/html)
43476 2176.923626 192.168.2.112 104.25.62.43 HTTP2 405 HEADERS[697]: GET /nation=byzant
43495 2176.970629 104.25.62.43 192.168.2.112 HTTP2 248 DATA[689], DATA[689]
43516 2177.026834 192.168.2.112 104.25.62.43 HTTP2 187 HEADERS[699]: GET /images/banners/t15.jpg
43535 2177.054365 104.25.62.43 192.168.2.112 HTTP2 672 HEADERS[699]: 200 OK, DATA[699]
43546 2177.055872 104.25.62.43 192.168.2.112 HTTP2 428 DATA[699], DATA[699]
43565 2177.058114 104.25.62.43 192.168.2.112 HTTP2 928 DATA[699]
43570 2177.058639 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[699], DATA[699] [TCP segment of a reassembled PDU]
43589 2177.061093 104.25.62.43 192.168.2.112 HTTP2 213 DATA[699]
43595 2177.061702 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[699], DATA[699] [TCP segment of a reassembled PDU]
43607 2177.063370 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[699], DATA[699] [TCP segment of a reassembled PDU]
43624 2177.065121 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[699] [TCP segment of a reassembled PDU]
43641 2177.067623 104.25.62.43 192.168.2.112 HTTP2 1331 DATA[699], DATA[699]
43642 2177.067623 104.25.62.43 192.168.2.112 HTTP2 112 DATA[699]
43660 2177.069880 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[699] [TCP segment of a reassembled PDU]
43661 2177.069880 104.25.62.43 192.168.2.112 HTTP2 359 DATA[699], DATA[699], DATA[699] (JPEG JFIF image)
43666 2177.115379 104.25.62.43 192.168.2.112 HTTP2 845 HEADERS[695]: 200 OK, DATA[695]
43667 2177.115621 104.25.62.43 192.168.2.112 HTTP2 1081 DATA[695]
43669 2177.116629 104.25.62.43 192.168.2.112 HTTP2 1184 DATA[695]
43670 2177.116851 104.25.62.43 192.168.2.112 HTTP2 210 DATA[695]
43672 2177.124135 104.25.62.43 192.168.2.112 HTTP2 1000 DATA[695]
43673 2177.125871 104.25.62.43 192.168.2.112 HTTP2 752 HEADERS[697]: 200 OK, DATA[697]
43674 2177.125871 104.25.62.43 192.168.2.112 HTTP2 138 DATA[697]
43676 2177.126623 104.25.62.43 192.168.2.112 HTTP2 1076 DATA[697]
43678 2177.127872 104.25.62.43 192.168.2.112 HTTP2 1178 DATA[697]
43679 2177.128345 104.25.62.43 192.168.2.112 HTTP2 207 DATA[697]
43681 2177.143080 104.25.62.43 192.168.2.112 HTTP2 974 DATA[697]
43682 2177.143080 104.25.62.43 192.168.2.112 HTTP2 86 DATA[689]
43683 2177.143080 104.25.62.43 192.168.2.112 HTTP2 85 DATA[689] (text/html)
43704 2177.202676 192.168.2.112 104.25.62.43 HTTP2 480 HEADERS[701]: GET /images/banners/b11.jpg
43706 2177.224368 104.25.62.43 192.168.2.112 HTTP2 690 HEADERS[701]: 200 OK, DATA[701]
43717 2177.225677 104.25.62.43 192.168.2.112 HTTP2 528 DATA[701], DATA[701]
43736 2177.230724 104.25.62.43 192.168.2.112 HTTP2 928 DATA[701]
43739 2177.230724 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[701], DATA[701] [TCP segment of a reassembled PDU]
43740 2177.230724 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[701] [TCP segment of a reassembled PDU]
43754 2177.230876 104.25.62.43 192.168.2.112 HTTP2 146 DATA[701]
43772 2177.233151 104.25.62.43 192.168.2.112 HTTP2 1466 DATA[701], DATA[701], DATA[701]
43780 2177.238958 104.25.62.43 192.168.2.112 HTTP2 659 DATA[701], DATA[701] (JPEG JFIF image)
43796 2177.285618 104.25.62.43 192.168.2.112 HTTP2 1375 DATA[695]
43797 2177.285618 104.25.62.43 192.168.2.112 HTTP2 85 DATA[695] (text/html)
43801 2177.296875 104.25.62.43 192.168.2.112 HTTP2 1449 DATA[697]
43804 2177.297120 104.25.62.43 192.168.2.112 HTTP2 924 DATA[697]
43806 2177.297598 104.25.62.43 192.168.2.112 HTTP2 483 DATA[697]
43807 2177.297598 104.25.62.43 192.168.2.112 HTTP2 85 DATA[697] (text/html)


I've attached the code to Relendo below. I feel confident that I'm not distributing an illegal script here, since I used network tracing to verify that Relendo itself does not initiate simultaneous requests. This also shows makeAjaxQuery(), the center piece of Reliant's simultaneity handling, and how meticulous it is at ensuring everything is above-board and site-legal. Note that Eluvatar will be able to easily confirm that Relendo is based on Reliant through his access to Reliant's git repository, but any code-knowledgable NS staff member can as well, since they were sent at least two instances of Reliant's source distribution via GHR near the beginning of the investigation. If you do compare, note that most of the Relendo code comes from src/ts/nation.ts, with some pieces from src/ts/main.ts.

There will be more in a follow-up post.

Code: Select all
// ==UserScript==
// @name         Relendo
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       Roavin+Haku
// @match        https://www.nationstates.net/nation=*
// @match        https://www.nationstates.net/template-overall=none/nation=*
// @icon         data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
// @grant        none
// ==/UserScript==

let inQuery = false;

function makeAjaxQuery(url, method, data)
{
    let ajaxButtons = document.querySelectorAll('.ajaxbutton');
    return new Promise((resolve, reject) =>
    {
        function onLoadStart(e)
        {
            startTime = Date.now();
            // In case we discover we somehow made a new request before our last one concluded,
            // immediately abort it
            if (inQuery)
                xhr.abort();
            // Each button with class 'ajaxbutton' make a request to the NS webiste.
            // In order to abide by rule "4. Avoid Simultaneous Requests" we will keep all buttons
            // with this class disabled until we receive a complete response from the NS server.
            for (let i = 0; i != ajaxButtons.length; i++)
                ajaxButtons[i].disabled = true;
            inQuery = true;
        }

        async function onLoadEnd(e)
        {
            // We've received a complete response from the NS server, so we can allow more user input
            for (let i = 0; i != ajaxButtons.length; i++)
                ajaxButtons[i].disabled = false;
            inQuery = false;
            let loadtime = document.querySelector('#load-time');
            if (loadtime !== null)
                loadtime.innerHTML = String(Date.now() - startTime) + ' ms';
            resolve(xhr.response);
        }

        let startTime = 0;
        let xhr = new XMLHttpRequest();
        xhr.addEventListener('loadstart', onLoadStart);
        xhr.addEventListener('loadend', onLoadEnd);
        // Recommended by Eluvatar: https://forum.nationstates.net/viewtopic.php?p=30083979#p30083979
        const fixedUrl = url + "/script=relendo_by_roavin/userclick=" + Date.now();
        xhr.open(method, fixedUrl);
        xhr.responseType = 'text';
        if (data !== undefined)
            xhr.send(data);
        else
            xhr.send();
    });
}


function canonicalize(str)
{
    return str.trim().toLowerCase().replace(/ /g, '_');
}

function pretty(str)
{
    return str.replace(/_/g, ' ').replace(/\w+\s*/g, (txt) => txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase());
}

const localId = document.querySelector('input[name=localid]').value;

function getUrlParameters(url)
{
    const reg = new RegExp('\/([A-Za-z0-9-]+?)=([A-Za-z0-9_.+]+)', 'g');
    let params = {};
    let match = [];
    while ((match = reg.exec(url)) !== null)
        params[match[1]] = match[2];
    return params;
}

const urlParameters = getUrlParameters(document.URL);

const nationTitle = document.querySelector('.newtitlename');
const crossButton = document.createElement('input');
crossButton.setAttribute('type', 'button');
crossButton.setAttribute('value', 'Set Cross');
crossButton.setAttribute('class', 'button');
nationTitle.appendChild(crossButton);

function getNationEndorsements()
{
    let names = [];
    document.querySelectorAll(".unbox a.nlink").forEach((elm) => {
        var name = elm.href.substring(elm.href.indexOf("=") + 1);
        names.push(name);
    });
    return names;
}

console.log(getNationEndorsements());

async function setCrossClick(e)
{
    const nationName = urlParameters['nation'];
    let endorsingNations = await getNationEndorsements();
    const sidePanel = document.querySelector('#panel');
    const endorsementList = document.createElement('ul');
    for (let i = 0; i !== endorsingNations.length; i++) {
        const listItem = document.createElement('li');
        const endorseButton = document.createElement('input');
        endorseButton.setAttribute('type', 'button');
        endorseButton.setAttribute('class', 'ajaxbutton cross');
        endorseButton.setAttribute('value', "Endorse " + pretty(endorsingNations[i]));

        async function onEndorseClick(e)
        {
            let formData = new FormData();
            formData.set('nation', endorsingNations[i]);
            formData.set('localid', localId);
            formData.set('action', 'endorse');
            await makeAjaxQuery('/cgi-bin/endorse.cgi', 'POST', formData);
            e.target.parentElement.removeChild(e.target);
        };
        endorseButton.addEventListener('click', onEndorseClick);
        listItem.appendChild(endorseButton);
        endorsementList.appendChild(listItem);
    }
    sidePanel.appendChild(endorsementList);
}

crossButton.addEventListener('click', setCrossClick);
Last edited by Roavin on Fri May 27, 2022 5:29 pm, edited 1 time in total.
Helpful Resources: One Stop Rules Shop | API documentation | NS Coders Discord
About me: Longest serving Prime Minister in TSP | Former First Warden of TGW | aka Curious Observations

Feel free to TG me, but not about moderation matters.

User avatar
Tinhampton
Postmaster-General
 
Posts: 13700
Founded: Oct 05, 2016
Civil Rights Lovefest

Postby Tinhampton » Sat May 28, 2022 3:55 am

Are WA-banned players allowed to be cited as proposal co-authors while serving their bans? (Not asking for a friend. I remember that those WA-banned for Predator, at least, could neither join the WA nor serve as regional officers in non-native regions, to stop them raiding during their bans.)
The Self-Administrative City of TINHAMPTON (pop. 329,537): Saffron Howard, Mayor (UCP); Alexander Smith, WA Delegate-Ambassador

Authorships & co-authorships: SC#250, SC#251, Issue #1115, SC#267, GA#484, GA#491, GA#533, GA#540, GA#549, SC#356, GA#559, GA#562, GA#567, GA#578, SC#374, GA#582, SC#375, GA#589, GA#590, SC#382, SC#385*, GA#597, GA#607, SC#415, GA#647, GA#656, GA#664, GA#671, GA#674, GA#675, GA#677, GA#680, Issue #1580, GA#682, GA#683, GA#684, GA#692, GA#693, GA#715
The rest of my CV: Cup of Harmony 73 champions; Philosopher-Queen of Sophia; *author of the most popular SC Res. ever; anti-NPO cabalist in good standing; 48yo Tory woman w/Asperger's; Cambridge graduate ~ currently reading The World by Simon Sebag Montefiore

User avatar
Crazy girl
Game Moderator
 
Posts: 6276
Founded: Antiquity
Mother Knows Best State

Postby Crazy girl » Sat May 28, 2022 4:11 am

The World Assembly ban is a ban on their nations joining the World Assembly.

If you want to list one as a co-author on a proposal, that's fine.

User avatar
Roavin
Admin
 
Posts: 1777
Founded: Apr 07, 2016
Democratic Socialists

Postby Roavin » Sat May 28, 2022 4:47 am

This is post 2 of 3, and covers what happened between here and the ruling. The third post will come later and will respond to the ruling itself.

The bug I mentioned in the post above turns out not to be the issue; the place that I thought was "late" (the loadstart event) actually wasn't late at all; contrary to documentation, that event (at least in Chromium-based browsers) is triggered immediately rather than when the request has already been issued. This was confirmed via testing as well as by looking at the Chromium source code; Elu told me during our screenshare that he had also tested this and was not able to reproduce this theory.

However, we've since identified and tested something else that could lead to simultaneous requests (if those are even a thing, given the ruling), and it's not even Reliant's fault. Some Reliant users (including Luca) didn't turn off Breeze++ while operating Reliant, and both tools have keybinds, and so in certain situations a key could lead to both tools doing something at the same time. I wrote a script that simulated this environment and tested various scenarios to see in which case dual requests would be sent by looking at network traffic with WireShark, and was able to confirm in which cases a simultaneity violation occurs. The signature marker here would be that the server logs show two simultaneous requests, one identifying as Reliant and one not identifying at all — Breeze++ does not identify itself since it only provides keybinds for existing NS functionality, while Reliant identifies with every request it creates itself, in the same way (and with literally the same code) as Relendo above does.

I also stepped through both Reliant and Breeze to identify overlaps and if they could cause a gameplay benefit. My thinking and methodology here was this: For any simultaneous requests, the result of one request is thrown away and never displayed. Therefore, if both requests are idempotent (meaning they don't cause a change in the NS universe), there is no gameplay benefit, only unnecessary server load. If one request is not idempotent and is the one whose result is being shown, the same principle applies. However, if a non-idempotent request is thrown away in favor of showing the result of an idempotent request, there could be a benefit there (saving a load that would be required to go to the other page after performing the action), and if both requests are non-idempotent, it's certainly a gameplay benefit. (NB: I considered all non-idempotent requests rather than just restricted actions, because for example adding a nation to the dossier is arguably not a restricted action but is most certainly not idempotent and often occurs when using Reliant to chase). I could not find a case where there is a theoretical gameplay benefit to be had from using Reliant and Breeze at the same time, though obviously I'm both biased and also human, so I may have missed a case.

I demonstrated all this to a very interested Elu via screenshare on April 16. Immediately after the screenshare session, we also gave Elu access to two additional git repositories, one being a clone of the source repository and the other being the release repository (as of a few days ago, these repositories had not been accessed yet). Finally, I also submitted all my findings as well as my test scripts via two massive GHRs (5kB and 13kB respectively), with the last being sent on April 23.

This was the primary hypothesis, based on the little information we had: it explains the simultaneity violations, it explains how it looks like not all usages violate simultaneity, and also explain why it looks like the tool does more than one action per user click. Confirming that this is indeed the issue should have been a relatively trivial matter with server logs. On May 12, I sent another GHR asking for a status update, and even gave a pair of specific requests (with the Reliant-request going to `/template-overall=none/region=<someregion>` and the non-Reliant-request going to `/template-overall=none/page=blank/reliant=main`) that were likely to have come from a specific Reliant user.

What follows is a specific collection of GHRs that I sent in the past months, which I'm posting here for full context and transparency. Note that in one case, I did not include the Tampermonkey script that I sent over since it reproduces a possible simultaneity violation.

GHR sent sometime in April (not sure when, possibly the 15th?), detailing how the initial bug I discovered wasn't the actual bug (includes references to Chromium source code as well as a test script I wrote):

Regarding Reliant:

I had previously submitted a GHR about finding a simultaneity bug within Reliant. I've done some tests, and it turns out that this is not the issue. I think I have, however, found the real issue, which I'll detail in a follow-up.

Now, the reason why loadstart isn't the issue (as I suspected before) is that the loadstart event, at least in Chromium, isn't fired when I expected. To quote MDN (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/loadstart_event):
> The loadstart event is fired when a request has started to load data.

I interpreted that to mean that the actual loading of the data has begun, i.e. it'd be fired when the response headers are received or maybe even when the first byte of content is received. The truth, however, is that at least in Chromium, loadstart is synchronously fired when XMLHttpRequest.send() is called. I confirmed that with a test (Tampermonkey script attached) plus by looking at the Chromium source code:
https://source.chromium.org/chromium/ch ... prequest.c

As you can see, XMLHttpRequest::send() will (in non-error cases) call XMLHttpRequest::CreateRequest(), which is what will call the loadstart event handler before even returning. (NB: the _async flag says whether the XHR-object is async, which it is and should always be)

This can be tested with the Tampermonkey printed below by opening page=blank/, pressing the "do it" button, and observing what happens in the text area. The variable "useReliantStyleHandling" in the script can even be set to true to disable the "do it" button in loadstart rather than before send(), like Reliant does (not that it makes a difference). An example output from just now looks like this:

2022-04-15T21:24:18.129Z Button press
2022-04-15T21:24:18.131Z XHR readystate=1
2022-04-15T21:24:18.131Z before send()
2022-04-15T21:24:18.132Z XHR loadstart
2022-04-15T21:24:18.132Z after send()
2022-04-15T21:24:18.688Z XHR readystate=2
2022-04-15T21:24:18.689Z XHR readystate=3
2022-04-15T21:24:18.740Z XHR readystate=3
2022-04-15T21:24:18.864Z XHR readystate=3
2022-04-15T21:24:18.865Z XHR readystate=4
2022-04-15T21:24:18.866Z XHR loadend

As you can see, loadstart is fired synchronously from send().

Code: Select all
// ==UserScript==
// @name         loadstart test
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       Roavin
// @match        https://www.nationstates.net/page=blank
// @icon         https://www.google.com/s2/favicons?sz=64&domain=nationstates.net
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // true if simultaneity blocking is performed in loadstart rather than when beginning the XHR
    var useReliantStyleHandling = false;

    var elmContent = document.getElementById("content");
    console.log(elmContent);

    var elmLog = document.createElement('textarea');
    elmLog.rows = 20;
    elmLog.cols = 100;
    elmContent.appendChild(elmLog);

    function log(str)
    {
        elmLog.value += (new Date()).toISOString() + ' ' + str + '\n';
        elmLog.scrollTop = elmLog.scrollHeight;
    }

    var currentXhr = null;

    var elmButton = document.createElement('button');
    elmButton.id = "simul_doit";
    elmButton.innerText = "do it";
    elmButton.onclick = function() {
        log("Button press");
        if (currentXhr != null)
            return;

        if (!useReliantStyleHandling)
            elmButton.disabled = true;
        currentXhr = new XMLHttpRequest();
        currentXhr.addEventListener('loadstart', function() {
            log("XHR loadstart");
            if (useReliantStyleHandling)
                elmButton.disabled = true;
        });
        currentXhr.addEventListener('loadend', function() {
            log("XHR loadend");
            elmButton.disabled = false;
            currentXhr = null;
        });
        currentXhr.addEventListener('readystatechange', function(event) {
            log("XHR readystate=" + currentXhr.readyState.toString());
        });
        var url = "https://www.nationstates.net/page=blank/script=simultest_by_roavin/userclick=" + Date();
        currentXhr.open("GET", url);
        currentXhr.responseType = 'text';
        log("before send()");
        currentXhr.send();
        log("after send()");
    };
    elmContent.appendChild(elmButton);
})();




A GHR I sent sometime in April, pointing out that VPN use may have made things difficult, explaining why VPNs were used, and offering further information about players using them:
Regarding Reliant:

As we were discussing Mall's most recent reply, we (collectively) stumbled upon what might be leading to the delays in "our own review on the back end to analyze what specific players did, when they did it, and what benefit was conferred by it", and it doesn't even have anything to do with Reliant itself.

Some players were using Reliant at update with VPNs despite normally operating NS without one. The reason here is simple, and explained in more detail below, but TL;DR it's to cut short the time it takes to do TLS handshakes between CloudFlare and the actual NS server, which depending on the geographical location of the player can improve the request latency by up to half a second. This roundtrip latency is a topic I had discussed with both [v] and Elu many times, as far back as February 2017 (!).

For me personally, not using a VPN meant I had page loads of 650-700ms with the occasional 250ms inbetween, while with a VPN in Seattle I could get relatively consistent 300ms page loads, a much improved experience.

The Reliant users that I know of that used a VPN in this way are Tim, Sir Merlin, and myself. I also know that Emodea and several others use a VPN in this fashion, but not with Reliant (they never got access to Reliant).

Could that be one of the issues, and if so, would it help if I were to reach out to Reliant users and provide a more definitive list of who used Reliant with a VPN?

---

Detailed explanation:

NS is accessed with CloudFlare, with each user's requests being routed to the closest CF ray (in my case, Frankfurt in Germany), which in turn then sends the request to the real NationStates IP. After NS switched to HTTPs (late 2016 or very early 2017, I don't remember), people in North America had no issues but those of us in Europe or elsewhere had much increased latencies to the site, which negatively impacted particularly those of us participating in military gameplay.

After some back and forth, I was able to reverse engineer the issue (which was later confirmed to me by Elu): While the Keep-Alive time of each player's connection to CloudFlare is huge, the Keep-Alive between CloudFlare and NS is only one second. Once the HTTP connection between CF and NS is down and needs to be established again, that requires a further TLS handshake, which adds an additional roundtrip. When operating from a CF ray in, say, Vancouver, that's not an issue, since the latencis are so short that a round trip is another 20-40ms. But from Frankfurt, the TLS handshake roundtrip alone costs around 400-500ms.

(CloudFlare actually recommends much higher Keep-Alive for the site's HTTP server, though NS uses Apache and Apache has trouble with too many simultaneous connections unlike newer HTTP servers like nginx - all of this I've discussed with Elu before).

Elu later made a change to NS' Apache settings that improved this slightly, but it's still an issue that crops up for military gameplayers across the (non-North American) world. Later, a player discovered that using a VPN to connect to a CF ray closer to where the NS servers are removes that issue - while the full round trip latency remains the same, the frequent TLS handshakes now only have the short roundtrip latency.



The big GHR I sent on April 23, detailing possible violations when using Reliant with Breeze, and showing why I did not believe there to be a gameplay benefit from it:
Regarding Reliant:

I do apologize that this follow-up took as long as it did. To summarize, I believe I have found the problem. When a user uses Reliant and Breeze++ at the same time, simultaneous requests are possible. This is a simultaneity violation resulting not from bugs (or malice) in either Reliant or Breeze, but rather due to the player running both tools. I have reproduced this behavior with a custom script (attached below). The tell-tale sign in the server logs should be that there are two simultaneous requests, one identifying as Reliant and the other one not identifying at all. I've furthermore analyzed possible instances where this could lead to a tangible gameplay benefit, and have found none. I demonstrated a first version of this hypothesis to via screenshare last weekend; this GHR contains much more analysis.

That using both tools at the same time could lead to two simultaneous requests is intuitively apparent: Both tools have keybinds, so it's easy to conceive of cases where a single key leads to two separate actions at the same time. The question is which such bindings could lead to such a case, and that is a much more difficult question to answer, because most keybinds in both Reliant and Breeze do different things based on the page they are on; in addition, Reliant allows the user to freely change their keybinds to their liking, and so there are a lot of different permutations. So, I took a different approach instead in analyzing this issue, quickly coming up with a theoretical reproduction.

I observed that Breeze will, upon a key press, do one of the folllowing: refresh, navigate to another page (via location.href), click an existing NS button, or do nothing. Reliant will, upon a key press, do any of those or issue an XHR. I noticed that for these purposes, a refresh and changing location.reload() act identically. I then wrote a Tampermonkey script (attached to this GHR) that registers itself for document 'keyup' events twice, once to simulate Reliant and once to simulate Breeze, and tested various permutations.

For all permutations with any combination of refreshes, href changes, or clicks (except two clicks), the two changes are so quick that the browser doesn't even send a request for the first href change (confirmed with Wireshark). There is a remote possibility that JS execution is delayed enough between setting the first href and setting the second one - I tested this case (with an explicit delay of 300ms) and that would lead to a second requst, but I think it's reasonable to consider this highly unlikely. Therefore, no violation here.

(NB: I could not get Wireshark to decode QUIC packets, so I turned off QUIC support in my browser and instead observed the HTTP2 traffic. I don't think this changes the result, however, since QUIC is just another transport for the same kind of thing issued to the CloudFlare server, and CloudFlare will interact with NS independently of that)

If two clicks are executed at the same time, the browser doesn't create a second request, therefore no violation here.

If a NS button that is hijacked to send a XHR is clicked twice, it only sends one XHR since the button's event handler calls preventDefault(), and therefore the second call never arrives.

Finally, If any one of a refresh, href change, or click happens at the same time as a XHR, then two simultaneous requests are sent. About half the time (on my machine), the XHR will progress to actually receiving data (readyState == 3) before the page is reloaded; in other words, there are two simultaneous requests on the wire in this situation, and therefore a simultaneity violation.

In conclusion, a simultaneity violation occurs only when a key leads Reliant to issue a XHR and Breeze to issue some other request at the same time.

So, now we have a repro for the bug and can move forward to determine when in practice it would appear. This is rather difficult however, due to the staggering amount of possible permutations to step through - both breeze and reliant do different things depending on the current page, and Reliant has configurable keybinds that could map any Reliant handler with any Breeze key. I had begun to make a list of all possible permutations in an excel file, but decided to not pursue that further due to the sheer amount of busy work to put that together. But I don't think such a master list is necessary anyway, for two reasons. First, It's much easier in reverse to verify that a pair of requests visible in the server log could be caused by Reliant+Breeze interplay, and if given such pairs of requests, I could absolutely do that if requested. Second, and more importantly, we already know that a simultaneity violation occurs.

Even though I'm (obviously) biased in this regard, I instead investigated the gameplay benefit that a player could receive from running both tools at the same time. My thinking here is this: For any simultaneous requests as above, the result of one request is thrown away and never displayed. Therefore, if both requests are idempotent, there is no gameplay benefit, only unnecessary server load. If one request is not idempotent and is the one whose result is being shown, the same principle applies. However, if a non-idempotent request is thrown away in favor of showing the result of an idempotent request, there could be a benefit there (saving a load that would be required to go to the other page after performing the action), and if both requests are non-idempotent, it's most likely a gameplay benefit.

(NB: I considered all non-idempotent requests rather than just restricted actions, because adding a nation to the dossier is arguably not a restricted action but is most certainly not idempotent and is frequently done by using Reliant idiomatically)

Reliant's main page does a lot of XHRs in response to keys. Breeze does not interact with it at all, except to refresh (N). This is not a benefit however, since the main page initially does not show (or even have) information queried from NS, but rather this information is retrieved via XHRs in response to clicks or button presses. So if a non-idempotent action is performed at the same time as a refresh through Breeze, the non-idempotent action is performed but the resulting page is a fresh instance of the main page containing no data, so if anything it's a gameplay detriment for this to happen.

Reliant's prep page also does XHRs and is only interacted with by Breeze through refreshes. Here, a refresh at the same time as an action is not a gameplay detriment (since the page is loaded again with information from Reliant's local state), but there is also no advantage there.

On region pages, Reliant hijacks the move button to replace it with a XHR. Breeze clicks that button, but no violation occurs as explained above. Reliant also adds other buttons but Breeze does not interact with them. If the buttons were brought to a state where Reliant would issue a restricted action bound to the M key, which also triggers a Breeze move, that also won't lead to a violation since the move button is now subject to Reliant's simultaneity handling. If anything is bound to Breeze' N key to refresh, that would lead to simultaneous requests but without gameplay benefit since the target page is once again the region page but with its Reliant state reset (same as with the main page).

On nation pages, Reliant does not hijack the endorsement button, and adds its own buttons that can be used to issue other endorsements (clickable through a keybind). Here, at first glance, one could think that two non-idempotent actions could take place at the same time: If the list of nations to cross-endorse with is already loaded, and Reliant's endorsekey is mapped to E or C, then pressing that key would endorse both the nation in question as well as its first endorsee at the same time with simultaneous requests. However, Reliant prioritizes endorsing the target nation over processing the cross list, so this reverts to both Reliant and Breeze clicking a form button at the same time which, as described above, does not lead to simultaneous requests.

Putting this together, I could not find a case where there is a theoretical gameplay benefit to be had from using Reliant and Breeze at the same time. Once again, though, I am most certainly biased and also human, so I may have missed a case.

[the test script, totalling 4806 characters over 156 lines, was printed here in the original GHR, but it has been removed as the script violates simultaneity and I don't want to be dinged for it]
Helpful Resources: One Stop Rules Shop | API documentation | NS Coders Discord
About me: Longest serving Prime Minister in TSP | Former First Warden of TGW | aka Curious Observations

Feel free to TG me, but not about moderation matters.

User avatar
Syberis
Diplomat
 
Posts: 689
Founded: Jan 21, 2016
Iron Fist Consumerists

Postby Syberis » Sat May 28, 2022 7:57 am

Great writeup Roavin. To your knowledge, was there any admin response to the GHRs sent, and was any of the suggested lookup or testing performed? I'm trying to wrap my head around the timeframe involved here and the workload requested.
I've finally found what I was looking for
A place where I can be without remorse
Because I am a stranger who has found
An even stranger war

Zaolat wrote:WHO THE F*** IS SYBERIS

User avatar
Roavin
Admin
 
Posts: 1777
Founded: Apr 07, 2016
Democratic Socialists

Postby Roavin » Sat May 28, 2022 8:05 am

[quick interlude before post 3 to answer Syb]

Syberis wrote:Great writeup Roavin. To your knowledge, was there any admin response to the GHRs sent


There was some brief back-and-forth via GHR in the first couple of days, as I clarified my involvement in Reliant. To the later GHRs (including the ones I posted), the response was either silence or a "thanks, passed on to admin".

Syberis wrote:was any of the suggested lookup or testing performed?


Elu did say during our screenshare that he investigated my (now-disproven) initial suspicion. I'm not aware of anything else being done after, despite asking several times. Which doesn't necessarily mean it wasn't done, of course, but I'm not aware of it.
Helpful Resources: One Stop Rules Shop | API documentation | NS Coders Discord
About me: Longest serving Prime Minister in TSP | Former First Warden of TGW | aka Curious Observations

Feel free to TG me, but not about moderation matters.

User avatar
Roavin
Admin
 
Posts: 1777
Founded: Apr 07, 2016
Democratic Socialists

Postby Roavin » Sat May 28, 2022 9:23 am

Now, onto the ruling. Let me start with a TL;DR: I believe the most reasonable course of action at this time is for site admins to reveal (either in public, or to Haku and/or myself) at least one pair of request URLs that were shown by server logs to violate simultaneity. This should be a low effort task, as non-admin staff and the community can do the rest; doing so is vital to maintain the image of integrity in site staff, to uphold the professed values and operating processes of site staff, and to maintain basic fairness to affected players.

Let me start by stepping through the justification in the ruling:




Sedgistan wrote:
  • We do not believe it is likely that the script was written with the intention of operating illegally.
  • The players who have developed and used Reliant have, to the best of our knowledge, cooperated in good faith with us since our announcement.


I'm happy to hear that. For the rest of the community, my previous post should give insight into Reliant's design and our cooperation with regard to operating within site rules so you should be able to mostly judge this for yourselves as well.



Sedgistan wrote:
  • We do not believe it is likely that all usage of Reliant was illegal, and it is probable that it was only in some cases that it violated the rules.


The emphasis here is a bit weird, so allow me to lightly rephrase: "We believe it is unlikely that all usage of Reliant was illegal[...]". With all the hypotheses I have been able to come up with over the past three months (even the original now-disproven loadstart idea), I certainly agree with this aspect.



Sedgistan wrote:
  • Nonetheless, in those cases, the use of Reliant in an illegal fashion is likely to have provided in-game advantage to those using it, potentially significantly so in some cases.


This part I disagree with, based on all the information I know.

In terms of conflicts between Reliant and Breeze, see my previous post and in particular the last GHR quoted there, where I stepped through potential sequence points between those two tools. I've since double checked my work there and have not found any additional cases beyond those I had already listed. A pair of example request URLs would help to see if there is such a case afterall.

Beyond that, Sedge stated the following:

Sedgistan wrote:This was observed with both requests to move region and to endorse nations - I don't think I need to explain the in-game benefit of carrying those out quicker?


Regarding moving regions, I'm confused what this could even mean, unless the move action is taken at the same time as another action. Note that it is physically impossible to have simultaneous requests to move and endorse. The quick non-technical explanation is this: NationStates generates a "localId" for a session, which is reset when doing things like logging in, admitting WA, or moving regions (but not endorsing). The "localId" is sent back to the NS server with any requests that are restricted actions (like endorsing a nation) and verified there - if they don't match, you get the dreaded "security check". So, a move+endo cannot be done with simultaneous requests, as the endorsement request does not yet have the new fresh "localId" it needs to do that endorsement.

Of course, it's possible that a move and another request that is not a restricted action are sent at the same time - that could be easily seen by a pair of example request URLs that violate simultaneity.

Regarding endorsing, the implication I (and others) have gotten from various posts is that this is based on endorsing really fast, but this on its own is not an indication of a simultaneity violation. Endorsing that fast is trivial for those in the right geographical location (and the right internet connection) with or without tools, as has been demonstrated in this very thread, so the idea that this on its own implies a violation is trivially disproven.

That Reliant, despite not needing it, violates simultaneity when rapidly endorsing is disproven by Relendo, and as I mentioned in that post, that Relendo is almost entirely Reliant's cross-endorsement code can be verified by NS admin or even any any appropriately code-savvy non-admin member of NS staff, given that the entire Reliant source code was submitted via GHR.

Of course, there could still be a bug in all of this that I was not able to find after all this time, which a pair of example request URLs could help to identify.



Sedgistan wrote:
  • We believe it is highly likely that those players that benefited from using Reliant in an illegal fashion could not have been unaware that they were violating the rules.


It's hard to address this without knowing what the actual violation was. Reliant does a lot of things - cross-endorsement, dossier management, chasing, activity watching, prepping, etc., and even though Reliant handles all its requests in essentially the same way - either through makeAjaxQuery() (as seen in Relendo), or through a separate function that also disables buttons and then uses normal browser functionality to change the current page, it would help to have a pair of example request URLs to see from which part of Reliant this originates.

That being said, if this is based on endorsing fast, then I sincerely don't know why NS staff claims that players "could not have been unaware" of such violations, since endorsing manually can be just as fast if not faster than using a tool like Reliant or Relendo, which principally make the process easier but not faster. I would love to be corrected on this, if I'm missing something.

If it's based on other things related to weird or unusual happenings, we don't track all happenings during chases, but we do see enough glitches here and there (which we do report at times), but none of them were in such a way that they could imply a violation. So, I don't understand how GK, Luca, and Alt (who all have extremely fast connections to NS) could have noticed.



So, based on the little information I have, and all the investigation I've already done, I cannot imagine a scenario where NS staff's portrayal of Reliant could be accurate. That being said, I could be wrong, but if I had just the tiniest bit of a lead on where to look, I could probably be able to find the actual problem pretty easily. You might have detected a theme in what I've written so far: a pair of example request URLs would do the trick, and I can do the rest, no additional admin input needed. Let me explain why this is, in my opinion, both appropriate and necessary.

First, the Reliant ruling explicitly states that site staff do not consider Reliant to be malicious on its own, ergo it falls under Category 3B, in which [violet] explicitly states that NS admin will "[...]generally respond to these bots by contacting the owner and informing them of the problem". I think it's reasonable to say that "informing [...] of the problem" will be a bit more specific than just the fact that there is a violation, and instead include some hint as to where the problem lies. In fact, when Storm had a bug where it spammed the servers with API requests, Eluvatar even submitted a bug report on Storm's github page, where it includes a (redacted) excerpt from the server logs — in other words, the very thing I had been asking for all this time (and more).

Second, in this post, Sedgistan lays out the staff goals for this kind of situation, with the last point being "Explain the above [rules violations] to avoid future such violations". This has not been done, except to state that there is a simultaneity violation. We have been prompted to fix whatever needs to be fixed within Reliant, and are more than happy to do so at some point, but we cannot as we don't know what it is. We cannot prevent future violations within Reliant or other scripts without either this explanation or, alternatively, at least a hint where to look so that the community (in this case, probably me) can find and explain what the actual problem was.

Third, it's relatively tame here but the mood off-site about this is quite sour, because to an observer (and also to Reliant users) this does not look like due process was done, but rather like the investigation was cancelled, and three people were picked to WA ban just to have done something and call it a day. The reasons it looks this way include:
  • Stating that ostensibly, the problem has not been reproduced despite being given pretty much everything and then some to do so.
  • Stating that the investigation has ceased and that it's not admin's job to investigate this, when this is ahistorical to admin-coder interaction in the past
  • The only bit of evidence given this entire time was just people endorsing very fast; the notion that this therefore implies a scripting violation was was immediately and independently disproven by the community.
  • The question whether the current toolset can even detect simultaneity violation, given that as I stated here, the web server software NS uses does not by default log sufficient information to determine it, and Elu's server log snippet in the Storm issue he filed also does not log sufficient information to determine actual simultaneity violations.
  • That this was ostensibly found based on a player report via GHR. Assuming that the initial report made via GHR that made mention is a military gameplayer (which is a reasonable assumption, as other kinds of NS players are unlikely to look at defender happenings that closely), the fact that the report was ostensibly simply based on endorsing fast casts strong doubts on their sincerity, and so in combination with the above points, it looks to some (not all or probably even most) observers like the initial case was started based on, and finally judged based upon, just the hunch or hope of one player with a grudge, rather than objective fact.



So, please, for literally everyone's benefit (be they defender, raider, neutral coder, players interested in site staff integrity, or site staff itself), can you provide just one pair of request URLs that were shown by server logs to violate simultaneity?
Helpful Resources: One Stop Rules Shop | API documentation | NS Coders Discord
About me: Longest serving Prime Minister in TSP | Former First Warden of TGW | aka Curious Observations

Feel free to TG me, but not about moderation matters.

User avatar
Bormiar
Ambassador
 
Posts: 1555
Founded: Mar 25, 2019
Inoffensive Centrist Democracy

Postby Bormiar » Sat May 28, 2022 12:19 pm

Wymondham wrote:I just want to note that, around 20 minutes ago, GCR Delegate North East Somerset achieved 6 endorsements in a second with no scripts at all and no containers; despite living over 4,500 miles from vancouver with an internet speed of 18.4Mb/s download and 5.4Mb/s upload.

(Image)

You do not even need to live 100km from Vancouver or have 1.5Gb/s internet to manage 6 endorsements in a second, so it's not even as if Luca's endorsement rate is unique to even a small group of people, I have managed 4 endorsements in a second myself in the past without scripts. Would the moderation team therefore be able to explain how achieving 6 endorsements in a second can therefore be taken as an indication of rulebreaking activity when it can easily be achieved with no scripts by someone with a poor internet connection living over 4,500 miles away from the server?

If the moderation team would like more examples of this being possible with no scripts, crap ping and abysmal internet, I'm more than happy to try and find some more.

I just noticed that since this (as well as Roav's example) is done manually, it could very easily — and legally — have been done with some simultaneity. In fact, I think it's likely. Please correct me if I've misunderstood, but it seems to me that that makes it much harder to compare with Luca's case, and therefore very bad evidence.

User avatar
Altmoras
Diplomat
 
Posts: 827
Founded: Jan 25, 2012
Inoffensive Centrist Democracy

Postby Altmoras » Sat May 28, 2022 3:31 pm

Sedgistan wrote:If you're asking for examples of the illegal behaviour, the majority of that comes in the form of server logs, which I'm not going to reformat for the sake of publishing (sorry; I've also spent a significant amount of my own time on the Reliant case and trying to get us to a resolution on it, and there's only so much more I'll put into it). I don't mind posting the publicly observable national happenings that were cited in the original GHR report:

2/14/2022, 5:48:22 PM MST: Emnietom endorsed Lunaflower-2.
2/14/2022, 5:48:22 PM MST: Emnietom endorsed Nivilons.
2/14/2022, 5:48:22 PM MST: Emnietom endorsed Imperial Sword.
2/14/2022, 5:48:22 PM MST: Emnietom endorsed Zequinha do Abacaxi.
2/14/2022, 5:48:22 PM MST: Emnietom endorsed Expansivian Onionist Revolutionary Force.
2/14/2022, 5:48:22 PM MST: Emnietom endorsed Little Mermraider.

2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Venicos Fiancee.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed The Airforce Guy.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed The Toukaian Night Bomber Squadron.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Scorchy Boi 1.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Tablerepublic.
2/14/2022, 5:55:57 PM MST: Lucabaduka endorsed Giraffe Liberator.



Is this a joke? If endorsing quickly is a punishable offense then I should have been DOS before Reliant was even a twinkle in Haku's eye. I go that fast or faster on every large cross I've ever done unless I show up early and have to endo piecemeal.

We believe it is highly likely that those players that benefited from using Reliant in an illegal fashion could not have been unaware that they were violating the rules.


Had I been aware of any rules violation committed by myself I would have gleefully confessed at the beginning of this 3 month saga. I have as little regard remaining for this game as this game apparently has for me.
Benevolent Thomas-Today at 11:15 AM
"I'm not sure if Altmoras has ever been wrong about anything."

Inhumanly good at the game according to official word of site staff.

User avatar
Syberis
Diplomat
 
Posts: 689
Founded: Jan 21, 2016
Iron Fist Consumerists

Postby Syberis » Sun May 29, 2022 10:25 am

It really disappoints me that after an initial wave of communication, after new details have come to light the site team has not posted at all outside of CG making a clarification on how... resolution authorship works. Not even a "yeah none of this is relevant" or "we're looking at things."

This lack of communication is exactly the problem that led to literal months of frustration and memes from the GP community, and we're right back to it.
I've finally found what I was looking for
A place where I can be without remorse
Because I am a stranger who has found
An even stranger war

Zaolat wrote:WHO THE F*** IS SYBERIS

User avatar
Sedgistan
Site Director
 
Posts: 35471
Founded: Oct 20, 2006
Anarchy

Postby Sedgistan » Sun May 29, 2022 12:57 pm

There isn't anything to update people with at present. CG posted yesterday; myself multiple times the day before.

As per my previous post, I've requested an admin comment here, to clarify where possible details around the legality issues. An appeal has also been lodged of the punishments; while those are tricky to handle in situations where rulings have had input from multiple staff members, it's going to be considered.

Further updates will come when there's actually something to update people on.

PreviousNext

Advertisement

Remove ads

Return to Technical

Who is online

Users browsing this forum: Abyssaly, Cot Deviet, Ferret Civilization, Great Indonesian Republic, Kinegiener, Lunayria, Oiapoque-Calcoene

Advertisement

Remove ads