package channelserver import ( "erupe-ce/network/mhfpacket" "net" ) // ChannelRegistry abstracts cross-channel operations behind an interface. // The default LocalChannelRegistry wraps the in-process []*Server slice. // Future implementations may use DB/Redis/NATS for multi-process deployments. type ChannelRegistry interface { // Worldcast broadcasts a packet to all sessions across all channels. Worldcast(pkt mhfpacket.MHFPacket, ignoredSession *Session, ignoredChannel *Server) // FindSessionByCharID looks up a session by character ID across all channels. FindSessionByCharID(charID uint32) *Session // DisconnectUser disconnects all sessions belonging to the given character IDs. DisconnectUser(cids []uint32) // FindChannelForStage searches all channels for a stage whose ID has the // given suffix and returns the owning channel's GlobalID, or "" if not found. FindChannelForStage(stageSuffix string) string // SearchSessions searches sessions across all channels using a predicate, // returning up to max snapshot results. SearchSessions(predicate func(SessionSnapshot) bool, max int) []SessionSnapshot // SearchStages searches stages across all channels with a prefix filter, // returning up to max snapshot results. SearchStages(stagePrefix string, max int) []StageSnapshot // NotifyMailToCharID finds the session for charID and sends a mail notification. NotifyMailToCharID(charID uint32, sender *Session, mail *Mail) } // SessionSnapshot is an immutable copy of session data taken under lock. type SessionSnapshot struct { CharID uint32 Name string StageID string ServerIP net.IP ServerPort uint16 UserBinary3 []byte // Copy of userBinaryParts index 3 } // StageSnapshot is an immutable copy of stage data taken under lock. type StageSnapshot struct { ServerIP net.IP ServerPort uint16 StageID string ClientCount int Reserved int QuestReserved int // Players who left to enter quest stages ("Qs" prefix) MaxPlayers uint16 RawBinData0 []byte RawBinData1 []byte RawBinData3 []byte }