2019-05-25 09:25:11 +02:00
package main
2019-05-25 09:37:45 +02:00
import (
2020-01-12 10:17:14 +01:00
"bytes"
"compress/zlib"
2020-01-02 11:12:14 +01:00
"encoding/json"
2019-06-10 07:48:36 +02:00
"errors"
2019-06-02 09:00:16 +02:00
"fmt"
2019-06-14 08:35:35 +02:00
"log"
2019-06-03 10:31:54 +02:00
"regexp"
2019-05-25 09:37:45 +02:00
"strconv"
2019-05-31 05:15:19 +02:00
"sync"
2019-05-25 09:37:45 +02:00
"time"
)
2019-05-25 09:25:11 +02:00
var (
2019-06-09 14:17:05 +02:00
cacheObjCastle * sync . Map
cacheObjGuild * sync . Map
cacheObjUser * sync . Map
2019-06-09 14:17:59 +02:00
cacheObjMsg * sync . Map
2019-07-22 09:40:52 +02:00
2020-01-02 11:04:48 +01:00
cacheObjType map [ string ] int64
cacheObjSubType map [ string ] int64
2019-08-21 05:46:42 +02:00
cacheObjItem map [ string ] ChatWarsItem
muxObjItem sync . Mutex
2020-01-12 10:11:34 +01:00
cacheObjItemId map [ int64 ] ChatWarsItem
2019-08-21 05:46:42 +02:00
muxObjItemId sync . Mutex
2020-01-12 10:11:34 +01:00
cacheObjJob map [ int64 ] Job
muxObjJob sync . Mutex
2019-05-25 09:25:11 +02:00
)
2020-01-02 11:04:48 +01:00
func initCache ( ) {
2020-01-02 11:23:29 +01:00
var err error
2020-01-02 11:04:48 +01:00
2020-01-02 16:53:54 +01:00
log . Println ( "Caching obj_type .." )
2020-01-02 16:11:03 +01:00
err = loadObjType ( )
logOnError ( err , "initCache : caching obj_type" )
2020-01-02 16:53:54 +01:00
log . Println ( "Caching obj_sub_type .." )
2020-01-02 16:11:03 +01:00
err = loadObjSubType ( )
logOnError ( err , "initCache : caching obj_sub_type" )
2020-01-02 16:53:54 +01:00
log . Println ( "Filling message parsing rules..." )
2020-01-02 11:04:48 +01:00
resetMsgParsingRules ( )
2020-01-02 11:23:29 +01:00
msgParsingRules , err = loadMsgParsingRules ( )
2020-01-02 11:04:48 +01:00
logOnError ( err , "initCache : message parsing rules" )
2020-01-02 16:53:54 +01:00
log . Println ( "Caching guilds .." )
2020-01-02 11:04:48 +01:00
err = loadObjGuild ( )
logOnError ( err , "initCache : caching guilds" )
2020-01-02 16:53:54 +01:00
log . Println ( "Caching users .." )
2020-01-02 11:04:48 +01:00
err = loadObjUser ( )
logOnError ( err , "initCache : caching user" )
2020-01-02 16:53:54 +01:00
log . Println ( "Caching items .." )
2020-01-02 11:04:48 +01:00
err = loadObjItem ( )
logOnError ( err , "initCache : caching items" )
2020-01-02 16:53:54 +01:00
log . Println ( "Caching messages .." )
2020-01-02 11:04:48 +01:00
err = loadObjMsg ( )
logOnError ( err , "initCache : caching msgs" )
2020-01-02 11:35:41 +01:00
2020-01-12 10:11:34 +01:00
log . Println ( "Caching jobs .." )
err = loadObjJob ( )
logOnError ( err , "initCache : caching jobs" )
2020-01-02 11:04:48 +01:00
}
func loadObjType ( ) error {
var obj [ ] ObjType
b , err := Asset ( "data/code_obj_type.json" )
logOnError ( err , "loadObjType : load data/code_obj_type.json" )
if err != nil {
return err
}
err = json . Unmarshal ( b , & obj )
logOnError ( err , "loadObjType : Unmarshal" )
if err != nil {
return err
}
cacheObjType = make ( map [ string ] int64 )
for _ , v := range obj {
2020-01-02 11:12:14 +01:00
id , err := codeObjTypeId ( v . IntlId )
if err == nil {
2020-01-02 11:04:48 +01:00
cacheObjType [ v . IntlId ] = id
} else {
err = insertObjType ( v . IntlId , v . Name )
logOnError ( err , "loadObjType : insertObjType" )
if err == nil {
2020-01-02 11:12:14 +01:00
id , err = codeObjTypeId ( v . IntlId )
if err == nil {
2020-01-02 11:04:48 +01:00
cacheObjType [ v . IntlId ] = id
} else {
2020-01-02 11:12:14 +01:00
logOnError ( err , "loadObjType : codeObjTypeId" )
2020-01-02 11:04:48 +01:00
}
}
}
}
return nil
}
func loadObjSubType ( ) error {
var obj [ ] ObjSubType
b , err := Asset ( "data/code_obj_sub_type.json" )
logOnError ( err , "loadObjSubType : load data/code_obj_sub_type.json" )
if err != nil {
return err
}
err = json . Unmarshal ( b , & obj )
logOnError ( err , "loadObjSubType : Unmarshal" )
if err != nil {
return err
}
cacheObjSubType = make ( map [ string ] int64 )
for _ , v := range obj {
2020-01-02 11:12:14 +01:00
id , err := codeObjSubTypeId ( v . IntlId )
if err == nil {
2020-01-02 11:04:48 +01:00
cacheObjSubType [ v . IntlId ] = id
} else {
err = insertObjSubType ( v . IntlId , v . Name , v . ObjType )
logOnError ( err , "loadObjSubType : insertObjSubType" )
if err == nil {
2020-01-02 11:12:14 +01:00
id , err = codeObjSubTypeId ( v . IntlId )
if err == nil {
2020-01-02 11:04:48 +01:00
cacheObjSubType [ v . IntlId ] = id
} else {
2020-01-02 11:12:14 +01:00
logOnError ( err , "loadObjSubType : codeObjSubTypeId" )
2020-01-02 11:04:48 +01:00
}
}
}
}
return nil
}
2019-12-29 12:45:26 +01:00
func codeObjTypeId ( intlId string ) ( int64 , error ) {
var objTypeId int64
2019-12-29 12:50:11 +01:00
stmt , err := db . Prepare ( ` SELECT c.id FROM code_obj_type c WHERE c.intl_id = ? ` )
2019-12-29 12:45:26 +01:00
if err != nil {
return 0 , err
}
defer stmt . Close ( )
err = stmt . QueryRow ( intlId ) . Scan ( & objTypeId )
if err != nil {
return 0 , err
}
return objTypeId , nil
}
func codeObjSubTypeId ( intlId string ) ( int64 , error ) {
var objSubTypeId int64
2019-12-29 12:50:11 +01:00
stmt , err := db . Prepare ( ` SELECT c.id FROM code_obj_sub_type c WHERE c.intl_id = ? ` )
2019-12-29 12:45:26 +01:00
if err != nil {
return 0 , err
}
defer stmt . Close ( )
err = stmt . QueryRow ( intlId ) . Scan ( & objSubTypeId )
if err != nil {
return 0 , err
}
return objSubTypeId , nil
}
2019-05-25 09:25:11 +02:00
func getObjTypeId ( objId int64 ) ( int64 , error ) {
var objTypeId int64
stmt , err := db . Prepare ( ` SELECT o.obj_type_id FROM obj o WHERE o.id = ? ` )
if err != nil {
return 0 , err
}
defer stmt . Close ( )
err = stmt . QueryRow ( objId ) . Scan ( & objTypeId )
if err != nil {
return 0 , err
}
return objTypeId , nil
}
func getObjSubTypeId ( objId int64 ) ( int64 , error ) {
var objSubTypeId int64
stmt , err := db . Prepare ( ` SELECT o.obj_sub_type_id FROM obj o WHERE o.id = ? ` )
if err != nil {
return 0 , err
}
defer stmt . Close ( )
err = stmt . QueryRow ( objId ) . Scan ( & objSubTypeId )
if err != nil {
return 0 , err
}
return objSubTypeId , nil
}
func setObjSubTypeId ( objId int64 , objSubTypeID64 int64 ) error {
stmt , err := db . Prepare ( ` UPDATE obj o SET o.obj_sub_type_id = ? WHERE o.id = ?; ` )
logOnError ( err , "setObjSubTypeId : prepare update" )
if err != nil {
return err
}
defer stmt . Close ( )
_ , err = stmt . Exec ( objSubTypeID64 , objId )
2019-12-20 04:10:26 +01:00
logOnError ( err , "setObjSubTypeId : exec update (" + strconv . FormatInt ( objId , 10 ) + ", " + strconv . FormatInt ( objSubTypeID64 , 10 ) + ")" )
2019-05-25 09:25:11 +02:00
return err
}
2019-06-14 12:13:10 +02:00
func objAddName ( objID64 int64 , name string ) error {
stmt , err := db . Prepare ( ` INSERT INTO obj_name ( obj_id , name , priority )
SELECT ? obj_id , ? name , ( SELECT MAX ( priority ) + 1 FROM obj_name WHERE obj_id = ? ) priority FROM DUAL ; ` )
2019-06-25 11:39:11 +02:00
_ , err = stmt . Exec ( objID64 , name , objID64 )
2019-06-14 12:13:10 +02:00
return err
}
2019-07-31 10:57:45 +02:00
func addObjMsg ( msgID64 int64 , msgChatID64 int64 , msgTGUserID64 int64 , msgTGSenderUserID64 int64 , msgDate time . Time , msgText string ) ( int64 , error ) {
2019-05-25 09:25:11 +02:00
tx , err := db . Begin ( )
logOnError ( err , "addObjMsg : start transaction" )
if err != nil {
return 0 , err
}
res , err := tx . Exec ( ` INSERT INTO obj ( obj_type_id , obj_sub_type_id )
2020-01-02 16:38:53 +01:00
VALUES ( ` + strconv.FormatInt(cacheObjType[ ` msg ` ], 10) + ` , ` + strconv.FormatInt(cacheObjSubType[ ` msg ` ], 10) + ` ) ; ` )
2019-05-25 09:25:11 +02:00
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjMsg : rollback insert obj" )
return 0 , err
}
objId , err := res . LastInsertId ( )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjMsg : rollback get lastInsertId" )
return 0 , err
}
stmt , err := tx . Prepare ( ` INSERT INTO obj_msg ( obj_id , msg_id , chat_id , user_id , sender_user_id , date , text )
VALUES ( ? , ? , ? , ? , ? , ? , ? ) ; ` )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjMsg : rollback prepare insert obj_msg" )
return 0 , err
}
defer stmt . Close ( )
2019-07-31 10:57:45 +02:00
_ , err = stmt . Exec ( objId , msgID64 , msgChatID64 , msgTGUserID64 , msgTGSenderUserID64 , msgDate , msgText )
2019-05-25 09:25:11 +02:00
if err != nil {
err2 := tx . Rollback ( )
2019-05-31 04:02:21 +02:00
logOnError ( err2 , "addObjMsg : rollback exec insert obj_msg" )
2019-05-25 09:25:11 +02:00
return 0 , err
}
err = tx . Commit ( )
if err != nil {
return 0 , err
}
2019-06-09 16:27:20 +02:00
m := new ( ChatWarsMessage )
m . ObjID64 = objId
2019-07-31 10:57:45 +02:00
m . TGUserID64 = msgTGUserID64
2019-07-31 10:59:11 +02:00
m . TGSenderUserID64 = msgTGSenderUserID64
2019-06-09 16:27:20 +02:00
m . Date = msgDate
m . ID64 = msgID64
m . ChatID64 = msgChatID64
m . Text = msgText
cacheObjMsg . Store ( objId , * m )
2019-05-25 09:25:11 +02:00
return objId , nil
}
2019-06-09 14:17:05 +02:00
func getObjMsg ( objId int64 ) ( * ChatWarsMessage , error ) {
if v , ok := cacheObjMsg . Load ( objId ) ; ok {
m := v . ( ChatWarsMessage )
2019-06-09 14:19:16 +02:00
return & m , nil
2019-06-09 14:17:05 +02:00
}
2019-06-09 14:18:54 +02:00
var m * ChatWarsMessage
2019-06-09 14:17:05 +02:00
stmt , err := db . Prepare ( ` SELECT om.msg_id, om.chat_id, om.user_id, om.sender_user_id, om.date, om.text FROM obj_msg om WHERE om.obj_id = ? ` )
if err != nil {
return m , err
}
defer stmt . Close ( )
m = new ( ChatWarsMessage )
2019-07-31 10:57:45 +02:00
err = stmt . QueryRow ( objId ) . Scan ( & m . ID64 , & m . ChatID64 , & m . TGUserID64 , & m . TGSenderUserID64 , & m . Date , & m . Text )
2019-06-09 14:17:05 +02:00
if err != nil {
return m , err
}
2019-10-11 03:32:52 +02:00
m . ObjID64 = objId
2019-06-09 14:17:05 +02:00
cacheObjMsg . Store ( objId , * m )
return m , nil
}
func loadObjMsg ( ) error {
cacheObjMsg = new ( sync . Map )
return nil
}
2019-06-10 06:03:47 +02:00
func delObj ( objId int64 ) error {
objSubTypeId , err := getObjSubTypeId ( objId )
if err != nil {
return err
}
2020-01-02 12:35:03 +01:00
if objSubTypeId != cacheObjSubType [ ` msg_auction_announce ` ] {
return errors . New ( "Can only delete cacheObjSubType[`msg_auction_announce`]." )
2019-06-10 06:03:47 +02:00
}
2019-06-10 14:31:59 +02:00
cacheObjMsg . Delete ( objId ) // better delete from cache before, worst case we reload after
2019-06-10 11:08:58 +02:00
stmt , err := db . Prepare ( ` DELETE FROM obj WHERE id = ? ` )
2019-06-10 06:03:47 +02:00
if err != nil {
return err
}
defer stmt . Close ( )
res , err := stmt . Exec ( objId )
if err != nil {
return err
}
count , err := res . RowsAffected ( )
if err != nil {
return err
}
2019-06-10 14:31:59 +02:00
if count > 1 {
return errors . New ( "More than one row impacted." )
} else if count == 0 {
return errors . New ( "No row impacted." )
}
2019-06-10 06:03:47 +02:00
return nil
}
2019-05-25 09:29:24 +02:00
func addObjCastle ( logo string , name string ) ( int64 , error ) {
2019-05-25 09:25:11 +02:00
tx , err := db . Begin ( )
logOnError ( err , "addObjCastle : start transaction" )
if err != nil {
return 0 , err
}
res , err := tx . Exec ( ` INSERT INTO obj ( obj_type_id , obj_sub_type_id )
2020-01-02 16:38:53 +01:00
VALUES ( ` + strconv.FormatInt(cacheObjType[ ` castle ` ], 10) + ` , ` + strconv.FormatInt(cacheObjSubType[ ` castle ` ], 10) + ` ) ; ` )
2019-05-25 09:25:11 +02:00
logOnError ( err , "addObjCastle : exec insert obj" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjCastle : rollback insert obj" )
return 0 , err
}
objId , err := res . LastInsertId ( )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjCastle : rollback get lastInsertId" )
return 0 , err
}
stmt , err := tx . Prepare ( ` INSERT INTO obj_castle ( obj_id , logo , name )
VALUES ( ? , ? , ? ) ; ` )
logOnError ( err , "addObjCastle : prepare insert obj_castle" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjCastle : rollback prepare insert obj_castle" )
return 0 , err
}
defer stmt . Close ( )
_ , err = stmt . Exec ( objId , logo , name )
logOnError ( err , "addObjCastle : exec insert obj_castle" )
if err != nil {
err2 := tx . Rollback ( )
2019-05-31 04:02:21 +02:00
logOnError ( err2 , "addObjCastle : rollback exec insert obj_castle" )
2019-05-25 09:25:11 +02:00
return 0 , err
}
err = tx . Commit ( )
logOnError ( err , "addObjCastle : commit" )
if err != nil {
return 0 , err
}
return objId , nil
}
2019-05-25 09:48:34 +02:00
func getObjCastleID ( s string ) int64 {
2019-06-11 04:14:19 +02:00
if v , ok := cacheObjCastle . Load ( s ) ; ok {
c := v . ( ChatWarsCastle )
return c . ObjID64
} else {
v , _ := cacheObjCastle . Load ( ` ⛔ ` )
c := v . ( ChatWarsCastle )
return c . ObjID64
}
2019-05-25 09:25:11 +02:00
}
func loadObjCastle ( ) error {
var (
id int64
logo string
name string
)
2019-05-31 05:27:44 +02:00
cacheObjCastle = new ( sync . Map )
2019-05-25 09:25:11 +02:00
2019-05-25 10:06:33 +02:00
castles , err := db . Query ( ` SELECT oc.obj_id, oc.logo, oc.name FROM obj_castle oc; ` )
2019-05-25 09:25:11 +02:00
if err != nil {
return err
}
defer castles . Close ( )
for castles . Next ( ) {
2019-05-25 09:37:45 +02:00
err = castles . Scan ( & id , & logo , & name )
2019-05-25 09:25:11 +02:00
if err != nil {
return err
}
c := new ( ChatWarsCastle )
c . ObjID64 = id
c . Logo = logo
c . Name = name
2019-05-31 05:15:19 +02:00
cacheObjCastle . Store ( logo , * c )
cacheObjCastle . Store ( name , * c )
2019-05-25 09:25:11 +02:00
}
return nil
}
2019-05-25 10:56:13 +02:00
func addObjGuild ( tag string , name string ) ( int64 , error ) {
tx , err := db . Begin ( )
logOnError ( err , "addObjGuild : start transaction" )
if err != nil {
return 0 , err
}
res , err := tx . Exec ( ` INSERT INTO obj ( obj_type_id , obj_sub_type_id )
2020-01-02 16:38:53 +01:00
VALUES ( ` + strconv.FormatInt(cacheObjType[ ` guild ` ], 10) + ` , ` + strconv.FormatInt(cacheObjSubType[ ` guild ` ], 10) + ` ) ; ` )
2019-05-25 10:56:13 +02:00
logOnError ( err , "addObjGuild : exec insert obj" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjGuild : rollback insert obj" )
return 0 , err
}
objId , err := res . LastInsertId ( )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjGuild : rollback get lastInsertId" )
return 0 , err
}
stmt , err := tx . Prepare ( ` INSERT INTO obj_guild ( obj_id , tag , name , chat_id , deposit_chat_id )
VALUES ( ? , ? , ? , NULL , NULL ) ; ` )
logOnError ( err , "addObjGuild : prepare insert obj_guild" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjGuild : rollback prepare insert obj_guild" )
return 0 , err
}
defer stmt . Close ( )
_ , err = stmt . Exec ( objId , tag , name )
logOnError ( err , "addObjGuild : exec insert obj_guild" )
if err != nil {
err2 := tx . Rollback ( )
2019-05-31 04:02:21 +02:00
logOnError ( err2 , "addObjGuild : rollback exec insert obj_guild" )
2019-05-25 10:56:13 +02:00
return 0 , err
}
err = tx . Commit ( )
logOnError ( err , "addObjGuild : commit" )
if err != nil {
return 0 , err
}
return objId , nil
}
func getObjGuildID ( s string ) int64 {
2019-05-31 05:26:47 +02:00
if v , ok := cacheObjGuild . Load ( s ) ; ok {
g := v . ( ChatWarsGuild )
2019-05-25 10:56:13 +02:00
return g . ObjID64
} else {
objID64 , err := addObjGuild ( s , ` ` )
logOnError ( err , "getObjGuildID" )
2019-05-31 05:26:47 +02:00
g := new ( ChatWarsGuild )
g . ObjID64 = objID64
g . Tag = s
g . Name = ` `
cacheObjGuild . Store ( s , * g )
2019-05-31 05:15:19 +02:00
return objID64
2019-05-25 10:56:13 +02:00
}
}
func loadObjGuild ( ) error {
var (
id int64
tag string
name string
)
2019-05-31 05:27:44 +02:00
cacheObjGuild = new ( sync . Map )
2019-05-25 10:56:13 +02:00
guilds , err := db . Query ( ` SELECT og.obj_id, og.tag, og.name FROM obj_guild og; ` )
if err != nil {
return err
}
defer guilds . Close ( )
for guilds . Next ( ) {
err = guilds . Scan ( & id , & tag , & name )
if err != nil {
return err
}
g := new ( ChatWarsGuild )
g . ObjID64 = id
g . Tag = tag
g . Name = name
2019-05-31 05:15:19 +02:00
cacheObjGuild . Store ( tag , * g )
2019-05-25 10:56:13 +02:00
}
return nil
}
func addObjUser ( name string ) ( int64 , error ) {
tx , err := db . Begin ( )
logOnError ( err , "addObjUser : start transaction" )
if err != nil {
return 0 , err
}
res , err := tx . Exec ( ` INSERT INTO obj ( obj_type_id , obj_sub_type_id )
2020-01-02 16:38:53 +01:00
VALUES ( ` + strconv.FormatInt(cacheObjType[ ` user ` ], 10) + ` , ` + strconv.FormatInt(cacheObjSubType[ ` user ` ], 10) + ` ) ; ` )
2019-05-25 10:56:13 +02:00
logOnError ( err , "addObjUser : exec insert obj" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjUser : rollback insert obj" )
return 0 , err
}
objId , err := res . LastInsertId ( )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjUser : rollback get lastInsertId" )
return 0 , err
}
stmt , err := tx . Prepare ( ` INSERT INTO obj_user ( obj_id , name )
VALUES ( ? , ? ) ; ` )
logOnError ( err , "addObjUser : prepare insert obj_user" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjUser : rollback prepare insert obj_user" )
return 0 , err
}
defer stmt . Close ( )
_ , err = stmt . Exec ( objId , name )
logOnError ( err , "addObjUser : exec insert obj_user" )
if err != nil {
err2 := tx . Rollback ( )
2019-05-31 04:02:21 +02:00
logOnError ( err2 , "addObjUser : rollback exec insert obj_user" )
2019-05-25 10:56:13 +02:00
return 0 , err
}
err = tx . Commit ( )
logOnError ( err , "addObjUser : commit" )
if err != nil {
return 0 , err
}
return objId , nil
}
func getObjUserID ( s string ) int64 {
2019-05-31 05:26:47 +02:00
if v , ok := cacheObjUser . Load ( s ) ; ok {
u := v . ( ChatWarsUser )
2019-05-31 05:28:16 +02:00
return u . ObjID64
2019-05-25 10:56:13 +02:00
} else {
2019-05-25 11:02:24 +02:00
objID64 , err := addObjUser ( s )
2019-05-25 10:56:13 +02:00
logOnError ( err , "getObjUserID" )
2019-05-31 05:26:47 +02:00
u := new ( ChatWarsUser )
u . ObjID64 = objID64
u . Name = s
cacheObjUser . Store ( s , * u )
2019-05-31 05:15:19 +02:00
return objID64
2019-05-25 10:56:13 +02:00
}
}
func loadObjUser ( ) error {
var (
id int64
name string
)
2019-05-31 05:27:44 +02:00
cacheObjUser = new ( sync . Map )
2019-05-25 10:56:13 +02:00
2019-05-25 10:59:14 +02:00
users , err := db . Query ( ` SELECT ou.obj_id, ou.name FROM obj_user ou; ` )
2019-05-25 10:56:13 +02:00
if err != nil {
return err
}
defer users . Close ( )
for users . Next ( ) {
2019-05-25 10:59:14 +02:00
err = users . Scan ( & id , & name )
2019-05-25 10:56:13 +02:00
if err != nil {
return err
}
2019-05-25 10:59:14 +02:00
u := new ( ChatWarsUser )
u . ObjID64 = id
u . Name = name
2019-05-31 05:15:19 +02:00
cacheObjUser . Store ( name , * u )
2019-05-25 10:56:13 +02:00
}
return nil
}
2019-05-30 07:49:11 +02:00
func getObjMsgDate ( objID64 int64 ) ( time . Time , error ) {
2019-06-09 14:17:59 +02:00
m , err := getObjMsg ( objID64 )
2019-05-30 07:49:11 +02:00
if err != nil {
2019-05-30 08:08:39 +02:00
return time . Now ( ) , err
} else {
return m . Date , nil
2019-05-30 07:49:11 +02:00
}
}
2019-05-31 04:02:21 +02:00
2019-05-31 04:05:58 +02:00
func addObjXP ( userID64 int64 , expNow int64 , expLvl int64 , level int64 , date time . Time ) ( int64 , error ) {
2019-05-31 04:02:21 +02:00
tx , err := db . Begin ( )
logOnError ( err , "addObjXP : start transaction" )
if err != nil {
return 0 , err
}
res , err := tx . Exec ( ` INSERT INTO obj ( obj_type_id , obj_sub_type_id )
2020-01-02 16:42:15 +01:00
VALUES ( ` + strconv.FormatInt(cacheObjType[ ` xp ` ], 10) + ` , ` + strconv.FormatInt(cacheObjSubType[ ` xp ` ], 10) + ` ) ; ` )
2019-05-31 04:02:21 +02:00
logOnError ( err , "addObjXP : exec insert obj" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjXP : rollback insert obj" )
return 0 , err
}
objId , err := res . LastInsertId ( )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjXP : rollback get lastInsertId" )
return 0 , err
}
stmt , err := tx . Prepare ( ` INSERT INTO obj_xp ( obj_id , user_id , val , target , level , date )
VALUES ( ? , ? , ? , ? , ? , ? ) ; ` )
logOnError ( err , "addObjXP : prepare insert obj_xp" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjXP : rollback prepare insert obj_xp" )
return 0 , err
}
defer stmt . Close ( )
2019-05-31 04:05:58 +02:00
_ , err = stmt . Exec ( objId , userID64 , expNow , expLvl , level , date )
2019-05-31 04:02:21 +02:00
logOnError ( err , "addObjXP : exec insert obj_xp" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjXP : rollback exec insert obj_xp" )
return 0 , err
}
err = tx . Commit ( )
logOnError ( err , "addObjXP : commit" )
if err != nil {
return 0 , err
}
return objId , nil
}
2019-06-02 08:48:16 +02:00
2020-01-02 16:38:53 +01:00
func addObjQuest ( userID64 int64 , questTypeID64 int64 , duration time . Duration , date time . Time ) ( int64 , error ) {
2019-07-09 06:56:41 +02:00
tx , err := db . Begin ( )
logOnError ( err , "addObjQuest : start transaction" )
if err != nil {
return 0 , err
}
res , err := tx . Exec ( ` INSERT INTO obj ( obj_type_id , obj_sub_type_id )
2020-01-02 16:38:53 +01:00
VALUES ( ` + strconv.FormatInt(cacheObjType[ ` quest ` ], 10) + ` , ` + strconv.FormatInt(questTypeID64, 10) + ` ) ; ` )
2019-07-09 06:56:41 +02:00
logOnError ( err , "addObjQuest : exec insert obj" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjQuest : rollback insert obj" )
return 0 , err
}
objId , err := res . LastInsertId ( )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjQuest : rollback get lastInsertId" )
return 0 , err
}
stmt , err := tx . Prepare ( ` INSERT INTO obj_quest ( obj_id , user_id , duration , date , exp , gold )
VALUES ( ? , ? , ? , ? , 0 , 0 ) ; ` )
logOnError ( err , "addObjQuest : prepare insert obj_quest" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjQuest : rollback prepare insert obj_quest" )
return 0 , err
}
defer stmt . Close ( )
_ , err = stmt . Exec ( objId , userID64 , duration , date )
logOnError ( err , "addObjQuest : exec insert obj_quest" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjQuest : rollback exec insert obj_quest" )
return 0 , err
}
err = tx . Commit ( )
logOnError ( err , "addObjQuest : commit" )
if err != nil {
return 0 , err
}
return objId , nil
}
2019-12-13 12:31:30 +01:00
func addObjItem ( code string , name string , itemTypeID64 int64 , weight int64 , exchange bool , auction bool ) ( int64 , error ) {
2019-07-22 09:40:52 +02:00
muxObjItem . Lock ( )
defer muxObjItem . Unlock ( )
2019-07-22 11:04:19 +02:00
if obj , ok := cacheObjItem [ code ] ; ok {
if _ , ok := cacheObjItem [ name ] ; ok {
2019-06-14 12:13:10 +02:00
// obj is already added ?
2019-07-22 11:04:19 +02:00
return obj . ObjID64 , nil
2019-06-14 12:13:10 +02:00
} else {
2019-07-22 11:04:19 +02:00
err := objAddName ( obj . ObjID64 , name )
2019-06-14 12:13:10 +02:00
if err != nil {
return 0 , nil
} else {
2019-07-22 11:04:56 +02:00
cacheObjItem [ name ] = obj
2019-07-22 11:04:19 +02:00
return obj . ObjID64 , nil
2019-06-14 12:13:10 +02:00
}
}
}
2019-07-22 09:40:52 +02:00
2019-06-02 08:48:16 +02:00
tx , err := db . Begin ( )
logOnError ( err , "addObjItem : start transaction" )
if err != nil {
return 0 , err
}
res , err := tx . Exec ( ` INSERT INTO obj ( obj_type_id , obj_sub_type_id )
2020-01-02 16:38:53 +01:00
VALUES ( ` + strconv.FormatInt(cacheObjType[ ` item ` ], 10) + ` , ` + fmt.Sprintf("%d", itemTypeID64) + ` ) ; ` )
2019-06-02 08:48:16 +02:00
logOnError ( err , "addObjItem : exec insert obj" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjItem : rollback insert obj" )
return 0 , err
}
objId , err := res . LastInsertId ( )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjItem : rollback get lastInsertId" )
return 0 , err
}
2019-08-21 05:46:42 +02:00
stmt , err := tx . Prepare ( ` INSERT INTO obj_item ( obj_id , intl_id , weight , exchange , auction )
VALUES ( ? , ? , ? , ? , ? ) ; ` )
2019-06-02 08:48:16 +02:00
logOnError ( err , "addObjItem : prepare insert obj_item" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjItem : rollback prepare insert obj_item" )
return 0 , err
}
defer stmt . Close ( )
2019-08-21 05:46:42 +02:00
var e , a int
if exchange {
e = 1
} else {
e = 0
}
if auction {
a = 1
} else {
a = 0
}
_ , err = stmt . Exec ( objId , code , weight , e , a )
2019-06-02 08:48:16 +02:00
logOnError ( err , "addObjItem : exec insert obj_item" )
if err != nil {
err2 := tx . Rollback ( )
logOnError ( err2 , "addObjItem : rollback exec insert obj_item" )
return 0 , err
}
err = tx . Commit ( )
logOnError ( err , "addObjItem : commit" )
if err != nil {
return 0 , err
}
2019-06-02 15:30:18 +02:00
2019-06-14 12:13:10 +02:00
err = objAddName ( objId , name )
logOnError ( err , "addObjItem : add name" )
2019-06-02 15:30:18 +02:00
c := new ( ChatWarsItem )
c . ObjID64 = objId
2019-08-23 12:31:43 +02:00
c . ItemTypeID = itemTypeID64
2019-06-02 15:30:18 +02:00
c . Code = code
2019-06-06 10:07:38 +02:00
c . Name = name
2019-06-02 15:30:18 +02:00
c . Weight = weight
2019-08-21 05:46:42 +02:00
c . Exchange = exchange
c . Auction = auction
2019-07-22 11:02:53 +02:00
cacheObjItem [ code ] = * c
cacheObjItem [ name ] = * c
2019-06-02 15:30:18 +02:00
2019-08-21 05:46:42 +02:00
muxObjItemId . Lock ( )
2019-08-21 06:04:56 +02:00
cacheObjItemId [ c . ObjID64 ] = * c
2019-08-21 05:46:42 +02:00
defer muxObjItemId . Unlock ( )
2019-06-02 08:48:16 +02:00
return objId , nil
}
2019-06-02 15:23:10 +02:00
func getObjItemID ( c string , n string ) int64 {
2019-07-22 09:40:52 +02:00
i := getSilentObjItemID ( c , n )
2019-06-03 03:40:37 +02:00
if i == 0 {
2019-07-09 10:02:50 +02:00
w := TGCommand {
Type : commandSendMsg ,
Text : fmt . Sprintf ( "Object unknown : %s - %s\n" , c , n ) ,
ToUserID64 : cfg . Bot . Admin ,
}
TGCmdQueue <- w
2019-06-03 03:40:37 +02:00
}
return i
}
2019-08-21 05:46:42 +02:00
func getObjItem ( objItemID64 int64 ) ( * ChatWarsItem , error ) {
muxObjItemId . Lock ( )
defer muxObjItemId . Unlock ( )
muxObjItem . Lock ( )
defer muxObjItem . Unlock ( )
if obj , ok := cacheObjItemId [ objItemID64 ] ; ok {
//log.Printf("Matching item name %s with %s.\n", name, obj.Name)
2019-08-21 05:54:01 +02:00
return & obj , nil
2019-08-21 05:46:42 +02:00
} else {
return nil , errors . New ( "Item not found." )
}
}
2019-07-22 09:40:52 +02:00
func getSilentObjItemID ( code string , name string ) int64 {
muxObjItem . Lock ( )
defer muxObjItem . Unlock ( )
2019-06-14 08:44:35 +02:00
if len ( code ) > 0 {
2019-07-22 09:40:52 +02:00
if obj , ok := cacheObjItem [ code ] ; ok {
//log.Printf("Matching item code %s with %s.\n", code, obj.Code)
return obj . ObjID64
2019-06-14 08:44:35 +02:00
}
2019-12-14 07:58:28 +01:00
if ok , _ := regexp . MatchString ( ` ^(a|w)[0-9]+[a-e]$ ` , code ) ; ok {
// log.Printf("Matching quality item code %s with %s.\n", code, code[:len(code)-1])
if obj , ok := cacheObjItem [ code [ : len ( code ) - 1 ] ] ; ok {
2019-12-13 13:13:57 +01:00
return obj . ObjID64
}
}
2019-06-14 08:44:35 +02:00
if ok , _ := regexp . MatchString ( ` ^u[0-9]+ ` , code ) ; ! ok {
return 0
}
}
if len ( name ) == 0 {
return 0
2019-06-02 08:48:16 +02:00
}
2019-07-22 09:40:52 +02:00
if obj , ok := cacheObjItem [ name ] ; ok {
//log.Printf("Matching item name %s with %s.\n", name, obj.Name)
return obj . ObjID64
2019-06-03 10:31:28 +02:00
}
2019-06-14 08:28:26 +02:00
if ok , _ := regexp . MatchString ( ` ^((u|e)[0-9]+|(a|w)[0-9]+[a-e] { 0,1})$ ` , code ) ; ok || len ( code ) == 0 {
2019-06-07 10:00:20 +02:00
r := regexp . MustCompile ( ` ^((?P<Modifier>⚡\+[0-9]+) ) { 0,1}(?P<BaseName>.+?)( \+(?P<Atk>[0-9]+)⚔) { 0,1}( \+(?P<Def>[0-9]+)🛡) { 0,1}( \+(?P<Mana>[0-9]+)💧) { 0,1}$ ` )
2019-06-14 08:28:26 +02:00
basename := r . ReplaceAllString ( name , "${BaseName}" )
2019-07-22 09:40:52 +02:00
if obj , ok := cacheObjItem [ basename ] ; ok && len ( basename ) > 0 {
//log.Printf("Matching item full basename %s with %s.\n", basename, obj.Name)
return obj . ObjID64
2019-06-03 10:31:28 +02:00
}
2019-07-22 09:40:52 +02:00
i := ChatWarsItem {
2019-06-14 08:30:18 +02:00
ObjID64 : 0 ,
}
2019-07-22 11:04:19 +02:00
for _ , obj := range cacheObjItem {
2019-07-22 09:40:52 +02:00
if ok , _ := regexp . MatchString ( ` ^(a|e|w)[0-9]+$ ` , obj . Code ) ; ok { //only gear can be custom named
m := fmt . Sprintf ( "^((%s.*)|(.*%s))$" , regexp . QuoteMeta ( obj . Name ) , regexp . QuoteMeta ( obj . Name ) )
if ok , _ := regexp . MatchString ( m , basename ) ; ok {
//log.Printf("LOOP : Matching item modified basename %s with %s (%d).\n", basename, item.Name, item.ObjID64)
i = obj
break
2019-06-14 06:01:59 +02:00
}
}
2019-07-22 09:40:52 +02:00
}
2019-06-14 06:01:59 +02:00
2019-07-22 09:40:52 +02:00
if i . ObjID64 != 0 {
2019-07-09 10:02:50 +02:00
//log.Printf("RETURN : Matching item modified basename %s with %s (%d).\n", basename, item.Name, item.ObjID64)
2019-07-22 09:40:52 +02:00
return i . ObjID64
2019-06-14 06:01:59 +02:00
} else {
2019-07-09 10:02:50 +02:00
/ *
fmt . Printf ( "silentGetObjItemID : Modifier : `%s`\n" , r . ReplaceAllString ( name , "${Modifier}" ) )
fmt . Printf ( "silentGetObjItemID : BaseName : `%s`\n" , r . ReplaceAllString ( name , "${BaseName}" ) )
fmt . Printf ( "silentGetObjItemID : Atk : `%s`\n" , r . ReplaceAllString ( name , "${Atk}" ) )
fmt . Printf ( "silentGetObjItemID : Def : `%s`\n" , r . ReplaceAllString ( name , "${Def}" ) )
fmt . Printf ( "silentGetObjItemID : Mana : `%s`\n" , r . ReplaceAllString ( name , "${Mana}" ) )
* /
2019-06-03 10:31:28 +02:00
}
2019-06-06 13:38:00 +02:00
2019-06-03 10:31:28 +02:00
}
return 0
2019-06-02 08:48:16 +02:00
}
func loadObjItem ( ) error {
var (
id int64
2019-08-23 12:37:33 +02:00
type_id int64
2019-06-02 08:48:16 +02:00
intl_id string
name string
2019-12-13 12:32:01 +01:00
weight int64
2019-06-02 08:48:16 +02:00
)
2019-07-22 09:40:52 +02:00
muxObjItem . Lock ( )
cacheObjItem = make ( map [ string ] ChatWarsItem )
muxObjItem . Unlock ( )
2019-06-02 08:48:16 +02:00
2019-08-21 06:04:56 +02:00
muxObjItemId . Lock ( )
cacheObjItemId = make ( map [ int64 ] ChatWarsItem )
muxObjItemId . Unlock ( )
2019-08-23 12:37:33 +02:00
items , err := db . Query ( ` SELECT oi.obj_id, o.obj_sub_type_id, oi.intl_id, obn.name, oi.weight FROM obj o, obj_item oi, obj_name obn WHERE o.id = oi.obj_id AND obn.obj_id = oi.obj_id AND obn.priority = 0; ` )
2019-06-02 08:48:16 +02:00
if err != nil {
return err
}
defer items . Close ( )
for items . Next ( ) {
2019-08-23 12:37:33 +02:00
err = items . Scan ( & id , & type_id , & intl_id , & name , & weight )
2019-06-02 08:48:16 +02:00
if err != nil {
return err
}
c := new ( ChatWarsItem )
c . ObjID64 = id
2019-08-23 12:37:33 +02:00
c . ItemTypeID = type_id
2019-06-02 08:48:16 +02:00
c . Code = intl_id
2019-06-06 10:02:41 +02:00
c . Name = name
2019-06-02 08:48:16 +02:00
c . Weight = weight
2019-08-21 06:23:59 +02:00
2019-07-22 09:40:52 +02:00
muxObjItem . Lock ( )
2019-07-22 11:02:53 +02:00
cacheObjItem [ intl_id ] = * c
cacheObjItem [ name ] = * c
2019-07-22 09:40:52 +02:00
muxObjItem . Unlock ( )
2019-08-21 06:23:59 +02:00
muxObjItemId . Lock ( )
cacheObjItemId [ id ] = * c
muxObjItemId . Unlock ( )
2019-06-02 08:48:16 +02:00
}
2019-06-25 11:58:17 +02:00
items2 , err := db . Query ( ` SELECT oi.obj_id, oi.intl_id, obn.name, oi.weight FROM obj_item oi, obj_name obn WHERE obn.obj_id = oi.obj_id AND obn.priority > 0; ` )
2019-06-14 12:13:10 +02:00
if err != nil {
return err
}
defer items2 . Close ( )
for items2 . Next ( ) {
err = items2 . Scan ( & id , & intl_id , & name , & weight )
if err != nil {
return err
}
2019-07-22 11:02:53 +02:00
if _ , ok := cacheObjItem [ intl_id ] ; ok {
2019-07-08 06:02:59 +02:00
c := new ( ChatWarsItem )
c . ObjID64 = id
c . Code = intl_id
c . Name = name
c . Weight = weight
2019-07-22 09:40:52 +02:00
muxObjItem . Lock ( )
2019-07-22 11:02:53 +02:00
cacheObjItem [ name ] = * c
2019-07-22 09:40:52 +02:00
muxObjItem . Unlock ( )
2019-06-14 12:13:10 +02:00
} else {
log . Printf ( "loadObjItem : orphaned obj_name for `%s` : %s.\n" , intl_id , name )
}
}
2019-07-22 09:40:52 +02:00
resetObjItem ( )
2019-06-02 08:48:16 +02:00
return nil
}
2020-01-12 10:11:34 +01:00
func loadObjJob ( ) error {
var (
id int64
type_id int64
trigger int64
timeout time . Time
user int64
zpayload [ ] byte
)
muxObjJob . Lock ( )
cacheObjJob = make ( map [ int64 ] Job )
muxObjItem . Unlock ( )
jobs , err := db . Query ( ` SELECT o.id, o.obj_sub_type_id, oj.trigger_id, oj.timeout, oj.user_id, oj.payload FROM obj o, obj_job oj WHERE o.id = oj.obj_id;; ` )
if err != nil {
return err
}
defer jobs . Close ( )
for jobs . Next ( ) {
err = jobs . Scan ( & id , & type_id , & trigger , & timeout , & user , & zpayload )
if err != nil {
return err
}
j := new ( Job )
j . ID64 = id
j . JobTypeID64 = type_id
j . Trigger = trigger
j . Timeout = timeout
j . UserID64 = user
zb := bytes . NewReader ( zpayload )
zr , err := zlib . NewReader ( zb )
if err != nil {
logOnError ( err , "loadObjJob : zlib.NewReader." )
continue
}
b := new ( bytes . Buffer )
b . ReadFrom ( zb )
payload := b . Bytes ( )
j . Payload = payload
muxObjJob . Lock ( )
cacheObjJob [ id ] = * j
muxObjJob . Unlock ( )
}
return nil
}