diff --git a/def.go b/def.go index 9122d4f..8085328 100644 --- a/def.go +++ b/def.go @@ -43,6 +43,11 @@ type ChatWarsGuild struct { Name string `json:"name"` } +type ChatWarsUser struct { + ObjID64 int64 `json:"obj_id"` + Name string `json:"name"` +} + type ChatWarsMessage struct { ObjID64 int64 `json:"obj_id"` UserID64 int64 `json:"user_id"` diff --git a/main.go b/main.go index 4801d89..6042b04 100644 --- a/main.go +++ b/main.go @@ -91,6 +91,7 @@ func main() { _, _ = addObjCastle(`🥔`, `Potato`) _, _ = addObjCastle(`🦈`, `Sharkteeth`) _, _ = addObjCastle(`🐺`, `Wolfpack`) + _, _ = addObjGuild(``, `No Guild`) } resetMsgParsingRules() diff --git a/obj.go b/obj.go index 4f88869..30e0893 100644 --- a/obj.go +++ b/obj.go @@ -283,3 +283,190 @@ func loadObjGuild() error { return nil } + +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) + 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(s string) int64 { + if g, ok := cacheObjGuild[s]; ok { + return g.ObjID64 + } else { + objID64, err := addObjGuild(s, ``) + logOnError(err, "getObjGuildID") + g := new(ChatWarsGuild) + g.ObjID64 = objID64 + g.Tag = s + g.Name = `` + cacheObjGuild[s] = *g + } + return cacheObjGuild[s].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;`) + 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 + cacheObjGuild[tag] = *g + } + + 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) + VALUES (` + strconv.Itoa(objTypeUser) + `,` + strconv.Itoa(objSubTypeUser) + `);`) + 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() + logOnError(err2, "addObjUser : rollback exec insert obj") + return 0, err + } + + err = tx.Commit() + logOnError(err, "addObjUser : commit") + if err != nil { + return 0, err + } + return objId, nil +} + +func getObjUserID(s string) int64 { + if u, ok := cacheObjUser[s]; ok { + return u.ObjID64 + } else { + objID64, err := addObjGuild(s, ``) + logOnError(err, "getObjUserID") + u := new(ChatWarsUser) + u.ObjID64 = objID64 + u.Name = s + cacheObjUser[s] = *u + } + return cacheObjUser[s].ObjID64 +} + +func loadObjUser() error { + var ( + id int64 + tag string + name string + ) + + cacheObjUser = make(map[string]ChatWarsGuild) + + users, err := db.Query(`SELECT og.obj_id, og.tag, og.name FROM obj_guild og;`) + if err != nil { + return err + } + defer users.Close() + + for users.Next() { + err = users.Scan(&id, &tag, &name) + if err != nil { + return err + } + g := new(ChatWarsUser) + g.ObjID64 = id + g.Tag = tag + g.Name = name + cacheObjUser[tag] = *g + } + + return nil +} diff --git a/sql.go b/sql.go index a9973ed..046a9c5 100644 --- a/sql.go +++ b/sql.go @@ -100,17 +100,8 @@ func initDB() { _, 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 ...") @@ -221,11 +212,11 @@ func initDB() { obj_id BIGINT UNSIGNED NOT NULL ,win_castle_id BIGINT UNSIGNED NOT NULL ,win_guild_id BIGINT UNSIGNED - ,win_user VARCHAR(32) + ,win_user_id BIGINT UNSIGNED NOT NULL ,win_life SMALLINT NOT NULL ,loss_castle_id BIGINT UNSIGNED NOT NULL ,loss_guild_id BIGINT UNSIGNED - ,loss_user VARCHAR(32) + ,loss_user_id BIGINT UNSIGNED NOT NULL ,loss_life SMALLINT NOT NULL ,exp INT UNSIGNED NOT NULL ,weapon VARCHAR(80) @@ -234,6 +225,8 @@ func initDB() { ,FOREIGN KEY (loss_castle_id) REFERENCES obj_castle(obj_id) ON DELETE CASCADE ,FOREIGN KEY (win_guild_id) REFERENCES obj_guild(obj_id) ON DELETE CASCADE ,FOREIGN KEY (loss_guild_id) REFERENCES obj_guild(obj_id) ON DELETE CASCADE + ,FOREIGN KEY (win_user_id) REFERENCES obj_user(obj_id) ON DELETE CASCADE + ,FOREIGN KEY (loss_user_id) REFERENCES obj_user(obj_id) ON DELETE CASCADE ) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`) failOnError(err, "initDB : create table obj_msg_duel_fight") log.Println("initDB : obj_msg_duel_fight created ...") @@ -1409,14 +1402,14 @@ func insertMsgDuelFight(m *ChatWarsMessageDuelFight) error { return errors.New("Message type mismatch") } - stmt, err := db.Prepare(`INSERT INTO obj_msg_duel_fight (obj_id, win_castle_id, win_guild_id, win_user, win_life, loss_castle_id, loss_guild_id, loss_user, loss_life, weapon) - VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`) + stmt, err := db.Prepare(`INSERT INTO obj_msg_duel_fight (obj_id, win_castle_id, win_guild_id, win_user_id, win_life, loss_castle_id, loss_guild_id, loss_user_id, loss_life, weapon) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);`) if err != nil { return err } defer stmt.Close() - _, err = stmt.Exec(m.ObjID64, getObjCastleID(m.WinCastle), getObjGuildID(m.WinGuild), m.WinUser, m.WinLife, getObjCastleID(m.LossCastle), getObjGuildID(m.LossGuild), m.LossUser, m.LossLife, m.Weapon) + _, err = stmt.Exec(m.ObjID64, getObjCastleID(m.WinCastle), getObjGuildID(m.WinGuild), getObjUserID(m.WinUser), m.WinLife, getObjCastleID(m.LossCastle), getObjGuildID(m.LossGuild), getObjUserID(m.LossUser), m.LossLife, m.Weapon) if err != nil { return err }