package main import ( "regexp" "sync" "time" "github.com/streadway/amqp" tb "gopkg.in/tucnak/telebot.v2" ) const maxUnixTimestamp int64 = 2147483647 const chtwrsbotID64 int64 = 408101137 const angrybirbsbotID64 int64 = 833409972 const timeFmt string = "2006-01-02T15:04:05+07:00" type Config struct { Telegram struct { URL string `json:"url"` Token string `json:"token"` } `json:"telegram"` SQL struct { Driver string `json:"driver"` Type string `json:"type"` Address string `json:"address"` Username string `json:"username"` Password string `json:"password"` Database string `json:"database"` } `json:"sql"` Rabbit struct { User string `json:"user"` Password string `json:"password"` Host string `json:"host"` Path string `json:"path"` } `json:"rabbit"` Bot struct { Admin int64 `json:"admin_id"` Guildname string `json:"guild_name"` Guild string `json:"guild"` Mainchat int64 `json:"main_chat_id"` Depositchat int64 `json:"deposit_chat_id"` Reportchat int64 `json:"report_chat_id"` AngryBirbs int64 `json:"angrybirbs_id"` VaultLimit []struct { Item string `json:"item"` Min int64 `json:"min_qty"` Max int64 `json:"max_qty"` } `json:"vault_limit"` Shops []struct { Username string `json:"username"` Link string `json:"link"` } `json:"shops"` } `json:"bot"` } type DataBackup struct { Messages []ChatWarsMessage `json:"messages"` } type ObjType struct { ID64 int64 IntlId string `json:"intl_id"` Name string `json:"name"` } type ObjSubType struct { ID64 int64 IntlId string `json:"intl_id"` Name string `json:"name"` ObjType string `json:"obj_type"` ObjTypeID64 int64 } type ObjClassif struct { ID64 int64 IntlId string `json:"intl_id"` Name string `json:"name"` ObjType string `json:"obj_type"` ObjTypeID64 int64 } type ObjClass struct { ID64 int64 IntlId string `json:"intl_id"` Name string `json:"name"` ObjClassif string `json:"obj_classif"` ObjClassifID64 int64 } type MQClient struct { User string `json:"user"` Password string `json:"passwd"` Host string `json:"host"` Path string `json:"path"` SSL bool `json:"ssl"` Connection *amqp.Connection `json:"-"` Channel *amqp.Channel `json:"-"` Queue amqp.Queue `json:"-"` } type ChirpConfig struct { InterceptPillage bool `json:"intercept_pillage"` AutoDeposit bool `json:"auto_deposit"` AutoDepositItems []string `json:"auto_deposit_items"` AutoDepositTypes []string `json:"auto_deposit_types"` Wartime string `json:"wartime"` } type ChirpClient struct { HeartBeat time.Time `json:"heart_beat"` Login string `json:"login"` Nickname string `json:"nickname"` Build string `json:"build"` Active bool `json:"active"` TGUserID64 int64 `json:"tg_user_id"` MQ MQClient `json:"mq"` CWUserID64 int64 `json:"user_id"` CWGuildID64 int64 `json:"guild_id"` CWRole string `json:"role"` CWState string `json:"state"` CWClass string `json:"class"` CWClass2 string `json:"class2"` CWBusyUntil time.Time `json:"busy_until"` CWLastUpdate time.Time `json:"last_update"` CWIdle bool `json:"game_idle"` BotIdle bool `json:"bot_idle"` Mux sync.Mutex `json:"-"` Config *ChirpConfig `json:"config"` } type MQKeepAlive struct { TGUserID64 int64 `json:"tg_user_id"` Nickname string `json:"nick"` Queue string `json:"queue"` Date time.Time `json:"date"` Build string `json:"build"` } type TGCommand struct { Type int64 `json:"type"` FromChatID64 int64 `json:"from_chat_id"` FromUserID64 int64 `json:"from_user_id"` FromMsgID64 int64 `json:"from_msg_id"` ToChatID64 int64 `json:"to_chat_id"` ToUserID64 int64 `json:"to_user_id"` Text string `json:"text"` Document tb.Document `json:"document"` ParseMode int64 `json:"parse_mode"` Delay time.Duration `json:"delay"` CallbackName string `json:"callback_name"` CallbackData []byte `json:"callback_data"` } type ChatWarsCastle struct { ObjID64 int64 `json:"obj_id"` Logo string `json:"logo"` Name string `json:"name"` } type ChatWarsGuild struct { ObjID64 int64 `json:"obj_id"` Tag string `json:"tag"` Name string `json:"name"` } type ChatWarsUser struct { ObjID64 int64 `json:"obj_id"` Name string `json:"name"` } type ChatWarsClass struct { ClassifID64 int64 Classif string `json:"classif"` ClassID64 int64 Class string `json:"class"` } type ChatWarsItem struct { ObjID64 int64 ItemTypeID int64 ItemType string `json:"item_type"` Code string `json:"code"` Names []string `json:"names"` Weight int64 `json:"weight"` Exchange string `json:"exchange"` Auction bool `json:"auction"` Craftable bool `json:"craftable"` Craft *ChatWarsItemCraft `json:"craft"` Classes []ChatWarsClass `json:"-"` } type ChatWarsItemCraft struct { Command string `json:"cmd"` Mana int64 `json:"mana"` Items []ChatWarsItems `json:"items"` } type ChatWarsItems struct { ItemID64 int64 `json:"item_id"` Code string `json:"code"` Name string `json:"name"` Quantity int64 `json:"quantity"` Quality string `json:"quality"` } type ChatWarsCallback struct { Name string `json:"name"` Data []byte `json:"data"` } type ChatWarsMessage struct { ObjID64 int64 `json:"obj_id"` TGUserID64 int64 `json:"tg_user_id"` TGSenderUserID64 int64 `json:"tg_sender_user_id"` Date time.Time `json:"date"` ID64 int64 `json:"id"` ChatID64 int64 `json:"chat_id"` Text string `json:"text"` IsForwarded bool `json:"is_forwarded"` Callbacks []ChatWarsCallback `json:"callbacks"` } type ChatWarsExchangeDeal struct { ItemID64 int64 `json:"item_id"` Quantity int64 `json:"quantity"` Price int64 `json:"price"` Status string `json:"status"` Link string `json:"link"` } type ChatWarsMessageExchangeAck struct { Msg *ChatWarsMessage `json:"msg"` ActiveDeals int64 `json:"active_deals"` MaxDeals int64 `json:"max_deals"` DealList []ChatWarsExchangeDeal `json:"deals"` } type ChatWarsMessageGStock struct { Msg *ChatWarsMessage `json:"msg"` OwnerID64 int64 `json:"owner_id"` Stock []ChatWarsItems `json:"stock"` } type ChatWarsMessageWithdrawRcv struct { Msg *ChatWarsMessage `json:"msg"` ItemList []ChatWarsItems `json:"item_list"` } type ChatWarsMessageGDepositReq struct { Msg *ChatWarsMessage `json:"msg"` ItemID64 int64 `json:"item_id"` Quantity int64 `json:"quantity"` } type ChatWarsMessageGDepositAck struct { Msg *ChatWarsMessage `json:"msg"` ItemID64 int64 `json:"item_id"` Quantity int64 `json:"quantity"` } type ChatWarsMessageReportAck struct { ObjID64 int64 `json:"obj_id"` } type ChatWarsMessageStockAck struct { Msg *ChatWarsMessage `json:"msg"` Used int64 `json:"used"` Available int64 `json:"available"` Stock []ChatWarsItems `json:"stock"` } type ChatWarsMessageStockAnyAck struct { Msg *ChatWarsMessage `json:"msg"` Stock []ChatWarsItems `json:"stock"` } type ChatWarsMessageOrderbookAck struct { Msg *ChatWarsMessage `json:"msg"` Name string `json:"name"` Code string `json:"code"` Qty1 int64 `json:"qty1"` Price1 int64 `json:"price1"` Qty2 int64 `json:"qty2"` Price2 int64 `json:"price2"` Qty3 int64 `json:"qty3"` Price3 int64 `json:"price3"` Qty int64 `json:"qty"` Gold int64 `json:"gold"` } type ChatWarsMessageMeAck struct { Msg *ChatWarsMessage `json:"msg"` CWUserID64 int64 `json:"user_id"` CWGuildID64 int64 `json:"guild_id"` State string `json:"state"` Class string `json:"class"` Level int64 `json:"level"` ExpNow int64 `json:"exp_now"` ExpLvl int64 `json:"exp_lvl"` ManaNow int64 `json:"mana_now"` ManaMax int64 `json:"mana_max"` } type ChatWarsMessageGRolesAck struct { Msg *ChatWarsMessage `json:"msg"` BartenderID64 int64 `json:"bartender"` CommanderID64 int64 `json:"commander"` SquireID64 int64 `json:"squire"` TreasurerID64 int64 `json:"treasurer"` } type ChatWarsMessageGoQuestAck struct { Msg *ChatWarsMessage `json:"msg"` QuestTypeID64 int64 `json:"quest"` Duration time.Duration `json:"duration"` } type ChatWarsMessageQuestResult struct { Msg *ChatWarsMessage `json:"msg"` Gold int64 `json:"gold"` Exp int64 `json:"exp"` Loot []ChatWarsItems `json:"loot"` RegenStamina bool `json:"regen_stamina"` LostTorch bool `json:"lost_torch"` } type ChatWarsMessageQuestResultAmbush struct { Msg *ChatWarsMessage `json:"msg"` Loot []ChatWarsItems `json:"loot"` Level int64 `json:"level"` Armored bool `json:"armored"` Enraged bool `json:"enraged"` SpearResists bool `json:"spear resists"` Toughness bool `json:"toughness"` PoisonBottles bool `json:"poison_bottles"` } type ChatWarsMessageDuelFight struct { ObjID64 int64 `json:"obj_id"` WinCastle string `json:"win_castle"` WinGuild string `json:"win_guild"` WinUser string `json:"win_user"` WinLife int64 `json:"win_life"` LossCastle string `json:"loss_castle"` LossGuild string `json:"loss_guild"` LossUser string `json:"loss_user"` LossLife int64 `json:"loss_life"` Exp int64 `json:"exp"` Weapon string `json:"weapon"` } type ChatWarsMessageAuctionAnnounce struct { ObjID64 int64 `json:"obj_id"` LotID int32 `json:"lot_id"` ItemID64 int64 `json:"item_id"` Cond string `json:"cond"` Mod string `json:"mod"` Quality string `json:"quality"` SellerUserID64 int64 `json:"seller_id"` SellerGuildID64 int64 `json:"seller_guild_id"` SellerCastleID64 int64 `json:"seller_castle_id"` BuyerUserID64 int64 `json:"buyer_id"` BuyerGuildID64 int64 `json:"buyer_guild_id"` BuyerCastleID64 int64 `json:"buyer_castle_id"` Price int32 `json:"price"` Status string `json:"status"` End time.Time `json:"end"` } type ChatWarsMessagePillageInc struct { ObjID64 int64 `json:"obj_id"` Attacker string `json:"attacker"` Guild string `json:"guild"` Castle string `json:"castle"` } type ChatWarsMessageUnionWar struct { } type ChatWarsMessageTimeAck struct { ObjID64 int64 `json:"obj_id"` RealTime time.Time `json:"real_time"` TimeOfDay string `json:"time_of_day"` Hour int64 `json:"hour"` Minute int64 `json:"minute"` Day int64 `json:"day"` Month int64 `json:"month"` Year int64 `json:"year"` Weather string `json:"weather"` WeatherNext string `json:"weather_next"` } type ChatWarsMessageInspectAck struct { Name string `json:"name"` } type ChatWarsMessageJobGWithdrawAck struct { Msg *ChatWarsMessage `json:"msg"` Ref string `json:"ref"` } type ChatWarsTribute struct { Date time.Time `json:"time"` ItemID64 int64 `json:"item_id"` Quantity int64 `json:"quantity"` Exp int64 `json:"exp"` } type ChatWarsMessageTributesStatsAck struct { Msg *ChatWarsMessage `json:"msg"` Tributes []ChatWarsTribute `json:"tributes"` } type ChatWarsMessageShopMainReq struct { Msg *ChatWarsMessage `json:"msg"` Link string `json:"link"` } type ChatWarsGuildMember struct { Name string `json:"name"` Level int `json:"level"` Atk int `json:"atk"` Def int `json:"def"` Class1 string `json:"class1"` Class2 string `json:"class2"` Status string `json:"status"` } type ChatWarsMessageGListAck struct { Msg *ChatWarsMessage `json:"msg"` Members []ChatWarsGuildMember `json:"members"` } type ChatWarsMessageGDefListAck struct { Msg *ChatWarsMessage `json:"msg"` Members []ChatWarsGuildMember `json:"members"` } type ChatWarsMessageGAtkListAck struct { Msg *ChatWarsMessage `json:"msg"` Members []ChatWarsGuildMember `json:"members"` } type ChatWarsMessageShopMainAck struct { Msg *ChatWarsMessage `json:"msg"` Name string `json:"name"` Link string `json:"link"` ShopNumber int64 `json:"shop_number"` User string `json:"user"` Mana int64 `json:"mana"` ManaTotal int64 `json:"mana_total"` Class string `json:"class"` CastleID64 int64 `json:"castle"` Fees string `json:"fees"` Guru string `json:"guru"` Open bool `json:"open"` } type MessageParsingRule struct { ID int32 Priority int32 `json:"prio"` Description string `json:"descn"` Rule string `json:"rule"` MsgType string `json:"msg_type"` MsgTypeID64 int64 ChatID64 int64 `json:"chat_id"` SenderUserID64 int64 `json:"sender_id"` BotCommand bool `json:"bot_cmd"` re *regexp.Regexp } type BotMsg struct { To tb.Recipient Text string } type Job struct { ID64 int64 JobTypeID64 int64 Trigger int64 Timeout time.Time UserID64 int64 Payload []byte } type JobPayloadGetHammerTime struct { } type JobPayloadSetDef struct { } type JobPayloadMsgFwd struct { ChatID64 int64 `json:"chat_id"` } type JobPayloadMsgDel struct { ObjMsgID64 int64 `json:"obj_msg_id"` Delay time.Duration `json:"delay"` MsgTypeID64 int64 `json:"msg_type_id"` } type JobPayloadMsgRefresh struct { ObjID64 int64 `json:"obj_id"` } type JobPayloadPillage struct { ObjID64 int64 `json:"obj_id"` Date time.Time `json:"date"` } type JobPayloadTribute struct { } type JobPayloadStatus struct { } type JobPayloadGStock struct { Status int64 `json:"status"` MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` VaultJobID64 int64 `json:"vault_job_id"` } type JobPayloadGWithdrawItem struct { Code string `json:"code"` Name string `json:"name"` Available int64 `json:"available"` Required int64 `json:"required"` Inspect bool `json:"inspect"` } type JobPayloadGWithdraw struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` UserID64 int64 `json:"user_id"` VaultJobID64 int64 `json:"vault_job_id"` Items []JobPayloadGWithdrawItem `json:"items"` Status int64 `json:"status"` CleanupMsg []ChatWarsMessage `json:"cleanup_msg"` Validated bool `json:"validated"` Inspecting string `json:"inspecting"` } type JobPayloadGDeposit struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` ResObjID64 []int64 `json:"res_obj_id"` Status int64 `json:"status"` } type JobPayloadGDepositForward struct { ItemID64 int64 `json:"item_id"` Quantity int64 `json:"quantity"` } type JobPayloadSaveRes struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` ResObjID64 int64 `json:"res_obj_id"` BuyRes bool `json:"buy_res"` } type JobPayloadRescanMsg struct { Query string `json:"query"` MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` } type JobPayloadSetDone struct { JobID64 int64 `json:"job_id"` MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` Text string `json:"test"` } type JobPayloadMsgClient struct { Text string `json:"msg"` MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` } type JobPayloadBackupExport struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` } type JobPayloadBackupImport struct { URL string `json:"url"` MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` } type JobPayloadVaultUserStatus struct { UserListID64 []int64 `json:"user_list"` ItemTypeListID64 []int64 `json:"item_type_list"` DepositChatID64 int64 `json:"deposit_chat_id"` UserID64 int64 `json:"user_id"` } type JobPayloadVaultItemStatus struct { ItemListID64 []int64 `json:"item_type_list"` DepositChatID64 int64 `json:"deposit_chat_id"` UserID64 int64 `json:"user_id"` } type JobPayloadCraftItem struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` ObjItemID64 int64 `json:"item_id"` Quantity int64 `json:"quantity"` Status int64 `json:"status"` VaultJobID64 int64 `json:"vault_job_id"` } type JobPayloadCraftAll struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` Status int64 `json:"status"` VaultJobID64 int64 `json:"vault_job_id"` } type JobPayloadAlchAll struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` Status int64 `json:"status"` ManaNow int64 `json:"mana_now"` ManaMax int64 `json:"mana_max"` } type JobPayloadBrewItem struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` ObjItemID64 int64 `json:"item_id"` Status int64 `json:"status"` ManaNow int64 `json:"mana_now"` ManaMax int64 `json:"mana_max"` VaultJobID64 int64 `json:"vault_job_id"` } type JobPayloadCheckVaultLimit struct { Status int64 `json:"status"` VaultPreJobID64 int64 `json:"vault_pre_job_id"` VaultPostJobID64 int64 `json:"vault_post_job_id` } type JobPayloadVaultVal struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` Status int64 `json:"status"` VaultJobID64 int64 `json:"vault_job_id` } type JobPayloadVaultValOth struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` Status int64 `json:"status"` VaultJobID64 int64 `json:"vault_job_id` Val []JobPayloadVaultValTab `json:"val_tab"` } type JobPayloadVaultValTab struct { ItemID64 int64 `json:"item_id"` Quality string `json:"quality"` Quantity int64 `json:"quantity"` Volume int64 `json:"volume"` Price float64 `json:"price"` Weight int64 `json:"weight"` } type JobPayloadGetVault struct { Status int64 `json:"status"` JobCallbackID64 int64 `json:"job_callback_id"` ItemTypeList []int64 `json:"item_type"` Vault []ChatWarsItems `json:"vault"` CleanupMsg []ChatWarsMessage `json:"cleanup_msg"` } type JobPayloadShops struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` Status int64 `json:"status"` Msgs []ChatWarsMessage `json:"msgs"` } type JobPayloadShopsSlave struct { Status int64 `json:"status"` JobCallbackID64 int64 `json:"job_callback_id"` Shops []string `json:"shops"` Slaves int64 `json:"slaves"` } type JobPayloadGetStash struct { MsgID64 int64 `json:"msg_id"` ChatID64 int64 `json:"chat_id"` UserID64 int64 `json:"user_id"` ClientID64 []int64 `json:"clients_id"` ClientCount int64 `json:"client_count"` Stash map[int64]int64 `json:"stock"` CleanupMsg []ChatWarsMessage `json:"cleanup_msg"` } const ( userID64ChtWrsBot = 408101137 commandForwardMsg = 1 commandReplyMsg = 2 commandSendMsg = 3 commandDeleteMsg = 4 commandRefreshMsg = 5 commandSendDocument = 6 commandCallback = 7 cmdParseModePlain = 1 cmdParseModeMarkDown = 2 cmdParseModeHTML = 3 castleDeer = 1 castleDragon = 2 castleHighnest = 3 castleMoon = 4 castlePotato = 5 castleShark = 6 castleWolf = 7 objJobStatusCallBack = -1 objJobStatusNew = 0 objJobStatusPillageGo = 1 objJonStatusPending = 10 objJobStatusDone = 20 objJobPriority = 1 objJobPriorityRescanMsg = 2 objJobPriorityRescanAllMsg = 3 objJobPriorityBackup = 4 MQGetMsgWorkers = 12 MQCWMsgQueueSize = 100 SQLCWMsgWorkers = 6 SQLIdentifyMsgWorkers = 6 SQLMsgIdentifyQueueSize = 100 SQLMsgRescanJobSize = 25 JobWorkers = 12 JobQueueSize = 100 TGCmdWorkers = 3 TGCmdQueueSize = 100 MQTGCmdWorkers = 3 MQTGCmdQueueSize = 100 SQLJobSliceSize = 25 KeepAliveHeartBeatSeconds = 5 ) var ( chatWarsMonth = map[string]int{ "Wintar": 1, "Hornung": 2, "Lenzin": 3, "Ōstar": 4, "Winni": 5, "Brāh": 6, "Hewi": 7, "Aran": 8, "Witu": 9, "Wīndume": 10, "Herbist": 11, "Hailag": 12} chatWarsDaysSpecial = map[int]map[int]int{ 1060: { 2: 29, 4: 29, }, 1064: {2: 29}, 1068: {2: 29}, } chatWarsDays = map[int]int{ 1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31} )