1,585
edits
DrinkyBird (talk | contribs) (Correct the flag value for SQF2_VOICECHAT) Tag: Source edit |
DrinkyBird (talk | contribs) (Document the rework segmented protocol) Tag: Source edit |
||
Line 189: | Line 189: | ||
|} | |} | ||
=== | === Challenge packet === | ||
Send the server the following packet: | Send the server the following packet: | ||
Line 232: | Line 195: | ||
! Type||Value||Description | ! Type||Value||Description | ||
|- | |- | ||
|Long || 199|| Launcher challenge | |Long || 199 || Launcher challenge | ||
|- | |- | ||
|Long || Flags || Desired information | |Long || Flags || Desired information | ||
Line 240: | Line 203: | ||
|Long || Flags2 || Optional. The extended information you want. Ensure you specify <tt>SQF_EXTENDED_INFO</tt> in the normal Flags field as well. | |Long || Flags2 || Optional. The extended information you want. Ensure you specify <tt>SQF_EXTENDED_INFO</tt> in the normal Flags field as well. | ||
|- | |- | ||
|Byte || Segmented || Optional. Set this to | |Byte || Segmented || Optional. Set this to '''2''' to indicate that you want a segmented response. | ||
|} | |} | ||
Line 261: | Line 224: | ||
|- | |- | ||
! <tt>SERVER_LAUNCHER_SEGMENTED_CHALLENGE</tt> | ! <tt>SERVER_LAUNCHER_SEGMENTED_CHALLENGE</tt> | ||
| | | 5660032 | ||
| Accepted; segmented information follows | | Accepted; segmented information follows | ||
|} | |} | ||
Line 273: | Line 236: | ||
|Byte || Segment || Segment number. If the most significant bit is set, then this is the last segment. | |Byte || Segment || Segment number. If the most significant bit is set, then this is the last segment. | ||
|- | |- | ||
| | |Byte || NumSegments || Total number of segments that will be sent. | ||
| | |- | ||
|Short || Size || The size of this. | |||
|- | |- | ||
| | |Short || Offset || Offset into the full packet this packet contains. | ||
|- | |- | ||
| | |Short || TotalSize || Total size of the data to be sent. | ||
|} | |} | ||
The segmented responses contain a full launcher packet split up into multiple segments. To use them, create a buffer of TotalSize bytes, then copy the data from each segment at the given offset. | |||
=== Packet contents === | |||
The full packet contains the following header: | |||
{| class="wikitable" | {| class="wikitable" | ||
Line 309: | Line 261: | ||
== Field data == | == Field data == | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 535: | Line 483: | ||
|} | |} | ||
=== | === Extended flags === | ||
{| class="wikitable" | {| class="wikitable" | ||
Line 608: | Line 556: | ||
! Type || Value || Description | ! Type || Value || Description | ||
|- | |- | ||
| Long || | | Long || 199 || The launcher challenge. | ||
|- | |- | ||
| Long || 1234 || Ping value. | | Long || 1234 || Ping value. | ||
|- | |- | ||
| Long || 36700161 || The | | Long || 36700161 || The flags we want: <tt><nowiki>SQF_NAME|SQF_PLAYERDATA|SQF_TEAMINFO_NUMBER|SQF_TESTING_SERVER</nowiki></tt> | ||
|- | |- | ||
| Long || 6 || The | | Long || 6 || The extended flags we want: <tt><nowiki>SQF2_COUNTRY|SQF2_GAMEMODE_NAME</nowiki></tt> | ||
|- | |||
| Byte || 2 || Indicates we want a segmented response, if the server supports it. | |||
|} | |} | ||
'''Response''' | '''Response''' | ||
{| class="wikitable" | {| class="wikitable" | ||
! Type || Value || Description | ! Type || Value || Description | ||
|- | |- | ||
| Long || | | Long || 5660032 || The server's response, indicating we're getting a segmented response packet. | ||
|- | |||
| Byte || 0 || The segment number. | |||
|- | |||
| Byte || 1 || Total number of segments. | |||
|- | |- | ||
| | | Short || 0 || Offset of the packet. | ||
|- | |- | ||
| Short || | | Short || 747 || Size of this packet | ||
|- | |- | ||
| | | Short || 747 || Total amount of data being sent. | ||
|- | |- | ||
| | | colspan = 3 | Packet data follows after this point. | ||
|- | |||
| Long || 1234 || The ping value we sent to the server. | |||
|- | |- | ||
| | | String || 3.2-alpha-r240718-2351 on Linux 6.9.9-1-default || The server's version. | ||
|- | |- | ||
| Long || 35127297 || The | | Long || 35127297 || The fields contained in the response. <tt><nowiki>SQF_NAME|SQF_NUMPLAYERS|SQF_PLAYERDATA|SQF_TESTING_SERVER|SQF_EXTENDED_INFO</nowiki></tt>. Observe how: | ||
* <tt>SQF_NUMPLAYERS</tt> was added by the server as we requested <tt>SQF_PLAYERDATA</tt>. | * <tt>SQF_NUMPLAYERS</tt> was added by the server as we requested <tt>SQF_PLAYERDATA</tt>. | ||
* <tt>SQF_EXTENDED_INFO</tt> was added indicating we'll get data from another flag set later in this segment. | * <tt>SQF_EXTENDED_INFO</tt> was added indicating we'll get data from another flag set later in this segment. | ||
Line 671: | Line 626: | ||
=== Example code === | === Example code === | ||
<syntaxhighlight lang="javascript" line="1"> | <syntaxhighlight lang="javascript" line="1"> | ||
function | function handlePacket(data) { | ||
const response = data.readLong(); | |||
const | switch (response) { | ||
case SERVER_LAUNCHER_CHALLENGE: { | |||
parseResponse(data); | |||
if ( | break; | ||
} | |||
case SERVER_LAUNCHER_SEGMENTED_CHALLENGE: { | |||
const segmentNumber = data.readByte(); | |||
const totalSegments = data.readByte(); | |||
const offset = data.readShort(); | |||
const size = data.readShort(); | |||
const totalSize = data.readShort(); | |||
if (buffer == null) { | |||
buffer = newBuffer(totalSize); | |||
} | } | ||
if ( | copyBuffer(from: data, to: buffer, toOffset: offset); | ||
if (segmentNumber == totalSegments) { | |||
parseResponse(buffer); | |||
} | } | ||
break; | |||
} | } | ||
case SERVER_LAUNCHER_BANNED: { | |||
// handle error | |||
break; | |||
} | } | ||
case SERVER_LAUNCHER_IGNORING: { | |||
// handle error | |||
break; | break; | ||
} | } | ||
} | } | ||
} | } | ||
function parseResponse(data) { | |||
const flags = data.readLong(); | |||
if (flags & SQF_NAME) { | |||
const name = data.readString(); | |||
} | } | ||
// ... | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> | ||
[[Category:Developers_Articles]] | [[Category:Developers_Articles]] |