mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-02-05 17:47:05 +01:00
implement mail locking
This commit is contained in:
@@ -12,12 +12,14 @@ type OperateMailOperation uint8
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
OPERATE_MAIL_DELETE = 0x01
|
OPERATE_MAIL_DELETE = 0x01
|
||||||
|
OPERATE_MAIL_LOCK = 0x02
|
||||||
|
OPERATE_MAIL_UNLOCK = 0x03
|
||||||
OPERATE_MAIL_ACQUIRE_ITEM = 0x05
|
OPERATE_MAIL_ACQUIRE_ITEM = 0x05
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgMhfOprtMail represents the MSG_MHF_OPRT_MAIL
|
// MsgMhfOprtMail represents the MSG_MHF_OPRT_MAIL
|
||||||
type MsgMhfOprtMail struct {
|
type MsgMhfOprtMail struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
AccIndex uint8
|
AccIndex uint8
|
||||||
Index uint8
|
Index uint8
|
||||||
Operation OperateMailOperation
|
Operation OperateMailOperation
|
||||||
@@ -34,7 +36,7 @@ func (m *MsgMhfOprtMail) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgMhfOprtMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgMhfOprtMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.AccIndex = bf.ReadUint8()
|
m.AccIndex = bf.ReadUint8()
|
||||||
m.Index = bf.ReadUint8()
|
m.Index = bf.ReadUint8()
|
||||||
m.Operation = OperateMailOperation(bf.ReadUint8())
|
m.Operation = OperateMailOperation(bf.ReadUint8())
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/Solenataris/Erupe/common/stringsupport"
|
|
||||||
"github.com/Solenataris/Erupe/network/binpacket"
|
"github.com/Solenataris/Erupe/network/binpacket"
|
||||||
"github.com/Solenataris/Erupe/network/mhfpacket"
|
"github.com/Solenataris/Erupe/network/mhfpacket"
|
||||||
"github.com/Andoryuuta/byteframe"
|
"github.com/Andoryuuta/byteframe"
|
||||||
@@ -19,9 +18,10 @@ type Mail struct {
|
|||||||
Body string `db:"body"`
|
Body string `db:"body"`
|
||||||
Read bool `db:"read"`
|
Read bool `db:"read"`
|
||||||
Deleted bool `db:"deleted"`
|
Deleted bool `db:"deleted"`
|
||||||
|
Locked bool `db:"locked"`
|
||||||
AttachedItemReceived bool `db:"attached_item_received"`
|
AttachedItemReceived bool `db:"attached_item_received"`
|
||||||
AttachedItemID *uint16 `db:"attached_item"`
|
AttachedItemID uint16 `db:"attached_item"`
|
||||||
AttachedItemAmount int16 `db:"attached_item_amount"`
|
AttachedItemAmount uint16 `db:"attached_item_amount"`
|
||||||
CreatedAt time.Time `db:"created_at"`
|
CreatedAt time.Time `db:"created_at"`
|
||||||
IsGuildInvite bool `db:"is_guild_invite"`
|
IsGuildInvite bool `db:"is_guild_invite"`
|
||||||
SenderName string `db:"sender_name"`
|
SenderName string `db:"sender_name"`
|
||||||
@@ -49,8 +49,8 @@ func (m *Mail) Send(s *Session, transaction *sql.Tx) error {
|
|||||||
zap.Uint32("recipientID", m.RecipientID),
|
zap.Uint32("recipientID", m.RecipientID),
|
||||||
zap.String("subject", m.Subject),
|
zap.String("subject", m.Subject),
|
||||||
zap.String("body", m.Body),
|
zap.String("body", m.Body),
|
||||||
zap.Uint16p("itemID", m.AttachedItemID),
|
zap.Uint16("itemID", m.AttachedItemID),
|
||||||
zap.Int16("itemAmount", m.AttachedItemAmount),
|
zap.Uint16("itemAmount", m.AttachedItemAmount),
|
||||||
zap.Bool("isGuildInvite", m.IsGuildInvite),
|
zap.Bool("isGuildInvite", m.IsGuildInvite),
|
||||||
)
|
)
|
||||||
return err
|
return err
|
||||||
@@ -110,6 +110,23 @@ func (m *Mail) MarkAcquired(s *Session) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (m *Mail) MarkLocked(s *Session, locked bool) error {
|
||||||
|
_, err := s.server.db.Exec(`
|
||||||
|
UPDATE mail SET locked = $1 WHERE id = $2
|
||||||
|
`, locked, m.ID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Error(
|
||||||
|
"failed to mark mail as locked",
|
||||||
|
zap.Error(err),
|
||||||
|
zap.Int("mailID", m.ID),
|
||||||
|
)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func GetMailListForCharacter(s *Session, charID uint32) ([]Mail, error) {
|
func GetMailListForCharacter(s *Session, charID uint32) ([]Mail, error) {
|
||||||
rows, err := s.server.db.Queryx(`
|
rows, err := s.server.db.Queryx(`
|
||||||
SELECT
|
SELECT
|
||||||
@@ -124,6 +141,7 @@ func GetMailListForCharacter(s *Session, charID uint32) ([]Mail, error) {
|
|||||||
m.created_at,
|
m.created_at,
|
||||||
m.is_guild_invite,
|
m.is_guild_invite,
|
||||||
m.deleted,
|
m.deleted,
|
||||||
|
m.locked,
|
||||||
c.name as sender_name
|
c.name as sender_name
|
||||||
FROM mail m
|
FROM mail m
|
||||||
JOIN characters c ON c.id = m.sender_id
|
JOIN characters c ON c.id = m.sender_id
|
||||||
@@ -171,6 +189,7 @@ func GetMailByID(s *Session, ID int) (*Mail, error) {
|
|||||||
m.created_at,
|
m.created_at,
|
||||||
m.is_guild_invite,
|
m.is_guild_invite,
|
||||||
m.deleted,
|
m.deleted,
|
||||||
|
m.locked,
|
||||||
c.name as sender_name
|
c.name as sender_name
|
||||||
FROM mail m
|
FROM mail m
|
||||||
JOIN characters c ON c.id = m.sender_id
|
JOIN characters c ON c.id = m.sender_id
|
||||||
@@ -255,8 +274,9 @@ func handleMsgMhfReadMail(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
_ = mail.MarkRead(s)
|
_ = mail.MarkRead(s)
|
||||||
|
|
||||||
bf := byteframe.NewByteFrame()
|
bf := byteframe.NewByteFrame()
|
||||||
bodyBytes, _ := stringsupport.ConvertUTF8ToShiftJIS(mail.Body)
|
|
||||||
bf.WriteNullTerminatedBytes(bodyBytes)
|
body := s.clientContext.StrConv.MustEncode(mail.Body)
|
||||||
|
bf.WriteNullTerminatedBytes(body)
|
||||||
|
|
||||||
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
doAckBufSucceed(s, pkt.AckHandle, bf.Data())
|
||||||
}
|
}
|
||||||
@@ -286,9 +306,10 @@ func handleMsgMhfListMail(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
s.mailList[accIndex] = m.ID
|
s.mailList[accIndex] = m.ID
|
||||||
s.mailAccIndex++
|
s.mailAccIndex++
|
||||||
|
|
||||||
itemAttached := m.AttachedItemID != nil
|
|
||||||
subjectBytes, _ := stringsupport.ConvertUTF8ToShiftJIS(m.Subject)
|
itemAttached := m.AttachedItemID != 0
|
||||||
senderNameBytes, _ := stringsupport.ConvertUTF8ToShiftJIS(m.SenderName)
|
subject := s.clientContext.StrConv.MustEncode(m.Subject)
|
||||||
|
sender := s.clientContext.StrConv.MustEncode(m.SenderName)
|
||||||
|
|
||||||
msg.WriteUint32(m.SenderID)
|
msg.WriteUint32(m.SenderID)
|
||||||
msg.WriteUint32(uint32(m.CreatedAt.Unix()))
|
msg.WriteUint32(uint32(m.CreatedAt.Unix()))
|
||||||
@@ -302,28 +323,34 @@ func handleMsgMhfListMail(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
flags |= 0x01
|
flags |= 0x01
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if m.Locked {
|
||||||
|
flags |= 0x02
|
||||||
|
}
|
||||||
|
|
||||||
|
// System message, hides ID
|
||||||
|
// flags |= 0x04
|
||||||
|
|
||||||
|
// Mitigate game crash
|
||||||
|
flags |= 0x08
|
||||||
if m.AttachedItemReceived {
|
if m.AttachedItemReceived {
|
||||||
flags |= 0x08
|
// flags |= 0x08
|
||||||
}
|
}
|
||||||
|
|
||||||
if m.IsGuildInvite {
|
if m.IsGuildInvite {
|
||||||
// Guild Invite
|
|
||||||
flags |= 0x10
|
flags |= 0x10
|
||||||
|
|
||||||
// System message?
|
|
||||||
flags |= 0x04
|
|
||||||
}
|
}
|
||||||
|
|
||||||
msg.WriteUint8(flags)
|
msg.WriteUint8(flags)
|
||||||
msg.WriteBool(itemAttached)
|
msg.WriteBool(itemAttached)
|
||||||
msg.WriteUint8(uint8(len(subjectBytes)+1))
|
msg.WriteUint8(uint8(len(subject)+1))
|
||||||
msg.WriteUint8(uint8(len(senderNameBytes)+1))
|
msg.WriteUint8(uint8(len(sender)+1))
|
||||||
msg.WriteNullTerminatedBytes(subjectBytes)
|
msg.WriteNullTerminatedBytes(subject)
|
||||||
msg.WriteNullTerminatedBytes(senderNameBytes)
|
msg.WriteNullTerminatedBytes(sender)
|
||||||
|
|
||||||
|
// TODO: The game will crash if it attempts to receive items
|
||||||
if itemAttached {
|
if itemAttached {
|
||||||
msg.WriteInt16(m.AttachedItemAmount)
|
msg.WriteUint16(m.AttachedItemAmount)
|
||||||
msg.WriteUint16(*m.AttachedItemID)
|
msg.WriteUint16(m.AttachedItemID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,6 +374,18 @@ func handleMsgMhfOprtMail(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
doAckSimpleFail(s, pkt.AckHandle, nil)
|
doAckSimpleFail(s, pkt.AckHandle, nil)
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
case mhfpacket.OPERATE_MAIL_LOCK:
|
||||||
|
err = mail.MarkLocked(s, true)
|
||||||
|
if err != nil {
|
||||||
|
doAckSimpleFail(s, pkt.AckHandle, nil)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
case mhfpacket.OPERATE_MAIL_UNLOCK:
|
||||||
|
err = mail.MarkLocked(s, false)
|
||||||
|
if err != nil {
|
||||||
|
doAckSimpleFail(s, pkt.AckHandle, nil)
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
case mhfpacket.OPERATE_MAIL_ACQUIRE_ITEM:
|
case mhfpacket.OPERATE_MAIL_ACQUIRE_ITEM:
|
||||||
err = mail.MarkAcquired(s)
|
err = mail.MarkAcquired(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user