379 lines
8.4 KiB
Go
379 lines
8.4 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/jinzhu/copier"
|
|
)
|
|
|
|
func loadClients() error {
|
|
var clts []ChirpClient
|
|
|
|
b, err := ioutil.ReadFile("./data/clients.json")
|
|
logOnError(err, "loadClients : ReadFile(./data/clients.json)")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
err = json.Unmarshal(b, &clts)
|
|
logOnError(err, "loadClients : Unmarshal(./data/clients.json)")
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
muxClients.Lock()
|
|
for _, c := range clts {
|
|
cx := ChirpClient{}
|
|
copier.Copy(&cx, &c)
|
|
cx.Active = false
|
|
if cx.Config.Wartime == `` {
|
|
cx.Config.Wartime = `🛡Defend`
|
|
}
|
|
|
|
/*
|
|
cx.MQ.Connection, err = amqp.Dial("amqp://" + cx.MQ.User + ":" + cx.MQ.Password + "@" + cx.MQ.Host + "/" + cx.MQ.Path)
|
|
logOnError(err, "loadClients : Failed to connect to RabbitMQ")
|
|
*/
|
|
clients[cx.TGUserID64] = &cx
|
|
log.Printf("loadClients[%s] : done\n", cx.Login)
|
|
|
|
}
|
|
muxClients.Unlock()
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
func getLockedRoleClient(role string) (*ChirpClient, error) {
|
|
muxClients.RLock()
|
|
defer muxClients.RUnlock()
|
|
|
|
ids := make([]int64, 0)
|
|
for _, c := range clients {
|
|
if c.CWRole == role {
|
|
ids = append(ids, c.TGUserID64)
|
|
fmt.Printf("getLockedRoleClient(%s) : appending %s (%d).\n", role, c.Login, c.TGUserID64)
|
|
}
|
|
}
|
|
if len(ids) == 0 {
|
|
return nil, errors.New("No client for the role.")
|
|
}
|
|
|
|
RndMux.Lock()
|
|
id := RndSrc.Intn(len(ids))
|
|
RndMux.Unlock()
|
|
|
|
clients[ids[id]].Mux.Lock()
|
|
|
|
return clients[ids[id]], nil
|
|
}
|
|
|
|
func getLockedRandomClient() (*ChirpClient, error) {
|
|
muxClients.RLock()
|
|
ids := make([]int64, 0)
|
|
for _, c := range clients {
|
|
if c.Active {
|
|
ids = append(ids, c.TGUserID64)
|
|
}
|
|
}
|
|
muxClients.RUnlock()
|
|
if len(ids) == 0 {
|
|
return nil, errors.New("No active client.")
|
|
}
|
|
|
|
RndMux.Lock()
|
|
id := RndSrc.Intn(len(ids))
|
|
RndMux.Unlock()
|
|
|
|
clients[ids[id]].Mux.Lock()
|
|
|
|
return clients[ids[id]], nil
|
|
}
|
|
|
|
func setClientBusy(userID64 int64, from time.Time, duration time.Duration) error {
|
|
if clt, ok := getLockedClient(userID64, false); ok {
|
|
if from.UTC().Add(duration).After(time.Now().UTC()) {
|
|
clt.CWIdle = false
|
|
clt.CWBusyUntil = from.UTC().Add(duration)
|
|
log.Printf("setClientBusy[%s] : set for %s.\n", clt.Login, duration.String())
|
|
} else {
|
|
log.Printf("setClientBusy[%s] : not updated.\n", clt.Login)
|
|
}
|
|
clt.Mux.Unlock()
|
|
return nil
|
|
} else {
|
|
return errors.New("Client not found.")
|
|
}
|
|
}
|
|
|
|
func setClientIdle(userID64 int64, from time.Time) error {
|
|
if clt, ok := getLockedClient(userID64, false); ok {
|
|
if from.UTC().After(clt.CWLastUpdate.UTC()) {
|
|
clt.CWBusyUntil = from
|
|
clt.CWIdle = true
|
|
clt.CWLastUpdate = from
|
|
} else {
|
|
}
|
|
clt.Mux.Unlock()
|
|
return nil
|
|
} else {
|
|
return errors.New("Client not found.")
|
|
}
|
|
}
|
|
|
|
func getLockedIdleClient() (*ChirpClient, error) {
|
|
muxClients.RLock()
|
|
ids := make([]int64, 0)
|
|
for _, c := range clients {
|
|
if c.CWIdle {
|
|
ids = append(ids, c.TGUserID64)
|
|
}
|
|
}
|
|
muxClients.RUnlock()
|
|
if len(ids) == 0 {
|
|
return nil, errors.New("No idle client.")
|
|
}
|
|
|
|
RndMux.Lock()
|
|
id := RndSrc.Intn(len(ids))
|
|
RndMux.Unlock()
|
|
|
|
clients[ids[id]].Mux.Lock()
|
|
|
|
return clients[ids[id]], nil
|
|
|
|
}
|
|
|
|
func getLockedAllIdleClientID64() ([]int64, error) {
|
|
muxClients.RLock()
|
|
ids := make([]int64, 0)
|
|
for _, c := range clients {
|
|
if c.CWIdle {
|
|
ids = append(ids, c.TGUserID64)
|
|
clients[c.TGUserID64].Mux.Lock()
|
|
}
|
|
}
|
|
muxClients.RUnlock()
|
|
|
|
return ids, nil
|
|
}
|
|
|
|
func getAllIdleClientID64() ([]int64, error) {
|
|
muxClients.RLock()
|
|
ids := make([]int64, 0)
|
|
for _, c := range clients {
|
|
if c.CWIdle {
|
|
ids = append(ids, c.TGUserID64)
|
|
}
|
|
}
|
|
muxClients.RUnlock()
|
|
|
|
return ids, nil
|
|
}
|
|
|
|
func getLockedClient(id int64, createMissing bool) (*ChirpClient, bool) {
|
|
muxClients.RLock()
|
|
if c, ok := clients[id]; ok {
|
|
c.Mux.Lock()
|
|
muxClients.RUnlock()
|
|
return c, true
|
|
} else if createMissing {
|
|
c := ChirpClient{
|
|
TGUserID64: id,
|
|
Active: false,
|
|
Config: &ChirpConfig{
|
|
InterceptPillage: true,
|
|
Wartime: `🛡Defend`,
|
|
},
|
|
}
|
|
c.Mux.Lock()
|
|
muxClients.RUnlock()
|
|
muxClients.Lock()
|
|
clients[id] = &c
|
|
muxClients.Unlock()
|
|
return &c, true
|
|
} else {
|
|
muxClients.RUnlock()
|
|
//c := new(ChirpClient)
|
|
//return c, false
|
|
return nil, false
|
|
}
|
|
}
|
|
|
|
func clientDelTGMsg(userID64 int64, fromMsgID64 int64, fromChatID64 int64) {
|
|
c := TGCommand{
|
|
Type: commandDeleteMsg,
|
|
FromUserID64: userID64,
|
|
FromMsgID64: fromMsgID64,
|
|
FromChatID64: fromChatID64,
|
|
}
|
|
MQTGCmdQueue <- c
|
|
}
|
|
|
|
func clientFwdCWMsg(userID64 int64, fromMsgID64 int64, fromChatID64 int64, toChatID64 int64) {
|
|
c := TGCommand{
|
|
Type: commandForwardMsg,
|
|
FromUserID64: userID64,
|
|
FromMsgID64: fromMsgID64,
|
|
FromChatID64: fromChatID64,
|
|
ToChatID64: toChatID64,
|
|
}
|
|
MQTGCmdQueue <- c
|
|
|
|
}
|
|
|
|
func clientSendTGMsgDelay(userID64 int64, chatID64 int64, s string, d time.Duration) {
|
|
c := TGCommand{
|
|
Type: commandSendMsg,
|
|
Text: s,
|
|
FromUserID64: userID64,
|
|
ToChatID64: chatID64,
|
|
Delay: d,
|
|
}
|
|
MQTGCmdQueue <- c
|
|
}
|
|
|
|
func clientSendTGMsg(userID64 int64, chatID64 int64, s string) {
|
|
clientSendTGMsgDelay(userID64, chatID64, s, 0)
|
|
}
|
|
|
|
func clientSendCWMsg(userID64 int64, s string) {
|
|
clientSendCWMsgDelay(userID64, s, 0)
|
|
}
|
|
|
|
func clientSendCWMsgDelay(userID64 int64, s string, d time.Duration) {
|
|
clientSendTGMsgDelay(userID64, userID64ChtWrsBot, s, d)
|
|
}
|
|
|
|
func clientRefreshCWMsg(userID64 int64, chatID64 int64, msgID64 int64) {
|
|
log.Printf("clientRefreshCWMsg(%d, %d, %d)\n", userID64, chatID64, msgID64)
|
|
c := TGCommand{
|
|
Type: commandRefreshMsg,
|
|
FromUserID64: userID64,
|
|
FromChatID64: chatID64,
|
|
FromMsgID64: msgID64,
|
|
Delay: 0,
|
|
}
|
|
MQTGCmdQueue <- c
|
|
}
|
|
|
|
func clientCallbackDelay(userID64 int64, msgID64 int64, chatID64 int64, name string, data []byte, d time.Duration) {
|
|
c := TGCommand{
|
|
Type: commandCallback,
|
|
FromUserID64: userID64,
|
|
FromChatID64: chatID64,
|
|
FromMsgID64: msgID64,
|
|
Delay: d,
|
|
CallbackName: name,
|
|
CallbackData: data,
|
|
}
|
|
MQTGCmdQueue <- c
|
|
}
|
|
|
|
func clientCallback(userID64 int64, msgID64 int64, chatID64 int64, name string, data []byte) {
|
|
clientCallbackDelay(userID64, msgID64, chatID64, name, data, 0)
|
|
}
|
|
|
|
func clientMsgMeAck(m *ChatWarsMessageMeAck) {
|
|
if clt, ok := getLockedClient(m.Msg.TGUserID64, false); ok {
|
|
if clt.Active {
|
|
if clt.CWLastUpdate.Before(m.Msg.Date) {
|
|
clt.CWGuildID64 = m.CWGuildID64
|
|
clt.CWUserID64 = m.CWUserID64
|
|
clt.CWState = m.State
|
|
clt.CWClass = m.Class
|
|
clt.CWLastUpdate = m.Msg.Date
|
|
if getObjGuildID(``) != m.CWGuildID64 && strings.Compare(clt.CWRole, ``) == 0 {
|
|
clientSendCWMsg(m.Msg.TGUserID64, "/g_roles")
|
|
}
|
|
if m.State == `🛌Rest` {
|
|
clt.CWIdle = true
|
|
}
|
|
}
|
|
}
|
|
clt.Mux.Unlock()
|
|
}
|
|
}
|
|
|
|
func clientMsgGListAck(msg *ChatWarsMessageGListAck) {
|
|
muxClients.Lock()
|
|
for _, clt := range clients {
|
|
for _, m := range msg.Members {
|
|
clt.Mux.Lock()
|
|
if m.Name == clt.Nickname {
|
|
if m.Class2 == `⚔️` {
|
|
clt.CWClass2 = `Knight`
|
|
}
|
|
}
|
|
clt.Mux.Unlock()
|
|
}
|
|
}
|
|
muxClients.Unlock()
|
|
}
|
|
|
|
func clientMsgGoQuestAck(m *ChatWarsMessageGoQuestAck) {
|
|
if clt, ok := getLockedClient(m.Msg.TGUserID64, false); ok {
|
|
if clt.Active {
|
|
if clt.CWLastUpdate.Before(m.Msg.Date) {
|
|
clt.CWLastUpdate = m.Msg.Date
|
|
clt.CWBusyUntil = m.Msg.Date.Add(m.Duration)
|
|
}
|
|
}
|
|
clt.Mux.Unlock()
|
|
}
|
|
}
|
|
|
|
func clientMsgGRolesAck(m *ChatWarsMessageGRolesAck) {
|
|
if clt, ok := getLockedClient(m.Msg.TGUserID64, false); ok {
|
|
if clt.Active {
|
|
if clt.CWLastUpdate.Before(m.Msg.Date) {
|
|
if m.CommanderID64 == clt.CWUserID64 {
|
|
clt.CWRole = `commander`
|
|
} else if m.BartenderID64 == clt.CWUserID64 {
|
|
clt.CWRole = `bartender`
|
|
} else if m.SquireID64 == clt.CWUserID64 {
|
|
clt.CWRole = `squire`
|
|
} else if m.TreasurerID64 == clt.CWUserID64 {
|
|
clt.CWRole = `treasurer`
|
|
} else {
|
|
clt.CWRole = `none`
|
|
}
|
|
clt.CWLastUpdate = m.Msg.Date
|
|
}
|
|
}
|
|
clt.Mux.Unlock()
|
|
}
|
|
}
|
|
|
|
func clientGetCWUserID64(tgUserID64 int64) (int64, error) {
|
|
if clt, ok := getLockedClient(tgUserID64, false); ok {
|
|
i := clt.CWUserID64
|
|
clt.Mux.Unlock()
|
|
return i, nil
|
|
}
|
|
return 0, errors.New("Unknown user_id.")
|
|
}
|
|
|
|
func clientSpreadQuestResultAmbush(cwm *ChatWarsMessageQuestResultAmbush) error {
|
|
/*
|
|
muxClients.RLock()
|
|
var ret string
|
|
for id, c := range clients {
|
|
if c.Active {
|
|
ret = fmt.Sprintf("%s%s | UserID : %d | TelegramID : %d (online)\n", ret, c.Login, c.CWUserID64, id)
|
|
} else {
|
|
ret = fmt.Sprintf("%s%s | UserID : %d | TelegramID : %d (offline)\n", ret, c.Login, c.CWUserID64, id)
|
|
}
|
|
}
|
|
muxClients.RUnlock()
|
|
*/
|
|
log.Printf("clientSpreadQuestResultAmbush : spreading.")
|
|
return nil
|
|
}
|