diff --git a/client.go b/client.go index d93fb6e..eaa6fa6 100644 --- a/client.go +++ b/client.go @@ -82,6 +82,18 @@ func clientMsgMeAck(m *ChatWarsMessageMeAck) { } } +func clientMsgGoQuestAck(m *ChatWarsMessageGoQuestAck) { + if _, ok := clientsQueue[m.Msg.UserID64]; ok { + if v, ok := clientsCW.Load(m.Msg.UserID64); ok { + c := v.(*ChatWarsClient) + if c.LastUpdate.Before(m.Msg.Date) { + c.LastUpdate = m.Msg.Date + c.BusyUntil = m.Msg.Date.Add(m.Duration) + } + } + } +} + func clientMsgGRolesAck(m *ChatWarsMessageGRolesAck) { if _, ok := clientsQueue[m.Msg.UserID64]; ok { if v, ok := clientsCW.Load(m.Msg.UserID64); ok { diff --git a/def.go b/def.go index 690f56a..88de1ea 100644 --- a/def.go +++ b/def.go @@ -121,9 +121,9 @@ type ChatWarsMessageGRolesAck struct { } type ChatWarsMessageGoQuestAck struct { - ObjID64 int64 `json:"obj_id"` - Quest string `json:"quest"` - Duration time.Duration `json:"duration"` + Msg *ChatWarsMessage `json:"msg"` + QuestTypeID int `json:"quest"` + Duration time.Duration `json:"duration"` } type ChatWarsMessageDuelFight struct { @@ -281,6 +281,7 @@ const ( objTypeUnion = 10 objTypeTribute = 11 objTypeExperience = 12 + objTypeQuest = 13 castleDeer = 1 castleDragon = 2 @@ -379,6 +380,9 @@ const ( objSubTypeUnion = 1001 objSubTypeTribute = 1101 objSubTypeExperience = 1201 + objSubTypeQuestForest = 1301 + objSubTypeQuestSwamp = 1302 + objSubTypeQuestValley = 1303 objJobStatusNew = 0 objJobStatusPillageGo = 1 diff --git a/obj.go b/obj.go index 85823f3..a060e2a 100644 --- a/obj.go +++ b/obj.go @@ -536,6 +536,55 @@ func addObjXP(userID64 int64, expNow int64, expLvl int64, level int64, date time return objId, nil } +func addObjQuest(userID64 int64, questTypeID int, duration time.Duration, date time.Time) (int64, error) { + 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) + VALUES (` + strconv.Itoa(objTypeQuest) + `,` + strconv.Itoa(questTypeID) + `);`) + 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 +} + func addObjItem(code string, name string, itemTypeID64 int64, weight int) (int64, error) { if v, ok := cacheObjItem.Load(code); ok { item := v.(ChatWarsItem) diff --git a/sql.go b/sql.go index 93239f4..073ff5d 100644 --- a/sql.go +++ b/sql.go @@ -133,6 +133,18 @@ func initDB() { failOnError(err, "initDB : create table obj_msg") log.Println("initDB : obj_msg created ...") + _, err = db.Exec(`CREATE VIEW obj_msg_v AS + SELECT om.obj_id + ,om.msg_id + ,om.chat_id + ,om.user_id + ,om.sender_user_id + ,om.date + ,om.text COLLATE utf8mb4_unicode_ci AS text + FROM obj_msg om;`) + failOnError(err, "initDB : create view obj_msg_v") + log.Println("initDB : obj_msg_v created ...") + _, err = db.Exec(`CREATE TABLE obj_msg_pillage_inc ( obj_id BIGINT UNSIGNED NOT NULL ,attacker VARCHAR(32) @@ -314,6 +326,20 @@ func initDB() { failOnError(err, "initDB : create table obj_xp") log.Println("initDB : obj_xp created ...") + _, err = db.Exec(`CREATE TABLE obj_quest ( + obj_id BIGINT UNSIGNED NOT NULL + ,user_id BIGINT UNSIGNED NOT NULL + ,duration SMALLINT UNSIGNED NOT NULL + ,date DATETIME NOT NULL + ,exp INT UNSIGNED NOT NULL + ,gold INT UNSIGNED NOT NULL + ,FOREIGN KEY (obj_id) REFERENCES obj(id) ON DELETE CASCADE + ,FOREIGN KEY (user_id) REFERENCES obj_user(obj_id) ON DELETE CASCADE + ,UNIQUE KEY (user_id, date) + ) ENGINE = InnoDB CHARSET=utf8mb4 COLLATE utf8mb4_unicode_ci;`) + failOnError(err, "initDB : create table obj_quest") + log.Println("initDB : obj_xp obj_quest ...") + _, err = db.Exec(`CREATE TABLE obj_job ( obj_id BIGINT UNSIGNED NOT NULL ,priority SMALLINT NOT NULL @@ -347,8 +373,9 @@ func initDB() { log.Println("initDB : obj_name created ...") _, err = db.Exec(`CREATE VIEW obj_name_v AS - SELECT obn.* - ,obn.name COLLATE utf8mb4_unicode_ci AS text + SELECT obn.obj_id + ,obn.name COLLATE utf8mb4_unicode_ci AS name + ,obn.priority FROM obj_name obn;`) failOnError(err, "initDB : create view obj_name_v") log.Println("initDB : obj_name_v created ...") @@ -366,6 +393,7 @@ func initDB() { ,(` + strconv.Itoa(objTypeUnion) + `, "union", "Trade Union") ,(` + strconv.Itoa(objTypeTribute) + `, "tribute", "Tribute") ,(` + strconv.Itoa(objTypeExperience) + `, "xp", "Experience") + ,(` + strconv.Itoa(objTypeQuest) + `, "quest", "Quest") ;`) failOnError(err, "initDB : populate table code_obj_type") log.Println("initDB : code_obj_type populated ...") @@ -458,6 +486,9 @@ func initDB() { ,(` + strconv.Itoa(objSubTypeFair) + `, "fair", "Fair", ` + strconv.Itoa(objTypeFair) + `) ,(` + strconv.Itoa(objSubTypeTribute) + `, "tribute", "Tribute", ` + strconv.Itoa(objTypeTribute) + `) ,(` + strconv.Itoa(objSubTypeExperience) + `, "xp", "Experience", ` + strconv.Itoa(objTypeExperience) + `) + ,(` + strconv.Itoa(objSubTypeQuestForest) + `, "forest", "Forest", ` + strconv.Itoa(objTypeQuest) + `) + ,(` + strconv.Itoa(objSubTypeQuestSwamp) + `, "swamp", "Swamp", ` + strconv.Itoa(objTypeQuest) + `) + ,(` + strconv.Itoa(objSubTypeQuestValley) + `, "valley", "Valley", ` + strconv.Itoa(objTypeQuest) + `) ;`) failOnError(err, "initDB : populate table code_obj_sub_type") log.Println("initDB : code_obj_sub_type populated ...") diff --git a/workers.go b/workers.go index 2728a42..cc95bdd 100644 --- a/workers.go +++ b/workers.go @@ -399,7 +399,9 @@ func SQLIdentifyMsgWorker(id int, objIds <-chan int64) { case objSubTypeMessageGoQuestAck: cwm, err := parseSubTypeMessageGoQuestAck(m, r) logOnError(err, "SQLIdentifyMsgWorker["+strconv.Itoa(id)+"] : Parsing objSubTypeMessageMeAck.") - cwm.ObjID64 = objId + cwm.Msg = m + clientMsgGoQuestAck(cwm) + _, err = addObjQuest(m.UserID64, cwm.Quest, cwm.Duration, m.Date.UTC()) case objSubTypeMessageDuelFight: cwm, err := parseSubTypeMessageDuelFight(m, r) logOnError(err, "SQLIdentifyMsgWorker["+strconv.Itoa(id)+"] : Parsing objSubTypeMessageDuelFight.")