Automatically reconnect if disconnected
This commit is contained in:
parent
2a715ac172
commit
a82b56b1bf
89
pkg/admin.go
89
pkg/admin.go
@ -10,15 +10,19 @@ import (
|
|||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// OpenTTDServer - an object representing the server connection
|
||||||
type OpenTTDServer struct {
|
type OpenTTDServer struct {
|
||||||
connection net.Conn
|
connection net.Conn
|
||||||
|
serverName string
|
||||||
rconDaily []string
|
rconDaily []string
|
||||||
rconMonthly []string
|
rconMonthly []string
|
||||||
rconYearly []string
|
rconYearly []string
|
||||||
|
connected chan bool
|
||||||
|
disconnected chan bool
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -83,22 +87,31 @@ const (
|
|||||||
adminFrequencyAUTOMATIC = 0x40 ///< The admin gets information about this when it changes.
|
adminFrequencyAUTOMATIC = 0x40 ///< The admin gets information about this when it changes.
|
||||||
)
|
)
|
||||||
|
|
||||||
// var conn int
|
|
||||||
|
|
||||||
// Connect to the OpenTTD server on the admin port
|
// 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) {
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
// fmt.Printf("array: %v (%T) %d\n", toSend, toSend, size)
|
// fmt.Printf("array: %v (%T) %d\n", toSend, toSend, size)
|
||||||
connectString := fmt.Sprintf("%s:%d", host, port)
|
connectString := fmt.Sprintf("%s:%d", host, port)
|
||||||
conn, err := net.Dial("tcp", connectString)
|
conn, err := net.Dial("tcp", connectString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("%v", err)
|
fmt.Printf("%v\n", err)
|
||||||
panic(err)
|
time.Sleep(time.Second * 2)
|
||||||
|
continue
|
||||||
|
//panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
go server.listenSocket()
|
||||||
|
|
||||||
|
server.connected = make(chan bool)
|
||||||
|
server.disconnected = make(chan bool)
|
||||||
|
|
||||||
|
fmt.Printf("saying we are connected\n")
|
||||||
server.connection = conn
|
server.connection = conn
|
||||||
|
server.connected <- true
|
||||||
|
|
||||||
// start listening
|
// start listening
|
||||||
go server.listenSocket()
|
|
||||||
|
|
||||||
// login
|
// login
|
||||||
var toSend []byte
|
var toSend []byte
|
||||||
@ -136,6 +149,12 @@ func (server *OpenTTDServer) Connect(host string, port int, password string, bot
|
|||||||
// fmt.Printf("array: %v (%T) %d\n", toSend, toSend, size)
|
// fmt.Printf("array: %v (%T) %d\n", toSend, toSend, size)
|
||||||
// conn.Write(toSend)
|
// conn.Write(toSend)
|
||||||
|
|
||||||
|
// wait until we are told we disconnected
|
||||||
|
<-server.disconnected
|
||||||
|
fmt.Printf("Reconnecting....")
|
||||||
|
time.Sleep(2 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// RegisterDateChange to send a command periodically
|
// RegisterDateChange to send a command periodically
|
||||||
@ -155,20 +174,20 @@ func (server *OpenTTDServer) RegisterDateChange(period string, command string) {
|
|||||||
func (server *OpenTTDServer) dateChanged(dt time.Time) {
|
func (server *OpenTTDServer) dateChanged(dt time.Time) {
|
||||||
// do every daily one
|
// do every daily one
|
||||||
for _, rconCommand := range server.rconDaily {
|
for _, rconCommand := range server.rconDaily {
|
||||||
server.rconCommand(rconCommand)
|
server.rconCommand(processCommand(rconCommand, dt))
|
||||||
}
|
}
|
||||||
|
|
||||||
// monthly ones on the 1st
|
// monthly ones on the 1st
|
||||||
if dt.Day() == 1 {
|
if dt.Day() == 1 {
|
||||||
for _, rconCommand := range server.rconMonthly {
|
for _, rconCommand := range server.rconMonthly {
|
||||||
server.rconCommand(rconCommand)
|
server.rconCommand(processCommand(rconCommand, dt))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// yearly on the 1st of jan
|
// yearly on the 1st of jan
|
||||||
if dt.Day() == 1 && dt.Month() == 1 {
|
if dt.Day() == 1 && dt.Month() == 1 {
|
||||||
for _, rconCommand := range server.rconYearly {
|
for _, rconCommand := range server.rconYearly {
|
||||||
server.rconCommand(rconCommand)
|
server.rconCommand(processCommand(rconCommand, dt))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,20 +202,31 @@ func (server OpenTTDServer) rconCommand(command string) {
|
|||||||
server.sendSocket(adminPacketAdminRCON, rconCommand)
|
server.sendSocket(adminPacketAdminRCON, rconCommand)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func processCommand(command string, dt time.Time) string {
|
||||||
|
command = strings.Replace(command, "%Y", fmt.Sprintf("%04d", dt.Year()), -1)
|
||||||
|
command = strings.Replace(command, "%M", fmt.Sprintf("%02d", dt.Month()), -1)
|
||||||
|
command = strings.Replace(command, "%D", fmt.Sprintf("%02d", dt.Day()), -1)
|
||||||
|
return command
|
||||||
|
}
|
||||||
|
|
||||||
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)
|
// 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
|
toSend := make([]byte, 3) // start with 3 bytes for the length and protocol
|
||||||
size := uint16(len(data) + 3) // size 2 bytes, plus protocol
|
size := uint16(len(data) + 3) // size 2 bytes, plus protocol
|
||||||
binary.LittleEndian.PutUint16(toSend, size)
|
binary.LittleEndian.PutUint16(toSend, size)
|
||||||
// toSend = append(toSend[:],
|
// toSend = append(toSend[:],
|
||||||
toSend[2] = byte(protocol)
|
toSend[2] = byte(protocol)
|
||||||
toSend = append(toSend, data...)
|
toSend = append(toSend, data...)
|
||||||
fmt.Printf("Going to send this: %v\n", toSend)
|
// fmt.Printf("Going to send this: %v\n", toSend)
|
||||||
server.connection.Write(toSend)
|
server.connection.Write(toSend)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (server *OpenTTDServer) listenSocket() {
|
func (server *OpenTTDServer) listenSocket() {
|
||||||
fmt.Printf("Listening to socket...\n")
|
|
||||||
|
fmt.Println("waiting for connection...")
|
||||||
|
// fmt.Printf("Listening to socket...\n")
|
||||||
|
<-server.connected
|
||||||
|
fmt.Println("connected indication")
|
||||||
|
|
||||||
var chunk []byte
|
var chunk []byte
|
||||||
|
|
||||||
@ -210,10 +240,18 @@ SocketLoop:
|
|||||||
if cErr, ok := err.(*net.OpError); ok {
|
if cErr, ok := err.(*net.OpError); ok {
|
||||||
if cErr.Err.Error() == "read: connection reset by peer" {
|
if cErr.Err.Error() == "read: connection reset by peer" {
|
||||||
fmt.Println("Connection reset by peer - check the openttd log for details")
|
fmt.Println("Connection reset by peer - check the openttd log for details")
|
||||||
os.Exit(1)
|
server.connection = nil
|
||||||
|
server.disconnected <- true
|
||||||
|
return
|
||||||
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("Error occurred on socket: ", err)
|
||||||
|
server.connection = nil
|
||||||
|
server.disconnected <- true
|
||||||
|
return
|
||||||
}
|
}
|
||||||
panic(err)
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// fmt.Printf("Read %d bytes from socket\n", s)
|
// fmt.Printf("Read %d bytes from socket\n", s)
|
||||||
@ -245,21 +283,23 @@ SocketLoop:
|
|||||||
// fmt.Printf("packet type %d and size is %v bytes, I read %d from socket\n", packetType, len(packetData), s)
|
// fmt.Printf("packet type %d and size is %v bytes, I read %d from socket\n", packetType, len(packetData), s)
|
||||||
|
|
||||||
if packetType == adminPacketServerPROTOCOL {
|
if packetType == adminPacketServerPROTOCOL {
|
||||||
fmt.Print(" - Got a adminPacketServerPROTOCOL packet\n")
|
// fmt.Print(" - Got a adminPacketServerPROTOCOL packet\n")
|
||||||
} else if packetType == adminPacketServerWELCOME {
|
} else if packetType == adminPacketServerWELCOME {
|
||||||
fmt.Print(" - Got a adminPacketServerWELCOME packet\n")
|
// fmt.Print(" - Got a adminPacketServerWELCOME packet\n")
|
||||||
serverName := extractString(packetData[0:])
|
server.serverName = extractString(packetData[0:])
|
||||||
fmt.Printf(" * server name: %s\n", serverName)
|
// fmt.Printf(" * server name: %s\n", serverName)
|
||||||
} else if packetType == adminPacketServerSHUTDOWN {
|
} else if packetType == adminPacketServerSHUTDOWN {
|
||||||
fmt.Print(" - Got a adminPacketServerSHUTDOWN packet\n")
|
fmt.Print("* Got a adminPacketServerSHUTDOWN packet - will try to reconnect\n")
|
||||||
os.Exit(1)
|
server.connection = nil
|
||||||
|
server.disconnected <- true
|
||||||
|
return
|
||||||
|
|
||||||
} else if packetType == adminPacketServerDATE {
|
} else if packetType == adminPacketServerDATE {
|
||||||
fmt.Print(" - Got a damn adminPacketServerDATE\n")
|
|
||||||
// [[7 0 107 84 252 10 0 0 0
|
// [[7 0 107 84 252 10 0 0 0
|
||||||
date := binary.LittleEndian.Uint32(packetData[0:4])
|
date := binary.LittleEndian.Uint32(packetData[0:4])
|
||||||
epochDate := time.Date(0, time.January, 1, 0, 0, 0, 0, time.UTC)
|
epochDate := time.Date(0, time.January, 1, 0, 0, 0, 0, time.UTC)
|
||||||
dt := epochDate.AddDate(0, 0, int(date))
|
dt := epochDate.AddDate(0, 0, int(date))
|
||||||
fmt.Printf(" * Date is %v\n", dt)
|
// fmt.Printf(" * Date is %v\n", dt)
|
||||||
server.dateChanged(dt)
|
server.dateChanged(dt)
|
||||||
// uint32
|
// uint32
|
||||||
} else if packetType == adminPacketServerCHAT {
|
} else if packetType == adminPacketServerCHAT {
|
||||||
@ -279,8 +319,7 @@ SocketLoop:
|
|||||||
string := extractString(packetData[0:])
|
string := extractString(packetData[0:])
|
||||||
fmt.Printf("rcon end : %s\n", string)
|
fmt.Printf("rcon end : %s\n", string)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf(" - Got an unknown packet %v\n", packetType)
|
fmt.Printf("* Unknown packet received from server: %v [%v]\n", string(packetData), packetData)
|
||||||
fmt.Printf(" - received from server: %v [%v]\n", string(packetData), packetData)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fmt.Printf("removing the chunk we have processed\n")
|
// fmt.Printf("removing the chunk we have processed\n")
|
||||||
@ -288,7 +327,7 @@ SocketLoop:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// check if there is data left to process in the current data
|
// check if there is data left to process in the current data
|
||||||
fmt.Printf("remaining in chunk %d bytes", len(chunk))
|
// fmt.Printf("remaining in chunk %d bytes", len(chunk))
|
||||||
if len(chunk) < 3 {
|
if len(chunk) < 3 {
|
||||||
// we don't even have enough for a length and protocol type, so may
|
// we don't even have enough for a length and protocol type, so may
|
||||||
// as well go sit on the socket
|
// as well go sit on the socket
|
||||||
|
Loading…
x
Reference in New Issue
Block a user