diff --git a/server/channelserver/handlers_stage.go b/server/channelserver/handlers_stage.go index 64a1153ef..53ea9f868 100644 --- a/server/channelserver/handlers_stage.go +++ b/server/channelserver/handlers_stage.go @@ -68,11 +68,11 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) { newNotif := byteframe.NewByteFrame() // Cast existing user data to new user - if !s.userEnteredStage { - s.userEnteredStage = true + if !s.loaded { + s.loaded = true for _, session := range s.server.sessions { - if s == session { + if s == session || !session.loaded { continue } temp = &mhfpacket.MsgSysInsertUser{CharID: session.charID} diff --git a/server/channelserver/sys_channel_server.go b/server/channelserver/sys_channel_server.go index f62db7e34..252a64d5c 100644 --- a/server/channelserver/sys_channel_server.go +++ b/server/channelserver/sys_channel_server.go @@ -49,7 +49,7 @@ type Server struct { acceptConns chan net.Conn deleteConns chan net.Conn sessions map[net.Conn]*Session - objectIDs map[*Session]uint16 + //objectIDs map[*Session]uint16 listener net.Listener // Listener that is created when Server.Start is called. isShuttingDown bool @@ -155,7 +155,7 @@ func NewServer(config *Config) *Server { acceptConns: make(chan net.Conn), deleteConns: make(chan net.Conn), sessions: make(map[net.Conn]*Session), - objectIDs: make(map[*Session]uint16), + //objectIDs: make(map[*Session]uint16), stages: make(map[string]*Stage), userBinaryParts: make(map[userBinaryPartID][]byte), semaphore: make(map[string]*Semaphore), @@ -280,6 +280,20 @@ func (s *Server) manageSessions() { } } +func (s *Server) getObjectId() uint16 { + ids := make(map[uint16]struct{}) + for _, sess := range s.sessions { + ids[sess.objectID] = struct{}{} + } + for i := uint16(1); i < 100; i++ { + if _, ok := ids[i]; !ok { + return i + } + } + s.logger.Warn("object ids overflowed", zap.Int("sessions", len(s.sessions))) + return 0 +} + func (s *Server) invalidateSessions() { for { if s.isShuttingDown { diff --git a/server/channelserver/sys_session.go b/server/channelserver/sys_session.go index 867c42b04..7ef70f0db 100644 --- a/server/channelserver/sys_session.go +++ b/server/channelserver/sys_session.go @@ -36,8 +36,10 @@ type Session struct { clientContext *clientctx.ClientContext lastPacket time.Time - objectIndex uint16 - userEnteredStage bool // If the user has entered a stage before + objectID uint16 + objectIndex uint16 + loaded bool + stage *Stage reservationStage *Stage // Required for the stateful MsgSysUnreserveStage packet. stagePass string // Temporary storage @@ -83,12 +85,12 @@ func NewSession(server *Server, conn net.Conn) *Session { sendPackets: make(chan packet, 20), clientContext: &clientctx.ClientContext{}, // Unused lastPacket: time.Now(), + objectID: server.getObjectId(), sessionStart: TimeAdjusted().Unix(), stageMoveStack: stringstack.New(), ackStart: make(map[uint32]time.Time), semaphoreID: make([]uint16, 2), } - s.SetObjectID() return s } @@ -292,30 +294,9 @@ func (s *Session) logMessage(opcode uint16, data []byte, sender string, recipien } } -func (s *Session) SetObjectID() { - for i := uint16(1); i < 127; i++ { - exists := false - for _, j := range s.server.objectIDs { - if i == j { - exists = true - break - } - } - if !exists { - s.server.objectIDs[s] = i - return - } - } - s.server.objectIDs[s] = 0 -} - -func (s *Session) NextObjectID() uint32 { - bf := byteframe.NewByteFrame() - bf.WriteUint16(s.server.objectIDs[s]) +func (s *Session) getObjectId() uint32 { s.objectIndex++ - bf.WriteUint16(s.objectIndex) - bf.Seek(0, 0) - return bf.ReadUint32() + return uint32(s.objectID)<<16 | uint32(s.objectIndex) } func (s *Session) GetSemaphoreID() uint32 {