Implement MsgSysEnumerateStage w/ stage map

This commit is contained in:
Andrew Gutekanst
2020-01-22 17:53:27 -05:00
parent b898614ddc
commit fa245e53fb
4 changed files with 62 additions and 10 deletions

View File

@@ -6,7 +6,12 @@ import (
)
// MsgSysEnumerateStage represents the MSG_SYS_ENUMERATE_STAGE
type MsgSysEnumerateStage struct{}
type MsgSysEnumerateStage struct {
AckHandle uint32
Unk0 uint8 // Hardcoded 1 in the binary
StageIDLength uint8
StageID string
}
// Opcode returns the ID associated with this packet type.
func (m *MsgSysEnumerateStage) Opcode() network.PacketID {
@@ -15,10 +20,14 @@ func (m *MsgSysEnumerateStage) Opcode() network.PacketID {
// Parse parses the packet from binary
func (m *MsgSysEnumerateStage) Parse(bf *byteframe.ByteFrame) error {
panic("Not implemented")
m.AckHandle = bf.ReadUint32()
m.Unk0 = bf.ReadUint8()
m.StageIDLength = bf.ReadUint8()
m.StageID = string(bf.ReadBytes(uint(m.StageIDLength)))
return nil
}
// Build builds a binary packet from the current data.
func (m *MsgSysEnumerateStage) Build(bf *byteframe.ByteFrame) error {
panic("Not implemented")
}
}

View File

@@ -32,8 +32,8 @@ type Server struct {
isShuttingDown bool
gameObjectLock sync.Mutex
gameObjectCount uint32
stagesLock sync.RWMutex
stages map[string]*Stage
}
// NewServer creates a new Server type.
@@ -45,7 +45,12 @@ func NewServer(config *Config) *Server {
acceptConns: make(chan net.Conn),
deleteConns: make(chan net.Conn),
sessions: make(map[net.Conn]*Session),
stages: make(map[string]*Stage),
}
// Default town stage that clients try to enter without creating.
s.stages["sl1Ns200p0a0u0"] = &Stage{}
return s
}

View File

@@ -9,6 +9,7 @@ import (
"github.com/Andoryuuta/Erupe/network/mhfpacket"
"github.com/Andoryuuta/byteframe"
"go.uber.org/zap"
"golang.org/x/text/encoding/japanese"
"golang.org/x/text/transform"
)
@@ -285,7 +286,25 @@ func handleMsgSysGetStageBinary(s *Session, p mhfpacket.MHFPacket) {}
func handleMsgSysEnumerateClient(s *Session, p mhfpacket.MHFPacket) {}
func handleMsgSysEnumerateStage(s *Session, p mhfpacket.MHFPacket) {}
func handleMsgSysEnumerateStage(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysEnumerateStage)
// Read-lock the stages.
s.server.stagesLock.RLock()
defer s.server.stagesLock.RUnlock()
// Build the response
resp := byteframe.NewByteFrame()
resp.WriteUint16(uint16(len(s.server.stages)))
for sid := range s.server.stages {
// Couldn't find the parsing code in the client, unk purpose & sizes:
resp.WriteBytes([]byte{0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x04, 0x00})
resp.WriteUint8(uint8(len(sid)))
resp.WriteBytes([]byte(sid))
}
doSizedAckResp(s, pkt.AckHandle, resp.Data())
}
func handleMsgSysCreateMutex(s *Session, p mhfpacket.MHFPacket) {}
@@ -322,11 +341,21 @@ func handleMsgSysNotifyRegister(s *Session, p mhfpacket.MHFPacket) {}
func handleMsgSysCreateObject(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysCreateObject)
// Get the current stage.
s.server.stagesLock.RLock()
defer s.server.stagesLock.RUnlock()
stage, ok := s.server.stages[s.stageID]
if !ok {
s.logger.Fatal("StageID not in the stages map!", zap.String("stageID", s.stageID))
}
// Lock the stage.
stage.Lock()
defer stage.Unlock()
// Make a new object ID.
s.server.gameObjectLock.Lock()
objID := s.server.gameObjectCount
s.server.gameObjectCount++
s.server.gameObjectLock.Unlock()
objID := stage.gameObjectCount
stage.gameObjectCount++
resp := byteframe.NewByteFrame()
resp.WriteUint32(0) // Unk, is this echoed back from pkt.Unk0?

View File

@@ -0,0 +1,9 @@
package channelserver
import "sync"
// Stage holds stage-specific information
type Stage struct {
sync.RWMutex
gameObjectCount uint32
}