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`]: