Documentation
¶
Overview ¶
Package gmcp handles Combat Cooldown timer updates for GMCP.
Sends high-frequency timer updates (5Hz) during combat for smooth countdown animations. Uses a dedicated timer that only runs when players are in combat to minimize CPU usage.
Package gmcp handles Combat Damage notification updates for GMCP.
Stateless module that immediately forwards damage/healing events to players. No deduplication needed as each damage event is meaningful.
Package gmcp handles Combat Enemies list updates for GMCP.
Tracks all mobs targeting the player and sends updates when the enemy list changes. Includes metadata like which enemy is the primary target. Updates on round checks and immediately when enemies die or flee.
Package gmcp handles Combat Event notifications for GMCP.
Stateless event transformer that converts internal combat events into GMCP messages. Each event (CombatStarted, AttackMissed, etc.) is meaningful and sent immediately.
Package gmcp handles Combat Status updates for GMCP.
Tracks combat state changes (entering/leaving combat) and sends updates only when state changes. Uses round-based checks with immediate updates on vitals changes for accurate HP snapshots.
Package gmcp handles Combat Target updates for GMCP.
Tracks the player's current combat target and HP changes, sending updates only when: - Target changes (different mob or cleared) - Target HP changes (damage/healing) - Target dies or moves away
Index ¶
- Constants
- Variables
- func CleanupUser(userId int)
- func GetUsersInCombat() []int
- func InitCombatCooldownTimer()
- func IsUserInCombat(userId int) bool
- func SendCombatDamage(userId int, amount int, damageType string, source string, target string)
- func SendFullGMCPUpdate(userId int)
- func TrackCombatPlayer(userId int)
- func UntrackCombatPlayer(userId int)
- type CombatCooldownTimer
- type EnemyInfo
- type GMCPCharModule
- type GMCPCharModule_Enemy
- type GMCPCharModule_Payload
- type GMCPCharModule_Payload_Affect
- type GMCPCharModule_Payload_Info
- type GMCPCharModule_Payload_Inventory
- type GMCPCharModule_Payload_Inventory_Backpack
- type GMCPCharModule_Payload_Inventory_Backpack_Summary
- type GMCPCharModule_Payload_Inventory_Item
- type GMCPCharModule_Payload_Inventory_Worn
- type GMCPCharModule_Payload_Pet
- type GMCPCharModule_Payload_Quest
- type GMCPCharModule_Payload_Stats
- type GMCPCharModule_Payload_Vitals
- type GMCPCharModule_Payload_Worth
- type GMCPCharUpdate
- type GMCPCombatCooldownUpdate
- type GMCPCombatDamageUpdate
- type GMCPCombatEnemiesUpdate
- type GMCPCombatEvent
- type GMCPCombatStatusUpdate
- type GMCPCombatTargetUpdate
- type GMCPCommModule
- type GMCPCommModule_Payload
- type GMCPDiscordMessage
- type GMCPDiscordStatusRequest
- type GMCPGameModule
- type GMCPGameUpdate
- type GMCPHello
- type GMCPLogin
- type GMCPModule
- type GMCPMudletDetected
- type GMCPMudletModule
- type GMCPOut
- type GMCPPartyModule
- type GMCPPartyModule_Payload
- type GMCPPartyModule_Payload_Info
- type GMCPPartyModule_Payload_User
- type GMCPPartyModule_Payload_Vitals
- type GMCPPartyUpdate
- type GMCPRoomModule
- type GMCPRoomModule_Payload
- type GMCPRoomModule_Payload_Contents
- type GMCPRoomModule_Payload_Contents_Character
- type GMCPRoomModule_Payload_Contents_Container
- type GMCPRoomModule_Payload_Contents_ExitInfo
- type GMCPRoomModule_Payload_Contents_Item
- type GMCPRoomUpdate
- type GMCPSettings
- type GMCPSupportsRemove
- type GMCPSupportsSet
- type MudletConfig
- type PartyUpdateVitals
Constants ¶
const (
TELNET_GMCP term.IACByte = 201 // https://tintin.mudhalla.net/protocols/gmcp/
)
Variables ¶
var ( /////////////////////////// // GMCP COMMANDS /////////////////////////// GmcpEnable = term.TerminalCommand{Chars: []byte{term.TELNET_IAC, term.TELNET_WILL, TELNET_GMCP}, EndChars: []byte{}} // Indicates the server wants to enable GMCP. GmcpDisable = term.TerminalCommand{Chars: []byte{term.TELNET_IAC, term.TELNET_WONT, TELNET_GMCP}, EndChars: []byte{}} // Indicates the server wants to disable GMCP. GmcpAccept = term.TerminalCommand{Chars: []byte{term.TELNET_IAC, term.TELNET_DO, TELNET_GMCP}, EndChars: []byte{}} // Indicates the client accepts GMCP sub-negotiations. GmcpRefuse = term.TerminalCommand{Chars: []byte{term.TELNET_IAC, term.TELNET_DONT, TELNET_GMCP}, EndChars: []byte{}} // Indicates the client refuses GMCP sub-negotiations. GmcpPayload = term.TerminalCommand{Chars: []byte{term.TELNET_IAC, term.TELNET_SB, TELNET_GMCP}, EndChars: []byte{term.TELNET_IAC, term.TELNET_SE}} // Wrapper for sending GMCP payloads GmcpWebPayload = term.TerminalCommand{Chars: []byte("!!GMCP("), EndChars: []byte{')'}} // Wrapper for sending GMCP payloads )
Functions ¶
func CleanupUser ¶
func CleanupUser(userId int)
CleanupUser removes all GMCP state for a disconnecting user
func GetUsersInCombat ¶
func GetUsersInCombat() []int
GetUsersInCombat returns a list of user IDs currently in combat
func InitCombatCooldownTimer ¶
func InitCombatCooldownTimer()
InitCombatCooldownTimer initializes the cooldown timer system
func IsUserInCombat ¶
IsUserInCombat checks if a specific user is in combat
func SendCombatDamage ¶
SendCombatDamage sends a damage/healing update This is exported so it can be called from combat code
func SendFullGMCPUpdate ¶
func SendFullGMCPUpdate(userId int)
SendFullGMCPUpdate sends all GMCP modules data to a specific user This is useful when a client needs to resync all GMCP data
func TrackCombatPlayer ¶
func TrackCombatPlayer(userId int)
TrackCombatPlayer starts tracking cooldown for a player entering combat
func UntrackCombatPlayer ¶
func UntrackCombatPlayer(userId int)
UntrackCombatPlayer stops tracking cooldown for a player leaving combat
Types ¶
type CombatCooldownTimer ¶
type CombatCooldownTimer struct {
// contains filtered or unexported fields
}
CombatCooldownTimer manages the fast 1/10 second cooldown updates
func (*CombatCooldownTimer) AddPlayer ¶
func (ct *CombatCooldownTimer) AddPlayer(userId int)
AddPlayer adds a player to cooldown tracking
func (*CombatCooldownTimer) RemovePlayer ¶
func (ct *CombatCooldownTimer) RemovePlayer(userId int)
RemovePlayer removes a player from cooldown tracking
type GMCPCharModule ¶
type GMCPCharModule struct {
// contains filtered or unexported fields
}
func (*GMCPCharModule) GetCharNode ¶
func (g *GMCPCharModule) GetCharNode(user *users.UserRecord, gmcpModule string) (data any, moduleName string)
type GMCPCharModule_Enemy ¶
type GMCPCharModule_Enemy struct {
Id string `json:"id"`
Name string `json:"name"`
Level int `json:"level"`
Health int `json:"health"`
HealthMax int `json:"health_max"`
Engaged bool `json:"engaged"`
}
///////////////// Char.Enemies /////////////////
type GMCPCharModule_Payload ¶
type GMCPCharModule_Payload struct {
Info *GMCPCharModule_Payload_Info `json:"info"`
Affects map[string]GMCPCharModule_Payload_Affect `json:"affects"`
Enemies []GMCPCharModule_Enemy `json:"enemies"`
Inventory *GMCPCharModule_Payload_Inventory `json:"inventory"`
Stats *GMCPCharModule_Payload_Stats `json:"stats"`
Vitals *GMCPCharModule_Payload_Vitals `json:"vitals"`
Worth *GMCPCharModule_Payload_Worth `json:"worth"`
Quests []GMCPCharModule_Payload_Quest `json:"quests"`
Pets []GMCPCharModule_Payload_Pet `json:"pets"`
}
type GMCPCharModule_Payload_Affect ¶
type GMCPCharModule_Payload_Affect struct {
Name string `json:"name"`
Description string `json:"description"`
DurationMax int `json:"duration_max"`
DurationLeft int `json:"duration_current"`
Type string `json:"type"`
Mods map[string]int `json:"affects"`
}
///////////////// Char.Affects /////////////////
type GMCPCharModule_Payload_Info ¶
type GMCPCharModule_Payload_Info struct {
Account string `json:"account"`
Name string `json:"name"`
Class string `json:"class"`
Race string `json:"race"`
Alignment string `json:"alignment"`
Level int `json:"level"`
}
///////////////// Char.Info /////////////////
type GMCPCharModule_Payload_Inventory ¶
type GMCPCharModule_Payload_Inventory struct {
Backpack *GMCPCharModule_Payload_Inventory_Backpack `json:"Backpack"`
Worn *GMCPCharModule_Payload_Inventory_Worn `json:"Worn"`
}
///////////////// Char.Inventory /////////////////
type GMCPCharModule_Payload_Inventory_Backpack ¶
type GMCPCharModule_Payload_Inventory_Backpack struct {
Items []GMCPCharModule_Payload_Inventory_Item `json:"Items"`
Summary GMCPCharModule_Payload_Inventory_Backpack_Summary `json:"Summary"`
}
type GMCPCharModule_Payload_Inventory_Worn ¶
type GMCPCharModule_Payload_Inventory_Worn struct {
Weapon GMCPCharModule_Payload_Inventory_Item `json:"weapon"`
Offhand GMCPCharModule_Payload_Inventory_Item `json:"offhand"`
Head GMCPCharModule_Payload_Inventory_Item `json:"head"`
Neck GMCPCharModule_Payload_Inventory_Item `json:"neck"`
Body GMCPCharModule_Payload_Inventory_Item `json:"body"`
Belt GMCPCharModule_Payload_Inventory_Item `json:"belt"`
Gloves GMCPCharModule_Payload_Inventory_Item `json:"gloves"`
Ring GMCPCharModule_Payload_Inventory_Item `json:"ring"`
Legs GMCPCharModule_Payload_Inventory_Item `json:"legs"`
Feet GMCPCharModule_Payload_Inventory_Item `json:"feet"`
}
type GMCPCharModule_Payload_Pet ¶
type GMCPCharModule_Payload_Pet struct {
Name string `json:"name"`
Type string `json:"type"`
Hunger string `json:"hunger"`
}
///////////////// Char.Pets /////////////////
type GMCPCharModule_Payload_Quest ¶
type GMCPCharModule_Payload_Quest struct {
Name string `json:"name"`
Description string `json:"description"`
Completion int `json:"completion"`
}
///////////////// Char.Quests /////////////////
type GMCPCharModule_Payload_Stats ¶
type GMCPCharModule_Payload_Stats struct {
Strength int `json:"strength"`
Speed int `json:"speed"`
Smarts int `json:"smarts"`
Vitality int `json:"vitality"`
Mysticism int `json:"mysticism"`
Perception int `json:"perception"`
}
///////////////// Char.Stats /////////////////
type GMCPCharModule_Payload_Vitals ¶
type GMCPCharModule_Payload_Vitals struct {
Health int `json:"health"`
HealthMax int `json:"health_max"`
SpellPoints int `json:"spell_points"`
SpellPointsMax int `json:"spell_points_max"`
}
///////////////// Char.Vitals /////////////////
type GMCPCharModule_Payload_Worth ¶
type GMCPCharModule_Payload_Worth struct {
GoldCarried int `json:"gold_carried"`
GoldBank int `json:"gold_bank"`
SkillPoints int `json:"skill_points"`
TrainingPoints int `json:"training_points"`
ToNextLevel int `json:"to_next_level"`
Experience int `json:"experience"`
}
///////////////// Char.Worth /////////////////
type GMCPCharUpdate ¶
Tell the system a wish to send specific GMCP Update data
func (GMCPCharUpdate) Type ¶
func (g GMCPCharUpdate) Type() string
type GMCPCombatCooldownUpdate ¶
type GMCPCombatCooldownUpdate struct {
UserId int
CooldownSeconds float64
MaxSeconds float64
NameActive string
NameIdle string
}
GMCPCombatCooldownUpdate is sent frequently during combat to update cooldown timers
func (GMCPCombatCooldownUpdate) Type ¶
func (g GMCPCombatCooldownUpdate) Type() string
type GMCPCombatDamageUpdate ¶
type GMCPCombatDamageUpdate struct {
UserId int
Amount int // Positive for damage, negative for healing
DamageType string // "physical", "magical", "heal", etc.
Source string // Name of attacker/healer
Target string // Name of target
}
GMCPCombatDamageUpdate is sent when damage or healing occurs
func (GMCPCombatDamageUpdate) Type ¶
func (g GMCPCombatDamageUpdate) Type() string
type GMCPCombatEnemiesUpdate ¶
GMCPCombatEnemiesUpdate is sent when the list of enemies changes
func (GMCPCombatEnemiesUpdate) Type ¶
func (g GMCPCombatEnemiesUpdate) Type() string
type GMCPCombatEvent ¶
GMCPCombatEvent is a generic GMCP event for combat notifications
func (GMCPCombatEvent) Type ¶
func (g GMCPCombatEvent) Type() string
type GMCPCombatStatusUpdate ¶
type GMCPCombatStatusUpdate struct {
UserId int
InCombat bool
RoundNumber uint64 // Current round number
}
GMCPCombatStatusUpdate is sent when combat status changes (entering/leaving combat)
func (GMCPCombatStatusUpdate) Type ¶
func (g GMCPCombatStatusUpdate) Type() string
type GMCPCombatTargetUpdate ¶
type GMCPCombatTargetUpdate struct {
UserId int
TargetName string // Name of current target
TargetHpCurrent int // Current HP of target
TargetHpMax int // Max HP of target
}
GMCPCombatTargetUpdate is sent when a player's combat target changes or target HP changes
func (GMCPCombatTargetUpdate) Type ¶
func (g GMCPCombatTargetUpdate) Type() string
type GMCPCommModule ¶
type GMCPCommModule struct {
// contains filtered or unexported fields
}
type GMCPCommModule_Payload ¶
type GMCPDiscordMessage ¶
GMCPDiscordMessage is an event fired when a client sends a Discord-related GMCP message
func (GMCPDiscordMessage) Type ¶
func (g GMCPDiscordMessage) Type() string
type GMCPDiscordStatusRequest ¶
type GMCPDiscordStatusRequest struct {
UserId int
}
GMCPDiscordStatusRequest is an event fired when a client requests Discord status information
func (GMCPDiscordStatusRequest) Type ¶
func (g GMCPDiscordStatusRequest) Type() string
type GMCPGameModule ¶
type GMCPGameModule struct {
// contains filtered or unexported fields
}
type GMCPGameUpdate ¶
GMCPGameUpdate is used to request Game module updates
func (GMCPGameUpdate) Type ¶
func (g GMCPGameUpdate) Type() string
type GMCPModule ¶
type GMCPModule struct {
// contains filtered or unexported fields
}
/////////////////// END EVENTS ///////////////////
func (*GMCPModule) HandleIAC ¶
func (g *GMCPModule) HandleIAC(connectionId uint64, iacCmd []byte) bool
func (*GMCPModule) IsMudletExportedFunction ¶
func (g *GMCPModule) IsMudletExportedFunction(connectionId uint64) bool
type GMCPMudletDetected ¶
GMCPMudletDetected is an event fired when a Mudlet client is detected
func (GMCPMudletDetected) Type ¶
func (g GMCPMudletDetected) Type() string
type GMCPMudletModule ¶
type GMCPMudletModule struct {
// contains filtered or unexported fields
}
GMCPMudletModule handles Mudlet-specific GMCP functionality
type GMCPPartyModule ¶
type GMCPPartyModule struct {
// contains filtered or unexported fields
}
func (*GMCPPartyModule) GetPartyNode ¶
type GMCPPartyModule_Payload ¶
type GMCPPartyModule_Payload struct {
Leader string
Members []GMCPPartyModule_Payload_User
Invited []GMCPPartyModule_Payload_User
Vitals map[string]GMCPPartyModule_Payload_Vitals
}
DEPRECATED: Old combined payload structure
type GMCPPartyModule_Payload_Info ¶
type GMCPPartyModule_Payload_Info struct {
Leader string `json:"leader"`
Members []GMCPPartyModule_Payload_User `json:"members"`
Invited []GMCPPartyModule_Payload_User `json:"invited"`
}
GMCPPartyModule_Payload_Info contains static party structure
type GMCPPartyUpdate ¶
GMCPPartyUpdate is used to request Party module updates
func (GMCPPartyUpdate) Type ¶
func (g GMCPPartyUpdate) Type() string
type GMCPRoomModule ¶
type GMCPRoomModule struct {
// contains filtered or unexported fields
}
func (*GMCPRoomModule) GetRoomNode ¶
func (g *GMCPRoomModule) GetRoomNode(user *users.UserRecord, gmcpModule string) (data any, moduleName string)
type GMCPRoomModule_Payload ¶
type GMCPRoomModule_Payload struct {
Id int `json:"id"`
Name string `json:"name"`
Area string `json:"area"`
MapId string `json:"map_id"`
Environment string `json:"environment"`
Coordinates string `json:"coordinates"`
Exits map[string]GMCPRoomModule_Payload_Contents_ExitInfo `json:"exits"`
Details []string `json:"details"`
Contents GMCPRoomModule_Payload_Contents `json:"contents"`
}
type GMCPRoomModule_Payload_Contents ¶
type GMCPRoomModule_Payload_Contents struct {
Players []GMCPRoomModule_Payload_Contents_Character `json:"players"`
Npcs []GMCPRoomModule_Payload_Contents_Character `json:"npcs"`
Items []GMCPRoomModule_Payload_Contents_Item `json:"items"`
Containers []GMCPRoomModule_Payload_Contents_Container `json:"containers"`
}
///////////////// Room.Contents /////////////////
type GMCPRoomModule_Payload_Contents_Character ¶
type GMCPRoomModule_Payload_Contents_Character struct {
Id string `json:"id"`
Name string `json:"name"`
Adjectives []string `json:"adjectives"`
QuestFlag bool `json:"quest_flag"`
ThreatLevel string `json:"threat_level"` // "peaceful", "hostile", "aggressive", "fighting"
Targeting []string `json:"targeting"` // array of player names this mob is targeting
}
type GMCPRoomUpdate ¶
Tell the system a wish to send specific GMCP Update data
func (GMCPRoomUpdate) Type ¶
func (g GMCPRoomUpdate) Type() string
type GMCPSettings ¶
type GMCPSettings struct {
Client struct {
Name string
Version string
IsMudlet bool // Knowing whether is a mudlet client can be useful, since Mudlet hates certain ANSI/Escape codes.
}
GMCPAccepted bool // Do they accept GMCP data?
}
/ SETTINGS
func (*GMCPSettings) IsMudlet ¶
func (gs *GMCPSettings) IsMudlet() bool
type GMCPSupportsRemove ¶
type GMCPSupportsRemove = []string
type GMCPSupportsSet ¶
type GMCPSupportsSet []string
func (GMCPSupportsSet) GetSupportedModules ¶
func (s GMCPSupportsSet) GetSupportedModules() map[string]int
type MudletConfig ¶
type MudletConfig struct {
// Mapper configuration
MapperVersion string `json:"mapper_version" yaml:"mapper_version"`
MapperURL string `json:"mapper_url" yaml:"mapper_url"`
// UI configuration
UIVersion string `json:"ui_version" yaml:"ui_version"`
UIURL string `json:"ui_url" yaml:"ui_url"`
// Map data configuration
MapVersion string `json:"map_version" yaml:"map_version"`
MapURL string `json:"map_url" yaml:"map_url"`
// Discord Rich Presence configuration
DiscordApplicationID string `json:"discord_application_id" yaml:"discord_application_id"`
DiscordInviteURL string `json:"discord_invite_url" yaml:"discord_invite_url"`
DiscordLargeImageKey string `json:"discord_large_image_key" yaml:"discord_large_image_key"`
DiscordDetails string `json:"discord_details" yaml:"discord_details"`
DiscordState string `json:"discord_state" yaml:"discord_state"`
DiscordSmallImageKey string `json:"discord_small_image_key" yaml:"discord_small_image_key"`
}
MudletConfig holds the configuration for Mudlet clients
type PartyUpdateVitals ¶
type PartyUpdateVitals struct {
LeaderId int
}
This is a uniqu event so that multiple party members moving thorugh an area all at once don't queue up a bunch for just one party
func (PartyUpdateVitals) Type ¶
func (g PartyUpdateVitals) Type() string
func (PartyUpdateVitals) UniqueID ¶
func (g PartyUpdateVitals) UniqueID() string