diff --git a/.gitignore b/.gitignore index 159c3f8..d084d83 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,6 @@ go.work /world_config.json /world_server /world.db +/login_config.json +/login_server +/login.db \ No newline at end of file diff --git a/internal/groups/group.go b/internal/groups/group.go index f92dfad..2534229 100644 --- a/internal/groups/group.go +++ b/internal/groups/group.go @@ -549,6 +549,22 @@ func (g *Group) GetGroupMemberByPosition(seeker Entity, mappedPosition int32) En return g.Members[mappedPosition].Member } +// RemoveClientReference removes client references when a client disconnects +// This is used for cleanup when a player disconnects but stays in the group +func (g *Group) RemoveClientReference(client any) { + g.membersMutex.Lock() + defer g.membersMutex.Unlock() + + for _, gmi := range g.Members { + if gmi.Client != nil && gmi.Client == client { + gmi.Client = nil + // Don't set Member to nil as the entity might still exist + // Only clear the client reference + break + } + } +} + // GetGroupOptions returns a copy of the group options func (g *Group) GetGroupOptions() GroupOptions { g.optionsMutex.RLock() diff --git a/internal/groups/manager_methods.go b/internal/groups/manager_methods.go index 33a58e5..e533aa3 100644 --- a/internal/groups/manager_methods.go +++ b/internal/groups/manager_methods.go @@ -515,3 +515,14 @@ func (m *Manager) fireGroupInviteDeclinedEvent(leader, member Entity) { go handler.OnGroupInviteDeclined(leader, member) } } + +// RemoveClientReference removes client references from all groups when a client disconnects +func (m *Manager) RemoveClientReference(client any) { + // Get all groups from the master list + groups := m.MasterList.GetAllGroups() + + // Remove client reference from all groups + for _, group := range groups { + group.RemoveClientReference(client) + } +} diff --git a/internal/groups/master.go b/internal/groups/master.go index c5a0155..a0b5839 100644 --- a/internal/groups/master.go +++ b/internal/groups/master.go @@ -141,12 +141,33 @@ func (ml *MasterList) refreshMetaCache() { // updateGroupIndices updates all indices for a group func (ml *MasterList) updateGroupIndices(group *Group, add bool) { + // Get all group data in one go to minimize lock contention + // This avoids holding the master list lock while calling multiple group methods groupID := group.GetID() - size := group.GetSize() - leaderName := group.GetLeaderName() - isRaid := group.IsGroupRaid() - isDisbanded := group.IsDisbanded() - members := group.GetMembers() + + // Create a snapshot of group data to avoid repeated method calls + groupData := struct { + id int32 + size int32 + leaderName string + isRaid bool + isDisbanded bool + members []*GroupMemberInfo + }{ + id: groupID, + size: group.GetSize(), + leaderName: group.GetLeaderName(), + isRaid: group.IsGroupRaid(), + isDisbanded: group.IsDisbanded(), + members: group.GetMembers(), + } + + // Use the snapshot data for indexing + size := groupData.size + leaderName := groupData.leaderName + isRaid := groupData.isRaid + isDisbanded := groupData.isDisbanded + members := groupData.members if add { // Add to size index diff --git a/login_server b/login_server deleted file mode 100755 index 053f95c..0000000 Binary files a/login_server and /dev/null differ