diff --git a/bot.go b/bot.go
index 7031183..8e006ce 100644
--- a/bot.go
+++ b/bot.go
@@ -966,7 +966,7 @@ func botGWithdraw(m *tb.Message) {
p := JobPayloadGWithdraw{
MsgID64: int64(m.ID),
ChatID64: m.Chat.ID,
- User: m.Sender.Username,
+ UserID64: int64(m.Sender.ID),
Status: 0,
Validated: false,
}
diff --git a/def.go b/def.go
index d051a75..1608998 100644
--- a/def.go
+++ b/def.go
@@ -413,7 +413,7 @@ type JobPayloadGWithdrawItem struct {
type JobPayloadGWithdraw struct {
MsgID64 int64 `json:"msg_id"`
ChatID64 int64 `json:"chat_id"`
- User string `json:"user"`
+ UserID64 int64 `json:"user_id"`
Items []JobPayloadGWithdrawItem `json:"items"`
Status int64 `json:"status"`
CleanupMsg []ChatWarsMessage `json:"cleanup_msg"`
diff --git a/job.go b/job.go
index 1be0029..790e29d 100644
--- a/job.go
+++ b/job.go
@@ -133,6 +133,42 @@ func setJobTimeout(jobID64 int64, d time.Duration) error {
return nil
}
+func setJobPayload(jobID64 int64, payload []byte) error {
+ var zb bytes.Buffer
+
+ zw := zlib.NewWriter(&zb)
+ zw.Write(payload)
+ zw.Close()
+ zpayload := zb.Bytes()
+
+ if len(zpayload) > 20000 {
+ return 0, errors.New("payload too long")
+ }
+
+ stmt, err := db.Prepare(`UPDATE obj_job j SET j.payload = ? WHERE j.obj_id = ?;`)
+ logOnError(err, "setJobTimeout : prepare update obj_job")
+ if err != nil {
+ return err
+ }
+ defer stmt.Close()
+
+ _, err = stmt.Exec(zpayload, jobID64)
+ logOnError(err, fmt.Sprintf("setJobTimeout, update obj_job(%d)", jobID64))
+ if err != nil {
+ return err
+ }
+
+ muxObjJob.Lock()
+ j := cacheObjJob[jobID64]
+ j.Payload = b
+ cacheObjJob[jobID64] = j
+ muxObjJob.Unlock()
+
+ log.Printf("setJobPayload[%d] : %s\n", string(payload))
+
+ return nil
+}
+
func setJobDone(jobID64 int64) error {
stmt, err := db.Prepare(`UPDATE obj_job j SET j.is_done = 1, j.in_work = 0, j.ended = ? WHERE j.obj_id = ?;`)
logOnError(err, "setJobDone : prepare update obj_job")
@@ -1442,30 +1478,95 @@ func jobGWithdraw(j Job) {
if j.Trigger != 0 {
id, err := getObjSubTypeId(j.Trigger)
logOnError(err, "jobGWithdraw : getObjSubType("+strconv.FormatInt(j.Trigger, 10)+")")
- if err == nil && id == cacheObjSubType[`msg_gstock_any_ack`] {
- m, err := getObjMsg(j.Trigger)
- logOnError(err, "jobGWithdraw : getObjMsg")
- rule, err := getMsgParsingRule(m)
- logOnError(err, "jobGWithdraw : getMsgParsingRule")
- cwm, err := parseSubTypeMessageGStockAnyAck(m, rule.re)
- logOnError(err, "jobGWithdraw : parseSubTypeMessageGStockAnyAck")
+ if err == nil {
+ if id == cacheObjSubType[`msg_gstock_any_ack`] {
+ m, err := getObjMsg(j.Trigger)
+ logOnError(err, "jobGWithdraw : getObjMsg")
+ rule, err := getMsgParsingRule(m)
+ logOnError(err, "jobGWithdraw : getMsgParsingRule")
+ cwm, err := parseSubTypeMessageGStockAnyAck(m, rule.re)
+ logOnError(err, "jobGWithdraw : parseSubTypeMessageGStockAnyAck")
- for k, req := range p.Items {
- for _, disp := range cwm.Stock {
- if req.Code == disp.Code {
- p.Items[k].Available = disp.Quantity
- p.Items[k].Name = disp.Name
- log.Printf("jobGWithdraw[%d] : Found %s - %s : %d.\n", j.ID64, disp.Code, disp.Name, disp.Quantity)
+ for k, req := range p.Items {
+ for _, disp := range cwm.Stock {
+ if req.Code == disp.Code {
+ p.Items[k].Available = disp.Quantity
+ p.Items[k].Name = disp.Name
+ log.Printf("jobGWithdraw[%d] : Found %s - %s : %d.\n", j.ID64, disp.Code, disp.Name, disp.Quantity)
+ }
}
}
+
+ p2 := JobPayloadMsgDel{
+ Delay: (10 * time.Second),
+ ObjMsgID64: j.Trigger,
+ }
+ b2, _ := json.Marshal(p2)
+ createJob(cacheObjSubType[`job_msg_del`], objJobPriority, j.UserID64, 0, time.Now().UTC(), b2)
}
- p2 := JobPayloadMsgDel{
- Delay: (10 * time.Second),
- ObjMsgID64: j.Trigger,
+ if id == cacheObjSubType[`msg_msg_job_gwithdraw_ack`] {
+ cwm, err := parseSubTypeMessageJobGWithdrawAck(m, rule.re)
+ logOnError(err, "jobGWithdraw : parseSubTypeMessageJobGWithdrawAck")
+ in, err := hex.DecodeString(cwm.Ref)
+ logOnError(err, "msgJobGWithdrawAck : DecodeString")
+
+ sha256 := sha256.Sum256([]byte(cfg.Telegram.Token))
+ sha128 := sha256[:aes.BlockSize]
+ c, err := aes.NewCipher(sha128)
+
+ out := make([]byte, len(in))
+
+ c.Decrypt(out, in)
+ id, n := binary.Uvarint(out[:8])
+ jobID64 := int64(id)
+ id, n = binary.Uvarint(out[8:16])
+ userID64 := int64(id)
+
+ if jobID64 == j.ID64 {
+ if userID64 == cwm.Msg.TGSenderUserID64 {
+ cmd := TGCommand{
+ Type: commandReplyMsg,
+ Text: "You cannot validate your own withdrawl",
+ FromMsgID64: cwm.Msg.MsgID64,
+ FromChatID64: cwm.Msg.ChatID64,
+ }
+ TGCmdQueue <- cmd
+ p.CleanupMsg = append(p.CleanupMsg, m)
+ b, err := json.Marshal(p)
+ err = setJobPayload(j.ID64, b)
+ logOnError(err, "jobGWithdraw : setJobPayload")
+ err = rescheduleJob(j.ID64, 0, time.Unix(maxUnixTimestamp, 0).UTC())
+ logOnError(err, "jobGWithdraw : rescheduleJob")
+ setJobCallback(j.ID64, int64(bot.Me.ID), cacheObjTypeId[`msg_job_gwithdraw_ack`])
+ return
+ } else {
+ p.Validated = true
+ for _, d := range p.CleanupMsg {
+ delmsg := tb.StoredMessage{
+ MessageID: fmt.Sprintf("%d", d.MsgID64),
+ ChatID: d.ChatID64,
+ }
+ err = bot.Delete(delmsg)
+ logOnError(err, "jobGWithdraw : Delete")
+ }
+ p.CleanupMsg = []ChatWarsMessage{}
+ delmsg := tb.StoredMessage{
+ MessageID: fmt.Sprintf("%d", cwm.Msg.MsgID64),
+ ChatID: cwm.Msg.ChatID64,
+ }
+ err = bot.Delete(delmsg)
+ logOnError(err, "jobGWithdraw : Delete")
+ }
+ } else {
+ err = rescheduleJob(j.ID64, 0, time.Unix(maxUnixTimestamp, 0).UTC())
+ logOnError(err, "jobGWithdraw : rescheduleJob")
+ setJobCallback(j.ID64, int64(bot.Me.ID), cacheObjTypeId[`msg_job_gwithdraw_ack`])
+ return
+ }
+
+ return
}
- b2, _ := json.Marshal(p2)
- createJob(cacheObjSubType[`job_msg_del`], objJobPriority, j.UserID64, 0, time.Now().UTC(), b2)
}
}
@@ -1581,6 +1682,7 @@ func jobGWithdraw(j Job) {
b, _ := json.Marshal(p)
id, err := createJob(cacheObjSubType[`job_gwithdraw`], objJobPriority, j.UserID64, 0, time.Unix(maxUnixTimestamp, 0).UTC(), b)
logOnError(err, "jobGWithdraw : createJob")
+ setJobCallback(id, int64(bot.Me.ID), cacheObjTypeId[`msg_job_gwithdraw_ack`])
sha256 := sha256.Sum256([]byte(cfg.Telegram.Token))
sha128 := sha256[:aes.BlockSize]
@@ -1590,7 +1692,7 @@ func jobGWithdraw(j Job) {
buf := make([]byte, 8)
binary.LittleEndian.PutUint64(buf, uint64(id))
in = append(in, buf...)
- binary.LittleEndian.PutUint64(buf, uint64(j.UserID64))
+ binary.LittleEndian.PutUint64(buf, uint64(p.UserID64))
in = append(in, buf...)
out := make([]byte, len(in))
@@ -1605,7 +1707,10 @@ func jobGWithdraw(j Job) {
b, err = json.Marshal(p)
log.Printf("jobGWithdraw[%d] : %s\n", string(b))
- msg := fmt.Sprintf("Click to validate @%s's withdrawal of%s
\n/withdraw_%s", p.User, stock, string(ref))
+ u, err := bot.ChatByID(fmt.Sprintf("%d", p.UserID64))
+ logOnError(err, "jobGWithdraw : ChatByID")
+
+ msg := fmt.Sprintf("Click to validate @%s's withdrawal of%s
\n/withdraw_%s", u.Username, stock, string(ref))
cmd := TGCommand{
Type: commandReplyMsg,
@@ -1633,27 +1738,6 @@ func jobGWithdraw(j Job) {
return
}
-func msgJobGWithdrawAck(cwm *ChatWarsMessageJobGWithdrawAck) error {
- in, err := hex.DecodeString(cwm.Ref)
- logOnError(err, "msgJobGWithdrawAck : DecodeString")
- if err != nil {
- return err
- }
-
- sha256 := sha256.Sum256([]byte(cfg.Telegram.Token))
- sha128 := sha256[:aes.BlockSize]
- c, err := aes.NewCipher(sha128)
-
- out := make([]byte, len(in))
-
- c.Decrypt(out, in)
- ref := hex.EncodeToString(out)
- log.Printf("msgJobGWithdrawAck : out string : %s.\n", ref)
-
- return nil
-
-}
-
func jobSetDef(j Job) {
var p JobPayloadSetDef
err := setJobStart(j.ID64)
diff --git a/workers.go b/workers.go
index 8e0f41a..8b2f023 100644
--- a/workers.go
+++ b/workers.go
@@ -506,10 +506,8 @@ func SQLIdentifyMsgWorker(id int, objIds <-chan int64) {
err = setClientIdle(m.TGUserID64, m.Date)
logOnError(err, "SQLIdentifyMsgWorker["+strconv.Itoa(id)+"] : setClientIdle")
case cacheObjSubType[`msg_job_gwithdraw_ack`]:
- cwm, err := parseSubTypeMessageJobGWithdrawAck(m, rule.re)
+ _, err := parseSubTypeMessageJobGWithdrawAck(m, rule.re)
logOnError(err, "SQLIdentifyMsgWorker["+strconv.Itoa(id)+"] : Parsing cacheObjSubType[`msg_quest_res`]")
- err = msgJobGWithdrawAck(cwm)
- logOnError(err, "SQLIdentifyMsgWorker["+strconv.Itoa(id)+"] : msgJobGWithdrawAck")
default:
//log.Printf("SQLIdentifyMsgWorker["+strconv.Itoa(id)+"] : Unknwon message type in rule %d : %d (%d)\n%s\n", msgParsingRules[i].ID, msgParsingRules[i].MsgTypeID64, objId, m.Text)
}
@@ -523,6 +521,15 @@ func SQLIdentifyMsgWorker(id int, objIds <-chan int64) {
mc1[rule.MsgTypeID64] = nil
}
}
+ if mc1, mok1 := callbacks[int64(bot.Me.ID)]; mok1 {
+ if mc2, mok2 := mc1[rule.MsgTypeID64]; mok2 {
+ for j := range mc2 {
+ err := rescheduleJob(mc2[j], m.ObjID64, time.Now().UTC())
+ logOnError(err, "SQLIdentifyMsgWorker["+strconv.Itoa(id)+"] : callbacks triggering")
+ }
+ mc1[rule.MsgTypeID64] = nil
+ }
+ }
muxCallbacks.Unlock()
}
}