chirpnest/client.go
2020-01-08 17:17:36 +08:00

251 lines
5.8 KiB
Go

package main
import (
"errors"
"fmt"
"log"
"strings"
"time"
)
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 from.UTC().Add(duration).After(time.Now().UTC()) {
if clt, ok := getLockedClient(userID64, false); ok {
clt.CWIdle = false
clt.CWBusyUntil = from.UTC().Add(duration)
clt.Mux.Unlock()
return nil
} else {
return errors.New("Client not found.")
}
}
return nil
}
func setClientIdle(userID64 int64, from time.Time) error {
fmt.Printf("setClientIdle : starting for %d.\n", userID64)
if clt, ok := getLockedClient(userID64, false); ok {
if from.UTC().After(clt.CWLastUpdate.UTC()) {
fmt.Printf("setClientIdle : updated.\n")
clt.CWBusyUntil = from
clt.CWIdle = true
clt.CWLastUpdate = from
} else {
fmt.Printf("setClientIdle : not updated.\n")
}
clt.Mux.Unlock()
return nil
} else {
return errors.New("Client not found.")
}
}
func getLockedIdleClient() (*ChirpClient, error) {
fmt.Printf("getLockedIdleClient : starting.\n")
muxClients.RLock()
ids := make([]int64, 0)
for _, c := range clients {
if c.CWIdle {
ids = append(ids, c.TGUserID64)
fmt.Printf("getLockedIdleClient : appending %s (%d).\n", c.Login, c.TGUserID64)
}
}
muxClients.RUnlock()
if len(ids) == 0 {
return nil, errors.New("No idle client.")
}
RndMux.Lock()
id := RndSrc.Intn(len(ids))
fmt.Printf("getLockedIdleClient : pulled (%d).\n", id)
RndMux.Unlock()
clients[ids[id]].Mux.Lock()
return clients[ids[id]], 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 := new(ChirpClient)
c.TGUserID64 = id
c.Active = false
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 clientDelCWMsg(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) {
c := TGCommand{
Type: commandRefreshMsg,
FromUserID64: userID64,
FromChatID64: chatID64,
FromMsgID64: msgID64,
Delay: 0,
}
MQTGCmdQueue <- c
}
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 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
}