-
Notifications
You must be signed in to change notification settings - Fork 12
/
ProtocolDescription.xml
2545 lines (2338 loc) · 108 KB
/
ProtocolDescription.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version='1.0'?>
<!DOCTYPE ProtocolDescription SYSTEM "ProtocolDescription.dtd">
<!-- transform this xml into html (so you can view it in a browser): -->
<?xml-stylesheet type="text/xsl" href="ProtocolDescription_xml2html.xsl"?>
<!--
NOTE: This document is available in HTML form at: https://springrts.com/dl/LobbyProtocol/
-->
<ProtocolDescription>
<Intro>
<h3>Introduction</h3>
<p>
This is a simple text protocol in a "human readable form". Text protocol was chosen because
it's easier to debug and implement on the client side. It does require some more overhead,
but since server and clients do not communicate much anyway, this is not an issue.
</p>
<h3>Nomenclature</h3>
<p>
We use two terms for "clients": <i>client</i> and <i>user</i>.
At first, <i>user</i> was considered to be a registered or logged-in client.
The two terms are used uncleanly though, so you may best think of them as equal.
</p>
<h4>Formating rules: lines, words and sentences</h4>
<p>
All communication must be encoded in utf-8. Binary data is not permitted.
</p>
<p>
A <i>line</i>, also known as a <i>message</i>, consists of a single protocol command, plus its arguments, communicated as a single string, and terminated by a newline character (\n).
Lines may be of any length, although the server enforces a somewhat (arbitrary) limit of 10,000 chars.
A natural implementation of the protocol will result in almost all lines being under 1,000 chars in length.
<!--Nevertheless, some commands (like <clink name="AGREEMENT"/>) do divide the data they send into several lines, but only for clarity.-->
</p>
<p>
Each line begins with a <i>command</i>, written in capitals.
The arguments of the command, which come next, come in two types: <i>words</i> and <i>sentences</i>.
Word arguments are sequences of non-whitespace characters, and are separated from each other by whitespaces.
Sentence arguments are sequences of words (separated by whitespaces),
which are considered as a single argument.
Sentences arguments are seperated from each other by tab characters (\t).
</p>
<p>
The word arguments of a command <i>always</i> come first, followed by its sentence arguments.
The last word argument is separated from the first sentence argument by a single whitespace.
Some examples:
</p>
<p>
<ul>
<li> <clink name="JOINEDBATTLE"/>, with 2 word arguments: <br/><code>JOINEDBATTLE 25869 oxido</code></li>
<li> <clink name="UPDATEBATTLEINFO"/>, with 4 words and 1 sentence argument: <br/><code>UPDATEBATTLEINFO 25903 1 0 -210360064 Trojan Hills v03</code></li>
<li> <clink name="BATTLEOPENED"/>, with 10 words and 4 sentences: <br/><code>BATTLEOPENED 4437 0 0 BlackHoleHost6 71.2.10.1 8626 10 0 0 -1213614804 Spring 104.0    Coastline_Dry_V1    The BlackHoleHost - Conflict    Balanced Annihilation V9.46</code></li>
</ul>
</p>
<p>
(So, when a client talks to the server, if you want to include a tab character in a sentence, you can't!)
</p>
<h4>Legend</h4>
<p>
The following notation is used within the arguments of a command.
A given argument should be assumed to be a word, unless {} is present, in which case it is a sentence.
<ul>
<li>{...} = a sentence arg </li>
<li>{...} {...} = two sentence args (which should be separated by a tab character!)</li>
<li>| = multiple choices for the argument i.e. "OR"</li>
<li>[...] = an optional argument</li>
</ul>
</p>
<p>
All commands, except for some developer/admin specific commands, are listed in the commands section of this document.
Their arguments are listed in order, and should be sent in that order.
</p>
<!--<p>
For future use (currently only applies to PROMOTE):
A few commands require that they be invoked using a JSON format, which allows arguments to be named (and, consequently, sent in any order).
Named arguments can be written in any order and the names are case sensitive, e.g. username != userName.
The main benefit of named arguments is that they help with backwards compatibility when the protocol changes, and it is planned that more commands will use JSON in future, particularly commands related to statuses and battles.
</p>
-->
<h3>Protocol rules</h3>
<h4> Keep-alive signals</h4>
<p>
A client must maintain a 'constant' connection with the server, to ensure that network timeouts and disconnects can be detected.
If no data is being transfered, the client must send <clink name="PING"/> commands to the server at regular intervals -- every 30 seconds is recommended.
The server will reply with a <clink name="PONG"/> command.
If no data or ping command has been sent for 60 seconds, the server will assume a network timeout and disconnect the client.
Similarly, if the client does not hear back within 30 seconds of a ping, it should assume the server has gone down.
</p>
<h4>Zero status assumption</h4>
<p>
When a client joins the server, the client will be notified about statuses of users only for cases where this status is non-zero.
A client's status and battle status should be assumed to be 0, if not specified otherwise by the server.
(This saves on bandwidth, not that we really need to...)
</p>
<h4> Status change updates </h4>
<p>
Most of the commands that notify about some changes are forwarded to the source of the change.
For example: When a client sends a <clink name="MYBATTLESTATUS"/> command,
the server sends a <clink name="CLIENTBATTLESTATUS"/> command to all users in the battle,
including the client who sent the <clink name="MYBATTLESTATUS"/> command.
This allows the client to synchronize their local status with the server's,
after the server has verified that the status change is valid; therefore, it also serves as confirmation mechanism.
</p>
<h4>Message IDs</h4>
<p>
Any message can be prefixed with a message ID.
For example:
<code>
'#123 SAY main hello world!'
</code>
is a valid <clink name="SAY"/> command with message ID 123. The server will use this ID in any message sent as a reply, for example:
<code>
'#123 SAID main Betalord hello world!'
</code>
would communicate the greeting on to other clients with a <clink name="SAID"/> command.
</p>
<p>
The message ID has only one function: to ease tracking server responses for the client.
They makes it easier to implement commands that require multiple responses in both directions.
You can also use them with <clink name="PING"/>/<clink name="PONG"/> to measure your round trip time.
</p>
<p>
Message IDs should be non-negative values, within 31-bit range (so, 0 up to 2147483647).
Negative values are reserved by the server for internal use.
</p>
<p>
<h3>Sub-systems</h3>
</p>
<h4>Email Verification</h4>
<p>
Uberserver carries out email verification for registering new accounts, for account recovery and for changing email address.
In order to verify an email address: the server sends a four or eight digit verification code to an email address, and the client must send this code back to the server.
Each verification code is valid for 48h, and allows max 3 attempts at verification.
</p>
<p>
The following pairs list which commands notify that verification codes were sent, and where they are expected back:
<ul>
<li> sent: <clink name="REGISTRATIONACCEPTED"/>, back: <clink name="CONFIRMAGREEMENT"/> </li>
<li> sent: <clink name="CHANGEEMAILREQUESTACCEPTED"/>, back: <clink name="CHANGEEMAIL"/> </li>
<li> sent: <clink name="RESETPASSWORDREQUESTACCEPTED"/>, back: <clink name="RESETPASSWORD"/></li>
</ul>
The code can be re-sent, up to three times, using <clink name="RESENDVERIFICATION:client"/>.
</p>
<h4> Channels and Battles </h4>
<p>
A channel is an IRC-like setting in which users can send messages, which are typically visible to all other users in the same channel.
A battle is a special type of channel, with extra properties corresponding to the extra information needed to set up and launch an online multiplayer game of Spring.
</p><p>
Channels can be either registered or unregistered. Unregistered channels simply forward messages between clients and have no stored settings or data.
Registered channels can set topics, password, mutes/bans, store a history, and so on; these data/settings are stored within the server database.
</p><p>
Each registered channel has a founder who sets the various permanent properties of the channel (such as a password).
The founder may also pick channel operators, who are able to handle day-to-day stuff like mutes, topics and bans.
</p>
<h4> ChanServ </h4>
<p>
ChanServ is a fake client, which the server shows as present in all registered channels and battles.
It listens for text-based channel commands (listed on <url>https://springrts.com/wiki/ChanServ</url>) and also carries them out.
The long term plan is that ChanServ will be replaced with server commands and a client-side GUI.
</p>
<h4> Bridge bots </h4>
<p>
The interface stemming from <clink name="BRIDGECLIENTFROM"/>, <clink name="JOINFROM"/> and <clink name="SAYFROM"/>
allows users in external chat channels (e.g. Discord, IRC) to join and talk natively within Uberserver channels and battles, via bridge bot.
Users talking via a bridge bot are referred to as bridged users.
</p>
<p>
Bridged users are identified to the bridge bot by a <i>(location, external_id)</i> pair, which should be unique (and should not change when the same user is bridged again).
Each external user also has a <i>external_username</i> which should be their current username within their location, and such the <i>(location, external_username)</i> is also unique (e.g. use the screenname on Discord, with the 'extra' #1234 part appended when necessary to achieve uniqueness).
At most one bridge bot can bridge users from any given location.
</p>
<p>
For non bridge bots, the server identifies bridged users by a username of the form <i>external_username:location</i> for bridged users.
Note that the ':' char is not permitted in normal usernames.
</p>
<h4>Syncing</h4>
<p>
To be in <i>sync</i> means to have the same versions of all the content
required to play a particular game (including the map, engine, dependencies, etc).
See <clink name="JOINBATTLE:server"/> or the unitsync documentation for details.
</p>
<h4>Hole punching</h4>
<p>
<quote>
Hole punching is a networking technique
for establishing communications between two parties in separate organizations
who are both behind restrictive firewalls.
</quote>
<url>https://en.wikipedia.org/wiki/Hole_punching</url>
We use it to allow clients to connect to the lobby server, that would otherwise not be able to.
See the commands
<clink name="TASSERVER"/>,
<clink name="OPENBATTLE"/>,
<clink name="UDPSOURCEPORT"/>,
<clink name="CLIENTIPPORT"/>,
<clink name="HOSTPORT"/>.
<!--It will probably not work in LAN mode, especially if combined with players from the internet.-->
</p>
<h3>Hosting battles</h3>
<p>
Any client may host a <i>battleroom</i>, also referred to as a <i>battle</i>, which is (effectively) a special type of chat channel with extra features related to setting up and launching a multi-player game.
A client may join at most one battleroom at any given time.
This includes when the client is hosting the battle. The server automatically enforces this rule.
</p>
<p>
Clients detect whether a battle has a game currently in progress by monitoring the hosts status.
For example, if the hosts status changes to "in game", then the battles is "in game".
</p>
<p>
<code>spring.exe</code> uses UDP connections for online multi-player games (TCP is not suitable due to latency).
These connections are made between the host client (of the battleroom) and non-host clients.
Consequently, the lobby protocol contains a set of commands dedicated to setting up UDP connections between host/non-host clients.
</p>
<h4> Setting up UDP connections: non-host perspective </h4>
<p>
Before joining a battle, a client is expected to first acquire their UDP source port from the server.
This is done by sending a UDP packet, which a response coming via <clink name="UDPSOURCEPORT"/>.
Once the client has done that, the client should keep sending UDP packets to the server at regular 20 second intervals,
to keep the connection alive and ensure that the clients router does not remove the UDP connection from its port translation table.
After <code>spring.exe</code> is launched, these UDP keep-alive signals may be discontinued (because then <code>spring.exe</code> will be sending regular UDP packets).
Once <code>spring.exe</code> exits, the client should resume sending UDP keep-alive signals.
</p>
<p>
Just before starting the game, the host should send a <clink name="HOSTPORT"/> command to the user,
containing the host's public UDP source port.
The lobby cient should replace the battles port with this one,
as it will have to connect to the game using this port and not the original one
(that was acquired through the <clink name="BATTLEOPENED"/> command).
</p>
<p>
Note: If the client is not hosting, then it does not need to "punch through", which is does have to do when hosting, because <code>spring.exe</code> will take care of that. <i> Todo: make this clearer!</i>
</p>
<h4> Setting up UDP connections: host perspective </h4>
<p>
Before sending the <clink name="OPENBATTLE"/> command,
the host should try to acquire its UDP source port from the server,
just to make sure it can acquire it at all
(better to find out it does not work before hosting,
than right before starting the game).
However, the client does not need to keep this UDP connection alive,
since it will not be used to actually host the game.
It is just a test to see if UDP connectivity works.
</p>
<p>
When a new client joins the battle,
the server will send a <clink name="CLIENTIPPORT"/> command to the host,
informing the host of this client's public UDP source port.
The host should remember this information,
as he will have to use it when starting the game.
</p>
<p>
Right before starting the game,
the host should try to acquire his source port again.
This time he will actually use this port to host the game.
Upon starting the game,
the server will notify all clients participating in his battle about his port,
using the <clink name="HOSTPORT"/> command.
The host does not need to keep refreshing his connection
to keep the port open,
as spring.exe will do that for him.
Upon returning from the first game that was hosted in his battleroom,
the host does not need to keep refreshing it either (as a client would have to do --
because when the host starts a new game
it will have to acquire a new source port anyway).
</p>
<h4> Why? </h4>
<p>
This setup exists because some host clients might play "single-player" games with bots
before opening their battleroom to other players,
in which case any UDP port that was originally set up would have long ago timed out (spring.exe would not keep it alive during a single player game!).
For this reason, the host has to acquire a new UDP port each time it starts a battle.
</p>
<h3> Further information </h3>
<p>
If this document doesn't provide what you are looking for,
you may have a look at the Uberserver source code, in <code>protocol.py</code>,
or ask for help in the <code>#sy</code> channel of the SpringRTS lobbyserver.
</p>
</Intro>
<CompatFlags>
This list details the current compatibility flags a client may send
with the <clink name="LOGIN:client"/> command.
Clients should update their behaviour for compatibility with the changes below, and send the appropriate flag to announce compatibility.
<br/><br/>
This list may be emptied when a new protocol version is released, at which point legacy clients may break.
<p><ul>
<li><b>b</b>: <clink name="JOINBATTLEREQUEST"/> and <clink name="JOINBATTLEACCEPT"/>, <clink name="JOINBATTLEDENY"/> (this flag is optional).</li>
<li><b>sp</b>: script passwords </li>
<li><b>u</b>: use <clink name="SAY"/> to talk in battles, support for <clink name="SAYFROM"/> command set.</li>
</ul></p>
<p>
In a small number of cases, the arguments of a command were different in earlier versions of the protocol.
The details below refer to the latest dev version of the protocol, and assume that the client has all the latest compatibility flag present.
</p>
</CompatFlags>
<Versions>
<Version Name="0.38+dev -- current live version --">
Nothing new yet!<br/><br/>
</Version>
<Version Name="0.38">
<ul>
<li> Added <b>u</b> compat flag, for Battle/Channel merge:
<ul>
<li><clink name="JOINBATTLE:server"/> sends an extra arg, the name of the channel in which the battle chat takes place.</li>
<li> Use <clink name="SAY"/> and <clink name="SAYEX"/> to talk in battles i.e. into that channel.</li>
<li> Users joining/leaving a battle are automatical joined/left to its channel.</li>
</ul>
</li>
<li> The functionality of some previous compat flags is now mandatory for all clients:
<ul>
<li> <b>t</b>: <clink name="CHANNELTOPIC"/> omits time, empty topic string signifies no topic </li>
<li> <b>l</b>: args of <clink name="ADDUSER"/></li>
<li> <b>cl</b>: Engine Name / Engine Version args of <clink name="BATTLEOPENED:server" />/ <clink name="OPENBATTLE:client"/> </li>
</ul>
</li>
<li> Removed support for some deprecated compat flags:
<ul>
<li> <b>et</b>: NOCHANNELTOPIC and related</li>
<li> <b>p</b>: <clink name="AGREEMENT:server"/>, the agreement is sent in plaintext format</li>
<li> <b>cu, sd, m, a</b>: superceeded or were already no ops</li>
</ul>
The server no longer expects to be sent these flags.
</li>
<li> Added new interface for bridge bots: <clink name="BRIDGECLIENTFROM"/>, <clink name="UNBRIDGECLIENTFROM"/>,
<clink name="JOINFROM"/>, <clink name="SAYFROM"/>, <clink name="LEAVEFROM"/>, <clink name="CLIENTSFROM"/>.
</li>
<li> Added email verification and related features:
<ul>
<li>Added/updated <clink name="CHANGEEMAIL"/> command set. </li>
<li>Added <clink name="RESENDVERIFICATION"/> command set. </li>
<li>Added <clink name="RESETPASSWORD"/> command set. </li>
<li> When email verification is enabled,
<ul>
<li> <clink name="REGISTER"/> requires an email arg</li>
<li> <clink name="CONFIRMAGREEMENT"/> requires a verification code arg</li>
<li> <clink name="CHANGEEMAIL"/> requires a verification code arg</li>
<li> <clink name="RESETPASSWORD"/> requires a verification code arg</li>
</ul>
</li>
</ul>
</li>
<li> Replaced the whole moderation interface, with new/updated commands.</li>
<li> Removed all cypto commands from 0.37. The server now uses TLS, beginning with <clink name="STLS"/>.</li>
<li> Removed SAYDATA command set. </li>
<li> Removed SAYBATTLEPRIVATE command set. </li>
<li> Removed FORCEJOINBATTLE. </li>
<li> Removed JOINBATTLEREQUEST command set.</li>
<li> Deprecated SAYBATTLE, SAYBATTLEEX. </li>
<li> Deprecated MUTE, UNMUTE, MUTELIST, SETCHANNELKEY. </li>
</ul>
</Version>
<Version Name="0.37">
<ul>
<li>Added the <clink name="NOCHANNELTOPIC:server"/> server command.</li>
<li>Added the <clink name="IGNORE"/> command set.</li>
<li>Added crypto commands for secure connections (edit: removed/replaced in 0.38).</li>
<li>Added the SAYDATA command set (edit: removed in 0.38).</li>
</ul>
</Version>
<Version Name="0.36">
<ul>
<li>Added the <clink name="LISTCOMPFLAGS:client"/> client command.</li>
<li>Added the <clink name="COMPFLAGS:server"/> server command.</li>
<li>Added the FORCEJOINBATTLE command set (edit: removed in 0.38).</li>
<li>Added the CONNECTUSER command set (edit: removed in 0.38).</li>
<li>Added the <clink name="CHANGEEMAIL:client"/> client command.</li>
<li>Added the <clink name="EXIT:client"/> client command.</li>
<li>Added the <clink name="GETINGAMETIME:client"/> client command.</li>
<li>removed REQUESTUPDATEFILE, OFFERFILE, FORGEREVERSEMSG, USERID, GENERATEUSERID, ACQUIREUSERID</li>
<li>'scriptPassword' argument added: This change affects the following commands:
<clink name="LOGIN"/>, <clink name="JOINBATTLE"/>, <clink name="JOINEDBATTLE"/>.</li>
</ul>
<ul>
<li>
<i>Compatibility-Flags</i>
<ul>
<li><b>sp</b>: the scriptPassword parameter, sent in the <clink name="JOINEDBATTLE"/> command</li>
</ul>
</li>
</ul>
</Version>
</Versions>
<CommandList>
<Command Name="PING" Source="client">
<Description>
Requests a <clink name="PONG"/> back from the server.
<br/><br/>
Clients should send <clink name="PING"/> once every 30 seconds, if no other data is being sent to the server. For details, see the notes above on keep-alive signals.
</Description>
<Response>
<clink name="PONG"/>
</Response>
</Command>
<Command Name="PONG" Source="server">
<Description>
Sent as the response to a <clink name="PING"/> command.
</Description>
</Command>
<!--- tls -->
<Command Name="STLS" Source="client">
<Description>
Initiate a TLS connection to the server.
</Description>
<Response>
<clink name="OK"/>
</Response>
</Command>
<Command Name="OK" Source="server">
<Description>
Sent as the response to a <clink name="STLS"/> command. The client now can now start the tls connection. The server will send again the greeting
<clink name="TASSERVER"/>.
</Description>
</Command>
<!--- greeting / exiting -->
<Command Name="TASSERVER" Source="server">
<Arguments>
<Argument Name="protocolVersion" Optional="no" Sentence="no">
This is the lobby protocol version used by the server.
The client may check if it supports this version before attempting to log in.
</Argument>
<Argument Name="springVersion" Optional="no" Sentence="no">
Default spring version used on lobby server. Can be locally determinated by calling unitsyncs GetSpringVersion(), IsSpringReleaseVersion() and GetSpringVersionPatchset(),
which will return the version, for example "95.0" or "94.1.1-1062-g9d16c2d develop".
<br/>
Note that if the value of this parameter is "*",
the client should simply ignore it since this means that
the server does not contain any updates nor does it require latest Spring version
(this is usually the case when the server is running in LAN mode).
</Argument>
<Argument Name="udpPort" Optional="no" Sentence="no">
This is server UDP port where the "NAT Help Server" is running.
This is the port to which clients should send their UDP packets
when trying to figure out their public UDP source port.
This is used with some NAT traversal techniques (e.g. "hole punching").
</Argument>
<Argument Name="serverMode" Optional="no" Sentence="no">
Tells what mode the server is in.
Currently valid are:
<ul>
<li>0 - normal mode</li>
<li>1 - LAN mode</li>
</ul>
</Argument>
</Arguments>
<Description>
This is the first message (i.e. "greeting message") that a client receives
upon connecting to the server.
</Description>
<Examples>
<Example>TASSERVER 0.35 0.72b1 8201 0</Example>
<Example>TASSERVER 0.35 * 8201 0</Example>
</Examples>
</Command>
<Command Name="EXIT" Source="client">
<Arguments>
<Argument Name="reason" Optional="yes" Sentence="yes">
Clients may optionally specify a reason for quitting.
If the user simply wished to exit, many lobby clients send their name and version.
</Argument>
</Arguments>
<Description>
Clients should send this as their last command before severing their connection to the server, to notify
a clean and deliberate disconnect.
</Description>
<Response>
The server is not required to acknowledge, or respond, to the exiting client. <br/>
Other clients via server messages or status change commands.
</Response>
</Command>
<!--- registration -->
<Command Name="REGISTER" Source="client">
<Arguments>
<Argument Name="userName" Optional="no" Sentence="no"/>
<Argument Name="password" Optional="no" Sentence="no">
The user's password string. If a client uses a secure session
(which means the command itself shall be encrypted, including
its arguments), it should send BASE64(password), otherwise it
should send BASE64(MD5(password)).
</Argument>
<Argument Name="email" Optional="yes" Sentence="no">
A valid email address. Case will not be considered.
</Argument>
</Arguments>
<Description>
The client sends this command when trying to register a new account.
Note that the client must not already be logged in,
or else the server will deny his request.
<br/>
<br/>
The username and password are given sanity/uniqueness checks, and these primarily determine the servers response. If email verification is enabled, and no valid email address is provided, the server will deny the registration.
</Description>
<Response>
<clink name="REGISTRATIONDENIED"/>
or <clink name="REGISTRATIONACCEPTED"/>.
</Response>
<Examples>
<Example>REGISTER Johnny Gnmk1g3mcY6OWzJuM4rlMw== enormous_crocodile@hawtmail.com</Example>
</Examples>
</Command>
<Command Name="REGISTRATIONDENIED" Source="server">
<Arguments>
<Argument Name="reason" Optional="no" Sentence="yes"/>
</Arguments>
<Description>
Sent in response to a <clink name="REGISTER"/> command,
if registration has been refused.
</Description>
</Command>
<Command Name="REGISTRATIONACCEPTED" Source="server">
<Description>
Sent in response to a <clink name="REGISTER"/> command,
if registration has been accepted.
<br/><br/>
If email verification is enabled, sending of this command notifies that the server has sent a verification code to the users email address. This verification code is expected back from the client in <clink name="CONFIRMAGREEMENT"/>
<br/><br/>
Upon reciept of this command, a lobby client would normally be expected to reply with a <clink name="LOGIN"/> attempt (but this is not a requirement of the protocol).
</Description>
</Command>
<!--- login -->
<Command Name="LOGIN" Source="client">
<Arguments>
<Argument Name="userName" Optional="no" Sentence="no"/>
<Argument Name="password" Optional="no" Sentence="no">
The user's password string. If a client uses a secure session
(which means the command itself shall be encrypted, including
its arguments), it should send BASE64(password), otherwise it
should send BASE64(MD5(password)).
</Argument>
<Argument Name="cpu" Optional="no" Sentence="no">
deprecated, set it to 0
</Argument>
<Argument Name="localIP" Optional="no" Sentence="no">
The client should supply his local IP (e.g. 192.168.x.y, or whatever it uses)
so the server can forward local IPs to clients behind the same NAT
(this resolves some of the host/joining issues).
If the client is unable to determine its local IP,
he should send "*" instead.
</Argument>
<Argument Name="lobby name and version" Optional="no" Sentence="yes"/>
<Argument Name="userID" Optional="yes" Sentence="no">
This is a unique user identification number provided by the client-side software.
It has to be an unsigned 32 bit integer which is generated by calculating the crc32
from the binary mac address of the primary network interface.
If it can't be determinated it has to be set to 0.
</Argument>
<Argument Name="compFlags" Optional="yes" Sentence="yes">
When connecting, the lobby client can tell the lobby server
that it is compatible with some optional functionalities
that break backward compatibility.
Each flag in this space separated parameter indicates a specific functionality
(like IRC user/channel flags).
By default, all the optional functionalities are considered as not supported by the client.
For the current list of flags, see the section on recent changes.
</Argument>
</Arguments>
<Description>
Sent by a client asking to log on to the server.
<br/><br/>
Note: if the client has not yet confirmed the user agreement,
then server will send the <clink name="AGREEMENT"/> to the client as a response to this command.
In this case the response to <clink name="LOGIN"/> will be delayed until after <clink name="CONFIRMAGREEMENT"/>.
<br/><br/>
Also see <clink name="LOGININFOEND"/> command.
</Description>
<Response>
If the client has previously accepted the user agreement: <clink name="ACCEPTED"/> or <clink name="DENIED"/>. <br/>
If the client has not already acepted the user agreement: <clink name="AGREEMENT"/>.<br/>
See these commands for further responses.
</Response>
<Examples>
<Example>LOGIN Johnny Gnmk1g3mcY6OWzJuM4rlMw== 3200 192.168.1.100 SpringLobby 0.264</Example>
<Example>LOGIN Johnny Gnmk1g3mcY6OWzJuM4rlMw== 3200 * SpringLobby 0.264</Example>
<Example>LOGIN Johnny Gnmk1g3mcY6OWzJuM4rlMw== 3200 * SpringLobby 0.264<b>[TAB]</b>123456</Example>
<Example>LOGIN Johnny Gnmk1g3mcY6OWzJuM4rlMw== 3200 * SpringLobby 0.264<b>[TAB]</b>0<b>[TAB]</b>a b</Example>
</Examples>
</Command>
<Command Name="ACCEPTED" Source="server">
<Arguments>
<Argument Name="userName" Optional="no" Sentence="no"/>
</Arguments>
<Description>
Sent as a response to the <clink name="LOGIN"/> command, if it succeeded.
Next, the server will send much info about clients and battles:
<ul>
<li>multiple <clink name="MOTD"/>, each giving one line of the current welcome message</li>
<li>multiple <clink name="ADDUSER"/>, listing all users currently logged in</li>
<li>multiple <clink name="BATTLEOPENED"/>, <clink name="UPDATEBATTLEINFO"/>, detailing the state of all currently open battles</li>
<li>multiple <clink name="JOINEDBATTLE"/>, indiciating the clients present in each battle</li>
<li>multiple <clink name="CLIENTSTATUS"/>, detailing the statuses of all currently logged in users</li>
</ul>
Finally,
it will send a <clink name="LOGININFOEND"/> command
indicating that it has finished sending all this info. Note that, except for this final command, the commands/info listed above may be sent to the client in any order.
</Description>
</Command>
<Command Name="DENIED" Source="server">
<Arguments>
<Argument Name="reason" Optional="no" Sentence="yes"/>
</Arguments>
<Description>
Sent as a response to a failed <clink name="LOGIN"/> command.
</Description>
</Command>
<Command Name="LOGININFOEND" Source="server">
<Description>
Sent by the server, indicating that it has finished sending the login info, completing the sequence initiated by <clink name="ACCEPTED"/>
</Description>
<Examples>
</Examples>
</Command>
<!--- agreement -->
<Command Name="AGREEMENT" Source="server">
<Arguments>
<Argument Name="agreement" Optional="no" Sentence="yes">
The user agreement is sent in "Text" format (.txt file streamed via socket).
</Argument>
</Arguments>
<Description>
Sent by the server upon receiving a <clink name="LOGIN"/> command,
if the client has not yet agreed to the server's "terms-of-use".
The server may send multiple AGREEMENT commands,
each of corresponds to a new line in the agreement text,
finishing with an <clink name="AGREEMENTEND"/> command.
The client should send <clink name="CONFIRMAGREEMENT"/>
and then resend the <clink name="LOGIN"/> command,
or disconnect from the server if he has chosen to refuse the agreement.
</Description>
<Response>
No response is expected until <clink name="AGREEMENTEND"/> is received.
See that command for more info.
</Response>
<Examples>
</Examples>
</Command>
<Command Name="AGREEMENTEND" Source="server">
<Description>
Sent by the server after multiple <clink name="AGREEMENT"/> commands.
This way, the server tells the client that he has finished sending the agreement
(this is the time when the lobby client should popup the "agreement" screen
and wait for the user to accept/reject it).
</Description>
<Response>
A response is not mandatory, but the server now awaits a <clink name="CONFIRMAGREEMENT"/> command from the client, providing that the user agreed to the agreement.
Otherwise, the client should disconnect from the server, and restart the <clink name="LOGIN"/> sequence.
</Response>
</Command>
<Command Name="CONFIRMAGREEMENT" Source="client">
<Arguments>
<Argument Name="verificationCode" Optional="yes" Sentence="no">
</Argument>
</Arguments>
<Description>
Confirm that the user agreed to the user agreement, and supply an email verification code (if necessary).
</Description>
<Response>
<clink name="ACCEPTED"/>, if the verification was either accepted or was not needed. <br/>
<clink name="DENIED"/>, if the verification code was not accepted.
</Response>
</Command>
<Command Name="MOTD" Source="server">
<Arguments>
<Argument Name="message" Optional="no" Sentence="yes"/>
</Arguments>
<Description>
Sent by the server after <clink name="ACCEPTED"/>.
The server may send multiple MOTD commands, each MOTD corresponds to one line of the current welcome message.
</Description>
<Examples>
</Examples>
</Command>
<!--- account management -->
<Command Name="RENAMEACCOUNT" Source="client">
<Arguments>
<Argument Name="newUsername" Optional="no" Sentence="no"/>
</Arguments>
<Description>
Will rename the current account name to newUsername.
The user has to be logged in for this to work.
After the server renames the account, it will disconnect the client.
</Description>
<Response>
No formal response is required,
although the server may reply with a <clink name="SERVERMSG"/>.
</Response>
<Examples>
<Example>RENAMEACCOUNT Johnny2</Example>
</Examples>
</Command>
<Command Name="CHANGEPASSWORD" Source="client">
<Arguments>
<Argument Name="oldPassword" Optional="no" Sentence="no"/>
<Argument Name="newPassword" Optional="no" Sentence="no"/>
</Arguments>
<Description>
Will change the password of the users's account.
</Description>
<Response>
No formal response is required,
although the server may reply with a <clink name="SERVERMSG"/>.
</Response>
</Command>
<Command Name="CHANGEEMAILREQUEST" Source="client">
<Arguments>
<Argument Name="newEmail" Optional="no" Sentence="no">
The email address the user wishes to change too.
</Argument>
</Arguments>
<Description>
Requests a verification code, to be sent to a new email address that the user wishes to associate to their account.
<br/><br/>
Even if email verification is disabled, it is intended that the client will call this before calling <clink name="CHANGEEMAIL"/>.
If email verification is disabled, the response will be a <clink name="CHANGEEMAILREQUESTDENIED"/>, containing a message informing the user that a blank verification code will be accepted.
</Description>
<Response>
<clink name="CHANGEEMAILREQUESTDENIED"/> or <clink name="CHANGEEMAILREQUESTACCEPTED"/>
</Response>
</Command>
<Command Name="CHANGEEMAILREQUESTACCEPTED" Source="server">
<Description>
Notifies that a verification code was sent, in response to <clink name="CHANGEEMAILREQUEST"/>.
<br/><br/>
No response is required from the client, although a <clink name="CHANGEEMAIL"/> command would normally be sent once the user has supplied their verification code.
</Description>
</Command>
<Command Name="CHANGEEMAILREQUESTDENIED" Source="server">
<Arguments>
<Argument Name="errorMsg" Optional="no" Sentence="yes"/>
</Arguments>
<Description>
Notifies that a verification code was not sent, in response to <clink name="CHANGEEMAILREQUEST"/>.
</Description>
</Command>
<Command Name="CHANGEEMAIL" Source="client">
<Arguments>
<Argument Name="newEmail" Optional="no" Sentence="no">
The email address the user wishes to change too.
</Argument>
<Argument Name="verificationCode" Optional="yes" Sentence="no">
The verification code recieved as a result of <clink name="CHANGEEMAILREQUESTACCEPTED"/>.
</Argument>
</Arguments>
<Description>
Asks the server to change the email address associated to the client. See also <clink name="CHANGEEMAILREQUEST"/>, which would typically be called first.
</Description>
<Response>
<clink name="CHANGEEMAILDENIED"/> or <clink name="CHANGEEMAILACCEPTED"/>
</Response>
</Command>
<Command Name="CHANGEEMAILACCEPTED" Source="server">
<Description>
Notifies that client that their email address was changed, in response to <clink name="CHANGEEMAIL"/>.
</Description>
</Command>
<Command Name="CHANGEEMAILDENIED" Source="server">
<Arguments>
<Argument Name="errorMsg" Optional="no" Sentence="yes"/>
</Arguments>
<Description>
Notifies that the email address could not be changed, in response to <clink name="CHANGEEMAIL"/>.
</Description>
</Command>
<Command Name="RESENDVERIFICATION" Source="client">
<Arguments>
<Argument Name="newEmail" Optional="no" Sentence="no">
The email address the user wished to change too, or register with, but has forgotten/lost/eaten or not recieved their verification code for.
</Argument>
</Arguments>
<Description>
Request that an active verification code to be re-sent.
</Description>
<Response>
<clink name="RESENDVERIFICATIONDENIED"/> or <clink name="RESENDVERIFICATIONACCEPTED"/>
</Response>
</Command>
<Command Name="RESENDVERIFICATIONACCEPTED" Source="server">
<Description>
Notifies that a verification code was re-sent, in response to <clink name="RESENDVERIFICATION"/>.
</Description>
</Command>
<Command Name="RESENDVERIFICATIONDENIED" Source="server">
<Arguments>
<Argument Name="errorMsg" Optional="no" Sentence="yes"/>
</Arguments>
<Description>
Notifies that a verification code was not re-sent, in response to <clink name="RESENDVERIFICATION"/>.
</Description>
</Command>
<Command Name="RESETPASSWORDREQUEST" Source="client">
<Arguments>
<Argument Name="email" Optional="no" Sentence="no">
The email address associated to the acccount.
</Argument>
</Arguments>
<Description>
Requests a verification code, to be sent to the email address of a user wishing to reset their password.
</Description>
<Response>
<clink name="RESETPASSWORDREQUESTACCEPTED"/> or <clink name="RESETPASSWORDREQUESTDENIED"/>
</Response>
</Command>
<Command Name="RESETPASSWORDREQUESTACCEPTED" Source="server">
<Description>
Notifies that a verification code was sent, in response to <clink name="RESETPASSWORDREQUEST"/>.
<br/><br/>
No response is required from the client, although a <clink name="RESETPASSWORD"/> command would normally be sent.
</Description>
</Command>
<Command Name="RESETPASSWORDREQUESTDENIED" Source="server">
<Arguments>
<Argument Name="errorMsg" Optional="no" Sentence="yes"/>
</Arguments>
<Description>
Notifies that a verification code was not sent, in response to <clink name="RESETPASSWORDREQUEST"/>.
</Description>
</Command>
<Command Name="RESETPASSWORD" Source="client">
<Arguments>
<Argument Name="email" Optional="no" Sentence="no">
The email address the user wishes to change too.
</Argument>
<Argument Name="verificationCode" Optional="no" Sentence="no">
The verification code recieved as a result of <clink name="RESETPASSWORDREQUESTACCEPTED"/>.
</Argument>
</Arguments>
<Description>
Asks the server to change the password associated to the client. See also <clink name="RESETPASSWORDREQUEST"/>, which would typically be called first.
</Description>
<Response>
<clink name="RESETPASSWORDDENIED"/> or <clink name="RESETPASSWORDACCEPTED"/>
</Response>
</Command>
<Command Name="RESETPASSWORDACCEPTED" Source="server">
<Description>
Notifies that client that their password was changed, in response to <clink name="RESETPASSWORD"/>. The new password will be emailed to the client.
</Description>
</Command>
<Command Name="RESETPASSWORDDENIED" Source="server">
<Arguments>
<Argument Name="errorMsg" Optional="no" Sentence="yes"/>
</Arguments>
<Description>
Notifies that the password could not be changed, in response to <clink name="RESETPASSWORD"/>.
</Description>
</Command>
<!--- other users logins -->
<Command Name="ADDUSER" Source="server">
<Arguments>
<Argument Name="userName" Optional="no" Sentence="no"/>
<Argument Name="country" Optional="no" Sentence="no">
A two-character country code based on ISO 3166 standard.
See <url>http://www.iso.org/iso/en/prods-services/iso3166ma/index.html</url>
</Argument>
<Argument Name="cpu" Optional="no" Sentence="no">
deprecated, see the <clink name="LOGIN"/> command.
</Argument>
<Argument Name="userID" Optional="no" Sentence="no"/>
<Argument Name="lobbyID" Optional="no" Sentence="yes">
A string of text sent by the client, typically identifying the lobby client they are using.
</Argument>
</Arguments>
<Description>
Tells the client that a new user joined a server.
The client should add this user to his clients list,
which he must maintain while he is connected to the server.
</Description>
</Command>
<Command Name="REMOVEUSER" Source="server">
<Arguments>
<Argument Name="userName" Optional="no" Sentence="no"/>
</Arguments>
<Description>
Indicates that a user disconnected from the server.
The client should remove this user from his clients list,
which he must maintain while he is connected to the server.
</Description>
</Command>
<!-- server messages -->
<Command Name="SERVERMSG" Source="server">
<Arguments>
<Argument Name="message" Optional="no" Sentence="yes"/>
</Arguments>
<Description>
A general purpose message sent by the server.
The lobby client program should display this message to the user in a non-invasive way, but clearly visible to the user
(for example, as a SAYEX-style message from the server, printed into all the users chat panels).
</Description>
<Examples>
<Example>SERVERMSG Server is going down in 5 minutes for a restart, due to a new update.</Example>
</Examples>
</Command>
<Command Name="SERVERMSGBOX" Source="server">
<Arguments>
<Argument Name="message" Optional="no" Sentence="yes"/>
<Argument Name="url" Optional="yes" Sentence="yes">
If specified, the lobby client should ask the user
if he wants this URL to be opened in a browser window.
The lobby client should then (once the user clicked OK)
launch the default browser and open this URL in there.
</Argument>
</Arguments>
<Description>
The lobby client program should display this message to the user in an invasive way, which requires response from the user (for example, in a dialogue box with an OK button).
</Description>
</Command>
<!-- channel commands -->
<Command Name="CHANNELS" Source="client">
<Description>
Sent by a client when requesting the list of all channels on the server
</Description>
<Response>
A series of <clink name="CHANNEL"/> commands,
followed by an <clink name="ENDOFCHANNELS"/> command.
</Response>