diff --git a/server/channelserver/handlers.go b/server/channelserver/handlers.go index da357700d..fc5d67de0 100644 --- a/server/channelserver/handlers.go +++ b/server/channelserver/handlers.go @@ -183,7 +183,6 @@ func logoutPlayer(s *Session) { delete(s.server.sessions, s.rawConn) } s.rawConn.Close() - delete(s.server.objectIDs, s) s.server.Unlock() for _, stage := range s.server.stages { diff --git a/server/channelserver/handlers_object.go b/server/channelserver/handlers_object.go index 41f28e5d3..4e8284939 100644 --- a/server/channelserver/handlers_object.go +++ b/server/channelserver/handlers_object.go @@ -12,7 +12,7 @@ func handleMsgSysCreateObject(s *Session, p mhfpacket.MHFPacket) { s.stage.Lock() newObj := &Object{ - id: s.NextObjectID(), + id: s.getObjectId(), ownerCharID: s.charID, x: pkt.X, y: pkt.Y, diff --git a/server/channelserver/handlers_stage.go b/server/channelserver/handlers_stage.go index 64a1153ef..b9bcb5ccf 100644 --- a/server/channelserver/handlers_stage.go +++ b/server/channelserver/handlers_stage.go @@ -8,6 +8,7 @@ import ( "erupe-ce/common/byteframe" ps "erupe-ce/common/pascalstring" "erupe-ce/network/mhfpacket" + "go.uber.org/zap" ) @@ -64,28 +65,24 @@ func doStageTransfer(s *Session, ackHandle uint32, stageID string) { // Confirm the stage entry. doAckSimpleSucceed(s, ackHandle, []byte{0x00, 0x00, 0x00, 0x00}) - var temp mhfpacket.MHFPacket 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} - newNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(newNotif, s.clientContext) - for i := 0; i < 3; i++ { - temp = &mhfpacket.MsgSysNotifyUserBinary{ - CharID: session.charID, - BinaryType: uint8(i + 1), - } - newNotif.WriteUint16(uint16(temp.Opcode())) - temp.Build(newNotif, s.clientContext) - } + session.QueueSendMHF(&mhfpacket.MsgSysInsertUser{CharID: s.charID}) + session.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: s.charID, BinaryType: 1}) + session.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: s.charID, BinaryType: 2}) + session.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: s.charID, BinaryType: 3}) + s.QueueSendMHF(&mhfpacket.MsgSysInsertUser{CharID: session.charID}) + s.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: session.charID, BinaryType: 1}) + s.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: session.charID, BinaryType: 2}) + s.QueueSendMHF(&mhfpacket.MsgSysNotifyUserBinary{CharID: session.charID, BinaryType: 3}) } } diff --git a/server/channelserver/sys_channel_server.go b/server/channelserver/sys_channel_server.go index f62db7e34..60dfcc773 100644 --- a/server/channelserver/sys_channel_server.go +++ b/server/channelserver/sys_channel_server.go @@ -49,7 +49,6 @@ type Server struct { acceptConns chan net.Conn deleteConns chan net.Conn sessions map[net.Conn]*Session - objectIDs map[*Session]uint16 listener net.Listener // Listener that is created when Server.Start is called. isShuttingDown bool @@ -155,7 +154,6 @@ 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), stages: make(map[string]*Stage), userBinaryParts: make(map[userBinaryPartID][]byte), semaphore: make(map[string]*Semaphore), @@ -280,6 +278,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 {