This may not be as progressive or useful of a topic as i foresee or would like to see it, but does anybody here have any input on the information i've gathered on starcraft's udp structure?
UDP Packet Struct:
Dword: 0 (Unknown/Not verified)
Word: CheckSum
Word: Packet Length
Word: Message Counter Sent
Word: Message Receive
Word: Command Type (0, 1, or 2)
Word: Player ID (0 to 7)
Void: Packet Data
I've seen little to no change on the first dword, and the message counter may be different depending on the command type...
I also realize this structure may be smaller or larger depending on the command type. I will be doing more research on this.
I'd like to progress on this in any way i can, does anybody have any useful info on what may be right or wrong.. or even missing?
Good job, This (http://forum.valhallalegends.com/index.php?topic=12107.msg130894#msg130894) should help out abit.
Excellent. Well i guess somebody can delete this thread now :-p Also, I think the bottom half of this struct may be a slight improvement on yours. I'm pretty sure those are words and not bytes... Either way, your still receiving the packet data in the same position, so yours will still work even if its wrong... If you have proof on these being bytes, please post. I've got no bnet buddies left so all my research is being done by myself.. maybe one or two random people join the game i create, but it's not the testing environment i'd like it to be.. Thanks.
By the way, here's the struct for udp packets that somebody reversed many years ago:
struct message {
unsigned long udptype;
unsigned short checksum;
unsigned short len;
unsigned short pos1;
unsigned short pos2;
unsigned char cls;
unsigned char cmd;
unsigned char sender;
unsigned char resend;
char data[];
};
Hope that helps.
MyndFyre edit: added code tags. You should know better, iago!
Quote from: Mesiah / haiseM on December 14, 2005, 07:21 AM
I think the bottom half of this struct may be a slight improvement on yours. I'm pretty sure those are words and not bytes... Either way, your still receiving the packet data in the same position, so yours will still work even if its wrong... If you have proof on these being bytes, please post. I've got no bnet buddies left so all my research is being done by myself.. maybe one or two random people join the game i create, but it's not the testing environment i'd like it to be.. Thanks.
They are bytes, im sure of that :)
Depending on the packet class/command depends on how the header is used, for example, command 0 will use the 14th byte for the packet ID, where as command 1 will use the 17th Byte as the packet ID, and command 2 is a header carrying a payload of queued packets.
The Resend (as iago put it) is used for abit more than just resending packets, it has multiple uses, and again that can depend on the packet command.
The status byte handles things like SEQ checks, SEQ Verifications and Resend requests.
Normaly* when the status is anything other than 0x00, the send and Recv will match, and Packet ID's and payloads shouldnt be used:
Command 0: SEQ Check of there Recv VS your Sent, any missing messages should trigger messages to be resent. (Normaly done over multiple messages)
Comamnd 1: SEQ Verifys the message was Recv (only true for the last message)
Command 2: Depending on SEQ Sent Vs Your sent, SEQ checks, extra game beats and resend requests
These are the incoming and out going structure's i wrote for my bot awhile ago, which might be worth reading through:
Public Type UDPPacketHeader
pIP As String
pPort As Long
pSum As Long
pSize As Long
pSent As Long
pRecv As Long
pCmd As Byte
pEvent As Byte
pSender As Byte
pStatus As Byte
End Type
Public Sub UDP_PARSER(ByVal Data As String, ByVal IP As String, ByVal Port As Long)
Dim packetID As Long
packetID = Buf.GetDWORD(Mid(Data, 1, 4))
Select Case packetID
Case &H0 'Game packets
If Len(Data) < 16 Then: MakeLog Data, vbRed, "Under Sized UDP Game Packet": Exit Sub
Dim P As UDPPacketHeader
With P
.pIP = IP
.pPort = Port
.pSum = Buf.GetWORD(Mid(Data, 5, 2))
.pSize = Buf.GetWORD(Mid(Data, 7, 2))
If Not .pSize = (Len(Data) - 4) Then
MakeLog Data, vbRed, "UDP Packet Lengh Doesnt Match Data Lengh!!!"
Exit Sub
End If
.pSent = Buf.GetWORD(Mid(Data, 9, 2))
.pRecv = Buf.GetWORD(Mid(Data, 11, 2))
.pCmd = Asc(Mid(Data, 13, 1))
If P.pCmd = 0 Then .pEvent = Asc(Mid(Data, 14, 1))
.pSender = Asc(Mid(Data, 15, 1))
.pStatus = Asc(Mid(Data, 16, 1))
If P.pCmd = 1 And .pStatus = 0 Then .pEvent = Asc(Mid(Data, 17, 1))
End With
Call CheckSEQ(Data, P) 'Parse it
Exit Sub
Case &H3: Call BNCS_UDP_H_0x03(Data, Buf.GetDWORD(Mid(Data, 5, 4)), IP, Port)
Case &H5: Call BNCS_UDP_H_0x05(Data, Buf.GetDWORD(Mid(Data, 5, 4)), IP, Port)
Case &H6: Call BNCS_UDP_H_0x06(Data, Buf.GetDWORD(Mid(Data, 5, 4)), IP, Port)
Case Else: MakeLog Data, vbRed, "Unknown UDP Data"
End Select
End Sub
Out going:
Public Enum PacketHeaders
BNCS_HEADER = 0
BNFTP_HEADER = 1
BNRS_HEADER = 2
BNLS_HEADER = 3
D2GS_HEADER = 4
W3DMGS_HEADER = 5
BNCS_UDPHEADER = 6
UDPG_HEADER = 7
End Enum
Public Sub InsertHEADER(ByVal packetID As Byte, _
Optional Header As PacketHeaders = BNCS_HEADER, _
Optional Sent As Long, _
Optional ByVal Recv As Long, _
Optional ByVal PacketType As Byte = 0, _
Optional ByVal Status As Byte = 0, _
Optional ByVal AddSEQ As Boolean = False)
Buffer = MakeHEADER(packetID, Header, Sent, Recv, PacketType, Status, AddSEQ) & Buffer
End Sub
Public Function MakeHEADER(ByVal packetID As Byte, _
Header As PacketHeaders, _
UDPSent As Long, _
ByVal UDPRecv As Long, _
ByVal UDPPacketCmd As Byte, _
ByVal UDPStatus As Byte, _
ByVal AddSEQ As Boolean) As String
Dim tmpDat As String
Select Case Header
Case BNCS_HEADER: tmpDat = Chr$(&HFF) & Chr$(packetID) & MakeWORD(Len(Buffer) + 4)
Case BNFTP_HEADER: tmpDat = MakeWORD(Len(Buffer) + 2)
Case BNCS_UDPHEADER: tmpDat = MakeDWORD(CLng(packetID))
Case BNRS_HEADER: tmpDat = MakeWORD(Len(Buffer) + 3) & Chr$(packetID)
Case BNLS_HEADER: tmpDat = MakeWORD(Len(Buffer) + 3) & Chr$(packetID)
Case D2GS_HEADER: tmpDat = Chr$(packetID)
Case W3DMGS_HEADER: tmpDat = Chr$(&HF7) & Chr$(packetID) & MakeWORD(Len(Buffer) + 4)
Case UDPG_HEADER
If AddSEQ = True Then UDPSent = UDPSent + 1
tmpDat = tmpDat & MakeWORD(UDPSent)
tmpDat = tmpDat & MakeWORD(UDPRecv)
tmpDat = tmpDat & Chr$(UDPPacketCmd)
'type 0 packet ID
If UDPPacketCmd = 0 Then
tmpDat = tmpDat & Chr$(packetID)
Else
tmpDat = tmpDat & Chr$(0)
End If
tmpDat = tmpDat & Chr$(MyPID)
tmpDat = tmpDat & Chr$(UDPStatus)
'type 1 packet ID
If UDPPacketCmd = 1 And UDPStatus = &H0 Then tmpDat = tmpDat & Chr$(packetID)
'queue the Null DWORD, UDP check sum and packet Len
tmpDat = MakeWORD(Len(tmpDat) + Len(Buffer) + 4) & tmpDat
tmpDat = MakeWORD(UDPCheckSum(MakeWORD(0) & tmpDat & Buffer)) & tmpDat
tmpDat = MakeDWORD(0) & tmpDat
End Select
MakeHEADER = tmpDat
tmpDat = ""
End Function
And you can kinda see how im useing it here (http://forum.valhallalegends.com/index.php?topic=13246.msg134363#msg134363)
Hrm... Thanks, i think i pretty much got it down now. Man, that was fast :)
Almost makes me wonder why I never tried this before.. Well... I did once, but i was just sending a buttload of hex characters :-P Thanks again.