support SJIS mail (#15)

This commit is contained in:
wish
2022-08-04 01:15:04 +10:00
committed by GitHub
parent af2cd5cd7c
commit 6424a5c639
5 changed files with 61 additions and 66 deletions

View File

@@ -16,6 +16,7 @@
"FestaEvent": 0, "FestaEvent": 0,
"TournamentEvent": 0, "TournamentEvent": 0,
"MezFesEvent": true, "MezFesEvent": true,
"DisableMailItems": true,
"SaveDumps": { "SaveDumps": {
"Enabled": true, "Enabled": true,
"OutputDir": "savedata" "OutputDir": "savedata"

View File

@@ -36,6 +36,7 @@ type DevModeOptions struct {
FestaEvent int // Hunter's Festa event status FestaEvent int // Hunter's Festa event status
TournamentEvent int // VS Tournament event status TournamentEvent int // VS Tournament event status
MezFesEvent bool // MezFes status MezFesEvent bool // MezFes status
DisableMailItems bool // Hack to prevent english versions of MHF from crashing
SaveDumps SaveDumpOptions SaveDumps SaveDumpOptions
} }

View File

@@ -1,20 +1,20 @@
package mhfpacket package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
) )
type OperateMailOperation uint8 type OperateMailOperation uint8
const ( const (
OPERATE_MAIL_DELETE = 0x01 OPERATE_MAIL_DELETE = 0x01
OPERATE_MAIL_LOCK = 0x02 OPERATE_MAIL_LOCK = 0x02
OPERATE_MAIL_UNLOCK = 0x03 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
@@ -23,10 +23,10 @@ type MsgMhfOprtMail struct {
AccIndex uint8 AccIndex uint8
Index uint8 Index uint8
Operation OperateMailOperation Operation OperateMailOperation
Unk0 uint8 Unk0 uint8
Data []byte Data []byte
Amount uint16 Amount uint16
ItemID uint16 ItemID uint16
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -40,12 +40,11 @@ func (m *MsgMhfOprtMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientCon
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())
m.Unk0 = bf.ReadUint8() m.Unk0 = bf.ReadUint8()
switch m.Operation { if m.Operation == OPERATE_MAIL_ACQUIRE_ITEM {
case OPERATE_MAIL_ACQUIRE_ITEM: m.Amount = bf.ReadUint16()
m.Amount = bf.ReadUint16() m.ItemID = bf.ReadUint16()
m.ItemID = bf.ReadUint16() }
}
return nil return nil
} }

View File

@@ -1,23 +1,24 @@
package mhfpacket package mhfpacket
import ( import (
"errors" "errors"
"erupe-ce/common/stringsupport"
"erupe-ce/network/clientctx"
"erupe-ce/network"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
"erupe-ce/network"
"erupe-ce/network/clientctx"
) )
// MsgMhfSendMail represents the MSG_MHF_SEND_MAIL // MsgMhfSendMail represents the MSG_MHF_SEND_MAIL
type MsgMhfSendMail struct { type MsgMhfSendMail struct {
AckHandle uint32 AckHandle uint32
RecipientID uint32 RecipientID uint32
SubjectLength uint16 SubjectLength uint16
BodyLength uint16 BodyLength uint16
Quantity uint32 Quantity uint32
ItemID uint16 ItemID uint16
Subject []byte Subject string
Body []byte Body string
} }
// Opcode returns the ID associated with this packet type. // Opcode returns the ID associated with this packet type.
@@ -27,15 +28,15 @@ func (m *MsgMhfSendMail) Opcode() network.PacketID {
// Parse parses the packet from binary // Parse parses the packet from binary
func (m *MsgMhfSendMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { func (m *MsgMhfSendMail) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
m.AckHandle = bf.ReadUint32() m.AckHandle = bf.ReadUint32()
m.RecipientID = bf.ReadUint32() m.RecipientID = bf.ReadUint32()
m.SubjectLength = bf.ReadUint16() m.SubjectLength = bf.ReadUint16()
m.BodyLength = bf.ReadUint16() m.BodyLength = bf.ReadUint16()
m.Quantity = bf.ReadUint32() m.Quantity = bf.ReadUint32()
m.ItemID = bf.ReadUint16() m.ItemID = bf.ReadUint16()
m.Subject = bf.ReadNullTerminatedBytes() m.Subject = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
m.Body = bf.ReadNullTerminatedBytes() m.Body = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
return nil return nil
} }
// Build builds a binary packet from the current data. // Build builds a binary packet from the current data.

View File

@@ -2,6 +2,7 @@ package channelserver
import ( import (
"database/sql" "database/sql"
"erupe-ce/common/stringsupport"
"time" "time"
"erupe-ce/common/byteframe" "erupe-ce/common/byteframe"
@@ -275,7 +276,7 @@ func handleMsgMhfReadMail(s *Session, p mhfpacket.MHFPacket) {
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
body := s.clientContext.StrConv.MustEncode(mail.Body) body := stringsupport.UTF8ToSJIS(mail.Body)
bf.WriteNullTerminatedBytes(body) bf.WriteNullTerminatedBytes(body)
doAckBufSucceed(s, pkt.AckHandle, bf.Data()) doAckBufSucceed(s, pkt.AckHandle, bf.Data())
@@ -307,13 +308,11 @@ func handleMsgMhfListMail(s *Session, p mhfpacket.MHFPacket) {
s.mailAccIndex++ s.mailAccIndex++
itemAttached := m.AttachedItemID != 0 itemAttached := m.AttachedItemID != 0
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()))
msg.WriteUint8(uint8(accIndex)) msg.WriteUint8(accIndex)
msg.WriteUint8(uint8(i)) msg.WriteUint8(uint8(i))
flags := uint8(0x00) flags := uint8(0x00)
@@ -329,8 +328,15 @@ func handleMsgMhfListMail(s *Session, p mhfpacket.MHFPacket) {
// System message, hides ID // System message, hides ID
// flags |= 0x04 // flags |= 0x04
if m.AttachedItemReceived { // Workaround until EN mail items are patched
flags |= 0x08 if s.server.erupeConfig.DevMode && s.server.erupeConfig.DevModeOptions.DisableMailItems {
if itemAttached {
flags |= 0x08
}
} else {
if m.AttachedItemReceived {
flags |= 0x08
}
} }
if m.IsGuildInvite { if m.IsGuildInvite {
@@ -339,11 +345,10 @@ func handleMsgMhfListMail(s *Session, p mhfpacket.MHFPacket) {
msg.WriteUint8(flags) msg.WriteUint8(flags)
msg.WriteBool(itemAttached) msg.WriteBool(itemAttached)
msg.WriteUint8(uint8(len(subject) + 1)) msg.WriteUint8(16)
msg.WriteUint8(uint8(len(sender) + 1)) msg.WriteUint8(21)
msg.WriteNullTerminatedBytes(subject) msg.WriteBytes(stringsupport.PaddedString(m.Subject, 16, true))
msg.WriteNullTerminatedBytes(sender) msg.WriteBytes(stringsupport.PaddedString(m.SenderName, 21, true))
if itemAttached { if itemAttached {
msg.WriteUint16(m.AttachedItemAmount) msg.WriteUint16(m.AttachedItemAmount)
msg.WriteUint16(m.AttachedItemID) msg.WriteUint16(m.AttachedItemID)
@@ -358,34 +363,22 @@ func handleMsgMhfOprtMail(s *Session, p mhfpacket.MHFPacket) {
mail, err := GetMailByID(s, s.mailList[pkt.AccIndex]) mail, err := GetMailByID(s, s.mailList[pkt.AccIndex])
if err != nil { if err != nil {
doAckSimpleFail(s, pkt.AckHandle, nil)
panic(err) panic(err)
} }
switch mhfpacket.OperateMailOperation(pkt.Operation) {
switch pkt.Operation {
case mhfpacket.OPERATE_MAIL_DELETE: case mhfpacket.OPERATE_MAIL_DELETE:
err = mail.MarkDeleted(s) err = mail.MarkDeleted(s)
if err != nil {
doAckSimpleFail(s, pkt.AckHandle, nil)
panic(err)
}
case mhfpacket.OPERATE_MAIL_LOCK: case mhfpacket.OPERATE_MAIL_LOCK:
err = mail.MarkLocked(s, true) err = mail.MarkLocked(s, true)
if err != nil {
doAckSimpleFail(s, pkt.AckHandle, nil)
panic(err)
}
case mhfpacket.OPERATE_MAIL_UNLOCK: case mhfpacket.OPERATE_MAIL_UNLOCK:
err = mail.MarkLocked(s, false) 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 { }
doAckSimpleFail(s, pkt.AckHandle, nil)
panic(err) if err != nil {
} panic(err)
} }
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4)) doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))