diff --git a/bot.go b/bot.go index 37a6e91..a2599d5 100644 --- a/bot.go +++ b/bot.go @@ -832,6 +832,66 @@ func botShops(m *ChatWarsMessage) { return } +func botBrewItem(m *ChatWarsMessage, r *regexp.Regexp) { + if hasUnfinishedJob(cacheObjSubType[`job_brew_item`]) { + c := TGCommand{ + Type: commandReplyMsg, + Text: "Brew Item is already running", + FromMsgID64: m.ID64, + FromChatID64: m.ChatID64, + } + TGCmdQueue <- c + return + } + + clt, err := getLockedIdleClient() + if err != nil { + c := TGCommand{ + Type: commandReplyMsg, + Text: "Busy, please retry later.", + FromMsgID64: m.ID64, + FromChatID64: m.ChatID64, + } + TGCmdQueue <- c + return + } + userID64 := clt.TGUserID64 + clt.Mux.Unlock() + + p := JobPayloadBrewItem{ + MsgID64: m.ID64, + ChatID64: m.ChatID64, + Status: 0, + } + + p.ObjItemID64, err = getCraftItemID(r.ReplaceAllString(m.Text, "${Code}")) + logOnError(err, "botBrewItem : getCraftItemID") + + b, _ := json.Marshal(p) + t := time.Now().UTC().Add(1 * time.Second) + _, err = createJob(cacheObjSubType[`job_brew_item`], objJobPriority, userID64, 0, t, b) + + if err != nil { + c := TGCommand{ + Type: commandReplyMsg, + Text: fmt.Sprintf("%s", err), + FromMsgID64: m.ID64, + FromChatID64: m.ChatID64, + } + TGCmdQueue <- c + } else { + c := TGCommand{ + Type: commandReplyMsg, + Text: "Brew item coming", + FromMsgID64: m.ID64, + FromChatID64: m.ChatID64, + } + TGCmdQueue <- c + } + + return +} + func botCraftItem(m *ChatWarsMessage, r *regexp.Regexp) { if hasUnfinishedJob(cacheObjSubType[`job_craft_item`]) { c := TGCommand{ diff --git a/data/code_obj_sub_type.json b/data/code_obj_sub_type.json index adea83b..33d3f8c 100644 --- a/data/code_obj_sub_type.json +++ b/data/code_obj_sub_type.json @@ -674,6 +674,11 @@ "name": "Craft check for specific item", "obj_type": "msg" }, + { + "intl_id": "msg_bot_brew_item", + "name": "Brew check for specific item", + "obj_type": "msg" + }, { "intl_id": "msg_bot_craft_all", "name": "Craft check for all items", @@ -884,6 +889,11 @@ "name": "Craft specific item summary job", "obj_type": "job" }, + { + "intl_id": "job_brew_item", + "name": "Brew specific item summary job", + "obj_type": "job" + }, { "intl_id": "job_craft_all", "name": "Craft all items summary job", diff --git a/def.go b/def.go index 252192c..a553040 100644 --- a/def.go +++ b/def.go @@ -627,6 +627,16 @@ type JobPayloadAlchAll struct { ManaMax int64 `json:"mana_max"` } +type JobPayloadBrewItem struct { + MsgID64 int64 `json:"msg_id"` + ChatID64 int64 `json:"chat_id"` + ObjItemID64 int64 `json:"item_id"` + Status int64 `json:"status"` + ManaNow int64 `json:"mana_now"` + ManaMax int64 `json:"mana_max"` + VaultJobID64 int64 `json:"vault_job_id"` +} + type JobPayloadCheckVaultLimit struct { Status int64 `json:"status"` VaultPreJobID64 int64 `json:"vault_pre_job_id"` diff --git a/job.go b/job.go index ef4de24..026f73f 100644 --- a/job.go +++ b/job.go @@ -2173,6 +2173,123 @@ func jobGetStash(j Job) { } +func jobBrewItem(j Job) { + var ( + p JobPayloadBrewItem + maxManaItems int64 + maxResItems map[int64]int64 + itemsCode map[int64]string + itemInStock, itemInserted bool + eta, out string + list []int64 + ) + + err := setJobStart(j.ID64) + logOnError(err, "jobBrewItem : setJobStart") + + err = json.Unmarshal(j.Payload, &p) + logOnError(err, "jobBrewItem : Unmarshal payload") + + if p.Status == 0 { + + p.Status = 1 + + err = setJobPayloadJSON(j.ID64, p) + logOnError(err, "jobBrewItem : setJobPayloadJSON(p)") + + setJobCallback(j.ID64, j.UserID64, cacheObjSubType[`msg_me_ack`]) + rescheduleJob(j.ID64, 0, time.Unix(maxUnixTimestamp, 0).UTC()) + clientSendCWMsgDelay(j.UserID64, "/me", 0*time.Second) + return + } else if p.Status == 1 && j.Trigger != 0 { + m, err := getObjMsg(j.Trigger) + logOnError(err, "jobBrewItem : getObjMsg("+strconv.FormatInt(j.Trigger, 10)+")") + if err == nil { + rule, err := getMsgParsingRule(m) + logOnError(err, "jobBrewItem : getMsgParsingRule") + if rule.MsgTypeID64 == cacheObjSubType[`msg_me_ack`] { + + cwm, err := parseSubTypeMessageMeAck(m, rule.re) + p.Status = 2 + p.ManaNow = cwm.ManaNow + p.ManaMax = cwm.ManaMax + + err = setJobPayloadJSON(j.ID64, p) + logOnError(err, "jobBrewItem : setJobPayloadJSON(p)") + + setJobCallback(j.ID64, j.UserID64, cacheObjSubType[`msg_skill_too_low`]) + setJobCallback(j.ID64, j.UserID64, cacheObjSubType[`msg_alch_stock_ack`]) + setJobCallback(j.ID64, j.UserID64, cacheObjSubType[`msg_busy`]) + rescheduleJob(j.ID64, 0, time.Unix(maxUnixTimestamp, 0).UTC()) + clientSendCWMsgDelay(j.UserID64, "/alch", 2*time.Second) + return + } + } + } else if p.Status == 2 && j.Trigger != 0 { + m, err := getObjMsg(j.Trigger) + logOnError(err, "jobBrewItem : getObjMsg("+strconv.FormatInt(j.Trigger, 10)+")") + if err == nil { + rule, err := getMsgParsingRule(m) + logOnError(err, "jobBrewItem : getMsgParsingRule") + if rule.MsgTypeID64 == cacheObjSubType[`msg_alch_stock_ack`] { + cwm, err := parseSubTypeMessageAlchStockAck(m, rule.re) + logOnError(err, "jobBrewItem : parseSubTypeMessageAlchStockAck") + if err == nil { + maxResItems = make(map[int64]int64) + itemsCode = make(map[int64]string) + + // pre-fill maps with references and quantities + o, _ := getObjItem(p.ObjItemID64) + maxManaItems = p.ManaMax / o.Craft.Mana + if p.ManaNow < p.ManaMax { + t := (p.ManaMax - p.ManaNow) / ((p.ManaMax / 250) + 1) + d := time.Duration(t) * time.Minute + if d.Hours() > 1 { + eta = fmt.Sprintf("%s%.0fh", eta, d.Hours()) + } + d = d - d.Truncate(1*time.Hour) + if d.Minutes() > 0 { + eta = fmt.Sprintf("%s%.0fm", eta, d.Minutes()) + } + } else { + eta = "0m" + } + + out = fmt.Sprintf("%3s - %20s - %3d", o.Code, maxManaItems, o.Code, o.Names[0], maxManaItems[i]) + + c := TGCommand{ + Type: commandReplyMsg, + Text: fmt.Sprintf("ETA : %s\n%s", eta, out), + FromMsgID64: p.MsgID64, + FromChatID64: p.ChatID64, + ParseMode: cmdParseModeHTML, + } + TGCmdQueue <- c + + err = setJobDone(j.ID64) + logOnError(err, "jobBrewItem : setJobDone") + + return + } + } + } + } + + c := TGCommand{ + Type: commandReplyMsg, + Text: "Failed.", + FromMsgID64: p.MsgID64, + FromChatID64: p.ChatID64, + ParseMode: cmdParseModeHTML, + } + TGCmdQueue <- c + + err = setJobDone(j.ID64) + logOnError(err, "jobBrewItem : setJobDone") + + return +} + func jobAlchAll(j Job) { var ( p JobPayloadAlchAll diff --git a/rules.go b/rules.go index 6e83f46..cd3127e 100644 --- a/rules.go +++ b/rules.go @@ -218,6 +218,23 @@ func resetMsgParsingRules() error { } rules2 = append(rules2, r) + muxObjItem.RLock() + for _, o := range objItems { + if o.Craft != nil && o.ItemTypeID == cacheObjSubType[`item_misc`] && len(o.Craft.Command) > 6 && o.Craft.Command[0:5] == "/brew_" { + r = MessageParsingRule{ + Priority: 9998, + Description: fmt.Sprintf("Specific item brew %s", o.Code), + Rule: fmt.Sprintf("^\/alch_(?P%s)$", regexp.QuoteMeta(o.Code)), + MsgTypeID64: cacheObjSubType[`msg_bot_brew_item`], + ChatID64: 0, + SenderUserID64: users[id], + BotCommand: true, + } + rules2 = append(rules2, r) + } + } + muxObjItem.RUnlock() + r = MessageParsingRule{ Priority: 9999, Description: "List exchange deals on hold", diff --git a/workers.go b/workers.go index 5b5914e..3c4b356 100644 --- a/workers.go +++ b/workers.go @@ -543,6 +543,8 @@ func SQLIdentifyMsgWorker(id int, objIds <-chan int64) { botShops(m) case cacheObjSubType[`msg_bot_craft_item`]: botCraftItem(m, rule.re) + case cacheObjSubType[`msg_bot_brew_item`]: + botBrewItem(m, rule.re) case cacheObjSubType[`msg_bot_craft_all`]: botCraftAll(m, rule.re) case cacheObjSubType[`msg_bot_get_stash`]: @@ -702,6 +704,8 @@ func JobWorker(id int, jobs <-chan Job) { jobGetVault(j) case cacheObjSubType[`job_craft_item`]: jobCraftItem(j) + case cacheObjSubType[`job_brew_item`]: + jobBrewItem(j) case cacheObjSubType[`job_get_stash`]: jobGetStash(j) case cacheObjSubType[`job_craft_all`]: