eq2go/internal/groups/interfaces.go

503 lines
16 KiB
Go

package groups
import (
"eq2emu/internal/entity"
"time"
)
// GroupAware interface for entities that can be part of groups
type GroupAware interface {
// GetGroupMemberInfo returns the group member info for this entity
GetGroupMemberInfo() *GroupMemberInfo
// SetGroupMemberInfo sets the group member info for this entity
SetGroupMemberInfo(info *GroupMemberInfo)
// GetGroupID returns the current group ID
GetGroupID() int32
// SetGroupID sets the current group ID
SetGroupID(groupID int32)
// IsInGroup returns true if the entity is in a group
IsInGroup() bool
}
// GroupManager interface for managing groups
type GroupManagerInterface interface {
// Group creation and management
NewGroup(leader entity.Entity, options *GroupOptions, overrideGroupID int32) (int32, error)
RemoveGroup(groupID int32) error
GetGroup(groupID int32) *Group
IsGroupIDValid(groupID int32) bool
// Member management
AddGroupMember(groupID int32, member entity.Entity, isLeader bool) error
AddGroupMemberFromPeer(groupID int32, info *GroupMemberInfo) error
RemoveGroupMember(groupID int32, member entity.Entity) error
RemoveGroupMemberByName(groupID int32, name string, isClient bool, charID int32) error
// Group updates
SendGroupUpdate(groupID int32, excludeClient interface{}, forceRaidUpdate bool)
// Invitations
Invite(leader entity.Entity, member entity.Entity) int8
AddInvite(leader entity.Entity, member entity.Entity) bool
AcceptInvite(member entity.Entity, groupOverrideID *int32, autoAddGroup bool) int8
DeclineInvite(member entity.Entity)
ClearPendingInvite(member entity.Entity)
HasPendingInvite(member entity.Entity) string
// Group utilities
GetGroupSize(groupID int32) int32
IsInGroup(groupID int32, member entity.Entity) bool
IsPlayerInGroup(groupID int32, charID int32) entity.Entity
IsSpawnInGroup(groupID int32, name string) bool
GetGroupLeader(groupID int32) entity.Entity
MakeLeader(groupID int32, newLeader entity.Entity) bool
// Messaging
SimpleGroupMessage(groupID int32, message string)
SendGroupMessage(groupID int32, msgType int8, message string)
GroupMessage(groupID int32, message string)
GroupChatMessage(groupID int32, from entity.Entity, language int32, message string, channel int16)
GroupChatMessageFromName(groupID int32, fromName string, language int32, message string, channel int16)
SendGroupChatMessage(groupID int32, channel int16, message string)
// Raid functionality
ClearGroupRaid(groupID int32)
RemoveGroupFromRaid(groupID, targetGroupID int32)
IsInRaidGroup(groupID, targetGroupID int32, isLeaderGroup bool) bool
GetRaidGroups(groupID int32) []int32
ReplaceRaidGroups(groupID int32, newGroups []int32)
// Group options
GetDefaultGroupOptions(groupID int32) (GroupOptions, bool)
SetGroupOptions(groupID int32, options *GroupOptions) error
// Statistics
GetStats() GroupManagerStats
GetGroupCount() int32
GetAllGroups() []*Group
}
// GroupEventHandler interface for handling group events
type GroupEventHandler interface {
// Group lifecycle events
OnGroupCreated(group *Group, leader entity.Entity) error
OnGroupDisbanded(group *Group) error
OnGroupMemberJoined(group *Group, member entity.Entity) error
OnGroupMemberLeft(group *Group, member entity.Entity) error
OnGroupLeaderChanged(group *Group, oldLeader, newLeader entity.Entity) error
// Invitation events
OnGroupInviteSent(leader, member entity.Entity) error
OnGroupInviteAccepted(leader, member entity.Entity, groupID int32) error
OnGroupInviteDeclined(leader, member entity.Entity) error
OnGroupInviteExpired(leader, member entity.Entity) error
// Raid events
OnRaidFormed(groups []*Group) error
OnRaidDisbanded(groups []*Group) error
OnRaidInviteSent(leaderGroup *Group, targetGroup *Group) error
OnRaidInviteAccepted(leaderGroup *Group, targetGroup *Group) error
OnRaidInviteDeclined(leaderGroup *Group, targetGroup *Group) error
// Group activity events
OnGroupMessage(group *Group, from entity.Entity, message string, channel int16) error
OnGroupOptionsChanged(group *Group, oldOptions, newOptions *GroupOptions) error
OnGroupMemberUpdate(group *Group, member *GroupMemberInfo) error
}
// GroupDatabase interface for database operations
type GroupDatabase interface {
// Group persistence
SaveGroup(group *Group) error
LoadGroup(groupID int32) (*Group, error)
DeleteGroup(groupID int32) error
// Group member persistence
SaveGroupMember(groupID int32, member *GroupMemberInfo) error
LoadGroupMembers(groupID int32) ([]*GroupMemberInfo, error)
DeleteGroupMember(groupID int32, memberName string) error
// Group options persistence
SaveGroupOptions(groupID int32, options *GroupOptions) error
LoadGroupOptions(groupID int32) (*GroupOptions, error)
// Raid persistence
SaveRaidGroups(groupID int32, raidGroups []int32) error
LoadRaidGroups(groupID int32) ([]int32, error)
// Statistics persistence
SaveGroupStats(stats *GroupManagerStats) error
LoadGroupStats() (*GroupManagerStats, error)
// Cleanup operations
CleanupExpiredGroups() error
CleanupOrphanedMembers() error
}
// GroupPacketHandler interface for handling group-related packets
type GroupPacketHandler interface {
// Group update packets
SendGroupUpdate(members []*GroupMemberInfo, excludeClient interface{}) error
SendGroupMemberUpdate(member *GroupMemberInfo, excludeClient interface{}) error
SendGroupOptionsUpdate(groupID int32, options *GroupOptions, excludeClient interface{}) error
// Group invitation packets
SendGroupInvite(inviter, invitee entity.Entity) error
SendGroupInviteResponse(inviter, invitee entity.Entity, accepted bool) error
// Group messaging packets
SendGroupMessage(members []*GroupMemberInfo, message *GroupMessage) error
SendGroupChatMessage(members []*GroupMemberInfo, from string, message string, channel int16, language int32) error
// Raid packets
SendRaidUpdate(raidGroups []*Group, excludeClient interface{}) error
SendRaidInvite(leaderGroup, targetGroup *Group) error
SendRaidInviteResponse(leaderGroup, targetGroup *Group, accepted bool) error
// Group UI packets
SendGroupWindowUpdate(client interface{}, group *Group) error
SendRaidWindowUpdate(client interface{}, raidGroups []*Group) error
// Group member packets
SendGroupMemberStats(member *GroupMemberInfo, excludeClient interface{}) error
SendGroupMemberZoneChange(member *GroupMemberInfo, oldZoneID, newZoneID int32) error
}
// GroupValidator interface for validating group operations
type GroupValidator interface {
// Group creation validation
ValidateGroupCreation(leader entity.Entity, options *GroupOptions) error
ValidateGroupJoin(group *Group, member entity.Entity) error
ValidateGroupLeave(group *Group, member entity.Entity) error
// Invitation validation
ValidateGroupInvite(leader, member entity.Entity) error
ValidateRaidInvite(leaderGroup, targetGroup *Group) error
// Group operation validation
ValidateLeadershipChange(group *Group, oldLeader, newLeader entity.Entity) error
ValidateGroupOptions(group *Group, options *GroupOptions) error
ValidateGroupMessage(group *Group, from entity.Entity, message string) error
// Raid validation
ValidateRaidFormation(groups []*Group) error
ValidateRaidOperation(raidGroups []*Group, operation string) error
}
// GroupNotifier interface for sending notifications
type GroupNotifier interface {
// Group notifications
NotifyGroupCreated(group *Group, leader entity.Entity) error
NotifyGroupDisbanded(group *Group, reason string) error
NotifyGroupMemberJoined(group *Group, member entity.Entity) error
NotifyGroupMemberLeft(group *Group, member entity.Entity, reason string) error
NotifyGroupLeaderChanged(group *Group, oldLeader, newLeader entity.Entity) error
// Invitation notifications
NotifyGroupInviteSent(leader, member entity.Entity) error
NotifyGroupInviteReceived(leader, member entity.Entity) error
NotifyGroupInviteAccepted(leader, member entity.Entity, groupID int32) error
NotifyGroupInviteDeclined(leader, member entity.Entity) error
NotifyGroupInviteExpired(leader, member entity.Entity) error
// Raid notifications
NotifyRaidFormed(groups []*Group) error
NotifyRaidDisbanded(groups []*Group, reason string) error
NotifyRaidInviteSent(leaderGroup, targetGroup *Group) error
NotifyRaidInviteReceived(leaderGroup, targetGroup *Group) error
NotifyRaidInviteAccepted(leaderGroup, targetGroup *Group) error
NotifyRaidInviteDeclined(leaderGroup, targetGroup *Group) error
// System notifications
NotifyGroupSystemMessage(group *Group, message string, msgType int8) error
NotifyGroupError(group *Group, error string, errorCode int8) error
}
// GroupStatistics interface for tracking group statistics
type GroupStatistics interface {
// Group statistics
RecordGroupCreated(group *Group, leader entity.Entity)
RecordGroupDisbanded(group *Group, duration int64)
RecordGroupMemberJoined(group *Group, member entity.Entity)
RecordGroupMemberLeft(group *Group, member entity.Entity, duration int64)
// Invitation statistics
RecordInviteSent(leader, member entity.Entity)
RecordInviteAccepted(leader, member entity.Entity, responseTime int64)
RecordInviteDeclined(leader, member entity.Entity, responseTime int64)
RecordInviteExpired(leader, member entity.Entity)
// Raid statistics
RecordRaidFormed(groups []*Group)
RecordRaidDisbanded(groups []*Group, duration int64)
// Activity statistics
RecordGroupMessage(group *Group, from entity.Entity, messageType int8)
RecordGroupActivity(group *Group, activityType string)
// Performance statistics
RecordGroupProcessingTime(operation string, duration int64)
RecordGroupMemoryUsage(groups int32, members int32)
// Statistics retrieval
GetGroupStatistics(groupID int32) map[string]interface{}
GetOverallStatistics() map[string]interface{}
GetStatisticsSummary() *GroupManagerStats
}
// GroupAdapter adapts group functionality for other systems
type GroupAdapter struct {
group *Group
}
// NewGroupAdapter creates a new group adapter
func NewGroupAdapter(group *Group) *GroupAdapter {
return &GroupAdapter{group: group}
}
// GetGroup returns the wrapped group
func (ga *GroupAdapter) GetGroup() *Group {
return ga.group
}
// GetGroupID returns the group ID
func (ga *GroupAdapter) GetGroupID() int32 {
return ga.group.GetID()
}
// GetGroupSize returns the group size
func (ga *GroupAdapter) GetGroupSize() int32 {
return ga.group.GetSize()
}
// GetMembers returns group members
func (ga *GroupAdapter) GetMembers() []*GroupMemberInfo {
return ga.group.GetMembers()
}
// GetLeader returns the group leader
func (ga *GroupAdapter) GetLeader() entity.Entity {
members := ga.group.GetMembers()
for _, member := range members {
if member.Leader {
return member.Member
}
}
return nil
}
// GetLeaderName returns the group leader's name
func (ga *GroupAdapter) GetLeaderName() string {
return ga.group.GetLeaderName()
}
// IsInRaid returns true if the group is part of a raid
func (ga *GroupAdapter) IsInRaid() bool {
return ga.group.IsGroupRaid()
}
// GetRaidGroups returns the raid groups
func (ga *GroupAdapter) GetRaidGroups() []int32 {
return ga.group.GetRaidGroups()
}
// IsMember checks if an entity is a member of the group
func (ga *GroupAdapter) IsMember(entity entity.Entity) bool {
if entity == nil {
return false
}
members := ga.group.GetMembers()
for _, member := range members {
if member.Member == entity {
return true
}
}
return false
}
// HasMemberNamed checks if the group has a member with the given name
func (ga *GroupAdapter) HasMemberNamed(name string) bool {
members := ga.group.GetMembers()
for _, member := range members {
if member.Name == name {
return true
}
}
return false
}
// GetMemberByName returns a member by name
func (ga *GroupAdapter) GetMemberByName(name string) *GroupMemberInfo {
members := ga.group.GetMembers()
for _, member := range members {
if member.Name == name {
return member
}
}
return nil
}
// GetMemberByEntity returns a member by entity
func (ga *GroupAdapter) GetMemberByEntity(entity entity.Entity) *GroupMemberInfo {
if entity == nil {
return nil
}
members := ga.group.GetMembers()
for _, member := range members {
if member.Member == entity {
return member
}
}
return nil
}
// IsLeader checks if an entity is the group leader
func (ga *GroupAdapter) IsLeader(entity entity.Entity) bool {
if entity == nil {
return false
}
members := ga.group.GetMembers()
for _, member := range members {
if member.Member == entity && member.Leader {
return true
}
}
return false
}
// GetOptions returns the group options
func (ga *GroupAdapter) GetOptions() GroupOptions {
return ga.group.GetGroupOptions()
}
// IsDisbanded returns true if the group has been disbanded
func (ga *GroupAdapter) IsDisbanded() bool {
return ga.group.IsDisbanded()
}
// GetCreatedTime returns when the group was created
func (ga *GroupAdapter) GetCreatedTime() time.Time {
return ga.group.GetCreatedTime()
}
// GetLastActivity returns the last activity time
func (ga *GroupAdapter) GetLastActivity() time.Time {
return ga.group.GetLastActivity()
}
// EntityGroupAdapter adapts entity functionality for group systems
type EntityGroupAdapter struct {
entity entity.Entity
}
// NewEntityGroupAdapter creates a new entity group adapter
func NewEntityGroupAdapter(entity entity.Entity) *EntityGroupAdapter {
return &EntityGroupAdapter{entity: entity}
}
// GetEntity returns the wrapped entity
func (ega *EntityGroupAdapter) GetEntity() entity.Entity {
return ega.entity
}
// GetName returns the entity name
func (ega *EntityGroupAdapter) GetName() string {
return ega.entity.GetName()
}
// GetLevel returns the entity level
func (ega *EntityGroupAdapter) GetLevel() int8 {
return ega.entity.GetLevel()
}
// GetClass returns the entity class
func (ega *EntityGroupAdapter) GetClass() int8 {
return ega.entity.GetClass()
}
// GetRace returns the entity race
func (ega *EntityGroupAdapter) GetRace() int8 {
return ega.entity.GetRace()
}
// GetZoneID returns the current zone ID
func (ega *EntityGroupAdapter) GetZoneID() int32 {
if zone := ega.entity.GetZone(); zone != nil {
return zone.GetZoneID()
}
return 0
}
// GetInstanceID returns the current instance ID
func (ega *EntityGroupAdapter) GetInstanceID() int32 {
if zone := ega.entity.GetZone(); zone != nil {
return zone.GetInstanceID()
}
return 0
}
// GetZoneName returns the current zone name
func (ega *EntityGroupAdapter) GetZoneName() string {
if zone := ega.entity.GetZone(); zone != nil {
return zone.GetZoneName()
}
return ""
}
// GetHP returns current HP
func (ega *EntityGroupAdapter) GetHP() int32 {
return ega.entity.GetHP()
}
// GetMaxHP returns maximum HP
func (ega *EntityGroupAdapter) GetMaxHP() int32 {
return ega.entity.GetTotalHP()
}
// GetPower returns current power
func (ega *EntityGroupAdapter) GetPower() int32 {
return ega.entity.GetPower()
}
// GetMaxPower returns maximum power
func (ega *EntityGroupAdapter) GetMaxPower() int32 {
return ega.entity.GetTotalPower()
}
// IsPlayer returns true if the entity is a player
func (ega *EntityGroupAdapter) IsPlayer() bool {
return ega.entity.IsPlayer()
}
// IsNPC returns true if the entity is an NPC
func (ega *EntityGroupAdapter) IsNPC() bool {
return ega.entity.IsNPC()
}
// IsBot returns true if the entity is a bot
func (ega *EntityGroupAdapter) IsBot() bool {
return ega.entity.IsBot()
}
// IsAlive returns true if the entity is alive
func (ega *EntityGroupAdapter) IsAlive() bool {
return !ega.entity.IsDead()
}
// IsDead returns true if the entity is dead
func (ega *EntityGroupAdapter) IsDead() bool {
return ega.entity.IsDead()
}
// GetDistance returns distance to another entity
func (ega *EntityGroupAdapter) GetDistance(other entity.Entity) float32 {
return ega.entity.GetDistance(&other.Spawn)
}