init commit

This commit is contained in:
Jose Luis Montañes Ojados
2026-01-14 21:33:21 +01:00
commit dbab788e6b
27 changed files with 4001 additions and 0 deletions

View 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
View 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.