emulate retail semaphore logic

This commit is contained in:
wish
2024-10-03 21:56:06 +10:00
parent 8f68e10f1d
commit b20969ddc6
4 changed files with 33 additions and 21 deletions

View File

@@ -65,6 +65,15 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
pkt := p.(*mhfpacket.MsgSysCreateAcquireSemaphore) pkt := p.(*mhfpacket.MsgSysCreateAcquireSemaphore)
SemaphoreID := pkt.SemaphoreID SemaphoreID := pkt.SemaphoreID
if s.server.HasSemaphore(s) {
s.semaphoreMode = !s.semaphoreMode
}
if s.semaphoreMode {
s.semaphoreID[1]++
} else {
s.semaphoreID[0]++
}
newSemaphore, exists := s.server.semaphore[SemaphoreID] newSemaphore, exists := s.server.semaphore[SemaphoreID]
if !exists { if !exists {
s.server.semaphoreLock.Lock() s.server.semaphoreLock.Lock()
@@ -77,7 +86,7 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
maxPlayers: 127, maxPlayers: 127,
} }
} else { } else {
s.server.semaphore[SemaphoreID] = NewSemaphore(s.server, SemaphoreID, 1) s.server.semaphore[SemaphoreID] = NewSemaphore(s, SemaphoreID, 1)
} }
newSemaphore = s.server.semaphore[SemaphoreID] newSemaphore = s.server.semaphore[SemaphoreID]
s.server.semaphoreLock.Unlock() s.server.semaphoreLock.Unlock()
@@ -103,7 +112,7 @@ func handleMsgSysCreateAcquireSemaphore(s *Session, p mhfpacket.MHFPacket) {
func handleMsgSysAcquireSemaphore(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 { if sema, exists := s.server.semaphore[pkt.SemaphoreID]; exists {
sema.clients[s] = s.charID sema.host = s
bf := byteframe.NewByteFrame() bf := byteframe.NewByteFrame()
bf.WriteUint32(sema.id) bf.WriteUint32(sema.id)
doAckSimpleSucceed(s, pkt.AckHandle, bf.Data()) doAckSimpleSucceed(s, pkt.AckHandle, bf.Data())

View File

@@ -424,24 +424,13 @@ func (s *Server) FindObjectByChar(charID uint32) *Object {
return nil return nil
} }
func (s *Server) NextSemaphoreID() uint32 { func (s *Server) HasSemaphore(ses *Session) bool {
for {
exists := false
s.semaphoreIndex = s.semaphoreIndex + 1
if s.semaphoreIndex > 0xFFFF {
s.semaphoreIndex = 1
}
for _, semaphore := range s.semaphore { for _, semaphore := range s.semaphore {
if semaphore.id == s.semaphoreIndex { if semaphore.host == ses {
exists = true return true
break
} }
} }
if !exists { return false
break
}
}
return s.semaphoreIndex
} }
func (s *Server) Season() uint8 { func (s *Server) Season() uint8 {

View File

@@ -22,15 +22,18 @@ type Semaphore struct {
// Max Players for Semaphore // Max Players for Semaphore
maxPlayers uint16 maxPlayers uint16
host *Session
} }
// NewSemaphore creates a new Semaphore with intialized values // NewSemaphore creates a new Semaphore with intialized values
func NewSemaphore(s *Server, ID string, MaxPlayers uint16) *Semaphore { func NewSemaphore(s *Session, ID string, MaxPlayers uint16) *Semaphore {
sema := &Semaphore{ sema := &Semaphore{
name: ID, name: ID,
id: s.NextSemaphoreID(), id: s.GetSemaphoreID(),
clients: make(map[*Session]uint32), clients: make(map[*Session]uint32),
maxPlayers: MaxPlayers, maxPlayers: MaxPlayers,
host: s,
} }
return sema return sema
} }

View File

@@ -49,6 +49,8 @@ type Session struct {
kqfOverride bool kqfOverride bool
semaphore *Semaphore // Required for the stateful MsgSysUnreserveStage packet. semaphore *Semaphore // Required for the stateful MsgSysUnreserveStage packet.
semaphoreMode bool
semaphoreID []uint16
// A stack containing the stage movement history (push on enter/move, pop on back) // A stack containing the stage movement history (push on enter/move, pop on back)
stageMoveStack *stringstack.StringStack stageMoveStack *stringstack.StringStack
@@ -79,6 +81,7 @@ func NewSession(server *Server, conn net.Conn) *Session {
sessionStart: TimeAdjusted().Unix(), sessionStart: TimeAdjusted().Unix(),
stageMoveStack: stringstack.New(), stageMoveStack: stringstack.New(),
ackStart: make(map[uint32]time.Time), ackStart: make(map[uint32]time.Time),
semaphoreID: make([]uint16, 2),
} }
s.SetObjectID() s.SetObjectID()
return s return s
@@ -310,6 +313,14 @@ func (s *Session) NextObjectID() uint32 {
return bf.ReadUint32() return bf.ReadUint32()
} }
func (s *Session) GetSemaphoreID() uint32 {
if s.semaphoreMode {
return 0x000E0000 + uint32(s.semaphoreID[1])
} else {
return 0x000F0000 + uint32(s.semaphoreID[0])
}
}
func (s *Session) isOp() bool { func (s *Session) isOp() bool {
var op bool var op bool
err := s.server.db.QueryRow(`SELECT op FROM users u WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)`, s.charID).Scan(&op) err := s.server.db.QueryRow(`SELECT op FROM users u WHERE u.id=(SELECT c.user_id FROM characters c WHERE c.id=$1)`, s.charID).Scan(&op)