diff --git a/pkg/admin.go b/pkg/admin.go index f41b3e0..8c2ac08 100644 --- a/pkg/admin.go +++ b/pkg/admin.go @@ -14,12 +14,11 @@ import ( "time" ) - type OpenTTDServer struct { - connection net.Conn - rconDaily []string - rconMonthly []string - rconYearly []string + connection net.Conn + rconDaily []string + rconMonthly []string + rconYearly []string } const ( @@ -61,7 +60,7 @@ const ( adminPacketServerRCON_END = 125 ///< The server indicates that the remote console command has completed. adminPacketServerPONG = 126 ///< The server replies to a ping request from the admin. - invalidAdminPacket = 255 ///< An invalid marker for admin packets. + invalidAdminPacket = 255 ///< An invalid marker for admin packets. adminUpdateDATE = 0 ///< Updates about the date of the game. adminUpdateCLIENT_INFO = 1 ///< Updates about the information of clients. @@ -87,24 +86,24 @@ const ( // var conn int // Connect to the OpenTTD server on the admin port -func ( server *OpenTTDServer ) Connect(host string, port int, password string, botName string, botVersion string) { +func (server *OpenTTDServer) Connect(host string, port int, password string, botName string, botVersion string) { - // fmt.Printf("array: %v (%T) %d\n", toSend, toSend, size) - connectString := fmt.Sprintf("%s:%d", host, port) + // fmt.Printf("array: %v (%T) %d\n", toSend, toSend, size) + connectString := fmt.Sprintf("%s:%d", host, port) conn, err := net.Dial("tcp", connectString) if err != nil { - fmt.Printf("%v", err) + fmt.Printf("%v", err) panic(err) } - server.connection = conn + server.connection = conn - // start listening - go server.listenSocket() + // start listening + go server.listenSocket() - // login + // login var toSend []byte toSend = append(toSend[:], adminPacketAdminJOIN) // type - toSend = append(toSend[:], []byte(password)...) // password + toSend = append(toSend[:], []byte(password)...) // password toSend = append(toSend[:], 0x0) toSend = append(toSend[:], []byte(botName)...) // client name toSend = append(toSend[:], 0x0) @@ -115,14 +114,14 @@ func ( server *OpenTTDServer ) Connect(host string, port int, password string, b toSend = append([]byte{byte(size), 0x0}, toSend[:]...) server.connection.Write(toSend) - // register for daily updates + // register for daily updates updateDateCmd := make([]byte, 2) - binary.LittleEndian.PutUint16(updateDateCmd,adminUpdateDATE) + binary.LittleEndian.PutUint16(updateDateCmd, adminUpdateDATE) updateDateDaily := make([]byte, 2) - binary.LittleEndian.PutUint16(updateDateDaily,adminFrequencyDAILY) + binary.LittleEndian.PutUint16(updateDateDaily, adminFrequencyDAILY) toSend = []byte{} - toSend = append(toSend, updateDateCmd...) + toSend = append(toSend, updateDateCmd...) toSend = append(toSend, updateDateDaily...) server.sendSocket(adminPacketAdminUPDATE_FREQUENCY, toSend) @@ -140,35 +139,51 @@ func ( server *OpenTTDServer ) Connect(host string, port int, password string, b } // RegisterDateChange to send a command periodically -func ( server *OpenTTDServer ) RegisterDateChange (period string, command string) { - if period == "daily" { - server.rconDaily = append(server.rconDaily, command) - } else if period == "monthly" { - server.rconMonthly = append(server.rconMonthly, command) - } else if period == "yearly" { - server.rconYearly = append(server.rconYearly, command) - } else { - panic("bad period " + period) - } - return +func (server *OpenTTDServer) RegisterDateChange(period string, command string) { + if period == "daily" { + server.rconDaily = append(server.rconDaily, command) + } else if period == "monthly" { + server.rconMonthly = append(server.rconMonthly, command) + } else if period == "yearly" { + server.rconYearly = append(server.rconYearly, command) + } else { + panic("bad period " + period) + } + return } -func (server *OpenTTDServer ) dateChanged(dt time.Time) { - for _, rconCommand := range server.rconDaily { +func (server *OpenTTDServer) dateChanged(dt time.Time) { + // do every daily one + for _, rconCommand := range server.rconDaily { server.rconCommand(rconCommand) } + + // monthly ones on the 1st + if dt.Day() == 1 { + for _, rconCommand := range server.rconMonthly { + server.rconCommand(rconCommand) + } + } + + // yearly on the 1st of jan + if dt.Day() == 1 && dt.Month() == 1 { + for _, rconCommand := range server.rconYearly { + server.rconCommand(rconCommand) + } + } + } -func (server OpenTTDServer ) rconCommand(command string) { +func (server OpenTTDServer) rconCommand(command string) { - var rconCommand []byte - rconCommand = append(rconCommand, command...) - rconCommand = append(rconCommand, 0000) + var rconCommand []byte + rconCommand = append(rconCommand, command...) + rconCommand = append(rconCommand, 0000) server.sendSocket(adminPacketAdminRCON, rconCommand) } -func ( server *OpenTTDServer ) sendSocket( protocol int, data []byte) { +func (server *OpenTTDServer) sendSocket(protocol int, data []byte) { fmt.Printf("Going to send using protocol %v this data: %v\n", protocol, data) toSend := make([]byte, 3) // start with 3 bytes for the length and protocol size := uint16(len(data) + 3) // size 2 bytes, plus protocol @@ -180,7 +195,7 @@ func ( server *OpenTTDServer ) sendSocket( protocol int, data []byte) { server.connection.Write(toSend) } -func ( server *OpenTTDServer ) listenSocket() { +func (server *OpenTTDServer) listenSocket() { fmt.Printf("Listening to socket...\n") var chunk []byte @@ -192,12 +207,12 @@ SocketLoop: socketData := make([]byte, 1024) s, err := server.connection.Read(socketData) if err != nil { - if cErr, ok := err.(*net.OpError); ok { - if cErr.Err.Error() == "read: connection reset by peer" { - fmt.Println("Connection reset by peer - check the openttd log for details") - os.Exit(1) - } - } + if cErr, ok := err.(*net.OpError); ok { + if cErr.Err.Error() == "read: connection reset by peer" { + fmt.Println("Connection reset by peer - check the openttd log for details") + os.Exit(1) + } + } panic(err) } @@ -245,7 +260,7 @@ SocketLoop: epochDate := time.Date(0, time.January, 1, 0, 0, 0, 0, time.UTC) dt := epochDate.AddDate(0, 0, int(date)) fmt.Printf(" * Date is %v\n", dt) - server.dateChanged(dt) + server.dateChanged(dt) // uint32 } else if packetType == adminPacketServerCHAT { // fmt.Printf(" - Got a chat packet:\n%v", packetData) @@ -256,14 +271,14 @@ SocketLoop: chatMsg := extractString(packetData[6:]) chatData := binary.LittleEndian.Uint64(packetData[len(packetData)-8:]) fmt.Printf("action %v desttype %v, client id %v msg %v data %v\n", chatAction, chatDestType, chatClientID, string(chatMsg), chatData) - } else if packetType == adminPacketServerRCON { - colour := binary.LittleEndian.Uint16(packetData[0:2]) - string := extractString(packetData[2:]) - fmt.Printf("rcon: colour %v : %s\n", colour, string) - } else if packetType == adminPacketServerRCON_END { - string := extractString(packetData[0:]) - fmt.Printf("rcon end : %s\n", string) - } else { + } else if packetType == adminPacketServerRCON { + colour := binary.LittleEndian.Uint16(packetData[0:2]) + string := extractString(packetData[2:]) + fmt.Printf("rcon: colour %v : %s\n", colour, string) + } else if packetType == adminPacketServerRCON_END { + string := extractString(packetData[0:]) + fmt.Printf("rcon end : %s\n", string) + } else { fmt.Printf(" - Got an unknown packet %v\n", packetType) fmt.Printf(" - received from server: %v [%v]\n", string(packetData), packetData) }