Games-Axmud
view release on metacpan or search on metacpan
lib/Games/Axmud/Session.pm view on Meta::CPAN
# Copy the contents of the other session's registries directly into this session
# Copy data that has already been loaded from the 'otherprof' file
$self->ivPoke('profPriorityList', $otherSession->profPriorityList);
$self->ivPoke('templateHash', $otherSession->templateHash);
$self->ivPoke('profHash', $otherSession->profHash);
$self->ivPoke('cageHash', $otherSession->cageHash);
# (Only one current profile so far - the world profile)
$self->ivAdd('currentProfHash', $worldObj->category, $worldObj);
$self->ivPoke('currentWorld', $worldObj);
# Copy data that has already been loaded from the 'worldmodel' file
$self->ivPoke('worldModelObj', $otherSession->worldModelObj);
# Copy the other session's file object registry
$self->ivPoke('sessionFileObjHash', $otherSession->sessionFileObjHash);
# Copy the other session's current dictionary
$self->ivPoke('currentDict', $otherSession->currentDict);
# PART 6 - Load data for an existing world profile
#
# Mode 'start'/'set_exist':
# If the world profile corresponding to $worldName exists and has been a current
# profile before, it already has things like cages, a world model, and so on. Load
# these things into memory from the 'otherprof' and 'worldmodel' files
} else {
# Mark this world profile as the current one
$self->ivAdd('profHash', $worldObj->name, $worldObj);
$self->ivAdd('currentProfHash', $worldObj->category, $worldObj);
$self->ivPoke('currentWorld', $worldObj);
# Create two file objects for the two files objects associated with this profile,
# replacing the ones that we deleted earlier in this function
$otherProfFileObj = Games::Axmud::Obj::File->new('otherprof', $worldName, $self);
$worldModelFileObj = Games::Axmud::Obj::File->new('worldmodel', $worldName, $self);
if (! $otherProfFileObj || ! $worldModelFileObj) {
# (Improper arguments error already displayed)
return $self->writeError(
'Could not set up current profiles - error creating file objects',
$self->_objClass . '->setupProfiles',
);
} else {
# Add these file objects to the file object registries
$self->ivAdd('sessionFileObjHash', 'otherprof', $otherProfFileObj);
$self->ivAdd('sessionFileObjHash', 'worldmodel', $worldModelFileObj);
# The world profile's file object must appear in the GA::Client's registry and
# the GA::Session's registry too
$self->ivAdd(
'sessionFileObjHash',
$worldName,
$axmud::CLIENT->ivShow('fileObjHash', $worldName),
);
# Load the 'otherprof' and 'worldmodel' data files (which sets IVs such as the
# cage registries). If the files are big, show a 'loading...' popup
$otherProfPath = $axmud::DATA_DIR . $otherProfFileObj->standardPath;
if (
(-e $otherProfPath)
&& (-s $otherProfPath) > $axmud::CLIENT->constLargeFileSize
) {
$self->mainWin->showBusyWin();
}
if (! $otherProfFileObj->loadDataFile()) {
# Try loading the automatic backup, i.e. 'otherprof.axm.bu'
if (! $otherProfFileObj->loadDataFile(undef, undef, undef, TRUE)) {
# (Error not already displayed)
return $self->writeError(
'Could not set up current profiles - error loading the'
. ' \'otherprof\' file (file might be corrupt or missing)',
$self->_objClass . '->setupProfiles',
);
} else {
# The contents of the backup, now loaded into memory, must be saved at
# some point
$otherProfFileObj->set_modifyFlag(TRUE);
# Don't overwrite the existing backup file with the faulty one
$otherProfFileObj->set_preserveBackupFlag(TRUE);
}
}
$worldModelPath = $axmud::DATA_DIR . $worldModelFileObj->standardPath;
if (
! $axmud::CLIENT->busyWin
&& (-e $worldModelPath)
&& (-s $worldModelPath) > $axmud::CLIENT->constLargeFileSize
) {
$self->mainWin->showBusyWin();
}
if (! $worldModelFileObj->loadDataFile()) {
# Try loading the automatic backup, i.e. 'worldmodel.axm.bu'
if (! $worldModelFileObj->loadDataFile(undef, undef, undef, TRUE)) {
# (Error not already displayed)
return $self->writeError(
'Could not set up current profiles - error loading the'
. ' \'worldmodel\' file (file might be corrupt or missing)',
$self->_objClass . '->setupProfiles',
);
} else {
# The contents of the backup, now loaded into memory, must be saved at
# some point
$worldModelFileObj->set_modifyFlag(TRUE);
# Don't overwrite the existing backup file with the faulty one
$worldModelFileObj->set_preserveBackupFlag(TRUE);
}
}
lib/Games/Axmud/Session.pm view on Meta::CPAN
$ivHash{$argName} = $argValue;
}
} until (! @argList);
}
# We can't process the link until the closing </SEND> tag is found, so store arguments
# temporarily in a GA::Obj::Link object
($line, $offset) = $textViewObj->getInsertPosn();
if (! defined $line) {
$self->mxpDebug($origToken, 'Internal error while processing send', 3012);
return @emptyList;
} else {
# Take account of any lines removed from the textview's Gtk3::TextBuffer
$line += $textViewObj->nextDeleteLine;
}
# The position of the link will be the textview's current insert position, plus the
# length of any already-processed text, that hasn't been displayed in the textview
# object yet, which has been stored for us in ->processStripLine
# (The -1 argument means this is an incomplete link object, not yet applied to the
# current textview and not yet stored in the textview object's registries)
if ($self->processOrigLine ne '') {
$offset += length($self->processStripLine);
}
$linkObj = Games::Axmud::Obj::Link->new(
-1,
$textViewObj,
$line,
$offset,
'cmd',
);
if (! $linkObj) {
$self->mxpDebug($origToken, 'Internal error while processing send', 3013);
return @emptyList;
}
# Set the link object's IVs
$linkObj->ivPoke('href', $ivHash{'href'}); # May be 'undef'
$linkObj->ivPoke('hint', $ivHash{'hint'}); # May be 'undef'
$linkObj->ivPoke('mxpPromptFlag', $ivHash{'prompt'}); # Never 'undef'
$linkObj->ivPoke('expireName', $ivHash{'expire'}); # May be 'undef'
$linkObj->ivPoke('mxpFlag', TRUE);
$href = $linkObj->href;
$hint = $linkObj->hint;
if (
$href
&& (! $hint || $href =~ m/.\|./ || $hint =~ m/.\|./)
) {
# When the link is clicked, a popup menu should be displayed. Set IVs to prepare
# for that
$linkObj->ivPoke('popupFlag', TRUE);
@cmdList = split('\|', $href);
if ($hint) {
@optionList = split('\|', $hint);
if (((scalar @cmdList) + 1) == (scalar @optionList)) {
# The first item in @optionList is the hint; the rest are menu items
$linkObj->ivPoke('hint', shift @optionList);
} elsif ((scalar @cmdList) > 1 && (scalar @optionList) == 1) {
# The only item in @optionList must be a hint, as there are more commands
# than hints
$linkObj->ivPoke('hint', shift @optionList);
} elsif ((scalar @cmdList) != (scalar @optionList)) {
$self->mxpDebug($origToken, 'Invalid SEND menu option format', 3014);
return @emptyList;
} else {
$linkObj->ivPoke('hint', undef);
}
} else {
$linkObj->ivPoke('hint', undef);
}
$linkObj->ivPoke('popupCmdList', @cmdList);
$linkObj->ivPoke('popupItemList', @optionList);
}
# Store the current link object (the link isn't applied to the textview until the
# corresponding </SEND> tag is processed, although any text inside the
# <SEND>...</SEND> is displayed immediately, as normal)
$self->ivPoke('mxpCurrentSend', $linkObj);
# Also need to create a new MXP stack object and store it in the current textview
# object, updating the latter's IVs
if (! $textViewObj->createMxpStackObj($self, 'SEND')) {
$self->mxpDebug($origToken, 'Internal error while processing element', 3015);
return @emptyList;
} else {
# Operation complete
return @emptyList;
}
# Process the <\SEND> tag
} else {
# Watch out for a <SEND> ... </SEND> ... </SEND> construction
if (! $self->mxpCurrentSend) {
# This a second </SEND> tag after an earlier </SEND> tag
$self->mxpDebug($origToken, '</SEND> tag does not match earlier <SEND> tag', 3021);
return @emptyList;
} else {
$linkObj = $self->mxpCurrentSend;
$self->ivUndef('mxpCurrentSend');
}
if (! $linkObj->text && $linkObj->type ne 'image') {
# There were no valid text tokens (or clickable images) between the <SEND>...</SEND>
# tags
$self->mxpDebug($origToken, 'Invalid <SEND>...</SEND> construction', 3022);
return @emptyList;
} else {
# The incomplete link object is now complete, but we can't apply the link to the
# current textview yet, as there may be some text before the link which hasn't
# been displayed yet
# Instead, store it temporarily in an IV, and let $self->processIncomingData call
# GA::Obj::TextView->add_incompleteLink as soon as it's ready
$self->ivPush('mxpTempLinkList', $linkObj);
# Process any entities. The MXP documentation documents the use of &text; but some
# MUDs might choose to use any entity in their <SEND>...</SEND> constructions
# Don't process entities for clickable images
$href = $linkObj->href;
$text = $linkObj->text;
if ($href && $text && $linkObj->type ne 'image') {
$href =~ s/\&text\;/$text/g;
$href = $self->replaceMxpEntities($href);
$linkObj->ivPoke('href', $href);
}
# Do the same, if a popup menu is to be created
foreach my $item ($linkObj->popupCmdList) {
$item =~ s/\&text\;/$text/g;
$item = $self->replaceMxpEntities($item);
push (@cmdList, $item);
}
foreach my $item ($linkObj->popupItemList) {
$item =~ s/\&text\;/$text/g;
$item = $self->replaceMxpEntities($item);
push (@optionList, $item);
}
$linkObj->ivPoke('popupCmdList', @cmdList);
$linkObj->ivPoke('popupItemList', @optionList);
}
# Close the <SEND>...</SEND> construction, if the calling function isn't doing that (the
# TRUE function means don't call this function back, as you normally would)
if (! $noPopFlag) {
return $self->popMxpStack($keyword, TRUE);
} else {
# Operation complete
return @emptyList;
}
}
}
sub processMxpSoundElement {
# Called by $self->processMxpElement
#
# Process an MXP sound element: <SOUND> or <MUSIC>
#
# Expected arguments
# $origToken - The original token text, before anything was extracted
# $tagMode - 'open' for <..> elements, 'close' for </..> elements, 'defn' for <!..>
# elements
# $keyword - The element keyword (already converted to upper case)
#
# Optional arguments
# @argList - If the element has arguments, a list in the form
# (arg_name, arg_value, arg_name, arg_value...)
# ...where each 'arg_value' is 'undef' is the argument wasn't a name=value
# construction
#
# Return values
# An empty list on improper arguments
# Otherwise returns an equivalent list of Axmud colour/style tags otherwise (may be an
# empty list)
my ($self, $origToken, $tagMode, $keyword, @argList) = @_;
# Local variables
my (
$token,
@emptyList,
);
# Check for improper arguments
if (! defined $origToken || ! defined $tagMode || ! defined $keyword) {
$axmud::CLIENT->writeImproper($self->_objClass . '->processMxpSoundElement', @_);
return @emptyList;
}
# <SOUND FName V=volume L=repeats P=priority C=continue T=type U=url>
# <MUSIC FName V=volume L=repeats P=priority C=continue T=type U=url>
# <SOUND Off>
# <SOUND Off U=default_url>
# <MUSIC Off>
# <MUSIC Off U=default_url>
( run in 1.185 second using v1.01-cache-2.11-cpan-364913b4093 )