mirror of
https://github.com/Mezeporta/Erupe.git
synced 2026-02-04 09:15:08 +01:00
port partial fix/mutex-rework
This commit is contained in:
@@ -3,7 +3,6 @@ package mhfpacket
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/common/bfutil"
|
|
||||||
"erupe-ce/network"
|
"erupe-ce/network"
|
||||||
"erupe-ce/network/clientctx"
|
"erupe-ce/network/clientctx"
|
||||||
)
|
)
|
||||||
@@ -13,7 +12,7 @@ type MsgSysCreateStage struct {
|
|||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint8 // Likely only has 1 and 2 as values.
|
Unk0 uint8 // Likely only has 1 and 2 as values.
|
||||||
PlayerCount uint8
|
PlayerCount uint8
|
||||||
StageID string // NULL terminated string.
|
StageID string
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -26,8 +25,8 @@ func (m *MsgSysCreateStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.Client
|
|||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint8()
|
m.Unk0 = bf.ReadUint8()
|
||||||
m.PlayerCount = bf.ReadUint8()
|
m.PlayerCount = bf.ReadUint8()
|
||||||
stageIDLength := bf.ReadUint8()
|
bf.ReadUint8() // Length StageID
|
||||||
m.StageID = string(bfutil.UpToNull(bf.ReadBytes(uint(stageIDLength))))
|
m.StageID = string(bf.ReadNullTerminatedBytes())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import (
|
|||||||
// MsgSysEnterStage represents the MSG_SYS_ENTER_STAGE
|
// MsgSysEnterStage represents the MSG_SYS_ENTER_STAGE
|
||||||
type MsgSysEnterStage struct {
|
type MsgSysEnterStage struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
UnkBool uint8
|
Unk bool
|
||||||
StageID string
|
StageID string
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,8 +23,8 @@ func (m *MsgSysEnterStage) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgSysEnterStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgSysEnterStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.UnkBool = bf.ReadUint8()
|
m.Unk = bf.ReadBool() // IsQuest?
|
||||||
bf.ReadUint8()
|
bf.ReadUint8() // Length StageID
|
||||||
m.StageID = string(bf.ReadNullTerminatedBytes())
|
m.StageID = string(bf.ReadNullTerminatedBytes())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package mhfpacket
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"erupe-ce/common/stringsupport"
|
|
||||||
|
|
||||||
"erupe-ce/common/byteframe"
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/network"
|
"erupe-ce/network"
|
||||||
"erupe-ce/network/clientctx"
|
"erupe-ce/network/clientctx"
|
||||||
@@ -12,8 +10,7 @@ import (
|
|||||||
// MsgSysEnumerateStage represents the MSG_SYS_ENUMERATE_STAGE
|
// MsgSysEnumerateStage represents the MSG_SYS_ENUMERATE_STAGE
|
||||||
type MsgSysEnumerateStage struct {
|
type MsgSysEnumerateStage struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint8 // Hardcoded 1 in the binary
|
StagePrefix string
|
||||||
StagePrefix string // NULL terminated string.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
@@ -24,9 +21,9 @@ func (m *MsgSysEnumerateStage) Opcode() network.PacketID {
|
|||||||
// Parse parses the packet from binary
|
// Parse parses the packet from binary
|
||||||
func (m *MsgSysEnumerateStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
func (m *MsgSysEnumerateStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint8()
|
bf.ReadUint8() // Always 1
|
||||||
bf.ReadUint8()
|
bf.ReadUint8() // Length StagePrefix
|
||||||
m.StagePrefix = stringsupport.SJISToUTF8(bf.ReadNullTerminatedBytes())
|
m.StagePrefix = string(bf.ReadNullTerminatedBytes())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,17 @@
|
|||||||
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"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgSysLockStage represents the MSG_SYS_LOCK_STAGE
|
// MsgSysLockStage represents the MSG_SYS_LOCK_STAGE
|
||||||
type MsgSysLockStage struct {
|
type MsgSysLockStage struct {
|
||||||
AckHandle uint32
|
AckHandle uint32
|
||||||
Unk0 uint8 // Hardcoded 1 in the binary
|
StageID string
|
||||||
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.
|
||||||
@@ -25,10 +22,10 @@ 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, ctx *clientctx.ClientContext) error {
|
func (m *MsgSysLockStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.AckHandle = bf.ReadUint32()
|
m.AckHandle = bf.ReadUint32()
|
||||||
m.Unk0 = bf.ReadUint8()
|
bf.ReadUint8() // Always 1
|
||||||
m.Unk1 = bf.ReadUint8()
|
bf.ReadUint8() // Always 1
|
||||||
m.StageIDLength = bf.ReadUint8()
|
bf.ReadUint8() // Length StageID
|
||||||
m.StageID = string(bf.ReadBytes(uint(m.StageIDLength)))
|
m.StageID = string(bf.ReadNullTerminatedBytes())
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,14 @@
|
|||||||
package mhfpacket
|
package mhfpacket
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
|
"erupe-ce/common/byteframe"
|
||||||
"erupe-ce/network"
|
"erupe-ce/network"
|
||||||
"erupe-ce/network/clientctx"
|
"erupe-ce/network/clientctx"
|
||||||
"erupe-ce/common/byteframe"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// MsgSysUnlockStage represents the MSG_SYS_UNLOCK_STAGE
|
// MsgSysUnlockStage represents the MSG_SYS_UNLOCK_STAGE
|
||||||
type MsgSysUnlockStage struct {
|
type MsgSysUnlockStage struct{}
|
||||||
Unk0 uint16 // Hardcoded 0 in the binary.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Opcode returns the ID associated with this packet type.
|
// Opcode returns the ID associated with this packet type.
|
||||||
func (m *MsgSysUnlockStage) Opcode() network.PacketID {
|
func (m *MsgSysUnlockStage) Opcode() network.PacketID {
|
||||||
@@ -18,12 +17,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, ctx *clientctx.ClientContext) error {
|
func (m *MsgSysUnlockStage) Parse(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
m.Unk0 = bf.ReadUint16()
|
bf.ReadUint16() // Zeroed
|
||||||
return nil
|
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, ctx *clientctx.ClientContext) error {
|
func (m *MsgSysUnlockStage) Build(bf *byteframe.ByteFrame, ctx *clientctx.ClientContext) error {
|
||||||
bf.WriteUint16(m.Unk0)
|
return errors.New("NOT IMPLEMENTED")
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -378,7 +378,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
if session.charID == CharID {
|
if session.charID == CharID {
|
||||||
count++
|
count++
|
||||||
sessionName := stringsupport.UTF8ToSJIS(session.Name)
|
sessionName := stringsupport.UTF8ToSJIS(session.Name)
|
||||||
sessionStage := stringsupport.UTF8ToSJIS(session.stageID)
|
sessionStage := stringsupport.UTF8ToSJIS(session.stage.id)
|
||||||
resp.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(c.IP).To4()))
|
resp.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(c.IP).To4()))
|
||||||
resp.WriteUint16(c.Port)
|
resp.WriteUint16(c.Port)
|
||||||
resp.WriteUint32(session.charID)
|
resp.WriteUint32(session.charID)
|
||||||
@@ -408,7 +408,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
if strings.Contains(session.Name, searchTerm) {
|
if strings.Contains(session.Name, searchTerm) {
|
||||||
count++
|
count++
|
||||||
sessionName := stringsupport.UTF8ToSJIS(session.Name)
|
sessionName := stringsupport.UTF8ToSJIS(session.Name)
|
||||||
sessionStage := stringsupport.UTF8ToSJIS(session.stageID)
|
sessionStage := stringsupport.UTF8ToSJIS(session.stage.id)
|
||||||
resp.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(c.IP).To4()))
|
resp.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(c.IP).To4()))
|
||||||
resp.WriteUint16(c.Port)
|
resp.WriteUint16(c.Port)
|
||||||
resp.WriteUint32(session.charID)
|
resp.WriteUint32(session.charID)
|
||||||
@@ -445,7 +445,7 @@ func handleMsgMhfTransitMessage(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
hrp := uint16(1)
|
hrp := uint16(1)
|
||||||
gr := uint16(0)
|
gr := uint16(0)
|
||||||
s.server.db.QueryRow("SELECT hrp, gr FROM characters WHERE id=$1", session.charID).Scan(&hrp, &gr)
|
s.server.db.QueryRow("SELECT hrp, gr FROM characters WHERE id=$1", session.charID).Scan(&hrp, &gr)
|
||||||
sessionStage := stringsupport.UTF8ToSJIS(session.stageID)
|
sessionStage := stringsupport.UTF8ToSJIS(session.stage.id)
|
||||||
sessionName := stringsupport.UTF8ToSJIS(session.Name)
|
sessionName := stringsupport.UTF8ToSJIS(session.Name)
|
||||||
resp.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(c.IP).To4()))
|
resp.WriteUint32(binary.LittleEndian.Uint32(net.ParseIP(c.IP).To4()))
|
||||||
resp.WriteUint16(c.Port)
|
resp.WriteUint16(c.Port)
|
||||||
|
|||||||
@@ -55,7 +55,6 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) {
|
|||||||
|
|
||||||
// Save our new stage ID and pointer to the new stage itself.
|
// Save our new stage ID and pointer to the new stage itself.
|
||||||
s.Lock()
|
s.Lock()
|
||||||
s.stageID = stageID
|
|
||||||
s.stage = s.server.stages[stageID]
|
s.stage = s.server.stages[stageID]
|
||||||
s.Unlock()
|
s.Unlock()
|
||||||
|
|
||||||
@@ -153,13 +152,13 @@ func handleMsgSysEnterStage(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
pkt := p.(*mhfpacket.MsgSysEnterStage)
|
pkt := p.(*mhfpacket.MsgSysEnterStage)
|
||||||
|
|
||||||
// Push our current stage ID to the movement stack before entering another one.
|
// Push our current stage ID to the movement stack before entering another one.
|
||||||
if s.stageID == "" {
|
if s.stage.id == "" {
|
||||||
s.stageMoveStack.Set(pkt.StageID)
|
s.stageMoveStack.Set(pkt.StageID)
|
||||||
} else {
|
} else {
|
||||||
s.stage.Lock()
|
s.stage.Lock()
|
||||||
s.stage.reservedClientSlots[s.charID] = false
|
s.stage.reservedClientSlots[s.charID] = false
|
||||||
s.stage.Unlock()
|
s.stage.Unlock()
|
||||||
s.stageMoveStack.Push(s.stageID)
|
s.stageMoveStack.Push(s.stage.id)
|
||||||
s.stageMoveStack.Lock()
|
s.stageMoveStack.Lock()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,9 +205,12 @@ 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)
|
pkt := p.(*mhfpacket.MsgSysLockStage)
|
||||||
// TODO(Andoryuuta): What does this packet _actually_ do?
|
if stage, exists := s.server.stages[pkt.StageID]; exists {
|
||||||
// I think this is supposed to mark a stage as no longer able to accept client reservations
|
stage.Lock()
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, []byte{0x00, 0x00, 0x00, 0x00})
|
stage.locked = true
|
||||||
|
stage.Unlock()
|
||||||
|
}
|
||||||
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgSysUnlockStage(s *Session, p mhfpacket.MHFPacket) {
|
func handleMsgSysUnlockStage(s *Session, p mhfpacket.MHFPacket) {
|
||||||
@@ -218,7 +220,9 @@ func handleMsgSysUnlockStage(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
|
|
||||||
for charID := range s.reservationStage.reservedClientSlots {
|
for charID := range s.reservationStage.reservedClientSlots {
|
||||||
session := s.server.FindSessionByCharID(charID)
|
session := s.server.FindSessionByCharID(charID)
|
||||||
session.QueueSendMHF(&mhfpacket.MsgSysStageDestruct{})
|
if session != nil {
|
||||||
|
session.QueueSendMHF(&mhfpacket.MsgSysStageDestruct{})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete(s.server.stages, s.reservationStage.id)
|
delete(s.server.stages, s.reservationStage.id)
|
||||||
@@ -241,6 +245,10 @@ func handleMsgSysReserveStage(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
}
|
}
|
||||||
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleSucceed(s, pkt.AckHandle, make([]byte, 4))
|
||||||
} else if uint16(len(stage.reservedClientSlots)) < stage.maxPlayers {
|
} else if uint16(len(stage.reservedClientSlots)) < stage.maxPlayers {
|
||||||
|
if stage.locked {
|
||||||
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
|
return
|
||||||
|
}
|
||||||
if len(stage.password) > 0 {
|
if len(stage.password) > 0 {
|
||||||
if stage.password != s.stagePass {
|
if stage.password != s.stagePass {
|
||||||
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
doAckSimpleFail(s, pkt.AckHandle, make([]byte, 4))
|
||||||
@@ -383,20 +391,17 @@ func handleMsgSysEnumerateStage(s *Session, p mhfpacket.MHFPacket) {
|
|||||||
joinable++
|
joinable++
|
||||||
|
|
||||||
bf.WriteUint16(uint16(len(stage.reservedClientSlots)))
|
bf.WriteUint16(uint16(len(stage.reservedClientSlots)))
|
||||||
bf.WriteUint16(0) // Unk
|
bf.WriteUint16(uint16(len(stage.clients)))
|
||||||
if len(stage.clients) > 0 {
|
bf.WriteUint16(uint16(len(stage.clients)))
|
||||||
bf.WriteUint16(1)
|
|
||||||
} else {
|
|
||||||
bf.WriteUint16(0)
|
|
||||||
}
|
|
||||||
bf.WriteUint16(stage.maxPlayers)
|
bf.WriteUint16(stage.maxPlayers)
|
||||||
if len(stage.password) > 0 {
|
var flags uint8
|
||||||
// This byte has also been seen as 1
|
if stage.locked {
|
||||||
// The quest is also recognised as locked when this is 2
|
flags |= 1
|
||||||
bf.WriteUint8(2)
|
|
||||||
} else {
|
|
||||||
bf.WriteUint8(0)
|
|
||||||
}
|
}
|
||||||
|
if len(stage.password) > 0 {
|
||||||
|
flags |= 2
|
||||||
|
}
|
||||||
|
bf.WriteUint8(flags)
|
||||||
ps.Uint8(bf, sid, false)
|
ps.Uint8(bf, sid, false)
|
||||||
stage.RUnlock()
|
stage.RUnlock()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,6 @@ type Session struct {
|
|||||||
|
|
||||||
objectIndex uint16
|
objectIndex uint16
|
||||||
userEnteredStage bool // If the user has entered a stage before
|
userEnteredStage bool // If the user has entered a stage before
|
||||||
stageID string
|
|
||||||
stage *Stage
|
stage *Stage
|
||||||
reservationStage *Stage // Required for the stateful MsgSysUnreserveStage packet.
|
reservationStage *Stage // Required for the stateful MsgSysUnreserveStage packet.
|
||||||
stagePass string // Temporary storage
|
stagePass string // Temporary storage
|
||||||
|
|||||||
@@ -47,6 +47,7 @@ type Stage struct {
|
|||||||
host *Session
|
host *Session
|
||||||
maxPlayers uint16
|
maxPlayers uint16
|
||||||
password string
|
password string
|
||||||
|
locked bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewStage creates a new stage with intialized values.
|
// NewStage creates a new stage with intialized values.
|
||||||
|
|||||||
Reference in New Issue
Block a user