Games-Axmud
view release on metacpan or search on metacpan
lib/Games/Axmud/Client.pm view on Meta::CPAN
# -------
# Registry list of plugins (.pm files) that should be loaded as plugins at startup. Each
# item in the list is the full file path
initPluginList => [], # [config]
# Registry hash of plugins (.pm files) that have been loaded, in the form
# $pluginHash{plugin_name} = blessed_reference_to_plugin_object
pluginHash => {},
# Registry hash of client commands that are created when a plugin is loaded, in the form
# $pluginCmdHash{command_name} = plugin_name
# ...where 'command_name' matches a key in $self->clientCmdHash (e.g. 'about') and
# 'plugin_name' matches a key in $self->pluginHash
# NB If a (built-in) client command of the same name already exists, it is replaced. If
# the plugin is later disabled, the original command is restored. If the plugin is
# then re-enabled, the original command is again replaced, and so on. This works very
# well as long as the plugins you load don't themselves have client commands of the
# same name, so try to avoid that
pluginCmdHash => {},
# Registry hash of tasks that are added when a plugin is loaded, in the form
# $pluginTaskHash{task_name} = plugin_name
# ...where 'task_name' matches the task's standard name (a key in
# $self->taskPackageHash) and 'plugin_name' matches a key in $self->pluginHash
# NB Tasks with the same name as existing tasks (built-in, or from a plugin that's
# already been loaded) will not be added
pluginTaskHash => {},
# Registry hash of 'grid' windows added by the plugin. If the plugin is disabled, the
# windows are closed (and, for 'main' windows, all sessions in the 'main' windows are
# terminated). Hash in the form
# $pluginGridWinHash{package_name} = plugin_name
pluginGridWinHash => {},
# Registry hash of 'free' windows added by the plugin (not including 'dialogue'
# windows). If the plugin is disabled, the windows are closed. Hash in the form
# $pluginFreeWinHash{package_name} = plugin_name
pluginFreeWinHash => {},
# Registry hash of strip objects added by the plugin. Strip objects are always
# available, even if their parent plugin is disabled. Hash in the form
# $pluginStripObjHash{package_name} = plugin_name
pluginStripObjHash => {},
# Registry hash of table objects added by the plugin. Table objects are always
# available, even if their parent plugin is disabled. Hash in the form
# $pluginTableObjHash{package_name} = plugin_name
pluginTableObjHash => {},
# Registry hash of cages that are added when a plugin is loaded, in the form
# $pluginCageHash{cage_name} = plugin_name
# ...where 'cage_name' matches the cage's name (an item in $self->cageTypeList) and
# 'plugin_name' matches a key in $self->pluginHash
pluginCageHash => {},
# For cages that have been added by a plugin, a registry hash of package names in the
# form
# $pluginCagePackageHash{cage_name} = cage_package
# ...where 'cage_name' is an item in $self->cageTypeList, and 'cage_package' is the
# package name of the Perl object
pluginCagePackageHash => {},
# For cages that have been added by a plugin, a registry hash of 'edit' windows added by
# the plugin (where available)
# Hash in the form
# $pluginCageEditWinHash{cage_name} = config_window_package_name
# NB If no 'edit' window exists for a particular cage, 'edit_window_package_name' will
# be 'undef'
pluginCageEditWinHash => {},
# Registry hash of functions to call every time a menu strip object (GA::Strip::MenuBar)
# creates a menu in an 'internal' window, in order to add menu menu items for the
# plugin. Hash in the form
# $pluginMenuFuncHash{plugin_name} = func_ref
# ...where 'func_ref' is a reference to a function within a plugin that creates menu
# items, when passed an existing Gtk3::Menu widget
pluginMenuFuncHash => {},
# For MXP file filters that must be passed to a plugin, a registry hash of the plugin
# functions to call when the filter is applied to a file. Hash in the form
# $pluginMxpFilterHash{package_name} = reference_to_function
pluginMxpFilterHash => {},
# System loops
# ------------
# The client time (used by various parts of the code that need a time that stays
# consistent for some measured period, but which is updated frequently). Set by
# $self->spinClientLoop, whenever the client loop spins, to the same value stored as
# $self->clientLoopObj->spinTime
# (See also the corresponding session IV, GA::Session->sessionTime)
clientTime => 0,
# Each session has a session loop, also called by a Glib timer. If a Perl error is
# generated, the code in axmud.pl this flag to TRUE, which suspends the client loop
# and
# all session loops until the user lifts the suspension with the ';restart' command
suspendSessionLoopFlag => FALSE,
# Client loop
# -----------
# The GA::Obj::Loop which handles the client loop
clientLoopObj => undef,
# Flag set to TRUE (by GA::Obj::Loop->spinLoop) when the client loop spins, set back to
# FALSE when the spin is complete. The TRUE setting prevents one client loop spin from
# taking place if another is still being processed
clientLoopSpinFlag => FALSE,
# The client loop default delay, in seconds (never changes once set; absolute minimum
# value is 0.01)
clientLoopDelay => 0.1,
# File objects
# When there are no file objects in GA::Client->fileObjHash whose ->modifyFlag is set to
# TRUE (meaning that none of them need to be saved), this flag is set to FALSE
# When the first file object has its ->modifyFlag set to TRUE, this flag is set to TRUE
# When the flag changes, $self->checkMainWinTitles changes the title of all 'main'
# windows together, with an asterisk if the flag is TRUE, and no asterisk if the flag
# is FALSE
showModFlag => FALSE,
# 'internal' window blinkers (not to be confused with blinking text in textviews)
# Blinkers in GA::Strip::ConnectInfo objects (in 'internal' windows) are handled by the
# client loop. Each session has its own ->blinkerStateHash, which specifies the
# current state of each blinker when that session is the window's visible session
# ('off' or 'on' for some specified time)
# This IV specifies the blinker delay - how many seconds until the blinker, having been
# turned on, should be turned off
blinkerDelay => 0.25,
# Blinking text in textviews (not to be confused with 'internal' window blinkers)
# The time per blink for 'blink_slow' text, in seconds
blinkSlowTime => 1, # 60 blinks per minute
# The time (matches $self->clientTime) at which the 'blink_slow' text should next appear
# or disappear (one blink = one appearance and disappearance)
blinkSlowCheckTime => undef,
# Flag set to TRUE when 'blink_slow' text is visible, FALSE when 'blink_slow' text is
# invisible
blinkSlowFlag => undef,
lib/Games/Axmud/Client.pm view on Meta::CPAN
# of new sessions
constSessionMax => 1024,
# The current number of sessions allowed (ignored when $axmud::BLIND_MODE_FLAG is TRUE,
# when only one session is allowed)
sessionMax => 16, # [config]
# The current session is set whenever a session's default tab becomes the visible tab in
# a 'main' window, and is set back to 'undef' when there are no sessions running
# Set/reset by $self->setCurrentSession
currentSession => undef,
# Flag set to TRUE when Axmud should be shut down. The END() function in axmud.pl checks
# this flag and, if it's still set to FALSE, calls GA::Client->stop() before
# terminating the script. If it's set to TRUE, GA::Client->stop() has already been
# called, and we don't need to call it again
shutdownFlag => FALSE,
# Flag set to TRUE when $self->stop is first called, to prevent multiple concurrent
# calls to that function
terminatingFlag => FALSE,
# Flag that determines how a session deals with a disconnection from a world (i.e. when
# its ->status is 'connected'). FALSE if it should switch to 'disconnected' mode, TRUE
# if it should switch to 'offline' mode (as if the user had clicked the 'Connect
# offline' button in the Connections window)
offlineOnDisconnectFlag => FALSE, # [config]
# The way in which text on each session's tab label (if it's visible) is displayed:
# 'bracket' - displayed as 'deathmud (Gandalf)'
# 'hyphen' - 'deathmud - Gandalf'
# 'world' - 'deathmud'
# 'char' - 'gandalf'
# NB If $self->xTermTitleFlag is TRUE and an xterm title is received, that title is
# displayed instead
# NB If $self->longTitleFlag is TRUE, the world's long name (rather than the world's
# profile name) is used
sessionTabMode => 'bracket', # [config]
# Flag set to TRUE if xterm titles (in the form ESC]0;stringBEL ) should be displayed
# in a 'main' window tab's title (if the tab is visible) when they are received from
# the world; set to FALSE if the normal text (specified by
# GA::Session->checkTabLabels) should be displayed there (if the tab is visible)
# NB If set to TRUE, the normal text is displayed until the first xterm title is
# received
xTermTitleFlag => TRUE, # [config]
# Flag set to TRUE if the tab label (if it's visible) should use the world's long name,
# FALSE if the tab label should use the profile name
longTabLabelFlag => TRUE, # [config]
# Flag set to TRUE if a so-called 'simple tab' (a standalone Gtk3::TextView, rather than
# a tab in a Gtk3::Notebook) should be displayed when only a single session is open
# in a 'main' window (it's replaced with a Gtk3::Notebook when a second session is
# opened in the same 'main' window)
# Flag set to FALSE if a Gtk3::Notebook should always be used
# NB This IV only applies to pane objects used for sessions' default tabs
simpleTabFlag => FALSE, # [config]
# Flag set to TRUE if the user should be prompted for a confirmation if they try to
# close a 'main' window by clicking on its 'X' widget, and any of the sessions using
# the window are connected to a world
confirmCloseMainWinFlag => TRUE, # [config]
# Flag set to TRUE if the user should be prompted for a confirmation if they try to
# close a tab by clicking on its 'X' widget, and the session is connected to a world
confirmCloseTabFlag => TRUE, # [config]
# Equivalent flag set to TRUE if the user should be prompted for a confirmation if they
# try to stop the session by clicking the main window menu, and the session is
# connected to a world
confirmCloseMenuFlag => TRUE, # [config]
# Equivalent flag set to TRUE if the user should be prompted for a confirmation if they
# try to stop the session by clicking the main window toolbutton, and the session is
# connected to a world
confirmCloseToolButtonFlag => TRUE, # [config]
# The default character set to use. Must be one of the character sets available with the
# Perl Encode module
constCharSet => 'iso-8859-1',
# The current character set. For each individual session, if the current world's
# ->worldCharSet IV is set, that character set is used instead
charSet => undef, # [config] Set below
# Ordered list of available character sets (from the Perl 'encode' module)
charSetList => [], # Set below
# Flag set to TRUE if details about every connection to a world should be stored in the
# world profile, FALSE if not
connectHistoryFlag => TRUE, # [config]
# Client commands
# ---------------
# All client command objects are stored in the following hash. Each command object
# inherits from GA::Generic::Cmd
# (Actually, there are two types of client command: 'built-in' commands which exist in
# every copy of Axmud, and commands loaded from plugins which Axmud treats in almost
# exactly the same way. If plugin client commands have the same name as built-in
# client commands, then the built-in command is not available for as long as the
# plugin is enabled)
#
# Registry hash of client command objects, in the form
# $clientCmdHash{command_name} = blessed_reference_to_command_object
# e.g. $clientCmdHash{'about'} = blessed_reference_to_command_object
clientCmdHash => {},
# When a plugin adds a command with same 'command_name' as an existing client
# command, the existing command is moved out of ->clientCmdHash and into this hash.
# Later, if the plugin is disabled, the original command is moved back into
# ->clientCmdHash, and the plugin command is moved into this hash - and so on,
# ad infinitum
replaceClientCmdHash => {},
# A constant list of built-in client commands, grouped thematically and in a pre-defined
# order. Elements beginning with the @ character are group headings; everything else
# is a built-in client command
constClientCmdPrettyList => [
'@Debug commands',
'Test', 'HelpTest', 'DumpAscii', 'TestColour', 'TestXTerm', 'TestFile',
'TestModel', 'TestPattern',
'QuickInput',
'SimulateWorld', 'SimulatePrompt', 'SimulateCommand', 'SimulateHook',
'DebugToggle', 'DebugConnection', 'Restart', 'Peek', 'Poke', 'PeekHelp',
'@Client commands',
'Help', 'Hint', 'QuickHelp', 'SearchHelp', 'Blind', 'ListReserved',
'About', 'OpenAboutWindow', 'CloseAboutWindow',
'EditQuick', 'EditClient', 'EditSession',
'SwitchSession', 'MaxSession', 'ListSession', 'SetSession',
'Connect', 'Reconnect', 'XConnect', 'Telnet', 'SSH', 'SSL',
'Login',
'Quit', 'Qquit', 'QuitAll', 'Exit', 'Xxit', 'ExitAll',
'AbortSelfDestruct', 'StopSession', 'StopClient', 'Panic',
'AwayFromKeys', 'SetReminder', 'SetCountdown', 'SetCountup',
'SetLookup', 'ResetLookup', 'ForceLookup', 'ListLookup',
lib/Games/Axmud/Client.pm view on Meta::CPAN
# A set of Gtk3::Gdk::Cursors, one for when the mouse is hovering over a normal part of
# a textview, and others when it is hovering over various kinds of clickable link
constNormalCursor => Gtk3::Gdk::Cursor->new('xterm'),
constWWWCursor => Gtk3::Gdk::Cursor->new('hand1'),
constPromptCursor => Gtk3::Gdk::Cursor->new('sb_down_arrow'),
constPopupCursor => Gtk3::Gdk::Cursor->new('target'),
constCmdCursor => Gtk3::Gdk::Cursor->new('mouse'),
constMailCursor => Gtk3::Gdk::Cursor->new('pencil'),
constTelnetCursor => Gtk3::Gdk::Cursor->new('trek'),
# Another set of Gtk3::Gdk::Cursors for the automapper window's free click mode
constMapCursor => Gtk3::Gdk::Cursor->new('arrow'),
constMapAddCursor => Gtk3::Gdk::Cursor->new('plus'),
constMapConnectCursor => Gtk3::Gdk::Cursor->new('crosshair'),
constMapMergeCursor => Gtk3::Gdk::Cursor->new('target'),
# Icon file paths (relative to the main directory) for the 'internal' window strip
# object, GA::Strip::SearchBox
constUpIconPath => '/icons/search/arrow_up.png',
constDownIconPath => '/icons/search/arrow_down.png',
constResetIconPath => '/icons/search/broom.png',
constCaseIconPath => '/icons/search/capitalization.png',
constRegexIconPath => '/icons/search/token_shortland_character.png',
constDivideIconPath => '/icons/search/application_tile_vertical.png',
# Icon file paths (relative to the main directory) for the 'internal' window strip
# object, GA::Strip::Entry
constWipeIconPath => '/icons/button/broom.png',
constAddIconPath => '/icons/button/textfield_add.png',
constEmptyIconPath => '/icons/button/console.png',
constSystemIconPath => '/icons/button/console_system.png',
constDebugIconPath => '/icons/button/console_debug.png',
constErrorIconPath => '/icons/button/console_error.png',
constMultiIconPath => '/icons/button/toggle_expand.png',
constSearchIconPath => '/icons/button/search.png',
constCancelIconPath => '/icons/button/wall.png',
constSwitchIconPath => '/icons/button/switch_windows.png',
constSplitIconPath => '/icons/button/application_tile_vertical.png',
constRestoreIconPath => '/icons/button/application.png',
constScrollIconPath => '/icons/button/lock_open.png',
constLockIconPath => '/icons/button/lock.png',
# The sizes of icon provided for Axmud (icon files are in /icons/win/
# Constant list of icon sizes (these values never change; in pixels)
constIconSizeList => [16, 32, 48, 64, 128],
# Standard shadow type for Gtk3::Frame and Gtk3::ScrolledWindows (possible values are
# 'in', 'out', 'etched-in', 'etched-out' or 'none')
constShadowType => 'in',
# 'Internal' windows
# ------------------
# Axmud keeps two lists of strip objects - one for Axmud's built-in strip objects, and
# another for all strip objects (built-in objects and custom objects added via a
# plugin, which should inherit from GA::Strip::Custom)
#
# The constant registry of strip objects (these values never change). A hash in the form
# $constStripHash{package_name} = pretty_name
# NB Both 'package_name' and 'pretty_name' should be unique. To avoid problems, use the
# plugin name in 'pretty_name', e.g. 'Myplugin toolbar'
constStripHash => {
'Games::Axmud::Strip::MenuBar'
=> $axmud::SCRIPT . ' menu bar',
'Games::Axmud::Strip::Toolbar'
=> $axmud::SCRIPT . ' toolbar',
'Games::Axmud::Strip::Table'
=> $axmud::SCRIPT . ' table',
'Games::Axmud::Strip::GaugeBox'
=> $axmud::SCRIPT . ' gauge box',
'Games::Axmud::Strip::SearchBox'
=> $axmud::SCRIPT . ' search box',
'Games::Axmud::Strip::Entry'
=> $axmud::SCRIPT . ' command entry box',
'Games::Axmud::Strip::ConnectInfo'
=> $axmud::SCRIPT . ' connection info box',
},
# The customisable registry hash of strip objects, in the form
# $customStripHash{package_name} = description
customStripHash => {}, # Set below
# Likewise, Axmud keeps two lists of table objects - one for Axmud's built-in table
# objects, and another for all table objects (built-in objects and custom objects
# added via a plugin, which should inherit from GA::Table::Custom)
#
# The constant registry of table objects (these values never change). A hash in the form
# $constTableHash{package_name} = pretty-name
# NB Both 'package_name' and 'pretty_name' should be unique. To avoid problems, use the
# plugin name in 'pretty_name', e.g. 'Myplugin button'
constTableHash => {
'Games::Axmud::Table::Holder'
=> $axmud::SCRIPT . ' holder',
'Games::Axmud::Table::Container'
=> $axmud::SCRIPT . ' generic container',
'Games::Axmud::Table::MiniTable'
=> $axmud::SCRIPT . ' mini-table',
'Games::Axmud::Table::Label'
=> $axmud::SCRIPT . ' label',
'Games::Axmud::Table::Button'
=> $axmud::SCRIPT . ' button',
'Games::Axmud::Table::CheckButton'
=> $axmud::SCRIPT . ' check button',
'Games::Axmud::Table::RadioButton'
=> $axmud::SCRIPT . ' radio button',
'Games::Axmud::Table::Entry'
=> $axmud::SCRIPT . ' entry box',
'Games::Axmud::Table::ComboBox'
=> $axmud::SCRIPT . ' combobox',
'Games::Axmud::Table::SimpleList'
=> $axmud::SCRIPT . ' simple list',
'Games::Axmud::Table::TextView'
=> $axmud::SCRIPT . ' simple textview',
'Games::Axmud::Table::Pane'
=> $axmud::SCRIPT . ' window pane',
'Games::Axmud::Table::PseudoWin'
=> $axmud::SCRIPT . ' pseudo-window',
},
# The customisable registry hash of table objects, in the form
# $customTableHash{package_name} = description
customTableHash => {}, # Set below
# Constant registry list used to initialise the default set of toolbar buttons used in
# 'internal' windows (usually only 'main' windows), when required. List in groups of
lib/Games/Axmud/Client.pm view on Meta::CPAN
foreach my $session ($self->ivValues('sessionHash')) {
if (
$session->initWorld eq $worldName
&& $session->initChar
&& $session->initChar eq $thisChar
) {
next INNER;
}
}
# Get connection details for this world
($host, $port, $char, $password, $account)
= $worldObj->getConnectDetails($thisChar);
# Connect with a character
if (
$self->startSession(
$worldName,
$host,
$port,
$char,
$password,
$account
)
&& $axmud::BLIND_MODE_FLAG
) {
# In blind mode, stop after the first successful connection
last OUTER;
}
}
}
}
# During this process, if no connections were actually initialised, open the Connections
# window as normal (except in Axmud blind mode)
if (! $self->sessionHash) {
if ($axmud::BLIND_MODE_FLAG) {
$self->connectBlind();
} else {
$self->mainWin->quickFreeWin('Games::Axmud::OtherWin::Connect');
}
}
} else {
# Open the Connections window. If the user wants to connect to a world, it calls
# GA::Client->startSession
$self->mainWin->quickFreeWin('Games::Axmud::OtherWin::Connect');
}
return 1;
}
sub stop {
# Called by axmud.pl on shutdown
# Also called by $self->stopSession, GA::Cmd::StopClient->do, GA::Cmd::Panic->do,
# GA::Cmd::RestoreWorld->do, GA::Win::Internal->setDeleteEvent and
# GA::Strip::MenuBar->drawWorldColumn
# Stops the client
#
# Expected arguments
# (none besides $self)
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $check) = @_;
# Local variables
my $tempDir;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->stop', @_);
}
# The END() function will call this function again, before terminating the script, unless
# we set this flag
# (The TRUE value also gives GA::Obj::WorkspaceGrid->stop to destroy a shared 'main'
# window, rather than just disengaging it)
$self->ivPoke('shutdownFlag', TRUE);
# This flag prevents multiple concurrent calls to this function if, for example, the user
# is repeatedly clicking the 'main' window's close button
if ($self->terminatingFlag) {
return undef;
} else {
$self->ivPoke('terminatingFlag', TRUE);
}
# If any text is being convertd to speech right now, interrupt it
$self->ttsInterruptJob();
# Perform an auto-backup of Axmud's data directory, if required
if (
$self->autoBackupMode eq 'all_stop'
|| (
$self->autoBackupMode eq 'interval_stop' && $self->checkBackupInterval()
)
) {
$self->doAutoBackup();
}
# Fire any hooks in any session that are using the 'close_disconnect' hook event
foreach my $sessionObj ($self->listSessions()) {
$sessionObj->checkHooks('close_disconnect');
}
# Stop every current session
if ($self->sessionHash && ! $self->stopAllSessions()) {
return $self->writeError(
lib/Games/Axmud/Client.pm view on Meta::CPAN
$session->currentWorld->name eq $world
&& $session->currentChar && $session->currentChar->name eq $char
&& (
! $ignoreFlag
|| ($ignoreFlag && $session->status ne 'disconnected')
)
) {
$count++;
}
}
return $count;
}
sub findSessions {
# Called by GA::Session->setupProfiles
# Compiles a list of sessions whose current world matches a specified world, and returns
# the list (in the order in which the sessions were created)
#
# Expected arguments
# $worldName - The name of a world profile
#
# Optional arguments
# $ignoreSession - If specified, ignore this session
#
# Return values
# An empty list on improper arguments or if no session is using $name as its current world
# Otherwise, returns the list of matching sessions
my ($self, $worldName, $ignoreSession, $check) = @_;
# Local variables
my (@emptyList, @returnArray);
# Check for improper arguments
if (defined $check) {
$axmud::CLIENT->writeImproper($self->_objClass . '->findSessions', @_);
return @emptyList;
}
foreach my $session ($self->listSessions()) {
if (
(! $ignoreSession || $ignoreSession ne $session)
&& $session->currentWorld
&& $session->currentWorld->name eq $worldName
) {
# This is a matching GA::Session
push (@returnArray, $session);
}
}
# Return the list of matching sessions (may be empty)
return @returnArray;
}
sub checkSessions {
# Called by GA::Strip::MenuBar->drawWorldColumn just before doing the ';stopsession' or
# ';stopclient' commands
# Checks every session to see whether any of them are connected, and whether there are any
# unsaved files at all (if not, the 'main' window doesn't have to prompt the user for
# confirmation, before stopping the session/client).
#
# Expected arguments
# (none besides $self)
#
# Optional arguments
# $session - If specified, ignore other GA::Session objects (but still check the
# client's file objects)
#
# Return values
# 'undef' on improper arguments or if there are any connected sessions or unsaved files
# 1 if there are absolutely no connected sessions or unsaved files
my ($self, $session, $check) = @_;
# Check for improper arguments
if (defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->checkSessions', @_);
}
# Check GA::Client file objects
foreach my $fileObj ($self->ivValues('fileObjHash')) {
if ($fileObj->modifyFlag) {
return undef;
}
}
# Check each session in turn
foreach my $otherSession ($self->listSessions()) {
if ($session && $session ne $otherSession) {
# Ignore this session
next OUTER;
}
# Check the session's connection status
if ($otherSession->status ne 'disconnected' && $otherSession->status ne 'offline') {
return undef;
}
# Check GA::Session file objects
foreach my $fileObj ($otherSession->ivValues('sessionFileObjHash')) {
if ($fileObj->modifyFlag) {
return undef;
}
}
}
# There are no connected sessions or unsaved files
return 1;
lib/Games/Axmud/Client.pm view on Meta::CPAN
} elsif (! $cageType) {
return $self->writeError(
'Could not add cage (no cage type specified)',
$self->_objClass . '->addPluginCages',
);
}
# Check that $cageType is not too long
if (length $cageType > 8) {
return $self->writeError(
'Cage type \'' . $cageType . '\' is too long (max 8 characters)',
$self->_objClass . '->addPluginCages',
);
}
# Check that the cage type doesn't already exist
foreach my $item (@cageTypeList) {
if ($item eq $cageType) {
return $self->writeError(
'The cage type \'' . $cageType . '\' already exists',
$self->_objClass . '->addPluginCages',
);
}
}
# Add the cage
$count++;
push (@cageTypeList, $cageType);
$pluginCageHash{$cageType} = $plugin;
$pluginCagePackageHash{$cageType} = $packageName;
$pluginCageEditWinHash{$cageType} = $editWinPackage;
} until (! @list);
}
# No errors, so we can now update the GA::Client IVs (if any cages were actually added)
if ($count) {
$self->ivPoke('cageTypeList', @cageTypeList);
$self->ivPoke('pluginCageHash', %pluginCageHash);
$self->ivPoke('pluginCagePackageHash', %pluginCagePackageHash);
$self->ivPoke('pluginCageEditWinHash', %pluginCageEditWinHash);
# Update existing profiles
foreach my $session ($self->listSessions()) {
# The TRUE argument means 'don't display a message for each cage created/destroyed'
$session->updateCages(TRUE);
}
}
# Operation complete
return $count;
}
sub addPluginMenus {
# Called by any Axmud plugin
# Adds menu items defined in the plugin to any menu strip object (GA::Strip::MenuBar)
# displayed in any 'internal' window while the client is running (and the plugin is
# enabled)
#
# Expected arguments
# $plugin - The plugin's main package (declared in the file header)
#
# Optional arguments
# $funcRef - Reference to a function which contain the code to add menu items to a
# Gtk3::Menu widget, pre-existing or created by this function. The
# referenced function must accept the strip object and Gtk3::Menu as
# arguments, and return 'undef' on failure or 1 on success
#
# Return values
# 'undef' on improper arguments or if the menu items can't be added
# 1 otherwise
my ($self, $plugin, $funcRef, $check) = @_;
# Local variables
my ($pluginObj, $subMenu);
# Check for improper arguments
if (! defined $plugin || ! defined $funcRef || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->addPluginWidgets', @_);
}
# Find the plugin object
$pluginObj = $self->ivShow('pluginHash', $plugin);
if (! $pluginObj) {
# Plugin not found - a very unlikely occurrence for this function, but it's worth
# checking anyway
return undef;
}
# Each plugin can only call this function once
if ($self->ivExists('pluginMenuFuncHash', $plugin)) {
return undef;
} else {
$self->ivAdd('pluginMenuFuncHash', $plugin, $funcRef);
}
# Any 'internal' windows which already exist and which have a menu strip object should add a
# sub-menu for this plugin now; any new 'internal' windows created from now will
# automatically call the referenced function to add their own sub-menus
foreach my $winObj ($self->desktopObj->ivValues('gridWinHash')) {
my ($stripObj, $subMenu);
if (
$winObj->winType eq 'main'
|| $winObj->winType eq 'protocol'
|| $winObj->winType eq 'custom'
) {
$stripObj = $winObj->ivShow('firstStripHash', 'Games::Axmud::Strip::MenuBar');
if ($stripObj) {
$subMenu = $stripObj->addPluginWidgets($plugin);
if (! $subMenu) {
return undef;
}
# Call the referenced function to add menu items to this sub-menu
if (! &$funcRef($stripObj, $subMenu)) {
return undef;
}
# Update the window to show the new menu items
$winObj->winShowAll($self->_objClass . '->addPluginMenus');
}
}
}
return 1;
}
sub addPluginMxpFilters {
# Called by any Axmud plugin
# Adds the plugin function that's used to apply MXP file filters
#
# Expected arguments
# $plugin - The plugin's main package (declared in the file header)
# $funcRef - Reference to the function that does the conversion
#
# Return values
# 'undef' on improper arguments
# 1 otherwise
my ($self, $plugin, $funcRef, $check) = @_;
# Local variables
my $pluginObj;
# Check for improper arguments
if (! defined $plugin || ! defined $funcRef || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->addPluginMxpFilters', @_);
}
# Find the plugin object
$pluginObj = $self->ivShow('pluginHash', $plugin);
if (! $pluginObj) {
# Plugin not found - a very unlikely occurrence for this function, but it's worth
# checking anyway
return undef;
}
# Update IVs
$self->ivAdd('pluginMxpFilterHash', $plugin, $funcRef);
# Operation complete
return 1;
}
sub addPluginMcpPackages {
# Called by any Axmud plugin
# Adds the MCP package object (inheriting from GA::Generic::Mcp) defined by the plugin
#
# Expected arguments
# $plugin - The plugin's main package (declared in the file header)
# $name - The name of the MCP package, e.g. 'mcp-negotiate-can'. Must conform to
# MCP's package name rules (see the MCP spec for more information);
# this function won't allow you to add 'official' MCP packages whose
# name starts 'mcp-'
# $perlPackage - The Perl package for the object, e.g. Games::Axmud::Mcp::MyPackage
# $minVersion - The minimum package version supported (e.g. '1.0', '2.0' etc). Should
lib/Games/Axmud/Client.pm view on Meta::CPAN
return undef;
} elsif (! $self->ttsFestivalSocket->print($cmd)) {
# Socket has closed; go back to using the command line engine
$self->ivPoke('ttsFestivalServerMode', 'cmd_line');
$self->ivPoke('ttsFestivalConnectMode', 'cmd_line');
$self->ivUndef('ttsFestivalSocket');
return undef;
} else {
return 1;
}
}
# External applications
sub openFileInBrowser {
# Called by GA::Cmd::Blind->do or any other function
# Opens a file in an external web browser (if allowed)
#
# Expected arguments
# $path - The file path to open
#
# Return values
# 'undef' on improper arguments or if the path can't be opened
# 1 otherwise
my ($self, $path, $check) = @_;
# Local variables
my $cmd;
# Check for improper arguments
if (! defined $path || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->openFileInBrowser', @_);
}
if (! $self->browserCmd || ! ($self->browserCmd =~ m/%s/)) {
# No browser command set, or it doesn't contain a %s (which is substituted for the path)
return undef;
} else {
$cmd = $self->browserCmd;
$cmd =~ s/%s/$path/;
system $cmd;
return 1;
}
}
sub openURL {
# Called by GA::Strip::MenuBar->drawHelpColumn, GA::Obj::TextView->setButtonPressEvent,
# GA::OtherWin::Connect->createTableWidgets or any other function
# Opens a URL link in an external web browser (if allowed)
#
# Expected arguments
# $link - The URL to open
#
# Return values
# 'undef' on improper arguments or if the link can't be opened
# 1 otherwise
my ($self, $link, $check) = @_;
# Local variables
my $cmd;
# Check for improper arguments
if (! defined $link || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->openURL', @_);
}
if (! $self->browserCmd || ! ($self->browserCmd =~ m/%s/)) {
# No browser command set, or it doesn't contain a %s (which is substituted for the link)
return undef;
} else {
$cmd = $self->browserCmd;
$cmd =~ s/%s/$link/;
system $cmd;
return 1;
}
}
sub openEmail {
# Called by GA::Obj::TextView->setButtonPressEvent or by any other function
# Opens an email link in an external email application (if allowed)
#
# Expected arguments
# $link - The email address to open
#
# Return values
# 'undef' on improper arguments or if the link can't be opened
# 1 otherwise
my ($self, $link, $check) = @_;
# Local variables
my $cmd;
# Check for improper arguments
if (! defined $link || defined $check) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->openEmail', @_);
}
lib/Games/Axmud/Client.pm view on Meta::CPAN
}
return $self->ivIncrement('sessionCount');
}
sub set_sessionMax {
my ($self, $num, $check) = @_;
# Check for improper arguments
if (
! defined $num
|| $num > $self->constSessionMax
|| defined $check
) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->set_sessionMax', @_);
}
$self->ivPoke('sessionMax', $num);
# The data stored in this IV is saved in the 'config' file
$self->setModifyFlag('config', TRUE, $self->_objClass . '->set_sessionMax');
return 1;
}
sub toggle_sessionFlag {
my ($self, $type, $check) = @_;
# Local variables
my $iv;
# Check for improper arguments
if (
! defined $type
|| (
$type ne 'xterm' && $type ne 'long' && $type ne 'simple' && $type ne 'close_main'
&& $type ne 'close_tab' && $type ne 'close_menu' && $type ne 'close_toolbutton'
&& $type ne 'switch_offline'
)
) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->toggle_sessionFlag', @_);
}
if ($type eq 'xterm') {
$iv = 'xTermTitleFlag';
} elsif ($type eq 'long') {
$iv = 'longTabLabelFlag';
} elsif ($type eq 'simple') {
$iv = 'simpleTabFlag';
} elsif ($type eq 'close_main') {
$iv = 'confirmCloseMainWinFlag';
} elsif ($type eq 'close_tab') {
$iv = 'confirmCloseTabFlag';
} elsif ($type eq 'switch_offline') {
$iv = 'offlineOnDisconnectFlag';
} elsif ($type eq 'close_menu') {
$iv = 'confirmCloseToolButtonFlag';
} elsif ($type eq 'close_toolbutton') {
$iv = 'confirmCloseMenuFlag';
}
if ($self->$iv) {
$self->ivPoke($iv, FALSE);
} else {
$self->ivPoke($iv, TRUE);
}
# Redraw the tab title in every session
if ($type ne 'switch_offline') {
foreach my $session ($self->listSessions()) {
# The TRUE argument means 'definitely update'
$session->checkTabLabels(TRUE);
}
}
# The data stored in these IVs are saved in the 'config' file
$self->setModifyFlag('config', TRUE, $self->_objClass . '->toggle_sessionFlag');
return 1;
}
sub set_sessionTabMode {
my ($self, $mode, $check) = @_;
# Check for improper arguments
if (
defined $check
|| ($mode ne 'bracket' && $mode ne 'hyphen' && $mode ne 'world' && $mode ne 'char')
) {
return $axmud::CLIENT->writeImproper($self->_objClass . '->set_sessionTabMode', @_);
}
# Update IVs
$self->ivPoke('sessionTabMode', $mode);
# Redraw the tab title in every session
foreach my $session ($self->listSessions()) {
# The TRUE argument means 'definitely update'
$session->checkTabLabels(TRUE);
}
# The data stored in this IV is saved in the 'config' file
$self->setModifyFlag('config', TRUE, $self->_objClass . '->set_sessionTabMode');
return 1;
}
sub set_shareMainWinFlag {
# Should only be called by GA::WizWin::Setup->saveChanges. Everything else should call
# $self->set_restartShareMainWinMode
my ($self, $flag, $check) = @_;
# Check for improper arguments
lib/Games/Axmud/Client.pm view on Meta::CPAN
sub autoSaveFlag
{ $_[0]->{autoSaveFlag} }
sub autoSaveWaitTime
{ $_[0]->{autoSaveWaitTime} }
sub autoRetainFileFlag
{ $_[0]->{autoRetainFileFlag} }
sub autoBackupMode
{ $_[0]->{autoBackupMode} }
sub autoBackupDir
{ $_[0]->{autoBackupDir} }
sub autoBackupInterval
{ $_[0]->{autoBackupInterval} }
sub autoBackupDate
{ $_[0]->{autoBackupDate} }
sub autoBackupFileType
{ $_[0]->{autoBackupFileType} }
sub autoBackupAppendFlag
{ $_[0]->{autoBackupAppendFlag} }
sub fileObjHash
{ my $self = shift; return %{$self->{fileObjHash}}; }
sub configFileObj
{ $_[0]->{configFileObj} }
sub configWorldProfList
{ my $self = shift; return @{$self->{configWorldProfList}}; }
sub constLargeFileSize
{ $_[0]->{constLargeFileSize} }
sub allowModelSplitFlag
{ $_[0]->{allowModelSplitFlag} }
sub constModelSplitSize
{ $_[0]->{constModelSplitSize} }
sub modelSplitSize
{ $_[0]->{modelSplitSize} }
sub initPluginList
{ my $self = shift; return @{$self->{initPluginList}}; }
sub pluginHash
{ my $self = shift; return %{$self->{pluginHash}}; }
sub pluginCmdHash
{ my $self = shift; return %{$self->{pluginCmdHash}}; }
sub pluginTaskHash
{ my $self = shift; return %{$self->{pluginTaskHash}}; }
sub pluginGridWinHash
{ my $self = shift; return %{$self->{pluginGridWinHash}}; }
sub pluginFreeWinHash
{ my $self = shift; return %{$self->{pluginFreeWinHash}}; }
sub pluginStripObjHash
{ my $self = shift; return %{$self->{pluginStripObjHash}}; }
sub pluginTableObjHash
{ my $self = shift; return %{$self->{pluginTableObjHash}}; }
sub pluginCageHash
{ my $self = shift; return %{$self->{pluginCageHash}}; }
sub pluginCagePackageHash
{ my $self = shift; return %{$self->{pluginCagePackageHash}}; }
sub pluginCageEditWinHash
{ my $self = shift; return %{$self->{pluginCageEditWinHash}}; }
sub pluginMenuFuncHash
{ my $self = shift; return %{$self->{pluginMenuFuncHash}}; }
sub pluginMxpFilterHash
{ my $self = shift; return %{$self->{pluginMxpFilterHash}}; }
sub clientTime
{ $_[0]->{clientTime} }
sub suspendSessionLoopFlag
{ $_[0]->{suspendSessionLoopFlag} }
sub clientLoopObj
{ $_[0]->{clientLoopObj} }
sub clientLoopSpinFlag
{ $_[0]->{clientLoopSpinFlag} }
sub clientLoopDelay
{ $_[0]->{clientLoopDelay} }
sub showModFlag
{ $_[0]->{showModFlag} }
sub blinkerDelay
{ $_[0]->{blinkerDelay} }
sub blinkSlowTime
{ $_[0]->{blinkSlowTime} }
sub blinkSlowCheckTime
{ $_[0]->{blinkSlowCheckTime} }
sub blinkSlowFlag
{ $_[0]->{blinkSlowFlag} }
sub blinkFastTime
{ $_[0]->{blinkFastTime} }
sub blinkFastCheckTime
{ $_[0]->{blinkFastCheckTime} }
sub blinkFastFlag
{ $_[0]->{blinkFastFlag} }
sub paneDelay
{ $_[0]->{paneDelay} }
sub paneRestoreHash
{ my $self = shift; return %{$self->{paneRestoreHash}}; }
sub systemMsgList
{ my $self = shift; return @{$self->{systemMsgList}}; }
sub sessionHash
{ my $self = shift; return %{$self->{sessionHash}}; }
sub sessionCount
{ $_[0]->{sessionCount} }
sub constSessionMax
{ $_[0]->{constSessionMax} }
sub sessionMax
{ $_[0]->{sessionMax} }
sub currentSession
{ $_[0]->{currentSession} }
sub shutdownFlag
{ $_[0]->{shutdownFlag} }
sub terminatingFlag
{ $_[0]->{terminatingFlag} }
sub offlineOnDisconnectFlag
{ $_[0]->{offlineOnDisconnectFlag} }
sub sessionTabMode
{ $_[0]->{sessionTabMode} }
sub xTermTitleFlag
{ $_[0]->{xTermTitleFlag} }
sub longTabLabelFlag
{ $_[0]->{longTabLabelFlag} }
sub simpleTabFlag
{ $_[0]->{simpleTabFlag} }
sub confirmCloseMainWinFlag
{ $_[0]->{confirmCloseMainWinFlag} }
sub confirmCloseTabFlag
{ $_[0]->{confirmCloseTabFlag} }
sub confirmCloseMenuFlag
{ $_[0]->{confirmCloseMenuFlag} }
sub confirmCloseToolButtonFlag
{ $_[0]->{confirmCloseToolButtonFlag} }
sub constCharSet
{ $_[0]->{constCharSet} }
sub charSet
{ $_[0]->{charSet} }
sub charSetList
{ my $self = shift; return @{$self->{charSetList}}; }
sub connectHistoryFlag
{ $_[0]->{connectHistoryFlag} }
sub clientCmdHash
{ my $self = shift; return %{$self->{clientCmdHash}}; }
sub replaceClientCmdHash
{ my $self = shift; return %{$self->{replaceClientCmdHash}}; }
sub constClientCmdPrettyList
{ my $self = shift; return @{$self->{constClientCmdPrettyList}}; }
sub clientCmdPrettyList
{ my $self = shift; return @{$self->{clientCmdPrettyList}}; }
sub clientCmdList
{ my $self = shift; return @{$self->{clientCmdList}}; }
sub clientCmdReplacePrettyHash
{ my $self = shift; return %{$self->{clientCmdReplacePrettyHash}}; }
sub constUserCmdHash
{ my $self = shift; return %{$self->{constUserCmdHash}}; }
sub userCmdHash
{ my $self = shift; return %{$self->{userCmdHash}}; }
sub constClientSigil
{ $_[0]->{constClientSigil} }
sub constForcedSigil
{ $_[0]->{constForcedSigil} }
sub constEchoSigil
{ $_[0]->{constEchoSigil} }
sub constPerlSigil
{ $_[0]->{constPerlSigil} }
sub constScriptSigil
{ $_[0]->{constScriptSigil} }
sub constMultiSigil
{ $_[0]->{constMultiSigil} }
sub constSpeedSigil
{ $_[0]->{constSpeedSigil} }
sub constBypassSigil
{ $_[0]->{constBypassSigil} }
sub echoSigilFlag
{ $_[0]->{echoSigilFlag} }
sub perlSigilFlag
{ $_[0]->{perlSigilFlag} }
sub scriptSigilFlag
{ $_[0]->{scriptSigilFlag} }
sub multiSigilFlag
{ $_[0]->{multiSigilFlag} }
sub speedSigilFlag
{ $_[0]->{speedSigilFlag} }
sub bypassSigilFlag
{ $_[0]->{bypassSigilFlag} }
( run in 2.831 seconds using v1.01-cache-2.11-cpan-140bd7fdf52 )