# Groups System The groups system (`internal/groups`) provides comprehensive player group and raid management for the EQ2Go server emulator. This system is converted from the original C++ EQ2EMu PlayerGroups implementation with modern Go concurrency patterns and clean architecture principles. ## Overview The groups system manages all aspects of player groups and raids including: - **Group Management**: Creation, disbanding, member management - **Raid Functionality**: Multi-group coordination with up to 4 groups (24 players) - **Cross-Server Groups**: Peer-to-peer group coordination across server instances - **Group Invitations**: Invitation system with timeouts and validation - **Group Communication**: Chat, messaging, and broadcast systems - **Group Options**: Loot distribution, auto-split, leadership settings - **Quest Sharing**: Share quests with group members - **Group Buffs**: Coordinated buff management across group members - **Statistics**: Comprehensive group activity tracking ## Architecture ### Core Components **Group** - Individual group with up to 6 members, options, and raid functionality **GroupManager** - Global group management, invitations, and coordination **Service** - High-level service interface with validation and configuration **GroupMemberInfo** - Detailed member information and statistics **GroupOptions** - Group behavior and loot configuration ### Key Files - `group.go` - Core Group struct and member management - `manager.go` - GroupManager with global group coordination - `service.go` - High-level Service interface with validation - `types.go` - Data structures and type definitions - `interfaces.go` - System integration interfaces and adapters - `constants.go` - All group system constants and limits - `README.md` - This documentation ## Group Creation and Management ```go // Create group service config := groups.DefaultServiceConfig() service := groups.NewService(config) service.Start() // Create a new group leader := &entity.Player{...} options := &groups.GroupOptions{ LootMethod: groups.LOOT_METHOD_ROUND_ROBIN, AutoSplit: groups.AUTO_SPLIT_ENABLED, } groupID, err := service.CreateGroup(leader, options) // Get group information groupInfo, err := service.GetGroupInfo(groupID) fmt.Printf("Group %d has %d members\n", groupInfo.GroupID, groupInfo.Size) ``` ## Group Invitations ```go // Invite a player to the group leader := &entity.Player{...} member := &entity.Player{...} // Send invitation err := service.InviteToGroup(leader, member) if err != nil { fmt.Printf("Invitation failed: %v\n", err) } // Accept invitation err = service.AcceptGroupInvite(member) if err != nil { fmt.Printf("Failed to accept: %v\n", err) } // Decline invitation service.DeclineGroupInvite(member) ``` ## Group Member Management ```go // Get group manager directly manager := service.GetManager() // Add member to existing group err := manager.AddGroupMember(groupID, member, false) // Remove member from group err := manager.RemoveGroupMember(groupID, member) // Transfer leadership err := service.TransferLeadership(groupID, newLeader) // Check if entity is in group isInGroup := manager.IsInGroup(groupID, member) // Get group leader leader := manager.GetGroupLeader(groupID) ``` ## Group Communication ```go // Send simple message to group manager.SimpleGroupMessage(groupID, "Welcome to the group!") // Send system message manager.SendGroupMessage(groupID, groups.GROUP_MESSAGE_TYPE_SYSTEM, "Group is ready!") // Send chat message from member manager.GroupChatMessage(groupID, fromEntity, 0, "Hello everyone!", groups.CHANNEL_GROUP_SAY) // Send formatted chat message manager.SendGroupChatMessage(groupID, groups.CHANNEL_GROUP_CHAT, "Raid starting in 5 minutes") ``` ## Group Options Configuration ```go // Configure group options options := groups.GroupOptions{ LootMethod: groups.LOOT_METHOD_NEED_BEFORE_GREED, LootItemsRarity: groups.LOOT_RARITY_RARE, AutoSplit: groups.AUTO_SPLIT_ENABLED, GroupLockMethod: groups.LOCK_METHOD_INVITE_ONLY, GroupAutolock: groups.AUTO_LOCK_ENABLED, AutoLootMethod: groups.AUTO_LOOT_ENABLED, } // Apply options to group err := manager.SetGroupOptions(groupID, &options) // Get current options currentOptions, exists := manager.GetDefaultGroupOptions(groupID) if exists { fmt.Printf("Loot method: %d\n", currentOptions.LootMethod) } ``` ## Raid Management ```go // Form a raid from multiple groups leaderGroupID := int32(1) targetGroups := []int32{2, 3, 4} err := service.FormRaid(leaderGroupID, targetGroups) if err != nil { fmt.Printf("Failed to form raid: %v\n", err) } // Check if groups are in same raid isInRaid := manager.IsInRaidGroup(groupID1, groupID2, false) // Get all raid groups for a group raidGroups := manager.GetRaidGroups(groupID) fmt.Printf("Raid has %d groups\n", len(raidGroups)) // Disband raid err := service.DisbandRaid(leaderGroupID) ``` ## Cross-Server Group Management ```go // Add member from peer server memberInfo := &groups.GroupMemberInfo{ Name: "RemotePlayer", Leader: false, IsClient: true, ClassID: 1, HPCurrent: 1500, HPMax: 1500, PowerCurrent: 800, PowerMax: 800, LevelCurrent: 50, LevelMax: 50, RaceID: 0, Zone: "commonlands", ZoneID: 220, InstanceID: 0, ClientPeerAddress: "192.168.1.10", ClientPeerPort: 9000, IsRaidLooter: false, } err := manager.AddGroupMemberFromPeer(groupID, memberInfo) // Remove peer member by name err = manager.RemoveGroupMemberByName(groupID, "RemotePlayer", true, 12345) ``` ## Group Statistics and Information ```go // Get service statistics stats := service.GetServiceStats() fmt.Printf("Active groups: %d\n", stats.ManagerStats.ActiveGroups) fmt.Printf("Total invites: %d\n", stats.ManagerStats.TotalInvites) fmt.Printf("Average group size: %.1f\n", stats.ManagerStats.AverageGroupSize) // Get all groups in a zone zoneGroups := service.GetGroupsByZone(zoneID) for _, group := range zoneGroups { fmt.Printf("Group %d has %d members in zone\n", group.GroupID, group.Size) } // Get groups containing specific members members := []entity.Entity{player1, player2} memberGroups := service.GetMemberGroups(members) ``` ## Event Handling ```go // Create custom event handler type MyGroupEventHandler struct{} func (h *MyGroupEventHandler) OnGroupCreated(group *groups.Group, leader entity.Entity) error { fmt.Printf("Group %d created by %s\n", group.GetID(), leader.GetName()) return nil } func (h *MyGroupEventHandler) OnGroupMemberJoined(group *groups.Group, member entity.Entity) error { fmt.Printf("%s joined group %d\n", member.GetName(), group.GetID()) return nil } func (h *MyGroupEventHandler) OnGroupDisbanded(group *groups.Group) error { fmt.Printf("Group %d disbanded\n", group.GetID()) return nil } // ... implement other required methods // Register event handler handler := &MyGroupEventHandler{} service.AddEventHandler(handler) ``` ## Database Integration ```go // Implement database interface type MyGroupDatabase struct { // database connection } func (db *MyGroupDatabase) SaveGroup(group *groups.Group) error { // Save group to database return nil } func (db *MyGroupDatabase) LoadGroup(groupID int32) (*groups.Group, error) { // Load group from database return nil, nil } // ... implement other required methods // Set database interface database := &MyGroupDatabase{} service.SetDatabase(database) ``` ## Packet Handling Integration ```go // Implement packet handler interface type MyGroupPacketHandler struct { // client connection management } func (ph *MyGroupPacketHandler) SendGroupUpdate(members []*groups.GroupMemberInfo, excludeClient interface{}) error { // Send group update packets to clients return nil } func (ph *MyGroupPacketHandler) SendGroupInvite(inviter, invitee entity.Entity) error { // Send invitation packet to client return nil } // ... implement other required methods // Set packet handler packetHandler := &MyGroupPacketHandler{} service.SetPacketHandler(packetHandler) ``` ## Validation and Security ```go // Implement custom validator type MyGroupValidator struct{} func (v *MyGroupValidator) ValidateGroupCreation(leader entity.Entity, options *groups.GroupOptions) error { // Custom validation logic if leader.GetLevel() < 10 { return fmt.Errorf("must be level 10+ to create groups") } return nil } func (v *MyGroupValidator) ValidateGroupInvite(leader, member entity.Entity) error { // Custom invitation validation if leader.GetZone() != member.GetZone() { return fmt.Errorf("cross-zone invites not allowed") } return nil } // ... implement other required methods // Set validator validator := &MyGroupValidator{} service.SetValidator(validator) ``` ## Configuration ### Service Configuration ```go config := groups.ServiceConfig{ ManagerConfig: groups.GroupManagerConfig{ MaxGroups: 1000, MaxRaidGroups: 4, InviteTimeout: 30 * time.Second, UpdateInterval: 1 * time.Second, BuffUpdateInterval: 5 * time.Second, EnableCrossServer: true, EnableRaids: true, EnableQuestSharing: true, EnableStatistics: true, }, AutoCreateGroups: true, AllowCrossZoneGroups: true, AllowBotMembers: true, AllowNPCMembers: false, MaxInviteDistance: 100.0, GroupLevelRange: 10, EnableGroupPvP: false, EnableGroupBuffs: true, DatabaseEnabled: true, EventsEnabled: true, StatisticsEnabled: true, ValidationEnabled: true, } service := groups.NewService(config) ``` ### Group Options Available group options for loot and behavior management: - **Loot Methods**: Leader only, round robin, need before greed, lotto - **Loot Rarity**: Common, uncommon, rare, legendary, fabled - **Auto Split**: Enable/disable automatic coin splitting - **Group Lock**: Open, invite only, closed - **Auto Lock**: Automatic group locking settings - **Auto Loot**: Automatic loot distribution ## Constants and Limits ### Group Limits - **MAX_GROUP_SIZE**: 6 members per group - **MAX_RAID_GROUPS**: 4 groups per raid - **MAX_RAID_SIZE**: 24 total raid members ### Invitation System - **Default invite timeout**: 30 seconds - **Invitation error codes**: Success, already in group, group full, declined, etc. ### Communication Channels - **CHANNEL_GROUP_SAY**: Group say channel (11) - **CHANNEL_GROUP_CHAT**: Group chat channel (31) - **CHANNEL_RAID_SAY**: Raid say channel (35) ## Thread Safety All group operations are thread-safe using appropriate synchronization: - **RWMutex** for read-heavy operations (member lists, group lookups) - **Atomic operations** for simple counters and flags - **Channel-based communication** for message and update processing - **Proper lock ordering** to prevent deadlocks - **Background goroutines** for periodic processing ## Integration with Other Systems The groups system integrates with: - **Entity System** - Groups work with any entity (players, NPCs, bots) - **Player System** - Player-specific group functionality and client handling - **Quest System** - Quest sharing within groups - **Spell System** - Group buffs and spell coordination - **Zone System** - Cross-zone group management - **Chat System** - Group communication channels - **Database System** - Group persistence and recovery - **Network System** - Cross-server group coordination ## Performance Considerations - **Efficient member tracking** with hash maps for O(1) lookups - **Batched message processing** to reduce overhead - **Background processing** for periodic updates and cleanup - **Memory-efficient data structures** with proper cleanup - **Statistics collection** with minimal performance impact - **Channel buffering** to prevent blocking on message queues ## Migration from C++ This Go implementation maintains compatibility with the original C++ EQ2EMu groups system while providing: - **Modern concurrency** with goroutines and channels - **Better error handling** with Go's error interface - **Cleaner architecture** with interface-based design - **Improved maintainability** with package organization - **Enhanced testing** capabilities - **Type safety** with Go's type system ## TODO Items The conversion includes TODO comments marking areas for future implementation: - **Quest sharing integration** with the quest system - **Complete spell/buff integration** for group buffs - **Advanced packet handling** for all client communication - **Complete database schema** implementation - **Cross-server peer management** completion - **Bot and NPC integration** improvements - **Advanced raid mechanics** (raid loot, raid targeting) - **Group PvP functionality** implementation - **Performance optimizations** for large-scale deployments ## Usage Examples See the code examples throughout this documentation for detailed usage patterns. The system is designed to be used alongside the existing EQ2Go server infrastructure with proper initialization and configuration. The groups system provides a solid foundation for MMO group mechanics while maintaining the flexibility to extend and customize behavior through the comprehensive interface system.