mirror of
https://github.com/Mezeporta/Erupe.git
synced 2025-12-16 08:55:31 +01:00
Implement stage binaries, stack locking, and logkeys
This commit is contained in:
@@ -6,7 +6,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// MsgSysGetStageBinary represents the MSG_SYS_GET_STAGE_BINARY
|
// MsgSysGetStageBinary represents the MSG_SYS_GET_STAGE_BINARY
|
||||||
type MsgSysGetStageBinary struct{}
|
type MsgSysGetStageBinary struct {
|
||||||
|
AckHandle uint32
|
||||||
|
BinaryType0 uint8
|
||||||
|
BinaryType1 uint8
|
||||||
|
Unk0 uint32 // Hardcoded 0
|
||||||
|
StageIDLength uint8
|
||||||
|
StageID string
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgSysGetStageBinary) Opcode() network.PacketID {
|
func (m *MsgSysGetStageBinary) Opcode() network.PacketID {
|
||||||
@@ -15,10 +22,16 @@ func (m *MsgSysGetStageBinary) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgSysGetStageBinary) Parse(bf *byteframe.ByteFrame) error {
|
func (m *MsgSysGetStageBinary) Parse(bf *byteframe.ByteFrame) error {
|
||||||
panic("Not implemented")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.BinaryType0 = bf.ReadUint8()
|
||||||
|
m.BinaryType1 = bf.ReadUint8()
|
||||||
|
m.Unk0 = bf.ReadUint32()
|
||||||
|
m.StageIDLength = bf.ReadUint8()
|
||||||
|
m.StageID = string(bf.ReadBytes(uint(m.StageIDLength)))
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
func (m *MsgSysGetStageBinary) Build(bf *byteframe.ByteFrame) error {
|
func (m *MsgSysGetStageBinary) Build(bf *byteframe.ByteFrame) error {
|
||||||
panic("Not implemented")
|
panic("Not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// MsgSysIssueLogkey represents the MSG_SYS_ISSUE_LOGKEY
|
// MsgSysIssueLogkey represents the MSG_SYS_ISSUE_LOGKEY
|
||||||
type MsgSysIssueLogkey struct{}
|
type MsgSysIssueLogkey struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint16 // Hardcoded 00 01 in binary
|
||||||
|
Unk1 uint16 // Hardcoded 0 in binary.
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgSysIssueLogkey) Opcode() network.PacketID {
|
func (m *MsgSysIssueLogkey) Opcode() network.PacketID {
|
||||||
@@ -15,10 +19,13 @@ func (m *MsgSysIssueLogkey) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgSysIssueLogkey) Parse(bf *byteframe.ByteFrame) error {
|
func (m *MsgSysIssueLogkey) Parse(bf *byteframe.ByteFrame) error {
|
||||||
panic("Not implemented")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint16()
|
||||||
|
m.Unk1 = bf.ReadUint16()
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
func (m *MsgSysIssueLogkey) Build(bf *byteframe.ByteFrame) error {
|
func (m *MsgSysIssueLogkey) Build(bf *byteframe.ByteFrame) error {
|
||||||
panic("Not implemented")
|
panic("Not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// MsgSysLockStage represents the MSG_SYS_LOCK_STAGE
|
// MsgSysLockStage represents the MSG_SYS_LOCK_STAGE
|
||||||
type MsgSysLockStage struct{}
|
type MsgSysLockStage struct {
|
||||||
|
AckHandle uint32
|
||||||
|
Unk0 uint8 // Hardcoded 1 in the binary
|
||||||
|
Unk1 uint8 // Hardcoded 1 in the binary
|
||||||
|
StageIDLength uint8
|
||||||
|
StageID string
|
||||||
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgSysLockStage) Opcode() network.PacketID {
|
func (m *MsgSysLockStage) Opcode() network.PacketID {
|
||||||
@@ -15,10 +21,15 @@ func (m *MsgSysLockStage) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgSysLockStage) Parse(bf *byteframe.ByteFrame) error {
|
func (m *MsgSysLockStage) Parse(bf *byteframe.ByteFrame) error {
|
||||||
panic("Not implemented")
|
m.AckHandle = bf.ReadUint32()
|
||||||
|
m.Unk0 = bf.ReadUint8()
|
||||||
|
m.Unk1 = 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.
|
// Build builds a binary packet from the current data.
|
||||||
func (m *MsgSysLockStage) Build(bf *byteframe.ByteFrame) error {
|
func (m *MsgSysLockStage) Build(bf *byteframe.ByteFrame) error {
|
||||||
panic("Not implemented")
|
panic("Not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ import (
|
|||||||
|
|
||||||
// MsgSysSetStageBinary represents the MSG_SYS_SET_STAGE_BINARY
|
// MsgSysSetStageBinary represents the MSG_SYS_SET_STAGE_BINARY
|
||||||
type MsgSysSetStageBinary struct {
|
type MsgSysSetStageBinary struct {
|
||||||
Unk0 uint8
|
BinaryType0 uint8
|
||||||
BinaryType uint8 // Index
|
BinaryType1 uint8 // Index
|
||||||
StageIDLength uint8 // <= 0x20
|
StageIDLength uint8 // <= 0x20
|
||||||
DataSize uint16 // <= 0x400
|
DataSize uint16 // <= 0x400
|
||||||
StageID string
|
StageID string
|
||||||
@@ -22,8 +22,8 @@ func (m *MsgSysSetStageBinary) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgSysSetStageBinary) Parse(bf *byteframe.ByteFrame) error {
|
func (m *MsgSysSetStageBinary) Parse(bf *byteframe.ByteFrame) error {
|
||||||
m.Unk0 = bf.ReadUint8()
|
m.BinaryType0 = bf.ReadUint8()
|
||||||
m.BinaryType = bf.ReadUint8()
|
m.BinaryType1 = bf.ReadUint8()
|
||||||
m.StageIDLength = bf.ReadUint8()
|
m.StageIDLength = bf.ReadUint8()
|
||||||
m.DataSize = bf.ReadUint16()
|
m.DataSize = bf.ReadUint16()
|
||||||
m.StageID = string(bf.ReadBytes(uint(m.StageIDLength)))
|
m.StageID = string(bf.ReadBytes(uint(m.StageIDLength)))
|
||||||
|
|||||||
@@ -15,10 +15,11 @@ func (m *MsgSysUnlockStage) Opcode() network.PacketID {
|
|||||||
|
|
||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgSysUnlockStage) Parse(bf *byteframe.ByteFrame) error {
|
func (m *MsgSysUnlockStage) Parse(bf *byteframe.ByteFrame) error {
|
||||||
panic("Not implemented")
|
// No data
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build builds a binary packet from the current data.
|
// Build builds a binary packet from the current data.
|
||||||
func (m *MsgSysUnlockStage) Build(bf *byteframe.ByteFrame) error {
|
func (m *MsgSysUnlockStage) Build(bf *byteframe.ByteFrame) error {
|
||||||
panic("Not implemented")
|
panic("Not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package channelserver
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"crypto/rand"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@@ -246,7 +247,26 @@ func handleMsgSysCastedBinary(s *Session, p mhfpacket.MHFPacket) {}
|
|||||||
|
|
||||||
func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgSysGetFile(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
func handleMsgSysIssueLogkey(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgSysIssueLogkey(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgSysIssueLogkey)
|
||||||
|
|
||||||
|
// Make a random log key for this session.
|
||||||
|
logKey := make([]byte, 8)
|
||||||
|
_, err := rand.Read(logKey)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
s.Lock()
|
||||||
|
s.logKey = logKey
|
||||||
|
s.Unlock()
|
||||||
|
|
||||||
|
// Issue it.
|
||||||
|
resp := byteframe.NewByteFrame()
|
||||||
|
resp.WriteBytes(logKey)
|
||||||
|
resp.WriteBytes([]byte{0x8E, 0x8E}) // Unk
|
||||||
|
doSizedAckResp(s, pkt.AckHandle, resp.Data())
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgSysRecordLog(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgSysRecordLog(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
@@ -383,7 +403,11 @@ func handleMsgSysMoveStage(s *Session, p mhfpacket.MHFPacket) {}
|
|||||||
|
|
||||||
func handleMsgSysLeaveStage(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgSysLeaveStage(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
func handleMsgSysLockStage(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgSysLockStage(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgSysLockStage)
|
||||||
|
// TODO(Andoryuuta): What does this packet _actually_ do?
|
||||||
|
s.QueueAck(pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00})
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgSysUnlockStage(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgSysUnlockStage(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
@@ -403,9 +427,56 @@ func handleMsgSysSetStagePass(s *Session, p mhfpacket.MHFPacket) {}
|
|||||||
|
|
||||||
func handleMsgSysWaitStageBinary(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgSysWaitStageBinary(s *Session, p mhfpacket.MHFPacket) {}
|
||||||
|
|
||||||
func handleMsgSysSetStageBinary(s *Session, p mhfpacket.MHFPacket) {}
|
func handleMsgSysSetStageBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgSysSetStageBinary)
|
||||||
|
|
||||||
func handleMsgSysGetStageBinary(s *Session, p mhfpacket.MHFPacket) {}
|
// Try to get the stage
|
||||||
|
stageID := stripNullTerminator(pkt.StageID)
|
||||||
|
s.server.stagesLock.Lock()
|
||||||
|
stage, gotStage := s.server.stages[stageID]
|
||||||
|
s.server.stagesLock.Unlock()
|
||||||
|
|
||||||
|
// If we got the stage, lock and set the data.
|
||||||
|
if gotStage {
|
||||||
|
stage.Lock()
|
||||||
|
stage.rawBinaryData[stageBinaryKey{pkt.BinaryType0, pkt.BinaryType1}] = pkt.RawDataPayload
|
||||||
|
stage.Unlock()
|
||||||
|
} else {
|
||||||
|
s.logger.Warn("Failed to get stage", zap.String("StageID", stageID))
|
||||||
|
}
|
||||||
|
s.logger.Debug("handleMsgSysSetStageBinary Done!")
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleMsgSysGetStageBinary(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
pkt := p.(*mhfpacket.MsgSysGetStageBinary)
|
||||||
|
|
||||||
|
// Try to get the stage
|
||||||
|
stageID := stripNullTerminator(pkt.StageID)
|
||||||
|
s.server.stagesLock.Lock()
|
||||||
|
stage, gotStage := s.server.stages[stageID]
|
||||||
|
s.server.stagesLock.Unlock()
|
||||||
|
|
||||||
|
// If we got the stage, lock and try to get the data.
|
||||||
|
var stageBinary []byte
|
||||||
|
var gotBinary bool
|
||||||
|
if gotStage {
|
||||||
|
stage.Lock()
|
||||||
|
stageBinary, gotBinary = stage.rawBinaryData[stageBinaryKey{pkt.BinaryType0, pkt.BinaryType1}]
|
||||||
|
stage.Unlock()
|
||||||
|
} else {
|
||||||
|
s.logger.Warn("Failed to get stage", zap.String("StageID", stageID))
|
||||||
|
}
|
||||||
|
|
||||||
|
if gotBinary {
|
||||||
|
doSizedAckResp(s, pkt.AckHandle, stageBinary)
|
||||||
|
} else {
|
||||||
|
s.logger.Warn("Failed to get stage binary", zap.Uint8("BinaryType0", pkt.BinaryType0), zap.Uint8("pkt.BinaryType1", pkt.BinaryType1))
|
||||||
|
s.logger.Warn("Sending blank stage binary")
|
||||||
|
doSizedAckResp(s, pkt.AckHandle, []byte{})
|
||||||
|
}
|
||||||
|
|
||||||
|
s.logger.Debug("MsgSysGetStageBinary Done!")
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgSysEnumerateClient(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgSysEnumerateClient(s *Session, p mhfpacket.MHFPacket) {
|
||||||
pkt := p.(*mhfpacket.MsgSysEnumerateClient)
|
pkt := p.(*mhfpacket.MsgSysEnumerateClient)
|
||||||
@@ -431,6 +502,8 @@ func handleMsgSysEnumerateClient(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
stage.RUnlock()
|
stage.RUnlock()
|
||||||
|
|
||||||
doSizedAckResp(s, pkt.AckHandle, resp.Data())
|
doSizedAckResp(s, pkt.AckHandle, resp.Data())
|
||||||
|
|
||||||
|
s.logger.Debug("MsgSysEnumerateClient Done!")
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgSysEnumerateStage(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgSysEnumerateStage(s *Session, p mhfpacket.MHFPacket) {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ type Session struct {
|
|||||||
stageID string
|
stageID string
|
||||||
stage *Stage
|
stage *Stage
|
||||||
charID uint32
|
charID uint32
|
||||||
|
logKey []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSession creates a new Session type.
|
// NewSession creates a new Session type.
|
||||||
|
|||||||
@@ -15,13 +15,19 @@ type StageObject struct {
|
|||||||
x, y, z float32
|
x, y, z float32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type stageBinaryKey struct {
|
||||||
|
id0 uint8
|
||||||
|
id1 uint8
|
||||||
|
}
|
||||||
|
|
||||||
// Stage holds stage-specific information
|
// Stage holds stage-specific information
|
||||||
type Stage struct {
|
type Stage struct {
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
id string // Stage ID string
|
id string // Stage ID string
|
||||||
gameObjectCount uint32 // Total count of objects ever created for this stage. Used for ObjID generation.
|
gameObjectCount uint32 // Total count of objects ever created for this stage. Used for ObjID generation.
|
||||||
objects map[uint32]*StageObject // Map of ObjID -> StageObject
|
objects map[uint32]*StageObject // Map of ObjID -> StageObject
|
||||||
clients map[*Session]uint32 // Map of session -> charID
|
clients map[*Session]uint32 // Map of session -> charID
|
||||||
|
rawBinaryData map[stageBinaryKey][]byte // Raw binary data set by the client.
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStage creates a new stage with intialized values.
|
// NewStage creates a new stage with intialized values.
|
||||||
@@ -30,6 +36,7 @@ func NewStage(ID string) *Stage {
|
|||||||
id: ID,
|
id: ID,
|
||||||
objects: make(map[uint32]*StageObject),
|
objects: make(map[uint32]*StageObject),
|
||||||
clients: make(map[*Session]uint32),
|
clients: make(map[*Session]uint32),
|
||||||
|
rawBinaryData: make(map[stageBinaryKey][]byte),
|
||||||
gameObjectCount: 1,
|
gameObjectCount: 1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user