gottdad/main.go

305 lines
8.5 KiB
Go
Raw Normal View History

2020-06-14 16:27:57 +02:00
package main
import (
2020-06-14 16:32:21 +02:00
"bufio"
2020-06-14 22:39:17 +02:00
"encoding/binary"
2020-06-21 19:55:32 +02:00
//"fmt"
2020-06-14 16:27:57 +02:00
"net"
2020-06-21 14:57:44 +02:00
"regexp"
2020-06-21 16:31:09 +02:00
"strconv"
2020-06-21 19:00:31 +02:00
"time"
2020-06-21 19:43:01 +02:00
tb "gopkg.in/tucnak/telebot.v2"
2020-06-14 16:27:57 +02:00
)
2020-06-21 16:10:45 +02:00
type Client struct {
ClientID uint32
Name string
Address string
CompanyID uint8
}
2020-06-21 19:42:41 +02:00
var (
bot *tb.Bot
clients map[uint32]*Client
paused bool = true
forcePaused bool = true
2020-06-21 19:54:01 +02:00
githash string
buildstamp string
commits string
2020-06-21 19:42:41 +02:00
)
2020-06-14 16:27:57 +02:00
func main() {
2020-06-15 15:04:55 +02:00
2020-06-21 16:34:12 +02:00
clients = make(map[uint32]*Client)
2020-06-14 16:32:21 +02:00
conn, err := net.Dial("tcp", "poop.siteop.biz:3977")
2020-06-14 16:27:57 +02:00
failError(err, "net.Dial")
logInfoDebug("Connected to poop.siteop.biz:3977")
2020-06-14 16:44:40 +02:00
//send auth
p := PacketAdminJoin{
2020-06-14 16:48:00 +02:00
Packet: Packet{PType: AdminPacketAdminJoin},
2020-06-14 17:13:25 +02:00
Password: "plop",
AppName: "gottdad",
AppVersion: "alpha",
2020-06-14 16:44:40 +02:00
}
_, err = conn.Write(p.Bytes())
failError(err, "conn.Write")
2020-06-14 22:16:39 +02:00
r := bufio.NewReader(conn)
2020-06-14 22:39:17 +02:00
b := make([]byte, 0xFFFF)
read := 0
n := 0
2020-06-14 16:44:40 +02:00
2020-06-21 19:42:41 +02:00
// Registering bot
bot, err = tb.NewBot(tb.Settings{
Token: "954090437:AAEMYeUWGluKZRwXi_K3-T23ZVpFoqQAmu0",
URL: "https://api.telegram.org",
Poller: &tb.LongPoller{Timeout: 10 * time.Second},
})
failError(err, "Registering bot")
logInfoDebug("Connected to Telegram")
2020-06-21 19:51:38 +02:00
go BotHandlers(bot)
2020-06-21 19:57:58 +02:00
u := tb.User{
ID: int(32173684),
}
bot.Send(&u, fmt.Sprintf("Started (%s-b%s - %s)", githash, commits, buildstamp))
2020-06-21 19:51:38 +02:00
2020-06-14 22:39:17 +02:00
for {
p := Packet{}
2020-06-14 22:05:45 +02:00
for {
2020-06-14 22:39:17 +02:00
if read >= 3 {
2020-06-15 12:48:31 +02:00
//logInfoDebug("Packet read")
2020-06-14 22:05:45 +02:00
break
}
2020-06-14 22:46:23 +02:00
n, err = r.Read(b[read:])
logErrorDebug(err, "r.Read")
read += n
2020-06-15 12:48:31 +02:00
//logInfoDebug("Waiting for packet, read %d bytes.", read)
2020-06-14 22:46:23 +02:00
2020-06-14 22:39:17 +02:00
}
p.PLength = binary.LittleEndian.Uint16(b[0:])
p.PType = b[2]
if p.PLength <= 3 {
logInfoAlert("Wrong packet length")
break
}
2020-06-14 22:20:19 +02:00
2020-06-15 12:48:31 +02:00
//logInfoDebug("Waiting for packet data : len : %d / type : %d", p.PLength, p.PType)
2020-06-14 22:44:39 +02:00
2020-06-14 22:39:17 +02:00
for {
2020-06-14 22:45:52 +02:00
if read >= int(p.PLength) {
2020-06-15 12:48:44 +02:00
//logInfoDebug("Data read")
2020-06-14 22:45:52 +02:00
break
}
2020-06-14 22:39:17 +02:00
n, err = r.Read(b[read:])
logErrorDebug(err, "r.Read")
read += n
2020-06-15 12:48:31 +02:00
//logInfoDebug("Waiting for data, read %d/%d bytes.", read, p.PLength)
2020-06-14 22:45:52 +02:00
2020-06-14 22:20:19 +02:00
}
2020-06-14 22:39:17 +02:00
2020-06-15 12:42:02 +02:00
switch p.PType {
case AdminPacketServerProtocol:
2020-06-15 15:04:55 +02:00
sp := PacketServerProtocol{
2020-06-15 12:42:02 +02:00
Packet: p,
}
sp.Read(b[:p.PLength])
logInfoDebug("AdminPacketServerProtocol :\n- ProtocolVersion: %v\n- FurtherData: %v\n- UpdatePacketType: %v\n- FrequenciesAllowed: %b", sp.ProtocolVersion, sp.FurtherData, sp.UpdatePacketType, sp.FrequenciesAllowed)
case AdminPacketServerWelcome:
2020-06-15 15:04:55 +02:00
sp := PacketServerWelcome{
2020-06-15 12:42:02 +02:00
Packet: p,
}
sp.Read(b[:p.PLength])
logInfoDebug("AdminPacketServerWelcome :\n- ServerName: %v\n- OpenTTDVersion: %v\n- Dedicated: %v\n- MapSeed: %x\n- MapLandscape: %v\n- MapStartDate: %v\n- Size: %v x %v", sp.ServerName, sp.OpenTTDVersion, sp.Dedicated, sp.MapSeed, sp.MapLandscape, sp.MapStartDate, sp.MapX, sp.MapY)
px := PacketAdminUpdateFrequency{
Packet: Packet{PType: AdminPacketAdminUpdateFrequency},
UpdateType: AdminUpdateDate,
UpdateFrequency: AdminFrequencyDaily,
}
2020-06-15 12:42:27 +02:00
_, err = conn.Write(px.Bytes())
2020-06-15 12:50:09 +02:00
2020-06-15 12:50:20 +02:00
px = PacketAdminUpdateFrequency{
2020-06-15 12:50:09 +02:00
Packet: Packet{PType: AdminPacketAdminUpdateFrequency},
UpdateType: AdminUpdateClientInfo,
UpdateFrequency: AdminFrequencyAutomatic,
}
_, err = conn.Write(px.Bytes())
2020-06-15 14:28:42 +02:00
2020-06-21 19:05:51 +02:00
px = PacketAdminUpdateFrequency{
Packet: Packet{PType: AdminPacketAdminUpdateFrequency},
UpdateType: AdminUpdateCompanyInfo,
UpdateFrequency: AdminFrequencyAutomatic,
}
_, err = conn.Write(px.Bytes())
2020-06-15 14:28:42 +02:00
px = PacketAdminUpdateFrequency{
Packet: Packet{PType: AdminPacketAdminUpdateFrequency},
UpdateType: AdminUpdateChat,
UpdateFrequency: AdminFrequencyAutomatic,
}
_, err = conn.Write(px.Bytes())
px = PacketAdminUpdateFrequency{
Packet: Packet{PType: AdminPacketAdminUpdateFrequency},
UpdateType: AdminUpdateConsole,
UpdateFrequency: AdminFrequencyAutomatic,
}
_, err = conn.Write(px.Bytes())
2020-06-15 12:47:05 +02:00
case AdminPacketServerDate:
2020-06-15 15:04:55 +02:00
sp := PacketServerDate{
2020-06-15 12:46:43 +02:00
Packet: p,
}
sp.Read(b[:p.PLength])
2020-06-21 19:35:29 +02:00
logInfoDebug("AdminPacketServerDate :\n- Date: %d\n- RealDate : %v", sp.Date, toDate(sp.Date))
2020-06-15 15:04:55 +02:00
paused = false
2020-06-15 14:14:24 +02:00
case AdminPacketServerClientJoin:
2020-06-15 15:04:55 +02:00
sp := PacketServerClientJoin{
2020-06-15 14:14:24 +02:00
Packet: p,
}
sp.Read(b[:p.PLength])
logInfoDebug("AdminPacketServerClientJoin :\n- ClientID: %d", sp.ClientID)
case AdminPacketServerClientInfo:
2020-06-15 15:04:55 +02:00
sp := PacketServerClientInfo{
2020-06-15 14:14:24 +02:00
Packet: p,
}
sp.Read(b[:p.PLength])
2020-06-21 19:15:20 +02:00
//logInfoDebug("AdminPacketServerClientInfo :\n- ClientID: %d\n- Address: %s\n- Name: %s\n- Lang: %d\n- Date: %d\n- CompanyID: %d", sp.ClientID, sp.Address, sp.Name, sp.Lang, sp.Date, sp.CompanyID)
2020-06-21 16:10:45 +02:00
clt := Client{
ClientID: sp.ClientID,
Name: sp.Name,
Address: sp.Address,
CompanyID: sp.CompanyID,
}
2020-06-21 16:34:51 +02:00
clients[sp.ClientID] = &clt
2020-06-21 16:10:45 +02:00
logInfoDebug("Clients : %v", clients)
2020-06-15 14:14:24 +02:00
case AdminPacketServerClientError:
2020-06-15 15:04:55 +02:00
sp := PacketServerClientError{
2020-06-15 14:14:24 +02:00
Packet: p,
}
sp.Read(b[:p.PLength])
logInfoDebug("AdminPacketServerClientError :\n- ClientID: %d\n- ErrorID: %d", sp.ClientID, sp.ErrorID)
2020-06-15 14:28:42 +02:00
case AdminPacketServerClientQuit:
2020-06-15 15:04:55 +02:00
sp := PacketServerClientQuit{
2020-06-15 14:28:42 +02:00
Packet: p,
}
sp.Read(b[:p.PLength])
2020-06-15 14:44:52 +02:00
logInfoDebug("AdminPacketServerClientQuit :\n- ClientID: %d", sp.ClientID)
2020-06-21 16:10:45 +02:00
delete(clients, sp.ClientID)
2020-06-15 14:44:52 +02:00
case AdminPacketServerChat:
2020-06-15 15:04:55 +02:00
sp := PacketServerChat{
2020-06-15 14:44:52 +02:00
Packet: p,
}
sp.Read(b[:p.PLength])
2020-06-21 15:33:53 +02:00
if sp.Message == "!unpause" {
logInfoDebug("AdminPacketServerChat : Unpausing")
forcePaused = false
2020-06-21 19:15:20 +02:00
} else if sp.Message == "!pause" {
2020-06-21 15:33:53 +02:00
logInfoDebug("AdminPacketServerChat : Pausing")
forcePaused = true
2020-06-21 19:15:20 +02:00
} else {
logInfoDebug("AdminPacketServerChat :\n- ActionID: %d\n- DestinationID: %d\n- ClientID: %d\n- Message: %s\n- Amount: %d", sp.ActionID, sp.DestinationID, sp.ClientID, sp.Message, sp.Amount)
2020-06-21 15:33:53 +02:00
}
2020-06-15 14:44:52 +02:00
case AdminPacketServerConsole:
2020-06-15 15:04:55 +02:00
sp := PacketServerConsole{
2020-06-15 14:44:52 +02:00
Packet: p,
}
sp.Read(b[:p.PLength])
2020-06-21 15:26:56 +02:00
ok, err := regexp.MatchString("\\[udp\\] queried from .*", sp.Text)
logErrorDebug(err, "queried from")
2020-06-21 15:20:36 +02:00
if sp.Origin != "net" || ok == false {
2020-06-21 15:22:09 +02:00
logInfoDebug("AdminPacketServerConsole :\n- Origin: %q\n- Text: %s", sp.Origin, sp.Text)
2020-06-21 14:57:15 +02:00
}
2020-06-21 15:47:37 +02:00
case AdminPacketServerRCon:
sp := PacketServerRCon{
Packet: p,
}
sp.Read(b[:p.PLength])
2020-06-21 16:30:04 +02:00
2020-06-21 16:33:29 +02:00
ok, _ := regexp.MatchString("Client #[0-9]+ name: '.*' company: [0-9]+ IP: .*", sp.Output)
2020-06-21 16:30:04 +02:00
if ok {
clt := Client{}
r, _ := regexp.Compile("Client #(?P<ClientID>[0-9]+) name: '(?P<Name>.*)' company: (?P<CompanyID>[0-9]+) IP: (?P<Address>.*)")
2020-06-21 16:33:13 +02:00
ID64, _ := strconv.ParseInt(r.ReplaceAllString(sp.Output, "${ClientID}"), 10, 32)
clt.ClientID = uint32(ID64)
2020-06-21 19:06:22 +02:00
clt.Name = r.ReplaceAllString(sp.Output, "${Name}")
2020-06-21 19:08:21 +02:00
if clt.Name == "" {
clt.Name = "server"
}
2020-06-21 16:33:13 +02:00
ID64, _ = strconv.ParseInt(r.ReplaceAllString(sp.Output, "${CompanyID}"), 10, 8)
clt.CompanyID = uint8(ID64)
2020-06-21 16:31:09 +02:00
clt.Address = r.ReplaceAllString(sp.Output, "${Address}")
2020-06-21 16:34:51 +02:00
clients[clt.ClientID] = &clt
2020-06-21 19:15:20 +02:00
} else {
logInfoDebug("AdminPacketServerRCon :\n- ColorID: %d\n- Output: %s", sp.ColorID, sp.Output)
2020-06-21 16:30:04 +02:00
}
2020-06-15 15:07:52 +02:00
case AdminPacketServerRConEnd:
sp := PacketServerRConEnd{
Packet: p,
}
sp.Read(b[:p.PLength])
2020-06-21 19:15:20 +02:00
2020-06-21 19:05:51 +02:00
if sp.Command == "clients" {
for k, v := range clients {
logInfoDebug("Client[%d] : %s - %d (%s)", k, v.Name, v.CompanyID, v.Address)
}
2020-06-21 19:15:20 +02:00
} else {
logInfoDebug("AdminPacketServerRConEnd :\n- Command: %s", sp.Command)
2020-06-21 19:05:51 +02:00
}
2020-06-15 12:42:02 +02:00
default:
logInfoDebug("Packet fully read : len : %d / type : %d", p.PLength, p.PType)
}
2020-06-14 23:31:31 +02:00
2020-06-14 22:39:17 +02:00
c := make([]byte, 0xFFFF)
copy(c, b[p.PLength:])
b = c
2020-06-14 22:42:34 +02:00
read -= int(p.PLength)
2020-06-15 15:04:55 +02:00
2020-06-21 16:10:45 +02:00
if len(clients) == 0 {
2020-06-21 15:37:17 +02:00
px := PacketAdminRCon{
Packet: Packet{PType: AdminPacketAdminRCon},
Command: "clients",
}
_, err = conn.Write(px.Bytes())
}
2020-06-21 15:20:36 +02:00
if !paused && forcePaused {
2020-06-21 19:13:13 +02:00
paused = true
2020-06-21 15:20:36 +02:00
px := PacketAdminRCon{
Packet: Packet{PType: AdminPacketAdminRCon},
Command: "pause",
}
_, err = conn.Write(px.Bytes())
2020-06-21 19:00:14 +02:00
logInfoDebug("Pause forced")
time.Sleep(1 * time.Second)
2020-06-21 15:20:36 +02:00
}
2020-06-21 16:10:45 +02:00
if paused && !forcePaused && len(clients) > 1 { // server is client #1
2020-06-15 15:04:55 +02:00
paused = false
2020-06-15 15:05:12 +02:00
px := PacketAdminRCon{
2020-06-15 15:04:55 +02:00
Packet: Packet{PType: AdminPacketAdminRCon},
Command: "unpause",
}
_, err = conn.Write(px.Bytes())
2020-06-21 19:00:14 +02:00
logInfoDebug("Unpause forced")
time.Sleep(1 * time.Second)
2020-06-15 15:04:55 +02:00
}
2020-06-21 16:10:45 +02:00
if !paused && len(clients) == 1 { // server is client #1
2020-06-15 15:04:55 +02:00
paused = true
2020-06-15 15:05:12 +02:00
px := PacketAdminRCon{
2020-06-15 15:04:55 +02:00
Packet: Packet{PType: AdminPacketAdminRCon},
Command: "pause",
}
_, err = conn.Write(px.Bytes())
2020-06-21 19:00:14 +02:00
logInfoDebug("Pausing")
time.Sleep(1 * time.Second)
2020-06-15 15:04:55 +02:00
}
2020-06-14 22:39:17 +02:00
}
2020-06-14 16:27:57 +02:00
}