• Welcome to Valhalla Legends Archive.
 

SCGP (Starcraft Game Protocol) Spec

Started by Ringo, November 03, 2008, 04:29 AM

Previous topic - Next topic

Ringo

I wouldn't normaly post this sort of infomation, but with starcraft2 just around the corner, and sc/bw pretty dead these days, I figger it's pretty harmless.
This infomation is for educational useage only.

This post will contain the basics infomation on the UDP header that starcraft uses for its game traffic.
The post below this one, will contain a list of command 0 messages.
The post below that one, will contain a list of command 1 messages.
Below that, a list of command 2 messages.

This is how I have formatted the documentation:
(BYTE) -- 8 bit integer
(WORD) -- 16 bit integer
(DWORD) -- 32 bit integer
(STRING) -- Null terminated string
(BYTE[X]) -- Array of bytes, where X is the amount of bytes (1 based)
(VOID) -- Variable lengh block of data

This documentation may not be explained (or spelt) very well, so if you have any questions, spot any errors or have things to add, feel free to post them!





Header

(DWORD) 0x00
(WORD) Checksum
(WORD) Lengh of message (Discluding the 1st dword)
(WORD) Sent Counter
(WORD) Recv Counter
(BYTE) Packet Command
(BYTE) Packet ID (command 0 only)
(BYTE) Player ID
(BYTE) Status


Commands
Command 0:
The data appends the header, the headers packet ID value, is the id of the packet.

Command 1:
The packet ID and its data appends the header. The packet ID is at offset 0x10
The packet ID in the header, is always zero.

Command 2:
Like command 1, the packet appends the header.
How ever, command 2 packets are bufferd and sent every X interval.
appending the header is a que of messages (1 or more)
Each has a unique lengh, and a select few are variable.

Status
Status:
0x00 = Normal Traffic
0x01 = Verification
0x02 = Resend request
0x04 = Callback

Verification:
Used to verify count's.

Resend:
Used to request a given count/packet be resend, due to a brakes in the UDP stream.
For command 2, its possible to have a byte appending the header -- This byte will be an ID of another player in the game. You should respond to such requests with a call back for that player. See callbacks (below)

Call Back:
Used to check up counts between other players.
For example, if player 0 sends a resend request to player 1, but appends player 2's ID behind it, based on the count, player 1 will send player 0 that packet he sent to player 2, including the packet data, but will use the callback status in the responce, as well as filling the player ID value in the header, to that of player 2.
Commonly used in command2 traffic.
For example, if player 0 and 1 has good synq and player 0 and 2 have good synq, but player 1 and 2 are lagging, player 0 will know he has to wait for them to catch up, aka "waiting for player".

Checksum
The checksum value, is of the whole packet buffer, from the lengh value onwards.
Take the following packet, as an example:

00 00 00 00 28 C4 10 00 00 00 01 00 00 01 FF 00    ....(...........
01 00 00 00                                        ....

The data that is checksum'ed is as followed:

00 00 00 00 28 C4 XX XX XX XX XX XX XX XX XX XX    ....(...........
XX XX XX XX                                        ....

Some easy-to-read VB6 code showing how the checksum is generated:
Note: BufLen is the last byte of the packet buffer, offset 6 would be where the lengh value starts in the header.

    Dim A           As Long
    Dim B           As Long
    Dim C           As Long
    For i = (BufLen) To 6 Step -1
        B = B + Buf(i)
        If (B > &HFF) Then B = B - &HFF
        A = A + B
    Next i
    C = (B * 256) Or (A Mod 255)
    A = &HFF - ((C And &HFF) + (C \ 256)) Mod &HFF
    B = (A + (C \ 256))
    B = &HFF - (B Mod &HFF)
    B = B Or (A * 256)
CheckSum = B And &HFFFF&

Ringo

0x01
SCGP_REQUESTJOIN [C>H]

(DWORD) 0x01

Sent to host's to start up the join game process.
Host's should respond by sending command 0, packet 0x02.


0x02
SCGP_REQUESTJOINOK [H>C]

(DWORD) 0x01

Sent to joining players, in responce to command 0, 0x01.


0x03
SCGP_REQUESTJOIN2 [C>H]

(DWORD) 0x01

Sent to the host in responce to command 0, packet 0x02.
You should also send command 0, packet 0x07 after this one.


0x04
SCGP_PING [C>C]

Blank

Sent to other players to time their latency, and verify they exist.
Sent every 20seconds.


0x05
SCGP_PONG [C>C]

Blank

Sent to other in responce to command 0, packet 0x04.
From this, you can calculate the time between 0x04/0x05 to derive the ping of a player.


0x06
SCGP_PLAYER  [H>C]

(DWORD) Unknown
(DWORD) Player ID
(BOOLEAN) IsHost
(DWORD) 0x00
(DWORD) Command 2 packet counter
(WORD) Sin_Family
(WORD) Sin_Port
(DWORD) Sin_addr
(DWORD) Sin_Zero - 0x00
(DWORD) Sin_Zero - 0x00
(STRING) Account Name
(STRING) Stat's String

Notify's player's of other players in the game, their IP, player number, account and account stats.
This packet is sent to you for each player in the game, other than you're self.
If this is about the hosting player, then the sockaddr_in structure and the account stats will be null.


0x07
SCGP_ENTER [C>H]

(STRING) Account name
(STRING) Stats string
(STRING) Game Password

Sent to the host after command 0, packet 0x03, to request entry into the game.
If it fails, the host will respond with command 0, 0x0A. Otherwise the host will send you the game data, starting with command 0, packet 0x08.


0x08
SCGP_GAMEDATA [H>C]

(DWORD) You're player ID
(DWORD) Max players
(DWORD) Command 2 packet count
(DWORD) Unknown
(DWORD) Game Uptime in seconds
(STRING) Game Name
(STRING) Game Stats String
(STRING) Game Password

This supplys you with all the display info, about the given game.
For example, the max number of slots, the game speed etc.


0x09
SCGP_GAMETYPE [H>C]

(BYTE) Game Type
(BYTE) League ID
(WORD) Penalty Index
(WORD) Penalty Value
(BYTE[24]) Configeration for said game type

This tells you everything you need to know about a given game type and how the game is to be played.
For example, if the game will be useing the map settings, if players teams will be bound (like team melee) and all the other things you can expect from all the other game types and more.
iirc, this game type data can be found in the mpq's.
For example: patch_rt.mpq\Templates\Top Vs. Bottom(1).got
This data can also be sent to clients via the battle.net server, when they logon. Like for example, if they are a WCG player.


0x0A
SCGP_JOINFAIL [H>C]

Blank

Sent in responce to command 0, packet 0x07, notifying you, that you're request to join the game was rejected.
For example: if you're game password is incorrect.


0x0B
SCGP_QUIT [C>C]

(DWORD) Command 2 packet count
(DWORD) 0x40000001

Notify's all other players, that the sender has quit the game.
The command 2 count, is used to verify exacly when the player quit.
This should be sent to each player in the game, 3 time's.


0x0C
SCGP_QUITVERIFY? [C>C]?

(DWORD) Unknown
(DWORD) Command 2 packet count
(DWORD) Unknown

I haven't looked into this packet at all yet, but somthing tells me that it has somthing to do with other player's quitting or dropping.


0x0E
SCGP_GAMESTATE? [H>C]

(DWORD) State?

I'm pretty sure this tell's players that the game state has changed. For example, game has players, game is full, game has started etc.


0x0F
SCGP_STATSCODE [H>C]

(DWORD) Stats Code

Notifys a joining player, what stats code to use for this game.
This value is then sent to battle.net in the end game report.
For example:
0x00 = Melee
0x01 = Ladder
0x02 = Iron
0x05 = Kbk etc
Again, iirc, this value is gotten from the .got files, or sent to a client from battle.net for custom game types (like WCG)

Ringo

#2
0x00
SCGP_GAMECHAT [C>C]

(BYTE) 0x00
(STRING) Chat message

Sent to talk to other ingame players.
Note: This packet is used for playing the game only.
If you want to talk to players in the game room, you must use command 1, 0x4A.

0x49
SCGP_PLAYERJOIN [H>C]

(DWORD) Player ID

Notifys other players, that this player has now join'ed the game.
For example, starcraft would display "X has joined the game" and then /stats them, in responce to this.
This is not sent for players who were already in the game.


0x4A
SCGP_ROOMDATA [H>C]

(WORD) Map Titleset
(WORD) Map Width
(WORD) Map Height
(BYTE[12]) OWNR
(BYTE[12]) SIDE
(BYTE[12]) OWNR Default
(BYTE[8]) FORC
(BYTE[4]) FORC Flag
(BYTE[8]) RACE

The titleset, width and hight, are used by the client and not goten from the map -- these 3 values are used on failth.
Valid titlesets:
0x00 = Badlands
0x01 = Space Platform
0x02 = Installation
0x03 = Ashworld
0x04 = Jungle
0x05 = Desert
0x06 = Arctic
0x07 = Twilight
The OWNR value's are the base room slot value's. They are modifyed values from the map to fit the given game type/room settings etc.
The OWNR default is simply that, the default values from the map file.
The 12 bytes is for each possible player (1 to 12)
See command 2, 0x3E for a list of these values.
The SIDE tells you the race for each player. Thses are modifyed SIDE values from the map file, to fit the given game configeration.
1 SIDE byte for each possible player (1 to 12)
see command 2, 0x3E for a list of SIDE values.
The FORC tells you the force/team index of each player.
For example, 0x00 would mean no team (like melee) and 0x01 to 0x04 means this player/slot belongs to this team.
The FORC Flag gives you the settings for each force.
0x01 = Random start locations
0x02 = Allies
0x04 = Allie victory
0x08 = Shared Vision
The RACE tells you if a player can change their race *I think*. I'm not to sure about the RACE part, but i'm pretty sure thats what it does. For example, disables a player from changing their race.


0x4B
SCGP_TEAMNAME [H>C]

(BYTE[30]) Force 1 Name
(BYTE[30]) Force 2 Name
(BYTE[30]) Force 3 Name
(BYTE[30]) Force 4 Name

Afaik, This is only sent to joining player's, in Use map setting games, so they can display the name of the teams, before they have downloaded the map.
Each block of 30 bytes is infact a null-terminated string.


0x4C
SCGP_ROOMCHAT [C>C]

(STRING) Chat message

Sent to talk to other players in the game room.
Note: If you're no longer in the game room, and are playing the game, you must use command 1, packet 0x00 to talk to other players.


0x4E
SCGP_REJECT [H>C]

(BYTE) Event

Notifys a player of an event.
0x01 = You have been banned.
0x02 = Game creater has closed all avalible slots.
0x03 = Game host has left the game.
0x04 = Unable to join the game.
0x05 = Save game file not found.
0x06 = Unable to write scenario file.
0x07 = Invalid game version.
0x08 = Invalid client version.
0x09 = Unable to authenticate map.
Other = You have been booted.


0x4F
SCGP_MAP [C>C]

(WORD) Lengh of payload (discluding this value)
(WORD) Event
Event 0x00:
    (WORD) 0x100
    (DWORD) File Position
Event 0x01:
    (DWORD) File Lengh
    (DWORD) File Checksum
    (STRING) File Name
Event 0x02:
    (BYTE) Player ID
    (DWORD) File Position
Event 0x03:
    Blank
Event 0x04:
    (BYTE) 0x00
    (DWORD) File Position
    (WORD) Data Block Lengh
    (VOID) File Data Block
Event 0x05:
    (BYTE) 0x00
    (DWORD) File Position

This packet is used to manage map downloading.
Some important things to note:
Players don't just download the map from the host. The host can request other ingame players send it, if they already have it.
Data blocks are send in blocks of 128 bytes at a time, but you can get away with 256 blocks with out issue.
Event 0x00 [C>H]:
Tells the host if you have the map or not.
For example, the map positon tells the host where to start sending the file from.
If you already have the map, then the Map position should be the lengh of the file.
Event 0x01 [H>C]:
Asks a player if they have the given map.
Player's should respond to this, with event 0x00.
Event 0x02 [H>C]:
Tells the recving player, to send the map to another player.
Event 0x03 [H>C]:
I'm not to sure about this one.
This is send to a player who has just finished sending the map to another player, and also when the game is starting.
Event 0x04 [C>C]:
used to send a block of the map to another player.
Recving players should verify the block of data, by sending event 0x05.
Any brakes in the UDP stream should be managed with standard resend requests.
Event 0x05 [C>C]:
Verifys the position of the map you are currently at.
This should be sent as a respone to event 0x04.


0x50
SCGP_CANTTHINKOFANAME [H>C]

blank

Player's should respond to this, by sending command 2, 0x40.
It's sent to joiner's as part of the join process, alot with/after command 1, 0x4A.

Ringo

#3
0x05
SCGP_NULL [C>C]

Blank

Sent in the stream, when theres nothing else to be sent.

0x3C
SCGP_GAMESTART [H>C]

Blank

Game is starting.


0x3D
SCGP_DOWNLOAD [C>C]

(BYTE) Download Percent

Notifys other player's of you're current download percent.
This should be sent in 1 second intervals when you're download percent has changed.


0x3E
SCGP_SLOTUPDATE [H>C]

(BYTE) Slot Index
(BYTE) Player Index
(BYTE) Slot State
(BYTE) Race
(BYTE) Team Index

Notifys player's of a given game room slot's status.
State's:
0x00 = slot doesnt exist
0x02 = slot is Taken/Human
0x03 = Slot is Rescuable
0x05 = slot is Computer
0x06 = slot is Open
0x07 = slot is Neutral
0x08 = slot is Closed
Race's
0x00 = Zerg
0x01 = Terran
0x02 = Protoss
0x03 = Independent
0x04 = Neutral
0x06 = Random
Note: Stats of Rescuable and Neutral are not shown.


0x3F
SCGP_HUMAN [H>C]

(BYTE) 0x00
(BYTE) 0x00
(BYTE) 0x00
(WORD) A
(WORD) B

I'm not really sure what this message means.
The value's A and B (and probly the null values) are carbon copys of the values a player sends in command 2, packet 0x40.


0x40
SCGP_MYSHIT [C>C]

(DWORD) 0x00
(DWORD) 0x00
(WORD) A
(WORD) B
(BYTE) 0x00
(DWORD) Uniqueness

I'm not sure what the A and B values in this message mean, how ever, it seems the host sends them to other players in command 2, packet 0x3F.



0x41
SCGP_CHANGERACE [C>C]

(BYTE) Slot Index
(BYTE) Race

Request's the race of a given slot be changed.
If changing you're own race, the slot index must be 0x08.
See command 2, packet 0x3E for a list of races.


0x42
SCGP_CHANGETEAMA [C>C]

(BYTE) Team Index

Request's you be moved to the given team.
Note: This packet is used for none-use map setting games.
To move team in a UMS game, use command 2, packet 0x43.

0x43
SCGP_CHANGETEAMB [C>C]

(BYTE) Team Index

Request's you be moved to the given team or a new slot with in you're team.
If you are already in the given team, you will be moved to the next avalible slot in you're team.
Note: This packet is used for map setting games only.
To move team in a none-UMS game, use command 2, packet 0x42.


0x44
SCGP_CHANGESLOTSTATE [H>C]

(BYTE) Slot Index
(BYTE) State

Changes a given slot index to a new state:
0x00 = Computer
0x01 = Open
0x02 = Closed


0x45
SCGP_SLOTSWITCH [H>C]

(BYTE) Slot Index From
(BYTE) Slot Index To

Switchs 2 slot's. Used in top vs bottom game's, when a host moves a player to another team.


0x48
SCGP_SEED [H>C]

(DWORD) Seconds since 1/1/1970
(BYTE) 0x08
(BYTE) 0x08
(BYTE) 0x08
(BYTE) 0x08
(BYTE) 0x08
(BYTE) 0x08
(BYTE) 0x08
(BYTE) 0x08

Sent in the cross over between game room and game play.
Seeds game randomization, like for example: Who gets what start location/color/race etc.


For more command 2 messages, see here:
http://forum.valhallalegends.com/index.php?topic=12107.msg130894#msg130894

Yegg


MysT_DooM



vb6, something about that combination of numbers and letters is sexy

Ringo

Quote from: Yegg on November 03, 2008, 01:57 PM
Excellent work, Ringo.

Thanks :)
Hopefully, it will spark abit of life back into bnet bot development.
I persionaly have lost most of my interest in it.
SCGP can be pretty fun at times tho.
Hmm, I think I should have posted this in the bnet bnet bot development references board. I will leave it up to the mods to decide if its worth it.

Yegg

I tried getting back into it, and still really wish I could. But due to financial issues, I'm working 62-65 hours a week (not counting breaks) and I'm also taking college classes. The free time that I do have is spent resting.

xpeh

Wow this is just amazing. It's just a thing i waited for.

I made a sniffer decoder for this, it partially works. I spend almost a day for it, now it shows packet headers and string packet type. I also have a beta decoder for bnet protocol. It's easy to extend and is written in xml for Analyzer network sniffer. Write if you are interested.

What do you think about posting it to bnetdocs.com? I remember a similar site, where you can make comments for every packet. It were much easier to discuss and edit as all in one thread.

Sixen

Not sure why I never posted here, but hawt Ringo.

Quote from: xpehI made a sniffer decoder for this, it partially works. I spend almost a day for it, now it shows packet headers and string packet type. I also have a beta decoder for bnet protocol. It's easy to extend and is written in xml for Analyzer network sniffer. Write if you are interested.

/interested
Blizzard Tech Support/Op W@R - FallenArms
The Chat Gem Lives!
http://www.diablofans.com
http://www.sixen.org

xpeh

I think we shall add some typical sequences.

For example, what should you send in order client shows you are in lobby?

xpeh

Did i understand correctly,

2nd post is about command 0, 3rd - command 1 and 4th - about command 2 codes?

Why do you call it 'command'?

How lond is 'boolean' in some packet?

Ribose

Quote from: xpeh on January 14, 2009, 10:04 PM
Did i understand correctly,

2nd post is about command 0, 3rd - command 1 and 4th - about command 2 codes?
Looks like it.
Quote from: xpeh on January 14, 2009, 10:04 PM
Why do you call it 'command'?
He made it up. What would you call it?
Quote from: xpeh on January 14, 2009, 10:04 PM
How lond is 'boolean' in some packet?
long*
Four bytes. It's a DWORD with value 0x00 (false) or 0x01 (true).
~Ribose

xpeh

 
Quote from: Ribose on January 15, 2009, 02:54 PM
Quote from: xpeh on January 14, 2009, 10:04 PM
Did i understand correctly,

2nd post is about command 0, 3rd - command 1 and 4th - about command 2 codes?
Looks like it.
I have to update my decoder.

Quote from: Ribose on January 15, 2009, 02:54 PM
Quote from: xpeh on January 14, 2009, 10:04 PM
Why do you call it 'command'?
He made it up. What would you call it?

Without more information about why he called it so i can say nothing.

Can some1 write what packets i must send and wait for to join a game? VB is not my strong side.

Ringo

Quote from: xpeh on January 15, 2009, 04:31 PM
Quote from: Ribose on January 15, 2009, 02:54 PM
Quote from: xpeh on January 14, 2009, 10:04 PM
Did i understand correctly,

2nd post is about command 0, 3rd - command 1 and 4th - about command 2 codes?
Looks like it.
I have to update my decoder.

Quote from: Ribose on January 15, 2009, 02:54 PM
Quote from: xpeh on January 14, 2009, 10:04 PM
Why do you call it 'command'?
He made it up. What would you call it?

Without more information about why he called it so i can say nothing.

Can some1 write what packets i must send and wait for to join a game? VB is not my strong side.
Why does it matter so much, what it's called. I persionaly call it "Packet Type", but seems as most people call it "command" on a flat out average, I called it that, so not to cause confusion.

If you read the info of all the above packets, it tells you what ones are used when entering agame, iirc.
Better yet, just packet log a client joining agame.

being good at VB or not, has nothing to do with anything related to this topic tbh, idk what you're getting at there.

I'm just wondering tho, what is you're "strong side" when it comes to computer programming language? are you actualy doing any "Bot Development", or are you just getting "Bot Support", and expressing "Bot Opinions"? :p