diff --git a/Erupe/common/stringstack/stringstack.go b/Erupe/common/stringstack/stringstack.go index aff33842e..5f936e6a2 100644 --- a/Erupe/common/stringstack/stringstack.go +++ b/Erupe/common/stringstack/stringstack.go @@ -2,33 +2,45 @@ package stringstack import ( "errors" - "sync" ) // StringStack is a basic LIFO "stack" for storing strings. type StringStack struct { - sync.Mutex - stack []string + Locked bool + stack []string } // New creates a new instance of StringStack func New() *StringStack { - return &StringStack{} + return &StringStack{Locked: false} +} + +// Set sets up a new StringStack +func (s *StringStack) Set(v string) { + s.stack = []string{v} +} + +// Lock freezes the StringStack +func (s *StringStack) Lock() { + if !s.Locked { + s.Locked = true + } +} + +// Unlock unfreezes the StringStack +func (s *StringStack) Unlock() { + if s.Locked { + s.Locked = false + } } // Push pushes a string onto the stack. func (s *StringStack) Push(v string) { - s.Lock() - defer s.Unlock() - s.stack = append(s.stack, v) } // Pop pops a string from the stack. func (s *StringStack) Pop() (string, error) { - s.Lock() - defer s.Unlock() - if len(s.stack) == 0 { return "", errors.New("no items on stack") } diff --git a/Erupe/server/channelserver/handlers_stage.go b/Erupe/server/channelserver/handlers_stage.go index ae0830846..9d9184106 100644 --- a/Erupe/server/channelserver/handlers_stage.go +++ b/Erupe/server/channelserver/handlers_stage.go @@ -120,10 +120,14 @@ func removeSessionFromStage(s *Session) { func handleMsgSysEnterStage(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysEnterStage) + // Push our current stage ID to the movement stack before entering another one. - s.Lock() - s.stageMoveStack.Push(s.stageID) - s.Unlock() + if s.stageID == "" { + s.stageMoveStack.Set(pkt.StageID) + } else { + s.stageMoveStack.Push(s.stageID) + s.stageMoveStack.Lock() + } s.QueueSendMHF(&mhfpacket.MsgSysCleanupObject{}) if s.reservationStage != nil { @@ -137,9 +141,8 @@ func handleMsgSysBackStage(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysBackStage) // Transfer back to the saved stage ID before the previous move or enter. - s.Lock() + s.stageMoveStack.Unlock() backStage, err := s.stageMoveStack.Pop() - s.Unlock() if err != nil { panic(err) @@ -151,10 +154,10 @@ func handleMsgSysBackStage(s *Session, p mhfpacket.MHFPacket) { func handleMsgSysMoveStage(s *Session, p mhfpacket.MHFPacket) { pkt := p.(*mhfpacket.MsgSysMoveStage) - // Push our current stage ID to the movement stack before entering another one. - s.Lock() - s.stageMoveStack.Push(s.stageID) - s.Unlock() + // Set a new move stack from the given stage ID if unlocked + if !s.stageMoveStack.Locked { + s.stageMoveStack.Set(pkt.StageID) + } doStageTransfer(s, pkt.AckHandle, pkt.StageID) }