init commit
This commit is contained in:
95
internal/protocol/codec.go
Normal file
95
internal/protocol/codec.go
Normal file
@@ -0,0 +1,95 @@
|
||||
package protocol
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"compress/zlib"
|
||||
"encoding/binary"
|
||||
"io"
|
||||
"math"
|
||||
)
|
||||
|
||||
func ZlibCompress(data []byte) []byte {
|
||||
var b bytes.Buffer
|
||||
w := zlib.NewWriter(&b)
|
||||
w.Write(data)
|
||||
w.Close()
|
||||
return b.Bytes()
|
||||
}
|
||||
|
||||
// Codec Functions (migrated from main.go)
|
||||
|
||||
func ReadVarint(r io.ByteReader) (uint64, error) {
|
||||
return binary.ReadUvarint(r)
|
||||
}
|
||||
|
||||
func ReadVarintInt64(r io.ByteReader) (int64, error) {
|
||||
v, err := binary.ReadUvarint(r)
|
||||
return int64(v), err
|
||||
}
|
||||
|
||||
func EncodeVarint(v uint64) []byte {
|
||||
buf := make([]byte, binary.MaxVarintLen64)
|
||||
n := binary.PutUvarint(buf, v)
|
||||
return buf[:n]
|
||||
}
|
||||
|
||||
func EncodeDouble(v float64) []byte {
|
||||
buf := make([]byte, 8)
|
||||
binary.LittleEndian.PutUint64(buf, math.Float64bits(v))
|
||||
return buf
|
||||
}
|
||||
|
||||
func SkipField(reader *bytes.Reader, wireType uint64) {
|
||||
switch wireType {
|
||||
case 0: // Varint
|
||||
ReadVarint(reader)
|
||||
case 1: // Fixed64
|
||||
reader.Seek(8, io.SeekCurrent)
|
||||
case 2: // Length-delimited
|
||||
length, _ := ReadVarint(reader)
|
||||
reader.Seek(int64(length), io.SeekCurrent)
|
||||
case 5: // Fixed32
|
||||
reader.Seek(4, io.SeekCurrent)
|
||||
}
|
||||
}
|
||||
|
||||
// Helper to read a packet length (4 bytes, Big Endian) as per official protocol
|
||||
func ReadPacketLength(conn io.Reader) (uint32, error) {
|
||||
var length uint32
|
||||
err := binary.Read(conn, binary.BigEndian, &length)
|
||||
return length, err
|
||||
}
|
||||
|
||||
// WrapPacket encapsulates a payload in the Message and Packet structure
|
||||
// 1. Message wrapper (Field 1: requestNumber, Field [requestNumber]: payload field)
|
||||
// 2. Packet wrapper (Field 1: packetID, Field 3: Message bytes)
|
||||
// 3. 4-byte Big Endian length prefix
|
||||
func WrapPacket(requestNumber int, payload []byte, packetID uint32) []byte {
|
||||
// 1. Wrap in Message
|
||||
msg := make([]byte, 0)
|
||||
// Field 1: request_number (Varint)
|
||||
msg = append(msg, 0x08)
|
||||
msg = append(msg, EncodeVarint(uint64(requestNumber))...)
|
||||
|
||||
// Field [requestNumber]: The actual response payload
|
||||
msg = append(msg, EncodeVarint(uint64(uint32(requestNumber)<<3|2))...)
|
||||
msg = append(msg, EncodeVarint(uint64(len(payload)))...)
|
||||
msg = append(msg, payload...)
|
||||
|
||||
// 2. Wrap in Packet
|
||||
packet := make([]byte, 0)
|
||||
// Field 1: Id (Varint)
|
||||
packet = append(packet, 0x08)
|
||||
packet = append(packet, EncodeVarint(uint64(packetID))...)
|
||||
// Field 3: Payload (Message)
|
||||
packet = append(packet, 0x1a)
|
||||
packet = append(packet, EncodeVarint(uint64(len(msg)))...)
|
||||
packet = append(packet, msg...)
|
||||
|
||||
// 3. Add 4-byte length prefix
|
||||
final := make([]byte, 4)
|
||||
binary.BigEndian.PutUint32(final, uint32(len(packet)))
|
||||
final = append(final, packet...)
|
||||
|
||||
return final
|
||||
}
|
||||
120
internal/protocol/types.go
Normal file
120
internal/protocol/types.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package protocol
|
||||
|
||||
// Enum Definitions
|
||||
type GameStatus int32
|
||||
|
||||
const (
|
||||
GameStatus_RESERVED GameStatus = 0
|
||||
GameStatus_IN_PROGRESS GameStatus = 1
|
||||
GameStatus_OVER GameStatus = 2
|
||||
GameStatus_NOT_STARTED GameStatus = 3
|
||||
GameStatus_ABORTED GameStatus = 4
|
||||
GameStatus_OUTCOME GameStatus = 5
|
||||
GameStatus_PLAYER_TIMEOUT GameStatus = 6
|
||||
GameStatus_ABORTING GameStatus = 7
|
||||
GameStatus_WAITING_INVITATION GameStatus = 8
|
||||
GameStatus_FIRST_USER_DATA_ROUND GameStatus = 9
|
||||
GameStatus_SIMULTANEOUS GameStatus = 10
|
||||
GameStatus_INTERRUPTIBLE GameStatus = 11
|
||||
)
|
||||
|
||||
type ErrorCode int32
|
||||
|
||||
const (
|
||||
ErrorCode_NO_ERROR ErrorCode = 0
|
||||
)
|
||||
|
||||
// Message Definitions
|
||||
|
||||
type GameConfiguration struct {
|
||||
Name string
|
||||
Private bool
|
||||
Lurkable bool
|
||||
Rated bool
|
||||
MinPlayers int32
|
||||
MaxPlayers int32
|
||||
MinKarma int32
|
||||
FirstPlayer int32
|
||||
GameMode int32
|
||||
Timeout int32
|
||||
Data []byte
|
||||
ReqFirstUserRound bool
|
||||
ObservableBy int32
|
||||
MinRankScore int32
|
||||
MainVariant string
|
||||
RulesVer int32
|
||||
IdleTime int32
|
||||
}
|
||||
|
||||
type Player struct {
|
||||
Id int32
|
||||
Name string
|
||||
Karma int32
|
||||
RankScore float64
|
||||
Rank int32
|
||||
NbGames int32
|
||||
Language int32
|
||||
Avatar string // Simplified for mock
|
||||
Tz string
|
||||
}
|
||||
|
||||
type SmallPlayer struct {
|
||||
WWWId int64
|
||||
Name string
|
||||
Karma int32
|
||||
RankScore float64
|
||||
Rank int32
|
||||
NbGames int32
|
||||
Language int32
|
||||
Avatar string
|
||||
}
|
||||
|
||||
type GameDetails struct {
|
||||
GameId int64
|
||||
Players []*Player
|
||||
Configuration *GameConfiguration
|
||||
Data []byte
|
||||
UserData []*PlayerPregameData
|
||||
}
|
||||
|
||||
type PlayerPregameData struct {
|
||||
PlayerId int32
|
||||
Data []byte
|
||||
}
|
||||
|
||||
type StatusReport struct {
|
||||
GameId int64
|
||||
Status GameStatus
|
||||
Data []byte
|
||||
TurnId int32
|
||||
NextPlayerIds []int32
|
||||
Players []*Player
|
||||
Configuration *GameConfiguration
|
||||
ActivePlayer int32
|
||||
// Add other fields as needed
|
||||
}
|
||||
|
||||
type Session struct {
|
||||
Id int64
|
||||
}
|
||||
|
||||
// Request/Response Wrappers (Simplification: We handle fields manually in codec mostly,
|
||||
// but these structs represent the data content)
|
||||
|
||||
type AsyncConnectedRequest struct {
|
||||
Session *Session
|
||||
Player *Player
|
||||
}
|
||||
|
||||
type ServerStatisticsRequest struct {
|
||||
HostedGames int32
|
||||
Players int32
|
||||
ConnectedPlayers int32
|
||||
}
|
||||
|
||||
type LobbyGameCreatedRequest struct {
|
||||
Game *GameDetails
|
||||
}
|
||||
|
||||
// Helper: Encode helpers can be added here or in codec.
|
||||
// For now, these structs serve as the 'definitions' requested by the user.
|
||||
Reference in New Issue
Block a user