This commit is contained in:
shoopea 2019-05-25 15:25:11 +08:00
parent efc04717f7
commit f13e7daea5
6 changed files with 340 additions and 157 deletions

21
def.go
View File

@ -31,7 +31,20 @@ type TGCommand struct {
Text string `json:"text"`
}
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 ChatWarsMessage struct {
ObjID64 int64 `json:"obj_id"`
UserID64 int64 `json:"user_id"`
SenderUserID64 int64 `json:"sender_user_id"`
Date time.Time `json:"date"`
@ -159,6 +172,7 @@ const (
objTypeWarReport = 5
objTypeJob = 6
objTypeItem = 7
objTypeCastle = 8
castleDeer = 1
castleDragon = 2
@ -168,6 +182,8 @@ const (
castleShark = 6
castleWolf = 7
objSubTypeUser = 101
objSubTypeGuild = 201
objSubTypeMessageUnknown = 301
objSubTypeMessageWar = 302 // from Chat Wars Reports (not done)
objSubTypeMessageMiniWar = 303 // from Chat Wars Mini Reports (done)
@ -216,6 +232,10 @@ const (
objSubTypeMessageStockAck = 346 // result from /stock (not done)
objSubTypeMessageMiscReq = 347 // /misc (done)
objSubTypeMEssageMiscAck = 348 // result from /misc (not done)
objSubTypeMessageUnionWar = 349 // from Chat Wars Reports (not done)
objSubTypeMessageFairWar = 350 // from Chat Wars Reports (not done)
objSubTypeMessageTUReportReq = 351 // /tu_report (not done)
objSubTypeMessageTUReportAck = 352 // result from /tu_report (not done)
objSubTypeJobPillage = 601
objSubTypeJobTribute = 602
objSubTypeJobStatus = 603
@ -229,6 +249,7 @@ const (
objSubTypeItemRecipe = 704
objSubTypeItemPart = 705
objSubTypeItemOther = 706
objSubTypeCastle = 801
objJobStatusNew = 0
objJobStatusPillageGo = 1

11
main.go
View File

@ -84,11 +84,22 @@ func main() {
if *initdb {
initDB()
_ = addObjCastle(`🦌`, `Deerhorn`)
_ = addObjCastle(`🐉`, `Dragonscale`)
_ = addObjCastle(`🦅`, `Highnest`)
_ = addObjCastle(`🌑`, `Moonlight`)
_ = addObjCastle(`🥔`, `Potato`)
_ = addObjCastle(`🦈`, `Sharkteeth`)
_ = addObjCastle(`🐺`, `Wolfpack`)
}
resetMsgParsingRules()
msgParsingRules, err = loadMsgParsingRules()
logOnError(err, "Message parsing rules")
err = loadObjCastle()
logOnError(err, "Caching castles")
err = loadObjGuild()
logOnError(err, "Caching guilds")
// Registering bot
b, err := tb.NewBot(tb.Settings{

269
obj.go Normal file
View File

@ -0,0 +1,269 @@
package main
var (
cacheObjCastle map[string]ChatWarsCastle
cacheObjGuild map[string]ChatWarsGuild
)
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)
logOnError(err, "setObjSubTypeId : exec update")
return err
}
func addObjMsg(msgID64 int64, msgChatID64 int64, msgUserID64 int64, msgSenderUserID64 int64, msgDate time.Time, msgText string) (int64, error) {
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)
VALUES (` + strconv.Itoa(objTypeMessage) + `,` + strconv.Itoa(objSubTypeMessageUnknown) + `);`)
logOnError(err, "addObjMsg : exec insert obj")
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 (?, ?, ?, ?, ?, ?, ?);`)
logOnError(err, "addObjMsg : prepare insert obj_msg")
if err != nil {
err2 := tx.Rollback()
logOnError(err2, "addObjMsg : rollback prepare insert obj_msg")
return 0, err
}
defer stmt.Close()
_, err = stmt.Exec(objId, msgID64, msgChatID64, msgUserID64, msgSenderUserID64, msgDate, msgText)
logOnError(err, "addObjMsg : exec insert obj_msg")
if err != nil {
err2 := tx.Rollback()
logOnError(err2, "addObjMsg : rollback exec insert obj")
return 0, err
}
err = tx.Commit()
logOnError(err, "addObjMsg : commit")
if err != nil {
return 0, err
}
return objId, nil
}
func addObjCastle(logo string, name string) error {
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)
VALUES (` + strconv.Itoa(objTypeCastle) + `,` + strconv.Itoa(objSubTypeCastle) + `);`)
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()
logOnError(err2, "addObjCastle : rollback exec insert obj")
return 0, err
}
err = tx.Commit()
logOnError(err, "addObjCastle : commit")
if err != nil {
return 0, err
}
return objId, nil
}
func getObjCastleID(string c) int64 {
return cacheObjCastle[c].ObjID64
}
func loadObjCastle() error {
var (
id int64
logo string
name string
)
cacheObjCastle = make(map[string]ChatWarsCastle)
castles, err := db.Query(`SELECT oc.obj_id, oc.logo, oc.name FROM obj_castle oc ORDER BY oc.id DESC;`)
if err != nil {
return err
}
defer castles.Close()
for castles.Next() {
err = rules.Scan(&id, &logo, &name)
if err != nil {
return err
}
c := new(ChatWarsCastle)
c.ObjID64 = id
c.Logo = logo
c.Name = name
cacheObjCastle[logo] = *c
cacheObjCastle[name] = *c
}
return nil
}
func addObjGuild(tag string, name string) 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)
VALUES (` + strconv.Itoa(objTypeGuild) + `,` + strconv.Itoa(objSubTypeGuild) + `);`)
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()
logOnError(err2, "addObjGuild : rollback exec insert obj")
return 0, err
}
err = tx.Commit()
logOnError(err, "addObjGuild : commit")
if err != nil {
return 0, err
}
return objId, nil
}
func getObjGuildID(g string) int64 {
return cacheObjGuild[g].ObjID64
}
func loadObjGuild() error {
var (
id int64
tag string
name string
)
cacheObjGuild = make(map[string]ChatWarsGuild)
guilds, err := db.Query(`SELECT og.obj_id, og.tag, og.name FROM obj_guild og ORDER BY oc.id DESC;`)
if err != nil {
return err
}
defer guilds.Close()
for guilds.Next() {
err = rules.Scan(&id, &tag, &name)
if err != nil {
return err
}
c := new(ChatWarsGuild)
c.ObjID64 = id
c.Tag = tag
c.Name = name
cacheObjGuild[tag] = *c
}
return nil
}

154
sql.go
View File

@ -66,16 +66,6 @@ func initDB() {
failOnError(err, "initDB : create table code_obj_sub_type")
log.Println("initDB : code_obj_sub_type created ...")
_, err = db.Exec(`CREATE TABLE code_obj_castle (
id SMALLINT UNSIGNED NOT NULL
,user_id VARCHAR(32) NOT NULL
,intl_id VARCHAR(32) NOT NULL
,name VARCHAR(80) NOT NULL
,PRIMARY KEY (id)
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
failOnError(err, "initDB : create table obj_castle")
log.Println("initDB : obj_guild created ...")
_, err = db.Exec(`CREATE TABLE obj (
id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT
,obj_type_id SMALLINT UNSIGNED NOT NULL
@ -88,31 +78,43 @@ func initDB() {
failOnError(err, "initDB : create table obj")
log.Println("initDB : obj created ...")
_, err = db.Exec(`CREATE TABLE obj_castle (
obj_id BIGINT UNSIGNED NOT NULL
,user_id VARCHAR(32) NOT NULL
,name VARCHAR(80) NOT NULL
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
failOnError(err, "initDB : create table obj_castle")
log.Println("initDB : obj_guild created ...")
_, err = db.Exec(`CREATE TABLE obj_guild (
obj_id BIGINT UNSIGNED NOT NULL
,tag VARCHAR(32) NOT NULL
,name VARCHAR(80) NOT NULL
,chat_id BIGINT
,deposit_chat_id BIGINT
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
failOnError(err, "initDB : create table obj_guild")
log.Println("initDB : obj_guild created ...")
_, err = db.Exec(`CREATE TABLE obj_user (
obj_id BIGINT UNSIGNED NOT NULL
,telegram_id BIGINT UNSIGNED NOT NULL
,user_id VARCHAR(32) NOT NULL
,name VARCHAR(80) NOT NULL
,guild_id BIGINT UNSIGNED
,castle_id BIGINT UNSIGNED
,last_msg TIMESTAMP
,busy_until TIMESTAMP
,role ENUM('commander', 'bartender', 'squire', 'none')
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
,FOREIGN KEY (guild_id) REFERENCES obj_guild(obj_id) ON DELETE CASCADE
,FOREIGN KEY (castle_id) REFERENCES obj_castle(obj_id) ON DELETE CASCADE
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
failOnError(err, "initDB : create table obj_user")
log.Println("initDB : obj_user created ...")
_, err = db.Exec(`CREATE TABLE obj_guild (
obj_id BIGINT UNSIGNED NOT NULL
,tag VARCHAR(32) NOT NULL
,name VARCHAR(80) NOT NULL
,chat_id BIGINT NOT NULL
,deposit_chat_id BIGINT NOT NULL
,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE
) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`)
failOnError(err, "initDB : create table obj_guild")
log.Println("initDB : obj_guild created ...")
_, err = db.Exec(`CREATE TABLE obj_war (
obj_id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT
,start_time DATETIME NOT NULL
@ -304,6 +306,9 @@ func initDB() {
,(` + strconv.Itoa(objTypeWarReport) + `, "war_report", "War Report")
,(` + strconv.Itoa(objTypeJob) + `, "job", "Job")
,(` + strconv.Itoa(objTypeItem) + `, "item", "Item")
,(` + strconv.Itoa(objTypeCastle) + `, "castle", "Castle")
,(` + strconv.Itoa(objTypeFair) + `, "fair", "Fair")
,(` + strconv.Itoa(objTypeUnion) + `, "union", "Trade Union")
;`)
failOnError(err, "initDB : populate table code_obj_type")
log.Println("initDB : code_obj_type populated ...")
@ -321,7 +326,12 @@ func initDB() {
log.Println("initDB : code_obj_castle populated ...")
_, err = db.Exec(`INSERT INTO code_obj_sub_type (id, intl_id, name, obj_type_id)
VALUES (` + strconv.Itoa(objSubTypeMessageUnknown) + `, "unknown", "Unknown", ` + strconv.Itoa(objTypeMessage) + `)
VALUES (` + strconv.Itoa(objSubTypeUser) + `, "user", "User", ` + strconv.Itoa(objTypeUser) + `)
(` + strconv.Itoa(objSubTypeGuild) + `, "guild", "Guild", ` + strconv.Itoa(objTypeGuild) + `)
(` + strconv.Itoa(objSubTypeCastle) + `, "castle", "Castle", ` + strconv.Itoa(objTypeCastle) + `)
(` + strconv.Itoa(objSubTypeUnion) + `, "union", "Union", ` + strconv.Itoa(objTypeUnion) + `)
(` + strconv.Itoa(objSubTypeFair) + `, "fair", "Fair", ` + strconv.Itoa(objTypeFair) + `)
(` + strconv.Itoa(objSubTypeMessageUnknown) + `, "unknown", "Unknown", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageWar) + `, "war", "War report", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageMiniWar) + `, "mini_war", "Mini war reprot", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageGuildWar) + `, "guild_war", "Guilds war report", ` + strconv.Itoa(objTypeMessage) + `)
@ -369,6 +379,10 @@ func initDB() {
,(` + strconv.Itoa(objSubTypeMessageStockAck) + `, "stock_ack", "Stock Ack", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageMiscReq) + `, "misc_req", "Misc Req", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMEssageMiscAck) + `, "misc_ack", "Misc Ack", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageTUReportReq) + `, "tureport_req", "Trade Union War Report Req", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageTUReportAck) + `, "tureport_ack", "Trade Union War Report Ack", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMessageFairWar) + `, "fair_war", "Fair war report", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeMEssageUnionWar) + `, "union_war", "Union war report", ` + strconv.Itoa(objTypeMessage) + `)
,(` + strconv.Itoa(objSubTypeJobPillage) + `, "job_pillage", "Pillage job", ` + strconv.Itoa(objTypeJob) + `)
,(` + strconv.Itoa(objSubTypeJobTribute) + `, "job_tribute", "Tribute job", ` + strconv.Itoa(objTypeJob) + `)
,(` + strconv.Itoa(objSubTypeJobWithdrawal) + `, "job_withdraw", "Withdrawal job", ` + strconv.Itoa(objTypeJob) + `)
@ -1343,55 +1357,6 @@ INSERT INTO obj_item (obj_id, intl_id, name, weight) VALUES
log.Println("initDB : Database set up")
}
func putUnprocessedMsg(m ChatWarsMessage) (int64, error) {
tx, err := db.Begin()
logOnError(err, "putUnprocessedMsg : start transaction")
if err != nil {
return 0, err
}
res, err := tx.Exec(`INSERT INTO obj (obj_type_id, obj_sub_type_id)
VALUES (` + strconv.Itoa(objTypeMessage) + `,` + strconv.Itoa(objSubTypeMessageUnknown) + `);`)
logOnError(err, "putUnprocessedMsg : exec insert obj")
if err != nil {
err2 := tx.Rollback()
logOnError(err2, "putUnprocessedMsg : rollback insert obj")
return 0, err
}
objId, err := res.LastInsertId()
if err != nil {
err2 := tx.Rollback()
logOnError(err2, "putUnprocessedMsg : 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 (?, ?, ?, ?, ?, ?, ?);`)
logOnError(err, "putUnprocessedMsg : prepare insert obj_msg")
if err != nil {
err2 := tx.Rollback()
logOnError(err2, "putUnprocessedMsg : rollback prepare insert obj_msg")
return 0, err
}
defer stmt.Close()
_, err = stmt.Exec(objId, m.ID64, m.ChatID64, m.UserID64, m.SenderUserID64, m.Date, m.Text)
logOnError(err, "putUnprocessedMsg : exec insert obj_msg")
if err != nil {
err2 := tx.Rollback()
logOnError(err2, "putUnprocessedMsg : rollback exec insert obj")
return 0, err
}
err = tx.Commit()
logOnError(err, "putUnprocessedMsg : commit")
if err != nil {
return 0, err
}
return objId, nil
}
func getMsg(objId int64) (*ChatWarsMessage, error) {
var m *ChatWarsMessage
@ -1411,53 +1376,6 @@ func getMsg(objId int64) (*ChatWarsMessage, error) {
return m, nil
}
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)
logOnError(err, "setObjSubTypeId : exec update")
return err
}
func insertMsgReport(objId int64, war_date int32, atk int32, def int32, exp int32, gold int32, stock int32, crit bool, stamina bool) error {
objSubTypeId, err := getObjSubTypeId(objId)
if err != nil {

View File

@ -20,7 +20,7 @@ func logOnError(err error, msg string) {
}
}
func Min(a int, b int) int {
func MinInt(a int, b int) int {
if a < b {
return a
} else {
@ -28,7 +28,7 @@ func Min(a int, b int) int {
}
}
func Max(a int, b int) int {
func MaxInt(a int, b int) int {
if a > b {
return a
} else {
@ -36,42 +36,6 @@ func Max(a int, b int) int {
}
}
func CastleID(c string) int {
switch c {
case "Deerhorn":
return castleDeer
case "Dragonscale":
return castleDragon
case "Highnest":
return castleHighnest
case "Moonlight":
return castleMoon
case "Potato":
return castlePotato
case "Sharkteeth":
return castleShark
case "Wolfpack":
return castleWolf
case "🦌":
return castleDeer
case "🐉":
return castleDragon
case "🦅":
return castleHighnest
case "🌑":
return castleMoon
case "🥔":
return castlePotato
case "🦈":
return castleShark
case "🐺":
return castleWolf
default:
return 0
}
return 0
}
func fromChatWarsDate(d string) (t time.Time, err error) {
r := regexp.MustCompile(`(?P<Day>[0-9]{2}) (?P<Month>(Wintar|Hornung|Lenzin|Ōstar|Winni|Brāh|Hewi|Aran|Witu|Wīndume|Herbist|Hailag)) (?P<Year>[0-9]{4})( (?P<Hour>[0-9]{2}):(?P<Minute>[0-9]{2})){0,1}`)
if r.FindStringSubmatch(d) != nil {

View File

@ -60,7 +60,7 @@ func MQGetMsgWorker(id int, msgs chan<- ChatWarsMessage) {
func SQLCWMsgWorker(id int, msgs <-chan ChatWarsMessage, objIds chan<- int64) {
log.Printf("SQLCWMsgWorker[" + strconv.Itoa(id) + "] : Starting.")
for m := range msgs {
objId, err := putUnprocessedMsg(m)
objId, err := addObjMsg(m.ID64, m.ChatID64, m.UserID64, m.SenderUserID64, m.Date, m.Text)
logOnError(err, "SQLCWMsgWorker["+strconv.Itoa(id)+"] : Inserting message.")
if err == nil && objId != 0 {
// log.Printf("SQLCWMsgWorker["+strconv.Itoa(id)+"] : Message inserted (%d).\n", objId)