chirpnest/obj.go

1166 lines
28 KiB
Go
Raw Normal View History

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-12 12:43:45 +01:00
err = loadObjItem2()
2020-01-02 11:04:48 +01:00
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
}
2020-01-12 13:03:30 +01:00
func addObjItem(code string, name string, itemTypeID64 int64, weight int64, exchange string, auction bool) (int64, error) {
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
2020-01-12 13:03:30 +01:00
if exchange != `` {
2019-08-21 05:46:42 +02:00
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 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
2020-01-12 13:11:42 +01:00
m := fmt.Sprintf("^((%s.*)|(.*%s))$", regexp.QuoteMeta(obj.Names[0]), regexp.QuoteMeta(obj.Names[0]))
2019-07-22 09:40:52 +02:00
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
}
2020-01-12 12:43:45 +01:00
func loadObjItem2() error {
2020-01-12 13:20:18 +01:00
var items []ChatWarsItem
2020-01-12 12:43:45 +01:00
muxObjItem.Lock()
2020-01-12 14:21:34 +01:00
defer muxObjItem.Unlock()
2020-01-12 12:43:45 +01:00
cacheObjItem = make(map[string]ChatWarsItem)
muxObjItemId.Lock()
2020-01-12 14:21:34 +01:00
defer muxObjItemId.Unlock()
2020-01-12 12:43:45 +01:00
cacheObjItemId = make(map[int64]ChatWarsItem)
b, err := Asset("data/obj_item.json")
logOnError(err, "loadObjItem2 : load data/obj_item.json")
if err != nil {
return err
}
err = json.Unmarshal(b, &items)
for _, i := range items {
2020-01-12 14:21:34 +01:00
if len(i.Names) == 0 {
log.Printf("loadObjItems2 : %s : name missing.\n", i.Code)
} else {
if obj, ok := cacheObjItem[i.Code]; ok {
log.Printf("loadObjItem2 : %s : duplicate code found. Belong to %s\n", i2.Code, n, obj.Code)
2020-01-12 13:03:30 +01:00
} else {
2020-01-12 14:21:34 +01:00
i2 := ChatWarsItem{
Auction: i.Auction,
Code: i.Code,
Exchange: i.Exchange,
ItemTypeID: i.ItemTypeID,
Weight: i.Weight,
Craft: ChatWarsItemCraft{},
Names: make([]string, 1),
}
for _, n := range i.Names {
if obj, ok := cacheObjItem[n]; ok {
log.Printf("loadObjItem2 : %s - %s : duplicate name found. Belongs to %s\n", i2.Code, n, obj.Code)
} else {
i2.Names = append(i2.Names, n)
}
}
cacheObjItem[i.Code] = *i2
for _, n := range i.Names {
cacheObjItem[n] = *i2
}
}
}
}
objs, err := db.Query(`SELECT oi.obj_id, o.obj_sub_type_id, oi.intl_id, oi.weight FROM obj o, obj_item oi WHERE o.id = oi.obj_id;`)
if err != nil {
logOnError("loadObjItem2 : querying items")
return err
}
defer objs.Close()
for objs.Next() {
err = objs.Scan(&id, &type_id, &intl_id, &weight)
if err != nil {
logOnError("loadObjItem2 : scanning items")
return err
}
if obj, ok := cacheObjItem[intl_id]; !ok {
log.Printf("loadObjItem2 : %s : orphaned item in database (id : %d)\n", intl_id, id)
} else {
obj.ObjID64 = id
cacheObjItem[intl_id] = obj
for _, n := range obj.Names {
cacheObjItem[n] = obj
}
if weight != obj.Weight {
log.Printf("loadObjItem2 : %s : weight changed : %d => %d\n", weight, obj.Weight)
2020-01-12 13:03:30 +01:00
}
2020-01-12 14:21:34 +01:00
cacheObjItemID[id] = obj
2020-01-12 12:43:45 +01:00
}
}
2020-01-12 14:21:34 +01:00
names, err := db.Query(`SELECT oi.obj_id, obn.name FROM obj_item oi, obj_name obn WHERE oi.obj_id = obn.obj_id;`)
if err != nil {
logOnError("loadObjItem2 : querying names")
return err
}
defer names.Close()
for names.Next() {
err = names.Scan(&id, &name)
if err != nil {
logOnError("loadObjItem2 : scanning names")
return err
}
if obj, ok := cacheObjItem[name]; !ok {
if obj2, ok := cacheObjItemId[id]; ok {
log.Printf("loadObjItem2 : %s : orphaned name in database for item %s\n", name, obj2.Code)
}
}
}
for _, i := range cacheObjItem {
if i.ObjID64 == 0 {
id, err := addObjItem(i.Code, i.Names[0], i.ItemTypeID, i.Weight, i.Exchange, i.Auction)
i.ObjID64 = id
cacheObjItemID[id] = obj
count := 0
for _, n := range i.Names {
if count == 0 {
cacheObjItemID[n] = obj
continue
} else {
objAddName(id, n)
cacheObjItem[n] = obj
}
}
}
}
2020-01-12 12:43:45 +01:00
log.Printf("%d items loaded.\n", len(items))
2020-01-12 13:26:25 +01:00
for _, v := range cacheObjItemId {
2020-01-12 13:29:46 +01:00
log.Printf("Item cached : %d\n", v.ObjID64)
2020-01-12 13:26:25 +01:00
for _, n := range v.Names {
2020-01-12 13:29:46 +01:00
log.Printf("cacheObjItemId[%d] : %s : %s.\n", v.ObjID64, v.Names[0], n)
2020-01-12 13:26:25 +01:00
}
}
2020-01-12 12:43:45 +01:00
return nil
}
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
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
2020-01-12 13:16:42 +01:00
n := make([]string, 1)
n = append(n, name)
c.Names = n
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
}
2020-01-12 13:16:42 +01:00
if c, ok := cacheObjItem[intl_id]; ok {
n := c.Names
n = append(n, name)
c.Names = n
2019-07-22 09:40:52 +02:00
muxObjItem.Lock()
2020-01-12 13:19:35 +01:00
cacheObjItem[intl_id] = c
2020-01-12 13:16:42 +01:00
for _, n := range c.Names {
2020-01-12 13:20:18 +01:00
cacheObjItem[n] = c
2020-01-12 13:16:42 +01:00
}
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-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)
2020-01-12 10:32:31 +01:00
muxObjJob.Unlock()
2020-01-12 10:11:34 +01:00
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 {
2020-01-12 10:37:46 +01:00
logOnError(err, "loadObjJob : zlib.NewReader")
2020-01-12 10:11:34 +01:00
continue
}
b := new(bytes.Buffer)
2020-01-12 10:21:48 +01:00
b.ReadFrom(zr)
2020-01-12 10:11:34 +01:00
payload := b.Bytes()
j.Payload = payload
muxObjJob.Lock()
cacheObjJob[id] = *j
muxObjJob.Unlock()
}
return nil
}