package main import ( "bufio" "bytes" "encoding/binary" ) const ( AdminPacketAdminJoin = 0 AdminPacketAdminQuit = 1 AdminPacketAdminUpdateFrequency = 2 AdminPacketAdminPoll = 3 AdminPacketAdminChat = 4 AdminPacketAdminRCon = 5 AdminPacketAdminGamescript = 6 AdminPacketAdminPing = 7 AdminPacketServerFull = 100 AdminPacketServerBanned = 101 AdminPacketServerError = 102 AdminPacketServerProtocol = 103 AdminPacketServerWelcome = 104 AdminPacketServerNewgame = 105 AdminPacketServerShutdown = 106 AdminPacketServerDate = 107 AdminPacketServerClientJoin = 108 AdminPacketServerClientInfo = 109 AdminPacketServerClientUpdate = 110 AdminPacketServerClientQuit = 111 AdminPacketServerClientError = 112 AdminPacketServerCompanyNew = 113 AdminPacketServerCompanyInfo = 114 AdminPacketServerCompanyUpdate = 115 AdminPacketServerCompanyRemove = 116 AdminPacketServerCompanyEconomy = 117 AdminPacketServerCompanyStats = 118 AdminPacketServerChat = 119 AdminPacketServerRCon = 120 AdminPacketServerConsole = 121 AdminPacketServerCmdNames = 122 AdminPacketServerCmdLogging = 123 AdminPacketServerGamescript = 124 AdminPacketServerRConEnd = 125 AdminPacketServerPong = 126 InvalidAdminPacket = 255 AdminUpdateDate = 0 AdminUpdateClientInfo = 1 AdminUpdateCompanyInfo = 2 AdminUpdateCompanyEconomy = 3 AdminUpdateCompanyStats = 4 AdminUpdateChat = 5 AdminUpdateConsole = 6 AdminUpdateCmdNames = 7 AdminUpdateCmdLogging = 8 AdminUpdateGamescript = 9 AdminUpdateEnd = 10 AdminFrequencyPoll = 0x01 AdminFrequencyDaily = 0x02 AdminFrequencyWeekly = 0x04 AdminFrequencyMonthly = 0x08 AdminFrequencyQuarterly = 0x10 AdminFrequencyAnnually = 0x20 AdminFrequencyAutomatic = 0x40 ) type Packet struct { PLength uint16 PType uint8 } type PacketAdminJoin struct { Packet Password string AppName string AppVersion string } type PacketAdminRCon struct { Packet Command string } type PacketServerProtocol struct { Packet ProtocolVersion uint8 FurtherData bool UpdatePacketType uint16 FrequenciesAllowed uint16 } type PacketServerWelcome struct { Packet ServerName string OpenTTDVersion string Dedicated bool MapName string MapSeed uint32 MapLandscape uint8 MapStartDate uint32 MapX uint16 MapY uint16 } type PacketAdminUpdateFrequency struct { Packet UpdateType uint16 UpdateFrequency uint16 } type PacketAdminPoll struct { Packet UpdateType uint8 UpdateID uint32 } type PacketServerDate struct { Packet Date uint32 } type PacketServerClientJoin struct { Packet ClientID uint32 } type PacketServerClientQuit struct { Packet ClientID uint32 } type PacketServerClientInfo struct { Packet ClientID uint32 Address string Name string Lang uint8 Date uint32 CompanyID uint8 } type PacketServerClientUpdate struct { Packet ClientID uint32 Name string CompanyID uint8 } type PacketServerClientError struct { Packet ClientID uint32 ErrorID uint8 } type PacketServerCompanyNew struct { Packet CompanyID uint8 } type PacketServerCompanyInfo struct { Packet CompanyID uint8 Name string President string Color uint8 Inauguration uint32 AI bool Protected bool Bankruptcies uint8 } type PacketServerCompanyUpdate struct { Packet CompanyID uint8 Name string President string Color uint8 Protected bool Bankruptcies uint8 } type PacketServerCompanyRemove struct { Packet CompanyID uint8 Reason uint8 } type PacketServerChat struct { Packet ActionID uint8 DestinationID uint8 ClientID uint32 Message string Amount uint64 } type PacketServerConsole struct { Packet Origin string Text string } type PacketServerRCon struct { Packet ColorID uint16 Output string } type PacketServerRConEnd struct { Packet Command string } func (p *PacketAdminJoin) Bytes() []byte { buf := new(bytes.Buffer) p.PLength = uint16(len(p.Password) + len(p.AppName) + len(p.AppVersion) + 6) binary.Write(buf, binary.LittleEndian, p.PLength) binary.Write(buf, binary.LittleEndian, p.PType) buf.WriteString(p.Password) buf.WriteByte(0) buf.WriteString(p.AppName) buf.WriteByte(0) buf.WriteString(p.AppVersion) buf.WriteByte(0) return buf.Bytes() } func (p *PacketAdminRCon) Bytes() []byte { buf := new(bytes.Buffer) p.PLength = uint16(len(p.Command) + 4) binary.Write(buf, binary.LittleEndian, p.PLength) binary.Write(buf, binary.LittleEndian, p.PType) buf.WriteString(p.Command) buf.WriteByte(0) return buf.Bytes() } func (p *PacketAdminUpdateFrequency) Bytes() []byte { buf := new(bytes.Buffer) p.PLength = 7 binary.Write(buf, binary.LittleEndian, p.PLength) binary.Write(buf, binary.LittleEndian, p.PType) binary.Write(buf, binary.LittleEndian, p.UpdateType) binary.Write(buf, binary.LittleEndian, p.UpdateFrequency) return buf.Bytes() } func (p *PacketAdminPoll) Bytes() []byte { buf := new(bytes.Buffer) p.PLength = 8 binary.Write(buf, binary.LittleEndian, p.PLength) binary.Write(buf, binary.LittleEndian, p.PType) binary.Write(buf, binary.LittleEndian, p.UpdateType) binary.Write(buf, binary.LittleEndian, p.UpdateID) return buf.Bytes() } func (p *PacketServerWelcome) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) p.ServerName, _ = r.ReadString(0) p.ServerName = p.ServerName[:len(p.ServerName)-1] p.OpenTTDVersion, _ = r.ReadString(0) p.OpenTTDVersion = p.OpenTTDVersion[:len(p.OpenTTDVersion)-1] c, _ := r.ReadByte() if c > 0 { p.Dedicated = true } else { p.Dedicated = false } p.MapName, _ = r.ReadString(0) p.MapName = p.MapName[:len(p.MapName)-1] bs := make([]byte, 13) _, _ = r.Read(bs) p.MapSeed = binary.LittleEndian.Uint32(bs[0:]) r.Discard(4) c, _ = r.ReadByte() p.MapLandscape = uint8(c) p.MapStartDate = binary.LittleEndian.Uint32(bs[5:]) p.MapX = binary.LittleEndian.Uint16(bs[9:]) p.MapY = binary.LittleEndian.Uint16(bs[11:]) } func (p *PacketServerProtocol) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) c, _ := r.ReadByte() p.ProtocolVersion = uint8(c) c, _ = r.ReadByte() if c > 0 { p.FurtherData = true } else { p.FurtherData = false } bs := make([]byte, 13) _, _ = r.Read(bs) p.UpdatePacketType = binary.LittleEndian.Uint16(bs[0:]) p.FrequenciesAllowed = binary.LittleEndian.Uint16(bs[2:]) } func (p *PacketServerDate) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) bs := make([]byte, 4) _, _ = r.Read(bs) p.Date = binary.LittleEndian.Uint32(bs[0:]) } func (p *PacketServerClientJoin) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) bs := make([]byte, 4) _, _ = r.Read(bs) p.ClientID = binary.LittleEndian.Uint32(bs[0:]) } func (p *PacketServerClientInfo) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) bs := make([]byte, 4) _, _ = r.Read(bs) p.ClientID = binary.LittleEndian.Uint32(bs[0:]) p.Address, _ = r.ReadString(0) p.Address = p.Address[:len(p.Address)-1] p.Name, _ = r.ReadString(0) p.Name = p.Name[:len(p.Name)-1] c, _ := r.ReadByte() p.Lang = uint8(c) bs = make([]byte, 4) _, _ = r.Read(bs) p.Date = binary.LittleEndian.Uint32(bs[0:]) c, _ = r.ReadByte() p.CompanyID = uint8(c) } func (p *PacketServerClientUpdate) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) bs := make([]byte, 4) _, _ = r.Read(bs) p.ClientID = binary.LittleEndian.Uint32(bs[0:]) p.Name, _ = r.ReadString(0) p.Name = p.Name[:len(p.Name)-1] c, _ := r.ReadByte() p.CompanyID = uint8(c) } func (p *PacketServerClientError) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) bs := make([]byte, 4) _, _ = r.Read(bs) p.ClientID = binary.LittleEndian.Uint32(bs[0:]) c, _ := r.ReadByte() p.ErrorID = uint8(c) } func (p *PacketServerClientQuit) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) bs := make([]byte, 4) _, _ = r.Read(bs) p.ClientID = binary.LittleEndian.Uint32(bs[0:]) } func (p *PacketServerCompanyNew) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) c, _ := r.ReadByte() p.CompanyID = uint8(c) } func (p *PacketServerCompanyInfo) Read(b []byte) { var err error r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) c, _ := r.ReadByte() p.CompanyID = uint8(c) p.Name, err = r.ReadString(0) logErrorDebug(err, "PacketServerCompanyInfo.Read : Name") if err != nil { p.Name = "Error" } else { p.Name = p.Name[:len(p.Name)-1] } p.President, err = r.ReadString(0) logErrorDebug(err, "PacketServerCompanyInfo.Read : President") if err != nil { p.President = "Error" } else { p.President = p.President[:len(p.President)-1] } c, _ = r.ReadByte() p.Color = uint8(c) c, _ = r.ReadByte() if c > 0 { p.Protected = true } else { p.Protected = false } bs := make([]byte, 4) _, _ = r.Read(bs) p.Inauguration = binary.LittleEndian.Uint32(bs[0:]) c, _ = r.ReadByte() if c > 0 { p.AI = true } else { p.AI = false } c, _ = r.ReadByte() p.Bankruptcies = uint8(c) } func (p *PacketServerCompanyUpdate) Read(b []byte) { var err error r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) c, _ := r.ReadByte() p.CompanyID = uint8(c) p.Name, err = r.ReadString(0) logErrorDebug(err, "PacketServerCompanyUpdate.Read : Name") if err != nil { p.Name = "Error" } else { p.Name = p.Name[:len(p.Name)-1] } p.President, _ = r.ReadString(0) logErrorDebug(err, "PacketServerCompanyUpdate.Read : President") if err != nil { p.President = "Error" } else { p.President = p.President[:len(p.President)-1] } c, _ = r.ReadByte() p.Color = uint8(c) c, _ = r.ReadByte() if c > 0 { p.Protected = true } else { p.Protected = false } c, _ = r.ReadByte() p.Bankruptcies = uint8(c) } func (p *PacketServerCompanyRemove) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) c, _ := r.ReadByte() p.CompanyID = uint8(c) c, _ = r.ReadByte() p.Reason = uint8(c) } func (p *PacketServerChat) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) c, _ := r.ReadByte() p.ActionID = uint8(c) c, _ = r.ReadByte() p.DestinationID = uint8(c) bs := make([]byte, 4) _, _ = r.Read(bs) p.ClientID = binary.LittleEndian.Uint32(bs[0:]) p.Message, _ = r.ReadString(0) p.Message = p.Message[:len(p.Message)-1] bs = make([]byte, 8) _, _ = r.Read(bs) p.Amount = binary.LittleEndian.Uint64(bs[0:]) } func (p *PacketServerConsole) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) p.Origin, _ = r.ReadString(0) p.Origin = p.Origin[:len(p.Origin)-1] p.Text, _ = r.ReadString(0) p.Text = p.Text[:len(p.Text)-1] } func (p *PacketServerRCon) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) bs := make([]byte, 2) _, _ = r.Read(bs) p.ColorID = binary.LittleEndian.Uint16(bs[0:]) p.Output, _ = r.ReadString(0) p.Output = p.Output[:len(p.Output)-1] } func (p *PacketServerRConEnd) Read(b []byte) { r := bufio.NewReader(bytes.NewReader(b)) r.Discard(3) p.Command, _ = r.ReadString(0) p.Command = p.Command[:len(p.Command)-1] }