549 lines
12 KiB
Go
549 lines
12 KiB
Go
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
|
|
|
|
AdminNetworkActionJoin = 0
|
|
AdminNetworkActionLeave = 1
|
|
AdminNetworkActionServerMessage = 2
|
|
AdminNetworkActionChat = 3
|
|
AdminNetworkActionChatCompany = 4
|
|
AdminNetworkActionChatClient = 5
|
|
AdminNetworkActionGiveMoney = 6
|
|
AdminNetworkActionNameChange = 7
|
|
AdminNetworkActionCompanySpectator = 8
|
|
AdminNetworkActionCompanyJoin = 9
|
|
AdminNetworkActionCompanyNew = 10
|
|
AdminNetworkActionKicked = 11
|
|
AdminNetworkActionExternalChat = 12
|
|
|
|
AdminDestinationTypeBroadcast = 0
|
|
AdminDestinationTypeTeam = 1
|
|
AdminDestinationTypeClient = 2
|
|
)
|
|
|
|
type Packet struct {
|
|
PLength uint16
|
|
PType uint8
|
|
}
|
|
|
|
type PacketAdminJoin struct {
|
|
Packet
|
|
Password string
|
|
AppName string
|
|
AppVersion string
|
|
}
|
|
|
|
type PacketAdminChat struct {
|
|
Packet
|
|
ActionType uint8
|
|
DestinationType uint8
|
|
DestinationID uint32
|
|
Message 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 *PacketServerChat) Bytes() []byte {
|
|
buf := new(bytes.Buffer)
|
|
p.PLength = uint16(len(p.Message) + 17)
|
|
|
|
binary.Write(buf, binary.LittleEndian, p.PLength)
|
|
binary.Write(buf, binary.LittleEndian, p.ActionID)
|
|
binary.Write(buf, binary.LittleEndian, p.DestinationID)
|
|
binary.Write(buf, binary.LittleEndian, p.ClientID)
|
|
buf.WriteString(p.Message)
|
|
buf.WriteByte(0)
|
|
binary.Write(buf, binary.LittleEndian, p.Amount)
|
|
|
|
return buf.Bytes()
|
|
|
|
}
|
|
|
|
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]
|
|
}
|