feat(channelserver): implement monthly guild item claim tracking

Players could never claim monthly guild items because the handler
always returned 0x01 (claimed). Now tracks per-character per-type
(standard/HLC/EXC) claim timestamps in the stamps table, comparing
against the current month boundary to determine claim eligibility.

Adds MonthStart() to gametime, extends StampRepo with
GetMonthlyClaimed/SetMonthlyClaimed, and includes schema migration
31-monthly-items.sql.
This commit is contained in:
Houmgaor
2026-02-22 16:46:57 +01:00
parent 302453ce8e
commit 2acbb5d03a
11 changed files with 187 additions and 4 deletions

View File

@@ -383,15 +383,48 @@ func handleMsgMhfSetGuildManageRight(s *Session, p mhfpacket.MHFPacket) {
doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4))
}
// monthlyTypeString maps the packet's Type field to the DB column prefix.
func monthlyTypeString(t uint8) string {
switch t {
case 0:
return "monthly"
case 1:
return "monthly_hl"
case 2:
return "monthly_ex"
default:
return ""
}
}
func handleMsgMhfCheckMonthlyItem(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfCheckMonthlyItem)
typeStr := monthlyTypeString(pkt.Type)
if typeStr == "" {
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
return
}
claimed, err := s.server.stampRepo.GetMonthlyClaimed(s.charID, typeStr)
if err != nil || claimed.Before(TimeMonthStart()) {
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
return
}
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x01})
// TODO: Implement month-by-month tracker, 0 = Not claimed, 1 = Claimed
// Also handles HLC and EXC items, IDs = 064D, 076B
}
func handleMsgMhfAcquireMonthlyItem(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgMhfAcquireMonthlyItem)
typeStr := monthlyTypeString(pkt.Unk0)
if typeStr != "" {
if err := s.server.stampRepo.SetMonthlyClaimed(s.charID, typeStr, TimeAdjusted()); err != nil {
s.logger.Error("Failed to set monthly item claimed", zap.Error(err))
}
}
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
}