From 08a7b91e11800b9e4460e654aa12da4078b75031 Mon Sep 17 00:00:00 2001 From: wish Date: Fri, 5 Aug 2022 01:57:56 +1000 Subject: [PATCH 1/5] handle TransitMessage --- main.go | 8 ++- network/mhfpacket/msg_mhf_transit_message.go | 28 ++++---- server/channelserver/handlers.go | 73 ++++++++++++++++++-- server/channelserver/sys_channel_server.go | 6 +- 4 files changed, 94 insertions(+), 21 deletions(-) diff --git a/main.go b/main.go index 3638a0093..c5ac726b3 100644 --- a/main.go +++ b/main.go @@ -180,7 +180,13 @@ func main() { DB: db, DiscordBot: discordBot, }) - err = c.Start(int(ce.Port)) + if ee.IP == "" { + c.IP = erupeConfig.Host + } else { + c.IP = ee.IP + } + c.Port = ce.Port + err = c.Start() if err != nil { preventClose(fmt.Sprintf("Failed to start channel server: %s", err.Error())) } else { diff --git a/network/mhfpacket/msg_mhf_transit_message.go b/network/mhfpacket/msg_mhf_transit_message.go index 32dba46d6..1d15c6d42 100644 --- a/network/mhfpacket/msg_mhf_transit_message.go +++ b/network/mhfpacket/msg_mhf_transit_message.go @@ -1,20 +1,20 @@ package mhfpacket import ( - "errors" + "errors" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgMhfTransitMessage represents the MSG_MHF_TRANSIT_MESSAGE type MsgMhfTransitMessage struct { - AckHandle uint32 - Unk0 uint8 - Unk1 uint8 - Unk2 uint16 - MessageData []byte + AckHandle uint32 + Unk0 uint8 + Unk1 uint8 + SearchType uint16 + MessageData []byte } // Opcode returns the ID associated with this packet type. @@ -24,12 +24,12 @@ func (m *MsgMhfTransitMessage) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgMhfTransitMessage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - m.AckHandle = bf.ReadUint32() - m.Unk0 = bf.ReadUint8() - m.Unk1 = bf.ReadUint8() - m.Unk2 = bf.ReadUint16() - m.MessageData = bf.ReadBytes(uint(bf.ReadUint16())) - return nil + m.AckHandle = bf.ReadUint32() + m.Unk0 = bf.ReadUint8() + m.Unk1 = bf.ReadUint8() + m.SearchType = bf.ReadUint16() + m.MessageData = bf.ReadBytes(uint(bf.ReadUint16())) + return nil } // Build builds a binary packet from the current data. diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index 60e120c42..b4d979c7e 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -4,7 +4,11 @@ import ( "bytes" "encoding/binary" "encoding/hex" + "erupe-ce/common/stringsupport" "fmt" + "io" + "net" + "strings" "io/ioutil" "math/bits" @@ -341,10 +345,71 @@ func handleMsgSysRightsReload(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfTransitMessage) - // TODO: figure out what this is supposed to return - // probably what world+land the targeted character is on? - // stubbed response will just say user not found - doAckBufSucceed(s, pkt.AckHandle, make([]byte, 4)) + // 1 -> CID + // 2 -> Name + // 4 -> Group + resp := byteframe.NewByteFrame() + resp.WriteUint16(0) + var count uint16 + switch pkt.SearchType { + case 1: + bf := byteframe.NewByteFrameFromBytes(pkt.MessageData) + CharID := bf.ReadUint32() + for _, c := range s.server.Channels { + for _, session := range c.sessions { + if session.charID == CharID { + count++ + sessionName := stringsupport.UTF8ToSJIS(session.Name) + sessionStage := stringsupport.UTF8ToSJIS(session.stageID) + resp.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(c.IP).To4())) + resp.WriteUint16(c.Port) + resp.WriteUint32(session.charID) + resp.WriteBool(true) + resp.WriteUint8(uint8(len(sessionName) + 1)) + resp.WriteUint16(0x180) // lenUserBinary + resp.WriteBytes(make([]byte, 40)) + resp.WriteUint8(uint8(len(sessionStage) + 1)) + resp.WriteBytes(make([]byte, 8)) + resp.WriteNullTerminatedBytes(sessionName) + resp.WriteBytes(c.userBinaryParts[userBinaryPartID{charID: session.charID, index: 3}]) + resp.WriteNullTerminatedBytes(sessionStage) + } + } + } + case 2: + bf := byteframe.NewByteFrameFromBytes(pkt.MessageData) + bf.ReadUint16() // lenSearchTerm + bf.ReadUint16() // maxResults + bf.ReadUint8() // Unk + searchTerm := stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) + for _, c := range s.server.Channels { + for _, session := range c.sessions { + if count == 100 { + break + } + if strings.Contains(session.Name, searchTerm) { + count++ + sessionName := stringsupport.UTF8ToSJIS(session.Name) + sessionStage := stringsupport.UTF8ToSJIS(session.stageID) + resp.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(c.IP).To4())) + resp.WriteUint16(c.Port) + resp.WriteUint32(session.charID) + resp.WriteBool(true) + resp.WriteUint8(uint8(len(sessionName) + 1)) + resp.WriteUint16(0x180) // lenUserBinary + resp.WriteBytes(make([]byte, 40)) + resp.WriteUint8(uint8(len(sessionStage) + 1)) + resp.WriteBytes(make([]byte, 8)) + resp.WriteNullTerminatedBytes(sessionName) + resp.WriteBytes(c.userBinaryParts[userBinaryPartID{charID: session.charID, index: 3}]) + resp.WriteNullTerminatedBytes(sessionStage) + } + } + } + } + resp.Seek(0, io.SeekStart) + resp.WriteUint16(count) + doAckBufSucceed(s, pkt.AckHandle, resp.Data()) } func handleMsgCaExchangeItem(s *Session, p mhfpacket.MHFPacket) {} diff --git a/server/channelserver/sys_channel_server.go b/server/channelserver/sys_channel_server.go index 69335280c..a23ec2834 100644 --- a/server/channelserver/sys_channel_server.go +++ b/server/channelserver/sys_channel_server.go @@ -54,6 +54,8 @@ type Server struct { sync.Mutex Channels []*Server ID uint16 + IP string + Port uint16 logger *zap.Logger db *sqlx.DB erupeConfig *config.Config @@ -196,8 +198,8 @@ func NewServer(config *Config) *Server { } // Start starts the server in a new goroutine. -func (s *Server) Start(port int) error { - l, err := net.Listen("tcp", fmt.Sprintf(":%d", port)) +func (s *Server) Start() error { + l, err := net.Listen("tcp", fmt.Sprintf(":%d", s.Port)) if err != nil { return err } From 820563dc4c4bad66269399a6627e520b8b6220b7 Mon Sep 17 00:00:00 2001 From: wish Date: Fri, 5 Aug 2022 07:39:37 +1000 Subject: [PATCH 2/5] matchmaking support --- .../mhfpacket/msg_sys_acquire_semaphore.go | 19 ++-- server/channelserver/handlers.go | 102 ++++++++++++++++-- server/channelserver/handlers_semaphore.go | 11 +- server/signserver/dsgn_resp.go | 2 +- 4 files changed, 118 insertions(+), 16 deletions(-) diff --git a/network/mhfpacket/msg_sys_acquire_semaphore.go b/network/mhfpacket/msg_sys_acquire_semaphore.go index 89b974ff4..2be7284d9 100644 --- a/network/mhfpacket/msg_sys_acquire_semaphore.go +++ b/network/mhfpacket/msg_sys_acquire_semaphore.go @@ -1,15 +1,19 @@ package mhfpacket -import ( - "errors" +import ( + "errors" + "erupe-ce/common/bfutil" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgSysAcquireSemaphore represents the MSG_SYS_ACQUIRE_SEMAPHORE -type MsgSysAcquireSemaphore struct{} +type MsgSysAcquireSemaphore struct { + AckHandle uint32 + SemaphoreID string +} // Opcode returns the ID associated with this packet type. func (m *MsgSysAcquireSemaphore) Opcode() network.PacketID { @@ -18,7 +22,10 @@ func (m *MsgSysAcquireSemaphore) Opcode() network.PacketID { // Parse parses the packet from binary func (m *MsgSysAcquireSemaphore) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { - return errors.New("NOT IMPLEMENTED") + m.AckHandle = bf.ReadUint32() + SemaphoreIDLength := bf.ReadUint8() + m.SemaphoreID = string(bfutil.UpToNull(bf.ReadBytes(uint(SemaphoreIDLength)))) + return nil } // Build builds a binary packet from the current data. diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index b4d979c7e..1cfe9e3ff 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -345,14 +345,11 @@ func handleMsgSysRightsReload(s *Session, p mhfpacket.MHFPacket) { func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgMhfTransitMessage) - // 1 -> CID - // 2 -> Name - // 4 -> Group resp := byteframe.NewByteFrame() resp.WriteUint16(0) var count uint16 switch pkt.SearchType { - case 1: + case 1: // CID bf := byteframe.NewByteFrameFromBytes(pkt.MessageData) CharID := bf.ReadUint32() for _, c := range s.server.Channels { @@ -366,17 +363,17 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { resp.WriteUint32(session.charID) resp.WriteBool(true) resp.WriteUint8(uint8(len(sessionName) + 1)) - resp.WriteUint16(0x180) // lenUserBinary + resp.WriteUint16(uint16(len(c.userBinaryParts[userBinaryPartID{charID: session.charID, index: 3}]))) resp.WriteBytes(make([]byte, 40)) resp.WriteUint8(uint8(len(sessionStage) + 1)) resp.WriteBytes(make([]byte, 8)) resp.WriteNullTerminatedBytes(sessionName) - resp.WriteBytes(c.userBinaryParts[userBinaryPartID{charID: session.charID, index: 3}]) + resp.WriteBytes(c.userBinaryParts[userBinaryPartID{session.charID, 3}]) resp.WriteNullTerminatedBytes(sessionStage) } } } - case 2: + case 2: // Name bf := byteframe.NewByteFrameFromBytes(pkt.MessageData) bf.ReadUint16() // lenSearchTerm bf.ReadUint16() // maxResults @@ -396,7 +393,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { resp.WriteUint32(session.charID) resp.WriteBool(true) resp.WriteUint8(uint8(len(sessionName) + 1)) - resp.WriteUint16(0x180) // lenUserBinary + resp.WriteUint16(uint16(len(c.userBinaryParts[userBinaryPartID{session.charID, 3}]))) resp.WriteBytes(make([]byte, 40)) resp.WriteUint8(uint8(len(sessionStage) + 1)) resp.WriteBytes(make([]byte, 8)) @@ -406,6 +403,95 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) { } } } + case 3: // Enumerate Party + bf := byteframe.NewByteFrameFromBytes(pkt.MessageData) + ip := bf.ReadBytes(4) + ipString := fmt.Sprintf("%d.%d.%d.%d", ip[3], ip[2], ip[1], ip[0]) + port := bf.ReadUint16() + bf.ReadUint16() // lenStage + maxResults := bf.ReadUint16() + bf.ReadBytes(1) + stageID := stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) + for _, c := range s.server.Channels { + if c.IP == ipString && c.Port == port { + for _, stage := range c.stages { + if stage.id == stageID { + if count == maxResults { + break + } + for session := range stage.clients { + count++ + sessionStage := stringsupport.UTF8ToSJIS(session.stageID) + sessionName := stringsupport.UTF8ToSJIS(session.Name) + resp.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(c.IP).To4())) + resp.WriteUint16(c.Port) + resp.WriteUint32(session.charID) + resp.WriteUint8(uint8(len(sessionStage) + 1)) + resp.WriteUint8(uint8(len(sessionName) + 1)) + resp.WriteUint8(0) + resp.WriteUint8(7) // lenBinary + resp.WriteBytes(make([]byte, 48)) + resp.WriteNullTerminatedBytes(sessionStage) + resp.WriteNullTerminatedBytes(sessionName) + resp.WriteUint16(999) // HR + resp.WriteUint16(999) // GR + resp.WriteBytes([]byte{0x06, 0x10, 0x00}) // Unk + } + } + } + } + } + case 4: // Find Party + bf := byteframe.NewByteFrameFromBytes(pkt.MessageData) + bf.ReadUint8() + maxResults := bf.ReadUint16() + bf.ReadUint8() + bf.ReadUint8() + partyType := bf.ReadUint16() + _ = bf.DataFromCurrent() // Restrictions + var stagePrefix string + switch partyType { + case 0: // Public Bar + stagePrefix = "sl2Ls210" + case 1: // Tokotoko Partnya + stagePrefix = "sl2Ls463" + case 2: // Hunting Prowess Match + stagePrefix = "sl2Ls286" + case 3: // Volpakkun Together + stagePrefix = "sl2Ls465" + case 5: // Quick Party + // Unk + } + for _, c := range s.server.Channels { + for _, stage := range c.stages { + if count == maxResults { + break + } + if strings.HasPrefix(stage.id, stagePrefix) { + count++ + sessionStage := stringsupport.UTF8ToSJIS(stage.id) + resp.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(c.IP).To4())) + resp.WriteUint16(c.Port) + + // TODO: This is half right, could be trimmed + resp.WriteUint16(0) + resp.WriteUint16(uint16(len(stage.clients))) + resp.WriteUint16(uint16(len(stage.clients))) + resp.WriteUint16(stage.maxPlayers) + resp.WriteUint16(0) + resp.WriteUint16(uint16(len(stage.clients))) + // + + resp.WriteUint16(uint16(len(sessionStage) + 1)) + resp.WriteUint8(1) + resp.WriteUint8(uint8(len(stage.rawBinaryData[stageBinaryKey{1, 1}]))) + resp.WriteBytes(make([]byte, 16)) + resp.WriteNullTerminatedBytes(sessionStage) + resp.WriteBytes([]byte{0x00}) + resp.WriteBytes(stage.rawBinaryData[stageBinaryKey{1, 1}]) + } + } + } } resp.Seek(0, io.SeekStart) resp.WriteUint16(count) diff --git a/server/channelserver/handlers_semaphore.go b/server/channelserver/handlers_semaphore.go index e7b9834ab..6659bd2da 100644 --- a/server/channelserver/handlers_semaphore.go +++ b/server/channelserver/handlers_semaphore.go @@ -124,7 +124,16 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) { } func handleMsgSysAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) { - //pkt := p.(*mhfpacket.MsgSysAcquireSemaphore) + pkt := p.(*mhfpacket.MsgSysAcquireSemaphore) + if sema, exists := s.server.semaphore[pkt.SemaphoreID]; exists { + sema.clients[s] = s.charID + bf := byteframe.NewByteFrame() + bf.WriteUint32(sema.id) + doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) + } else { + doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4)) + } + } func handleMsgSysReleaseSemaphore(s *Session, p mhfpacket.MHFPacket) { diff --git a/server/signserver/dsgn_resp.go b/server/signserver/dsgn_resp.go index fee38c1d3..80764c408 100644 --- a/server/signserver/dsgn_resp.go +++ b/server/signserver/dsgn_resp.go @@ -136,7 +136,7 @@ func (s *Session) makeSignInResp(uid int) []byte { bf.WriteUint32(uint32(channelserver.Time_Current_Adjusted().Add(24 * time.Hour * 7).Unix())) bf.WriteUint8(2) // Unk bf.WriteUint32(20) // Single tickets - bf.WriteUint32(0) // Group tickets + bf.WriteUint32(10) // Group tickets bf.WriteUint8(8) // Stalls open bf.WriteUint8(0xA) // Unk bf.WriteUint8(0x3) // Pachinko From 56841a5ab37e59c05f27d2f8f63388a515cf941b Mon Sep 17 00:00:00 2001 From: wish Date: Fri, 5 Aug 2022 07:42:45 +1000 Subject: [PATCH 3/5] add config option to toggle MF MP game --- config.json | 1 + config/config.go | 1 + server/signserver/dsgn_resp.go | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/config.json b/config.json index 976756597..29af1fb8d 100644 --- a/config.json +++ b/config.json @@ -17,6 +17,7 @@ "FestaEvent": 0, "TournamentEvent": 0, "MezFesEvent": true, + "MezFesAlt": false, "DisableMailItems": true, "DisableTokenCheck": false, "SaveDumps": { diff --git a/config/config.go b/config/config.go index 8b7daf7ee..b025e7a0a 100644 --- a/config/config.go +++ b/config/config.go @@ -37,6 +37,7 @@ type DevModeOptions struct { FestaEvent int // Hunter's Festa event status TournamentEvent int // VS Tournament event status MezFesEvent bool // MezFes status + MezFesAlt bool // Swaps out Volpakkun for Tokotoko DisableTokenCheck bool // Disables checking login token exists in the DB (security risk!) DisableMailItems bool // Hack to prevent english versions of MHF from crashing SaveDumps SaveDumpOptions diff --git a/server/signserver/dsgn_resp.go b/server/signserver/dsgn_resp.go index 80764c408..650188000 100644 --- a/server/signserver/dsgn_resp.go +++ b/server/signserver/dsgn_resp.go @@ -128,7 +128,7 @@ func (s *Session) makeSignInResp(uid int) []byte { bf.WriteUint32(0x0A5197DF) mezfes := s.server.erupeConfig.DevModeOptions.MezFesEvent - alt := false + alt := s.server.erupeConfig.DevModeOptions.MezFesAlt if mezfes { // Start time bf.WriteUint32(uint32(channelserver.Time_Current_Adjusted().Add(-5 * time.Minute).Unix())) From 09812fa81b220769a06a012c59f65b0f4b8ce4ea Mon Sep 17 00:00:00 2001 From: wish Date: Fri, 5 Aug 2022 16:38:42 +1000 Subject: [PATCH 4/5] stage improvements --- network/mhfpacket/msg_sys_enumerate_stage.go | 20 ++++++++-------- server/channelserver/handlers_stage.go | 24 +++++++++++--------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/network/mhfpacket/msg_sys_enumerate_stage.go b/network/mhfpacket/msg_sys_enumerate_stage.go index 802b385f5..925f8944d 100644 --- a/network/mhfpacket/msg_sys_enumerate_stage.go +++ b/network/mhfpacket/msg_sys_enumerate_stage.go @@ -1,19 +1,19 @@ package mhfpacket -import ( - "errors" +import ( + "errors" + "erupe-ce/common/stringsupport" - "erupe-ce/network/clientctx" - "erupe-ce/network" "erupe-ce/common/byteframe" + "erupe-ce/network" + "erupe-ce/network/clientctx" ) // MsgSysEnumerateStage represents the MSG_SYS_ENUMERATE_STAGE type MsgSysEnumerateStage struct { - AckHandle uint32 - Unk0 uint8 // Hardcoded 1 in the binary - StageIDLength uint8 - StageID string // NULL terminated string. + AckHandle uint32 + Unk0 uint8 // Hardcoded 1 in the binary + StageID string // NULL terminated string. } // Opcode returns the ID associated with this packet type. @@ -25,8 +25,8 @@ func (m *MsgSysEnumerateStage) Opcode() network.PacketID { func (m *MsgSysEnumerateStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error { m.AckHandle = bf.ReadUint32() m.Unk0 = bf.ReadUint8() - m.StageIDLength = bf.ReadUint8() - m.StageID = string(bf.ReadBytes(uint(m.StageIDLength))) + bf.ReadUint8() + m.StageID = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) return nil } diff --git a/server/channelserver/handlers_stage.go b/server/channelserver/handlers_stage.go index 4fcdcbfc2..81ddb36f4 100644 --- a/server/channelserver/handlers_stage.go +++ b/server/channelserver/handlers_stage.go @@ -2,6 +2,7 @@ package channelserver import ( "fmt" + "strings" "time" "erupe-ce/common/byteframe" @@ -198,22 +199,24 @@ func handleMsgSysLeaveStage(s *Session, p mhfpacket.MHFPacket) {} func handleMsgSysLockStage(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysLockStage) // TODO(Andoryuuta): What does this packet _actually_ do? + // I think this is supposed to mark a stage as no longer able to accept client reservations doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00}) } func handleMsgSysUnlockStage(s *Session, p mhfpacket.MHFPacket) { - s.reservationStage.RLock() - defer s.reservationStage.RUnlock() + if s.reservationStage != nil { + s.reservationStage.RLock() + defer s.reservationStage.RUnlock() - for charID := range s.reservationStage.reservedClientSlots { - session := s.server.FindSessionByCharID(charID) - session.QueueSendMHF(&mhfpacket.MsgSysStageDestruct{}) + for charID := range s.reservationStage.reservedClientSlots { + session := s.server.FindSessionByCharID(charID) + session.QueueSendMHF(&mhfpacket.MsgSysStageDestruct{}) + } + + delete(s.server.stages, s.reservationStage.id) } - s.server.Lock() - defer s.server.Unlock() - - delete(s.server.stages, s.reservationStage.id) + destructEmptyStages(s) } func handleMsgSysReserveStage(s *Session, p mhfpacket.MHFPacket) { @@ -366,8 +369,7 @@ func handleMsgSysEnumerateStage(s *Session, p mhfpacket.MHFPacket) { continue } - // Check for valid stage type - if sid[3:5] != "Qs" && sid[3:5] != "Ms" && sid[3:5] != "Ls" { + if !strings.Contains(stage.id, pkt.StageID) { continue } From 43beb462212c2e764f14b24016cd9536d6842850 Mon Sep 17 00:00:00 2001 From: wish Date: Fri, 5 Aug 2022 16:41:49 +1000 Subject: [PATCH 5/5] rename EnumerateStage variable --- network/mhfpacket/msg_sys_enumerate_stage.go | 8 ++++---- server/channelserver/handlers_stage.go | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/network/mhfpacket/msg_sys_enumerate_stage.go b/network/mhfpacket/msg_sys_enumerate_stage.go index 925f8944d..a3f125941 100644 --- a/network/mhfpacket/msg_sys_enumerate_stage.go +++ b/network/mhfpacket/msg_sys_enumerate_stage.go @@ -11,9 +11,9 @@ import ( // MsgSysEnumerateStage represents the MSG_SYS_ENUMERATE_STAGE type MsgSysEnumerateStage struct { - AckHandle uint32 - Unk0 uint8 // Hardcoded 1 in the binary - StageID string // NULL terminated string. + AckHandle uint32 + Unk0 uint8 // Hardcoded 1 in the binary + StagePrefix string // NULL terminated string. } // Opcode returns the ID associated with this packet type. @@ -26,7 +26,7 @@ func (m *MsgSysEnumerateStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Cli m.AckHandle = bf.ReadUint32() m.Unk0 = bf.ReadUint8() bf.ReadUint8() - m.StageID = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) + m.StagePrefix = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes()) return nil } diff --git a/server/channelserver/handlers_stage.go b/server/channelserver/handlers_stage.go index 81ddb36f4..4bf19d114 100644 --- a/server/channelserver/handlers_stage.go +++ b/server/channelserver/handlers_stage.go @@ -369,7 +369,7 @@ func handleMsgSysEnumerateStage(s *Session, p mhfpacket.MHFPacket) { continue } - if !strings.Contains(stage.id, pkt.StageID) { + if !strings.Contains(stage.id, pkt.StagePrefix) { continue }