Commands.pm
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:160k
- #########################################################################
- # OpenKore - Commandline
- #
- # This software is open source, licensed under the GNU General Public
- # License, version 2.
- # Basically, this means that you're allowed to modify and distribute
- # this software. However, if you distribute modified versions, you MUST
- # also distribute the source code.
- # See http://www.gnu.org/licenses/gpl.html for the full license.
- #
- # $Revision: 6780 $
- # $Id: Commands.pm 6780 2009-07-23 21:32:55Z Technologyguild $
- #
- #########################################################################
- ##
- # MODULE DESCRIPTION: Commandline input processing
- #
- # This module processes commandline input.
- package Commands;
- use strict;
- use warnings;
- no warnings qw(redefine uninitialized);
- use Time::HiRes qw(time);
- use encoding 'utf8';
- use Modules 'register';
- use Globals;
- use Log qw(message debug error warning);
- use Network;
- use Network::Send ();
- use Settings;
- use Plugins;
- use Skill;
- use Utils;
- use Utils::Exceptions;
- use Misc;
- use AI;
- use Task;
- use Task::ErrorReport;
- use Match;
- use Translation;
- use I18N qw(stringToBytes);
- our %handlers;
- our %completions;
- undef %handlers;
- undef %completions;
- our %customCommands;
- sub initHandlers {
- %handlers = (
- a => &cmdAttack,
- ai => &cmdAI,
- aiv => &cmdAIv,
- al => &cmdShopInfoSelf,
- arrowcraft => &cmdArrowCraft,
- as => &cmdAttackStop,
- autobuy => &cmdAutoBuy,
- autosell => &cmdAutoSell,
- autostorage => &cmdAutoStorage,
- auth => &cmdAuthorize,
- bangbang => &cmdBangBang,
- bingbing => &cmdBingBing,
- buy => &cmdBuy,
- c => &cmdChat,
- card => &cmdCard,
- cart => &cmdCart,
- chat => &cmdChatRoom,
- chist => &cmdChist,
- cil => &cmdItemLogClear,
- cl => &cmdChatLogClear,
- closeshop => &cmdCloseShop,
- conf => &cmdConf,
- damage => &cmdDamage,
- deal => &cmdDeal,
- debug => &cmdDebug,
- dl => &cmdDealList,
- doridori => &cmdDoriDori,
- drop => &cmdDrop,
- dump => &cmdDump,
- dumpnow => &cmdDumpNow,
- e => &cmdEmotion,
- eq => &cmdEquip,
- eval => &cmdEval,
- exp => &cmdExp,
- falcon => &cmdFalcon,
- follow => &cmdFollow,
- friend => &cmdFriend,
- homun => &cmdSlave,
- merc => &cmdSlave,
- g => &cmdGuildChat,
- getplayerinfo => &cmdGetPlayerInfo,
- # GM Commands - Start
- gmb => &cmdGmb,
- gmbb => &cmdGmbb,
- gmnb => &cmdGmnb,
- gmlb => &cmdGmlb,
- gmlbb => &cmdGmlbb,
- gmnlb => &cmdGmnlb,
- gmmapmove => &cmdGmmapmove,
- gmcreate => &cmdGmcreate,
- gmhide => &cmdGmhide,
- gmwarpto => &cmdGmwarpto,
- gmsummon => &cmdGmsummon,
- gmrecall => &cmdGmrecall,
- gmremove => &cmdGmremove,
- gmdc => &cmdGmdc,
- gmresetskill => &cmdGmresetskill,
- gmresetstate => &cmdGmresetstate,
- gmmute => &cmdGmmute,
- gmunmute => &cmdGmunmute,
- gmkillall => &cmdGmkillall,
- # GM Commands - End
- guild => &cmdGuild,
- help => &cmdHelp,
- i => &cmdInventory,
- identify => &cmdIdentify,
- ignore => &cmdIgnore,
- ihist => &cmdIhist,
- il => &cmdItemList,
- im => &cmdUseItemOnMonster,
- ip => &cmdUseItemOnPlayer,
- is => &cmdUseItemOnSelf,
- kill => &cmdKill,
- look => &cmdLook,
- lookp => &cmdLookPlayer,
- memo => &cmdMemo,
- ml => &cmdMonsterList,
- move => &cmdMove,
- nl => &cmdNPCList,
- openshop => &cmdOpenShop,
- p => &cmdPartyChat,
- party => &cmdParty,
- pecopeco => &cmdPecopeco,
- #pet => &cmdPet,
- petl => &cmdPetList,
- pl => &cmdPlayerList,
- plugin => &cmdPlugin,
- pm => &cmdPrivateMessage,
- pml => &cmdPMList,
- portals => &cmdPortalList,
- quit => &cmdQuit,
- rc => &cmdReloadCode,
- reload => &cmdReload,
- relog => &cmdRelog,
- repair => &cmdRepair,
- respawn => &cmdRespawn,
- s => &cmdStatus,
- sell => &cmdSell,
- send => &cmdSendRaw,
- sit => &cmdSit,
- skills => &cmdSkills,
- sll => &cmdSlaveList,
- spells => &cmdSpells,
- storage => &cmdStorage,
- store => &cmdStore,
- sl => &cmdUseSkill,
- sm => &cmdUseSkill,
- sp => &cmdUseSkill,
- ss => &cmdUseSkill,
- ssp => &cmdUseSkill,
- st => &cmdStats,
- stand => &cmdStand,
- stat_add => &cmdStatAdd,
- switchconf => &cmdSwitchConf,
- take => &cmdTake,
- talk => &cmdTalk,
- talknpc => &cmdTalkNPC,
- tank => &cmdTank,
- tele => &cmdTeleport,
- testshop => &cmdTestShop,
- timeout => &cmdTimeout,
- top10 => &cmdTop10,
- uneq => &cmdUnequip,
- vender => &cmdVender,
- verbose => &cmdVerbose,
- version => &cmdVersion,
- vl => &cmdVenderList,
- warp => &cmdWarp,
- weight => &cmdWeight,
- where => &cmdWhere,
- who => &cmdWho,
- whoami => &cmdWhoAmI,
- m => &cmdMail, # see commands
- ms => &cmdMail, # send
- mi => &cmdMail, # inbox
- mo => &cmdMail, # open
- md => &cmdMail, # delete
- mw => &cmdMail, # window
- mr => &cmdMail, # return
- ma => &cmdMail, # attachement
-
- au => &cmdAuction, # see commands
- aua => &cmdAuction, # add item
- aur => &cmdAuction, # remove item
- auc => &cmdAuction, # create auction
- aue => &cmdAuction, # auction end
- aus => &cmdAuction, # search auction
- aub => &cmdAuction, # make bid
- aui => &cmdAuction, # info on buy/sell
- aud => &cmdAuction, # delete auction
- north => &cmdManualMove,
- south => &cmdManualMove,
- east => &cmdManualMove,
- west => &cmdManualMove,
- northeast => &cmdManualMove,
- northwest => &cmdManualMove,
- southeast => &cmdManualMove,
- southwest => &cmdManualMove,
- );
- }
- sub initCompletions {
- %completions = ();
- }
- ##
- # Commands::run(input)
- # input: a command.
- #
- # Processes $input. See also <a href="http://openkore.sourceforge.net/docs.php">the user documentation</a>
- # for a list of commands.
- #
- # Example:
- # # Same effect as typing 's' in the console. Displays character status
- # Commands::run("s");
- sub run {
- my $input = shift;
- my $handler;
- initHandlers() if (!%handlers);
- # Resolve command aliases
- my ($switch, $args) = split(/ +/, $input, 2);
- if (my $alias = $config{"alias_$switch"}) {
- $input = $alias;
- $input .= " $args" if defined $args;
- }
- my @commands = split(';;', $input);
- # Loop through all of the commands...
- foreach my $command (@commands) {
- my ($switch, $args) = split(/ +/, $command, 2);
- $handler = $customCommands{$switch}{callback} if ($customCommands{$switch});
- $handler = $handlers{$switch} if (!$handler && $handlers{$switch});
- if (($switch eq 'pause') && (!$cmdQueue) && (!$AI_forcedOff) && ($net->getState() == Network::IN_GAME)) {
- $cmdQueue = 1;
- $cmdQueueStartTime = time;
- if ($args > 0) {
- $cmdQueueTime = $args;
- } else {
- $cmdQueueTime = 1;
- }
- debug "Command queueing startedn", "ai";
- } elsif (($switch eq 'pause') && ($cmdQueue > 0)) {
- push(@cmdQueueList, $command);
- } elsif (($switch eq 'pause') && (($AI_forcedOff == 1) || ($net->getState() != Network::IN_GAME))) {
- error TF("Cannot use pause command now.n");
- } elsif (($handler) && ($cmdQueue > 0) && (!defined binFind(@cmdQueuePriority,$switch) && ($command ne 'cart') && ($command ne 'storage'))) {
- push(@cmdQueueList, $command);
- } elsif ($handler) {
- my %params;
- $params{switch} = $switch;
- $params{args} = $args;
- Plugins::callHook("Commands::run/pre", %params);
- $handler->($switch, $args);
- Plugins::callHook("Commands::run/post", %params);
- # undef the handler here, this is needed to make sure the other commands in the chain (if any) are run properly.
- undef $handler;
- } else {
- my %params = ( switch => $switch, input => $command );
- Plugins::callHook('Command_post', %params);
- if (!$params{return}) {
- error TF("Unknown command '%s'. Please read the documentation for a list of commands.n", $switch);
- } else {
- return $params{return}
- }
- }
- }
- return 1;
- }
- ##
- # Commands::register([name, description, callback]...)
- # Returns: an ID for use with Commands::unregister()
- #
- # Register new commands.
- #
- # Example:
- # my $ID = Commands::register(
- # ["my_command", "My custom command's description", &my_callback],
- # ["another_command", "Yet another command description", &another_callback]
- # );
- # Commands::unregister($ID);
- sub register {
- my @result;
- foreach my $cmd (@_) {
- my $name = $cmd->[0];
- my %item = (
- desc => $cmd->[1],
- callback => $cmd->[2]
- );
- $customCommands{$name} = %item;
- push @result, $name;
- }
- return @result;
- }
- ##
- # Commands::unregister(ID)
- # ID: an ID returned by Commands::register()
- #
- # Unregisters a registered command.
- sub unregister {
- my $ID = shift;
- foreach my $name (@{$ID}) {
- delete $customCommands{$name};
- }
- }
- sub complete {
- my $input = shift;
- my ($switch, $args) = split(/ +/, $input, 2);
- return if ($input eq '');
- initCompletions() if (!%completions);
- # Resolve command aliases
- if (my $alias = $config{"alias_$switch"}) {
- $input = $alias;
- $input .= " $args" if defined $args;
- ($switch, $args) = split(/ +/, $input, 2);
- }
- my $completor;
- if ($completions{$switch}) {
- $completor = $completions{$switch};
- } else {
- $completor = &defaultCompletor;
- }
- my ($last_arg_pos, $matches) = $completor->($switch, $input, 'c');
- if (@{$matches} == 1) {
- my $arg = $matches->[0];
- $arg = ""$arg"" if ($arg =~ / /);
- my $new = substr($input, 0, $last_arg_pos) . $arg;
- if (length($new) > length($input)) {
- return "$new ";
- } elsif (length($new) == length($input)) {
- return "$input ";
- }
- } elsif (@{$matches} > 1) {
- $interface->writeOutput("message", "n" . join("t", @{$matches}) . "n", "info");
- ## Find largest common prefix
- # Find item with smallest length
- my $smallest;
- foreach (@{$matches}) {
- if (!defined $smallest || length($_) < $smallest) {
- $smallest = length($_);
- }
- }
- my $commonStr;
- for (my $len = $smallest; $len >= 0; $len--) {
- my $first = lc(substr($matches->[0], 0, $len));
- my $common = 1;
- foreach (@{$matches}) {
- if ($first ne lc(substr($_, 0, $len))) {
- $common = 0;
- last;
- }
- }
- if ($common) {
- $commonStr = $first;
- last;
- }
- }
- my $new = substr($input, 0, $last_arg_pos) . $commonStr;
- return $new if (length($new) > length($input));
- }
- return $input;
- }
- ##################################
- sub completePlayerName {
- my $arg = quotemeta shift;
- my @matches;
- foreach (@playersID) {
- next if (!$_);
- if ($players{$_}{name} =~ /^$arg/i) {
- push @matches, $players{$_}{name};
- }
- }
- return @matches;
- }
- sub defaultCompletor {
- my $switch = shift;
- my $last_arg_pos;
- my @args = parseArgs(shift, undef, undef, $last_arg_pos);
- my @matches;
- my $arg = $args[$#args];
- @matches = completePlayerName($arg);
- return ($last_arg_pos, @matches);
- }
- ##################################
- sub cmdAI {
- my (undef, $args) = @_;
- $args =~ s/ .*//;
- # Clear AI
- @cmdQueueList = ();
- $cmdQueue = 0;
- if ($args eq 'clear') {
- AI::clear;
- $taskManager->stopAll() if defined $taskManager;
- delete $ai_v{temp};
- undef $char->{dead};
- message T("AI sequences clearedn"), "success";
- } elsif ($args eq 'print') {
- # Display detailed info about current AI sequence
- message T("------ AI Sequence ---------------------n"), "list";
- my $index = 0;
- foreach (@ai_seq) {
- message("$index: $_ " . dumpHash(%{$ai_seq_args[$index]}) . "nn", "list");
- $index++;
- }
- message T("------ AI Sequences --------------------n"), "list";
- } elsif ($args eq 'ai_v') {
- message dumpHash(%ai_v) . "n", "list";
- } elsif ($args eq 'on' || $args eq 'auto') {
- # Set AI to auto mode
- if ($AI == 2) {
- message T("AI is already set to auto moden"), "success";
- } else {
- $AI = 2;
- undef $AI_forcedOff;
- message T("AI set to auto moden"), "success";
- }
- } elsif ($args eq 'manual') {
- # Set AI to manual mode
- if ($AI == 1) {
- message T("AI is already set to manual moden"), "success";
- } else {
- $AI = 1;
- $AI_forcedOff = 1;
- message T("AI set to manual moden"), "success";
- }
- } elsif ($args eq 'off') {
- # Turn AI off
- if ($AI) {
- undef $AI;
- $AI_forcedOff = 1;
- message T("AI turned offn"), "success";
- } else {
- message T("AI is already offn"), "success";
- }
- } elsif ($args eq '') {
- # Toggle AI
- if ($AI == 2) {
- undef $AI;
- $AI_forcedOff = 1;
- message T("AI turned offn"), "success";
- } elsif (!$AI) {
- $AI = 1;
- $AI_forcedOff = 1;
- message T("AI set to manual moden"), "success";
- } elsif ($AI == 1) {
- $AI = 2;
- undef $AI_forcedOff;
- message T("AI set to auto moden"), "success";
- }
- } else {
- error T("Syntax Error in function 'ai' (AI Commands)n" .
- "Usage: ai [ clear | print | ai_v | auto | manual | off ]n");
- }
- }
- sub cmdAIv {
- # Display current AI sequences
- my $on;
- if (!$AI) {
- message TF("ai_seq (off) = %sn", "@ai_seq"), "list";
- } elsif ($AI == 1) {
- message TF("ai_seq (manual) = %sn", "@ai_seq"), "list";
- } elsif ($AI == 2) {
- message TF("ai_seq (auto) = %sn", "@ai_seq"), "list";
- }
- message T("solutionn"), "list" if (AI::args->{'solution'});
- message TF("Active tasks: %sn", (defined $taskManager) ? $taskManager->activeTasksString() : ''), "info";
- message TF("Inactive tasks: %sn", (defined $taskManager) ? $taskManager->inactiveTasksString() : ''), "info";
- }
- sub cmdArrowCraft {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- my ($arg1) = $args =~ /^(w+)/;
- my ($arg2) = $args =~ /^w+ (d+)/;
- #print "-$arg1-n";
- if ($arg1 eq "") {
- if (@arrowCraftID) {
- message T("----------------- Item To Craft -----------------n"), "info";
- for (my $i = 0; $i < @arrowCraftID; $i++) {
- next if ($arrowCraftID[$i] eq "");
- message(swrite(
- "@<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<",
- [$i, $char->inventory->get($arrowCraftID[$i])->{name}]),"list");
- }
- message("-------------------------------------------------n","list")
- } else {
- error T("Error in function 'arrowcraft' (Create Arrows)n" .
- "Type 'arrowcraft use' to get list.n");
- }
- } elsif ($arg1 eq "use") {
- if (defined binFind(@skillsID, 'AC_MAKINGARROW')) {
- main::ai_skillUse('AC_MAKINGARROW', 1, 0, 0, $accountID);
- } else {
- error T("Error in function 'arrowcraft' (Create Arrows)n" .
- "You don't have Arrow Making Skill.n");
- }
- } elsif ($arg1 eq "forceuse") {
- my $item = $char->inventory->get($arg2);
- if ($item) {
- $messageSender->sendArrowCraft($item->{nameID});
- } else {
- error TF("Error in function 'arrowcraft forceuse #' (Create Arrows)n" .
- "You don't have item %s in your inventory.n", $arg2);
- }
- } else {
- if ($arrowCraftID[$arg1] ne "") {
- $messageSender->sendArrowCraft($char->inventory->get($arrowCraftID[$arg1])->{nameID});
- } else {
- error T("Error in function 'arrowcraft' (Create Arrows)n" .
- "Usage: arrowcraft [<identify #>]n" .
- "Type 'arrowcraft use' to get list.n");
- }
- }
- }
- sub cmdAttack {
- my (undef, $arg1) = @_;
- if ($arg1 =~ /^d+$/) {
- if ($monstersID[$arg1] eq "") {
- error TF("Error in function 'a' (Attack Monster)n" .
- "Monster %s does not exist.n", $arg1);
- } else {
- main::attack($monstersID[$arg1]);
- }
- } elsif ($arg1 eq "no") {
- configModify("attackAuto", 1);
- } elsif ($arg1 eq "yes") {
- configModify("attackAuto", 2);
- } else {
- error T("Syntax Error in function 'a' (Attack Monster)n" .
- "Usage: attack <monster # | no | yes >n");
- }
- }
- sub cmdAttackStop {
- my $index = AI::findAction("attack");
- if ($index ne "") {
- my $args = AI::args($index);
- my $monster = Actor::get($args->{ID});
- if ($monster) {
- $monster->{ignore} = 1;
- stopAttack();
- message TF("Stopped attacking %s (%s)n",
- $monster->{name}, $monster->{binID}), "success";
- AI::clear("attack");
- }
- }
- }
- sub cmdAuthorize {
- my (undef, $args) = @_;
- my ($arg1, $arg2) = $args =~ /^([sS]*) ([sS]*?)$/;
- if ($arg1 eq "" || ($arg2 ne "1" && $arg2 ne "0")) {
- error T("Syntax Error in function 'auth' (Overall Authorize)n" .
- "Usage: auth <username> <flag>n");
- } else {
- auth($arg1, $arg2);
- }
- }
- sub cmdAutoBuy {
- message T("Initiating auto-buy.n");
- AI::queue("buyAuto");
- }
- sub cmdAutoSell {
- message T("Initiating auto-sell.n");
- AI::queue("sellAuto");
- }
- sub cmdAutoStorage {
- message T("Initiating auto-storage.n");
- AI::queue("storageAuto");
- }
- sub cmdBangBang {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my $bodydir = $char->{look}{body} - 1;
- $bodydir = 7 if ($bodydir == -1);
- $messageSender->sendLook($bodydir, $char->{look}{head});
- }
- sub cmdBingBing {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my $bodydir = ($char->{look}{body} + 1) % 8;
- $messageSender->sendLook($bodydir, $char->{look}{head});
- }
- sub cmdBuy {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- my ($arg1) = $args =~ /^(d+)/;
- my ($arg2) = $args =~ /^d+ (d+)$/;
- if ($arg1 eq "") {
- error T("Syntax Error in function 'buy' (Buy Store Item)n" .
- "Usage: buy <item #> [<amount>]n");
- } elsif ($storeList[$arg1] eq "") {
- error TF("Error in function 'buy' (Buy Store Item)n" .
- "Store Item %s does not exist.n", $arg1);
- } else {
- if ($arg2 <= 0) {
- $arg2 = 1;
- }
- $messageSender->sendBuy($storeList[$arg1]{'nameID'}, $arg2);
- }
- }
- sub cmdCard {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $input) = @_;
- my ($arg1) = $input =~ /^(w+)/;
- my ($arg2) = $input =~ /^w+ (d+)/;
- my ($arg3) = $input =~ /^w+ d+ (d+)/;
- if ($arg1 eq "mergecancel") {
- if (!defined $messageSender) {
- error T("Error in function 'bingbing' (Change look direction)n" .
- "Can't use command while not connected to server.n");
- } elsif ($cardMergeIndex ne "") {
- undef $cardMergeIndex;
- $messageSender->sendCardMerge(-1, -1);
- message T("Cancelling card merge.n");
- } else {
- error T("Error in function 'card mergecancel' (Cancel a card merge request)n" .
- "You are not currently in a card merge session.n");
- }
- } elsif ($arg1 eq "mergelist") {
- # FIXME: if your items change order or are used, this list will be wrong
- if (@cardMergeItemsID) {
- my $msg;
- $msg .= T("-----Card Merge Candidates-----n");
- foreach my $card (@cardMergeItemsID) {
- next if $card eq "" || !$char->inventory->get($card);
- $msg .= swrite(
- "@<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<",
- [$card, $char->inventory->get($card)]);
- }
- $msg .= "-------------------------------n";
- message $msg, "list";
- } else {
- error T("Error in function 'card mergelist' (List availible card merge items)n" .
- "You are not currently in a card merge session.n");
- }
- } elsif ($arg1 eq "merge") {
- if ($arg2 =~ /^d+$/) {
- my $found = binFind(@cardMergeItemsID, $arg2);
- if (defined $found) {
- $messageSender->sendCardMerge($char->inventory->get($cardMergeIndex)->{index},
- $char->inventory->get($arg2)->{index});
- } else {
- if ($cardMergeIndex ne "") {
- error TF("Error in function 'card merge' (Finalize card merging onto item)n" .
- "There is no item %s in the card mergelist.n", $arg2);
- } else {
- error T("Error in function 'card merge' (Finalize card merging onto item)n" .
- "You are not currently in a card merge session.n");
- }
- }
- } else {
- error T("Syntax Error in function 'card merge' (Finalize card merging onto item)n" .
- "Usage: card merge <item number>n" .
- "<item number> - Merge item number. Type 'card mergelist' to get number.n");
- }
- } elsif ($arg1 eq "use") {
- if ($arg2 =~ /^d+$/) {
- if ($char->inventory->get($arg2)) {
- $cardMergeIndex = $arg2;
- $messageSender->sendCardMergeRequest($char->inventory->get($cardMergeIndex)->{index});
- message TF("Sending merge list request for %s...n",
- $char->inventory->get($cardMergeIndex)->{name});
- } else {
- error TF("Error in function 'card use' (Request list of items for merging with card)n" .
- "Card %s does not exist.n", $arg2);
- }
- } else {
- error T("Syntax Error in function 'card use' (Request list of items for merging with card)n" .
- "Usage: card use <item number>n" .
- "<item number> - Card inventory number. Type 'i' to get number.n");
- }
- } elsif ($arg1 eq "list") {
- my $msg;
- $msg .= T("-----------Card List-----------n");
- foreach my $item (@{$char->inventory->getItems()}) {
- if ($item->{type} == 6) {
- $msg .= "$item->{invIndex} $item->{name} x $item->{amount}n";
- }
- }
- $msg .= "-------------------------------n";
- message $msg, "list";
- } elsif ($arg1 eq "forceuse") {
- if (!$char->inventory->get($arg2)) {
- error TF("Error in function 'arrowcraft forceuse #' (Create Arrows)n" .
- "You don't have item %s in your inventory.n", $arg2);
- } elsif (!$char->inventory->get($arg3)) {
- error TF("Error in function 'arrowcraft forceuse #' (Create Arrows)n" .
- "You don't have item %s in your inventory.n"), $arg3;
- } else {
- $messageSender->sendCardMerge($char->inventory->get($arg2)->{index},
- $char->inventory->get($arg3)->{index});
- }
- } else {
- error T("Syntax Error in function 'card' (Card Compounding)n" .
- "Usage: card <use|mergelist|mergecancel|merge>n");
- }
- }
- sub cmdCart {
- my (undef, $input) = @_;
- my ($arg1, $arg2) = split(' ', $input, 2);
- my $hasCart = $cart{exists};
- if ($char && $char->{statuses}) {
- foreach (keys %{$char->{statuses}}) {
- if ($_ =~ /^Level d Cart$/) {
- $hasCart = 1;
- last;
- }
- }
- }
- if (!$hasCart) {
- error T("Error in function 'cart' (Cart Management)n" .
- "You do not have a cart.n");
- return;
-
- } elsif (!defined $cart{'inventory'}) {
- error T("Cart inventory is not available.n");
- return;
- } elsif ($arg1 eq "") {
- my $msg = T("-------------Cart--------------n" .
- "# Namen");
- for (my $i = 0; $i < @{$cart{'inventory'}}; $i++) {
- next if (!$cart{'inventory'}[$i] || !%{$cart{'inventory'}[$i]});
- my $display = "$cart{'inventory'}[$i]{'name'} x $cart{'inventory'}[$i]{'amount'}";
- $display .= T(" -- Not Identified") if !$cart{inventory}[$i]{identified};
- $msg .= sprintf("%-2d %-34sn", $i, $display);
- }
- $msg .= TF("nCapacity: %d/%d Weight: %d/%dn",
- int($cart{'items'}), int($cart{'items_max'}), int($cart{'weight'}), int($cart{'weight_max'}));
- $msg .= "-------------------------------n";
- message($msg, "list");
- } elsif ($arg1 eq "desc") {
- if (!($arg2 =~ /d+/)) {
- error TF("Syntax Error in function 'cart desc' (Show Cart Item Description)n" .
- "'%s' is not a valid cart item number.n", $arg2);
- } elsif (!$cart{'inventory'}[$arg2]) {
- error TF("Error in function 'cart desc' (Show Cart Item Description)n" .
- "Cart Item %s does not exist.n", $arg2);
- } else {
- printItemDesc($cart{'inventory'}[$arg2]{'nameID'});
- }
- } elsif ($arg1 eq "add") {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", 'cart ' . $arg1);
- return;
- }
- cmdCart_add($arg2);
- } elsif ($arg1 eq "get") {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", 'cart ' . $arg1);
- return;
- }
- cmdCart_get($arg2);
- } elsif ($arg1 eq "release") {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", 'cart ' . $arg1);
- return;
- }
- $messageSender->sendCompanionRelease();
- if ($net && $net->getState() == Network::IN_GAME) {
- message T("Cart released.n"), "success";
- $cart{exists} = 0;
- }
-
- } else {
- error TF("Error in function 'cart'n" .
- "Command '%s' is not a known command.n", $arg1);
- }
- }
- sub cmdCart_add {
- my ($name) = @_;
- if (!defined $name) {
- error T("Syntax Error in function 'cart add' (Add Item to Cart)n" .
- "Usage: cart add <item>n");
- return;
- }
- my $amount;
- if ($name =~ /^(.*?) (d+)$/) {
- $name = $1;
- $amount = $2;
- }
- my $item = Match::inventoryItem($name);
- if (!$item) {
- error TF("Error in function 'cart add' (Add Item to Cart)n" .
- "Inventory Item %s does not exist.n", $name);
- return;
- }
- if (!$amount || $amount > $item->{amount}) {
- $amount = $item->{amount};
- }
- $messageSender->sendCartAdd($item->{index}, $amount);
- }
- sub cmdCart_get {
- my ($name) = @_;
- if (!defined $name) {
- error T("Syntax Error in function 'cart get' (Get Item from Cart)n" .
- "Usage: cart get <cart item>n");
- return;
- }
- my $amount;
- if ($name =~ /^(.*?) (d+)$/) {
- $name = $1;
- $amount = $2;
- }
- my $item = Match::cartItem($name);
- if (!$item) {
- error TF("Error in function 'cart get' (Get Item from Cart)n" .
- "Cart Item %s does not exist.n", $name);
- return;
- }
- if (!$amount || $amount > $item->{amount}) {
- $amount = $item->{amount};
- }
- $messageSender->sendCartGet($item->{index}, $amount);
- }
- sub cmdChat {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $arg1) = @_;
- if ($arg1 eq "") {
- error T("Syntax Error in function 'c' (Chat)n" .
- "Usage: c <message>n");
- } else {
- sendMessage($messageSender, "c", $arg1);
- }
- }
- sub cmdChatLogClear {
- chatLog_clear();
- message T("Chat log cleared.n"), "success";
- }
- sub cmdChatRoom {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- my ($arg1) = $args =~ /^(w+)/;
- if ($arg1 eq "bestow") {
- my ($arg2) = $args =~ /^w+ (d+)/;
- if ($currentChatRoom eq "") {
- error T("Error in function 'chat bestow' (Bestow Admin in Chat)n" .
- "You are not in a Chat Room.n");
- } elsif ($arg2 eq "") {
- error T("Syntax Error in function 'chat bestow' (Bestow Admin in Chat)n" .
- "Usage: chat bestow <user #>n");
- } elsif ($currentChatRoomUsers[$arg2] eq "") {
- error TF("Error in function 'chat bestow' (Bestow Admin in Chat)n" .
- "Chat Room User %s doesn't exist; type 'chat info' to see the list of usersn", $arg2);
- } else {
- $messageSender->sendChatRoomBestow($currentChatRoomUsers[$arg2]);
- }
- } elsif ($arg1 eq "modify") {
- my ($title) = $args =~ /^w+ "([sS]*?)"/;
- my ($users) = $args =~ /^w+ "[sS]*?" (d+)/;
- my ($public) = $args =~ /^w+ "[sS]*?" d+ (d+)/;
- my ($password) = $args =~ /^w+ "[sS]*?" d+ d+ ([sS]+)/;
- if ($title eq "") {
- error T("Syntax Error in function 'chatmod' (Modify Chat Room)n" .
- "Usage: chat modify "<title>" [<limit #> <public flag> <password>]n");
- } else {
- if ($users eq "") {
- $users = 20;
- }
- if ($public eq "") {
- $public = 1;
- }
- $messageSender->sendChatRoomChange($title, $users, $public, $password);
- }
- } elsif ($arg1 eq "kick") {
- my ($arg2) = $args =~ /^w+ (d+)/;
- if ($currentChatRoom eq "") {
- error T("Error in function 'chat kick' (Kick from Chat)n" .
- "You are not in a Chat Room.n");
- } elsif ($arg2 eq "") {
- error T("Syntax Error in function 'chat kick' (Kick from Chat)n" .
- "Usage: chat kick <user #>n");
- } elsif ($currentChatRoomUsers[$arg2] eq "") {
- error TF("Error in function 'chat kick' (Kick from Chat)n" .
- "Chat Room User %s doesn't existn", $arg2);
- } else {
- $messageSender->sendChatRoomKick($currentChatRoomUsers[$arg2]);
- }
- } elsif ($arg1 eq "join") {
- my ($arg2) = $args =~ /^w+ (d+)/;
- my ($arg3) = $args =~ /^w+ d+ (d+)/;
- if ($arg2 eq "") {
- error T("Syntax Error in function 'chat join' (Join Chat Room)n" .
- "Usage: chat join <chat room #> [<password>]n");
- } elsif ($currentChatRoom ne "") {
- error T("Error in function 'chat join' (Join Chat Room)n" .
- "You are already in a chat room.n");
- } elsif ($chatRoomsID[$arg2] eq "") {
- error TF("Error in function 'chat join' (Join Chat Room)n" .
- "Chat Room %s does not exist.n", $arg2);
- } else {
- $messageSender->sendChatRoomJoin($chatRoomsID[$arg2], $arg3);
- }
- } elsif ($arg1 eq "leave") {
- if ($currentChatRoom eq "") {
- error T("Error in function 'chat leave' (Leave Chat Room)n" .
- "You are not in a Chat Room.n");
- } else {
- $messageSender->sendChatRoomLeave();
- }
- } elsif ($arg1 eq "create") {
- my ($title) = $args =~ /^w+ "([sS]*?)"/;
- my ($users) = $args =~ /^w+ "[sS]*?" (d+)/;
- my ($public) = $args =~ /^w+ "[sS]*?" d+ (d+)/;
- my ($password) = $args =~ /^w+ "[sS]*?" d+ d+ ([sS]+)/;
- if ($title eq "") {
- error T("Syntax Error in function 'chat create' (Create Chat Room)n" .
- "Usage: chat create "<title>" [<limit #> <public flag> <password>]n");
- } elsif ($currentChatRoom ne "") {
- error T("Error in function 'chat create' (Create Chat Room)n" .
- "You are already in a chat room.n");
- } else {
- if ($users eq "") {
- $users = 20;
- }
- if ($public eq "") {
- $public = 1;
- }
- $title = ($config{chatTitleOversize}) ? $title : substr($title,0,36);
- $messageSender->sendChatRoomCreate($title, $users, $public, $password);
- %createdChatRoom = ();
- $createdChatRoom{title} = $title;
- $createdChatRoom{ownerID} = $accountID;
- $createdChatRoom{limit} = $users;
- $createdChatRoom{public} = $public;
- $createdChatRoom{num_users} = 1;
- $createdChatRoom{users}{$char->{name}} = 2;
- }
- } elsif ($arg1 eq "list") {
- message T("------------------------------- Chat Room List --------------------------------n" .
- "# Title Owner Users Typen"), "list";
- for (my $i = 0; $i < @chatRoomsID; $i++) {
- next if (!defined $chatRoomsID[$i]);
- my $room = $chatRooms{$chatRoomsID[$i]};
- my $owner_string = Actor::get($room->{ownerID})->name;
- my $public_string = ($room->{public}) ? "Public" : "Private";
- my $limit_string = $room->{num_users} . "/" . $room->{limit};
- message(swrite(
- "@<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<< @<<<<<< @<<<<<<",
- [$i, $room->{title}, $owner_string, $limit_string, $public_string]),
- "list");
- }
- message("-------------------------------------------------------------------------------n", "list");
- } elsif ($arg1 eq "info") {
- if ($currentChatRoom eq "") {
- error T("There is no chat room info - you are not in a chat roomn");
- } else {
- message T("-----------Chat Room Info-----------n" .
- "Title Users Public/Privaten"), "list";
- my $public_string = ($chatRooms{$currentChatRoom}{'public'}) ? "Public" : "Private";
- my $limit_string = $chatRooms{$currentChatRoom}{'num_users'}."/".$chatRooms{$currentChatRoom}{'limit'};
- message(swrite(
- "@<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<< @<<<<<<<<<",
- [$chatRooms{$currentChatRoom}{'title'}, $limit_string, $public_string]),
- "list");
- # Translation Comment: Users in chat room
- message T("-- Users --n"), "list";
- for (my $i = 0; $i < @currentChatRoomUsers; $i++) {
- next if ($currentChatRoomUsers[$i] eq "");
- my $user_string = $currentChatRoomUsers[$i];
- my $admin_string = ($chatRooms{$currentChatRoom}{'users'}{$currentChatRoomUsers[$i]} > 1) ? "(Admin)" : "";
- message(swrite(
- "@<< @<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<",
- [$i, $user_string, $admin_string]),
- "list");
- }
- message("------------------------------------n", "list");
- }
- } else {
- error T("Syntax Error in function 'chat' (Chat room management)n" .
- "Usage: chat <create|modify|join|kick|leave|info|list|bestow>n");
- }
- }
- sub cmdChist {
- # Display chat history
- my (undef, $args) = @_;
- $args = 5 if ($args eq "");
- if (!($args =~ /^d+$/)) {
- error T("Syntax Error in function 'chist' (Show Chat History)n" .
- "Usage: chist [<number of entries #>]n");
- } elsif (open(CHAT, "<:utf8", $Settings::chat_log_file)) {
- my @chat = <CHAT>;
- close(CHAT);
- message T("------ Chat History --------------------n"), "list";
- my $i = @chat - $args;
- $i = 0 if ($i < 0);
- for (; $i < @chat; $i++) {
- message($chat[$i], "list");
- }
- message "----------------------------------------n", "list";
- } else {
- error TF("Unable to open %sn", $Settings::chat_log_file);
- }
- }
- sub cmdCloseShop {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- main::closeShop();
- }
- sub cmdConf {
- my (undef, $args) = @_;
- my ($arg1) = $args =~ /^(w*.*w+)/;
- my ($arg2) = $args =~ /^w*.*w+s+([sS]+)s*$/;
- # Basic Support for "label" in blocks. Thanks to "piroJOKE"
- if ($arg1 =~ /./) {
- $arg1 =~ s/.+/./; # Filter Out Unnececary dot's
- my ($label, $param) = split /./, $arg1, 2; # Split the label form parameter
- # This line is used for debug
- # message TF("Params label '%s' param '%s' arg1 '%s' arg2 '%s'n", $label, $param, $arg1, $arg2), "info";
- foreach (%config) {
- if ($_ =~ /_d+_label/){ # we only need those blocks witch have labels
- if ($config{$_} eq $label) {
- my ($real_key, undef) = split /_label/, $_, 2;
- # "<label>.block" param support. Thanks to "vit"
- if ($param ne "block") {
- $real_key .= "_";
- $real_key .= $param;
- }
- $arg1 = $real_key;
- last;
- };
- };
- };
- };
- if ($arg1 eq "") {
- error T("Syntax Error in function 'conf' (Change a Configuration Key)n" .
- "Usage: conf <variable> [<value>|none]n");
- } elsif (!exists $config{$arg1}) {
- error TF("Config variable %s doesn't existn", $arg1);
- } elsif ($arg2 eq "") {
- my $value = $config{$arg1};
- if ($arg1 =~ /password/i) {
- message TF("Config '%s' is not displayedn", $arg1), "info";
- } else {
- if (defined $value) {
- message TF("Config '%s' is %sn", $arg1, $value), "info";
- } else {
- message TF("Config '%s' is not setn", $arg1, $value), "info";
- }
- }
- } else {
- undef $arg2 if ($arg2 eq "none");
- Plugins::callHook('Commands::cmdConf', {
- key => $arg1,
- val => $arg2
- });
- configModify($arg1, $arg2);
- Log::initLogFiles();
- }
- }
- sub cmdDamage {
- my (undef, $args) = @_;
-
- if ($args eq "") {
- my $total = 0;
- message T("Damage Taken Report:n"), "list";
- message(sprintf("%-40s %-20s %-10sn", 'Name', 'Skill', 'Damage'), "list");
- for my $monsterName (sort keys %damageTaken) {
- my $monsterHref = $damageTaken{$monsterName};
- for my $skillName (sort keys %{$monsterHref}) {
- message sprintf("%-40s %-20s %10dn", $monsterName, $skillName, $monsterHref->{$skillName}), "list";
- $total += $monsterHref->{$skillName};
- }
- }
- message TF("Total Damage Taken: %sn", $total), "list";
- message T("End of report.n"), "list";
- } elsif ($args eq "reset") {
- undef %damageTaken;
- message T("Damage Taken Report reset.n"), "success";
- } else {
- error T("Syntax error in function 'damage' (Damage Report)n" .
- "Usage: damage [reset]n");
- }
- }
- sub cmdDeal {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- my @arg = split / /, $args;
- if (%currentDeal && $arg[0] =~ /d+/) {
- error T("Error in function 'deal' (Deal a Player)n" .
- "You are already in a dealn");
- } elsif (%incomingDeal && $arg[0] =~ /d+/) {
- error T("Error in function 'deal' (Deal a Player)n" .
- "You must first cancel the incoming dealn");
- } elsif ($arg[0] =~ /d+/ && !$playersID[$arg[0]]) {
- error TF("Error in function 'deal' (Deal a Player)n" .
- "Player %s does not existn", $arg[0]);
- } elsif ($arg[0] =~ /d+/) {
- my $ID = $playersID[$arg[0]];
- my $player = Actor::get($ID);
- message TF("Attempting to deal %sn", $player);
- deal($player);
- } elsif ($arg[0] eq "no" && !%incomingDeal && !%outgoingDeal && !%currentDeal) {
- error T("Error in function 'deal' (Deal a Player)n" .
- "There is no incoming/current deal to canceln");
- } elsif ($arg[0] eq "no" && (%incomingDeal || %outgoingDeal)) {
- $messageSender->sendDealCancel();
- } elsif ($arg[0] eq "no" && %currentDeal) {
- $messageSender->sendCurrentDealCancel();
- } elsif ($arg[0] eq "" && !%incomingDeal && !%currentDeal) {
- error T("Error in function 'deal' (Deal a Player)n" .
- "There is no deal to acceptn");
- } elsif ($arg[0] eq "" && $currentDeal{'you_finalize'} && !$currentDeal{'other_finalize'}) {
- error TF("Error in function 'deal' (Deal a Player)n" .
- "Cannot make the trade - %s has not finalizedn", $currentDeal{'name'});
- } elsif ($arg[0] eq "" && $currentDeal{'final'}) {
- error T("Error in function 'deal' (Deal a Player)n" .
- "You already accepted the final dealn");
- } elsif ($arg[0] eq "" && %incomingDeal) {
- $messageSender->sendDealAccept();
- } elsif ($arg[0] eq "" && $currentDeal{'you_finalize'} && $currentDeal{'other_finalize'}) {
- $messageSender->sendDealTrade();
- $currentDeal{'final'} = 1;
- message T("You accepted the final Dealn"), "deal";
- } elsif ($arg[0] eq "" && %currentDeal) {
- $messageSender->sendDealAddItem(0, $currentDeal{'you_zenny'});
- $messageSender->sendDealFinalize();
- } elsif ($arg[0] eq "add" && !%currentDeal) {
- error T("Error in function 'deal_add' (Add Item to Deal)n" .
- "No deal in progressn");
- } elsif ($arg[0] eq "add" && $currentDeal{'you_finalize'}) {
- error T("Error in function 'deal_add' (Add Item to Deal)n" .
- "Can't add any Items - You already finalized the dealn");
- } elsif ($arg[0] eq "add" && $arg[1] =~ /d+/ && !$char->inventory->get($arg[1])) {
- error TF("Error in function 'deal_add' (Add Item to Deal)n" .
- "Inventory Item %s does not exist.n", $arg[1]);
- } elsif ($arg[0] eq "add" && $arg[2] && $arg[2] !~ /d+/) {
- error T("Error in function 'deal_add' (Add Item to Deal)n" .
- "Amount must either be a number, or not specified.n");
- } elsif ($arg[0] eq "add" && $arg[1] =~ /d+/) {
- if ($currentDeal{you_items} < 10) {
- my $item = $char->inventory->get($arg[1]);
- my $amount = $item->{amount};
- if (!$arg[2] || $arg[2] > $amount) {
- $arg[2] = $amount;
- }
- dealAddItem($item, $arg[2]);
- } else {
- error T("You can't add any more items to the dealn"), "deal";
- }
- } elsif ($arg[0] eq "add" && $arg[1] eq "z") {
- if (!$arg[2] && !($arg[2] eq "0") || $arg[2] > $char->{'zenny'}) {
- $arg[2] = $char->{'zenny'};
- }
- $currentDeal{'you_zenny'} = $arg[2];
- message TF("You put forward %sz to Dealn", formatNumber($arg[2])), "deal";
- } else {
- error T("Syntax Error in function 'deal' (Deal a player)n" .
- "Usage: deal [<Player # | no | add>] [<item #>] [<amount>]n");
- }
- }
- sub cmdDealList {
- if (!%currentDeal) {
- error T("There is no deal list - You are not in a dealn");
- } else {
- message T("-----------Current Deal-----------n"), "list";
- my $other_string = $currentDeal{'name'};
- my $you_string = "You";
- if ($currentDeal{'other_finalize'}) {
- $other_string .= " - Finalized";
- }
- if ($currentDeal{'you_finalize'}) {
- $you_string .= " - Finalized";
- }
- message(swrite(
- "@<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<",
- [$you_string, $other_string]),
- "list");
- my @currentDealYou;
- my @currentDealOther;
- foreach (keys %{$currentDeal{'you'}}) {
- push @currentDealYou, $_;
- }
- foreach (keys %{$currentDeal{'other'}}) {
- push @currentDealOther, $_;
- }
- my ($lastindex, $display, $display2);
- $lastindex = @currentDealOther;
- $lastindex = @currentDealYou if (@currentDealYou > $lastindex);
- for (my $i = 0; $i < $lastindex; $i++) {
- if ($i < @currentDealYou) {
- $display = ($items_lut{$currentDealYou[$i]} ne "")
- ? $items_lut{$currentDealYou[$i]}
- : "Unknown ".$currentDealYou[$i];
- $display .= " x $currentDeal{'you'}{$currentDealYou[$i]}{'amount'}";
- } else {
- $display = "";
- }
- if ($i < @currentDealOther) {
- $display2 = ($items_lut{$currentDealOther[$i]} ne "")
- ? $items_lut{$currentDealOther[$i]}
- : "Unknown ".$currentDealOther[$i];
- $display2 .= " x $currentDeal{'other'}{$currentDealOther[$i]}{'amount'}";
- } else {
- $display2 = "";
- }
- message(swrite(
- "@<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<",
- [$display, $display2]),
- "list");
- }
- $you_string = ($currentDeal{'you_zenny'} ne "") ? $currentDeal{'you_zenny'} : 0;
- $other_string = ($currentDeal{'other_zenny'} ne "") ? $currentDeal{'other_zenny'} : 0;
- message TF("Zenny: %-25s Zenny: %-14s",
- formatNumber($you_string), formatNumber($other_string)), "list";
- message("----------------------------------n", "list");
- }
- }
- sub cmdDebug {
- my (undef, $args) = @_;
- my ($arg1) = $args =~ /^([wd]+)/;
- if ($arg1 eq "0") {
- configModify("debug", 0);
- } elsif ($arg1 eq "1") {
- configModify("debug", 1);
- } elsif ($arg1 eq "2") {
- configModify("debug", 2);
- } elsif ($arg1 eq "info") {
- my $connected = "server=".($net->serverAlive ? "yes" : "no").
- ",client=".($net->clientAlive ? "yes" : "no");
- my $time = sprintf("%.2f", time - $lastPacketTime);
- my $ai_timeout = sprintf("%.2f", time - $timeout{'ai'}{'time'});
- my $ai_time = sprintf("%.4f", time - $ai_v{'AI_last_finished'});
- message TF("------------ Debug information ------------n" .
- "ConState: %s Connected: %sn" .
- "AI enabled: %s AI_forcedOff: %sn" .
- "@ai_seq = %sn" .
- "Last packet: %.2f secs agon" .
- "$timeout{ai}: %.2f secs ago (value should be >%s)n" .
- "Last AI() call: %.2f secs agon" .
- "-------------------------------------------n",
- $conState, $connected, $AI, $AI_forcedOff, @ai_seq, $time, $ai_timeout,
- $timeout{'ai'}{'timeout'}, $ai_time), "list";
- }
- }
- sub cmdDoriDori {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my $headdir;
- if ($char->{look}{head} == 2) {
- $headdir = 1;
- } else {
- $headdir = 2;
- }
- $messageSender->sendLook($char->{look}{body}, $headdir);
- }
- sub cmdDrop {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- my ($arg1) = $args =~ /^([d,-]+)/;
- my ($arg2) = $args =~ /^[d,-]+ (d+)$/;
- if ($arg1 eq "") {
- error T("Syntax Error in function 'drop' (Drop Inventory Item)n" .
- "Usage: drop <item #> [<amount>]n");
- } else {
- my @temp = split(/,/, $arg1);
- @temp = grep(!/^$/, @temp); # Remove empty entries
- my @items = ();
- foreach (@temp) {
- if (/(d+)-(d+)/) {
- for ($1..$2) {
- push(@items, $_) if ($char->inventory->get($_));
- }
- } else {
- push @items, $_ if ($char->inventory->get($_));
- }
- }
- if (@items > 0) {
- main::ai_drop(@items, $arg2);
- } else {
- error T("No items were dropped.n");
- }
- }
- }
- sub cmdDump {
- dumpData((defined $incomingMessages) ? $incomingMessages->getBuffer() : '');
- quit();
- }
- sub cmdDumpNow {
- dumpData((defined $incomingMessages) ? $incomingMessages->getBuffer() : '');
- }
- sub cmdEmotion {
- # Show emotion
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- my $num = getEmotionByCommand($args);
- if (!defined $num) {
- error T("Syntax Error in function 'e' (Emotion)n" .
- "Usage: e <command>n");
- } else {
- $messageSender->sendEmotion($num);
- }
- }
- sub cmdEquip {
- # Equip an item
- my (undef, $args) = @_;
- my ($arg1,$arg2) = $args =~ /^(S+)s*(.*)/;
- my $slot;
- my $item;
- if ($arg1 eq "") {
- cmdEquip_list();
- return;
- }
- if ($arg1 eq "slots") {
- # Translation Comment: List of equiped items on each slot
- message T("Slots:n") . join("n", @Actor::Item::slots). "n", "list";
- return;
- }
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", 'eq ' . $args);
- return;
- }
- if ($equipSlot_rlut{$arg1}) {
- $slot = $arg1;
- } else {
- $arg1 .= " $arg2" if $arg2;
- }
- $item = Actor::Item::get(defined $slot ? $arg2 : $arg1, undef, 1);
- if (!$item) {
- $args =~ s/^($slot)s//g if ($slot);
- error TF("No such non-equipped Inventory Item: %sn", $args);
- return;
- }
- if (!$item->{type_equip} && $item->{type} != 10 && $item->{type} != 16 && $item->{type} != 17) {
- error TF("Inventory Item %s (%s) can't be equipped.n",
- $item->{name}, $item->{invIndex});
- return;
- }
- if ($slot) {
- $item->equipInSlot($slot);
- } else {
- $item->equip();
- }
- }
- sub cmdEquip_list {
- if (!$char) {
- error T("Character equipment not yet readyn");
- return;
- }
- for my $slot (@Actor::Item::slots) {
- my $item = $char->{equipment}{$slot};
- my $name = $item ? $item->nameString : '-';
- message sprintf("%-15s: %sn", $slot, $name), "list";
- }
- }
- sub cmdEval {
- if (!$Settings::lockdown) {
- if ($_[1] eq "") {
- error T("Syntax Error in function 'eval' (Evaluate a Perl expression)n" .
- "Usage: eval <expression>n");
- } else {
- package main;
- no strict;
- undef $@;
- eval $_[1];
- if (defined $@ && $@ ne '') {
- $@ .= "n" if ($@ !~ /n$/s);
- Log::error($@);
- }
- }
- }
- }
- sub cmdExp {
- my (undef, $args) = @_;
- my $knownArg;
-
- # exp report
- my ($arg1) = $args =~ /^(w+)/;
-
- if ($arg1 eq "reset") {
- $knownArg = 1;
- ($bExpSwitch,$jExpSwitch,$totalBaseExp,$totalJobExp) = (2,2,0,0);
- $startTime_EXP = time;
- $startingZenny = $char->{zenny} if $char;
- undef @monsters_Killed;
- $dmgpsec = 0;
- $totaldmg = 0;
- $elasped = 0;
- $totalelasped = 0;
- undef %itemChange;
- $bytesSent = 0;
- $bytesReceived = 0;
- message T("Exp counter reset.n"), "success";
- return;
- }
-
- if (!$char) {
- error T("Exp report not yet readyn");
- return;
- }
- if (($arg1 eq "") || ($arg1 eq "report")) {
- $knownArg = 1;
- my ($endTime_EXP, $w_sec, $bExpPerHour, $jExpPerHour, $EstB_sec, $percentB, $percentJ, $zennyMade, $zennyPerHour, $EstJ_sec, $percentJhr, $percentBhr);
- $endTime_EXP = time;
- $w_sec = int($endTime_EXP - $startTime_EXP);
- if ($w_sec > 0) {
- $zennyMade = $char->{zenny} - $startingZenny;
- $bExpPerHour = int($totalBaseExp / $w_sec * 3600);
- $jExpPerHour = int($totalJobExp / $w_sec * 3600);
- $zennyPerHour = int($zennyMade / $w_sec * 3600);
- if ($char->{exp_max} && $bExpPerHour){
- $percentB = "(".sprintf("%.2f",$totalBaseExp * 100 / $char->{exp_max})."%)";
- $percentBhr = "(".sprintf("%.2f",$bExpPerHour * 100 / $char->{exp_max})."%)";
- $EstB_sec = int(($char->{exp_max} - $char->{exp})/($bExpPerHour/3600));
- }
- if ($char->{exp_job_max} && $jExpPerHour){
- $percentJ = "(".sprintf("%.2f",$totalJobExp * 100 / $char->{exp_job_max})."%)";
- $percentJhr = "(".sprintf("%.2f",$jExpPerHour * 100 / $char->{exp_job_max})."%)";
- $EstJ_sec = int(($char->{'exp_job_max'} - $char->{exp_job})/($jExpPerHour/3600));
- }
- }
- $char->{deathCount} = 0 if (!defined $char->{deathCount});
- message TF( "------------Exp Report------------n" .
- "Botting time : %sn" .
- "BaseExp : %s %sn" .
- "JobExp : %s %sn" .
- "BaseExp/Hour : %s %sn" .
- "JobExp/Hour : %s %sn" .
- "Zenny : %sn" .
- "Zenny/Hour : %sn" .
- "Base Levelup Time Estimation : %sn" .
- "Job Levelup Time Estimation : %sn" .
- "Died : %sn" .
- "Bytes Sent : %sn" .
- "Bytes Rcvd : %sn",
- timeConvert($w_sec), formatNumber($totalBaseExp), $percentB, formatNumber($totalJobExp), $percentJ,
- formatNumber($bExpPerHour), $percentBhr, formatNumber($jExpPerHour), $percentJhr,
- formatNumber($zennyMade), formatNumber($zennyPerHour), timeConvert($EstB_sec), timeConvert($EstJ_sec),
- $char->{'deathCount'}, formatNumber($bytesSent), formatNumber($bytesReceived)), "info";
-
- if ($arg1 eq "") {
- message("---------------------------------n", "list");
- }
- }
-
- if (($arg1 eq "monster") || ($arg1 eq "report")) {
- my $total;
-
- $knownArg = 1;
- message T("-[Monster Killed Count]-----------------------n" .
- "# ID Name Countn"), "list";
- for (my $i = 0; $i < @monsters_Killed; $i++) {
- next if ($monsters_Killed[$i] eq "");
- message(swrite(
- "@<< @<<<<< @<<<<<<<<<<<<<<<<<<<<<< @<<<<< ",
- [$i, $monsters_Killed[$i]{nameID}, $monsters_Killed[$i]{name}, $monsters_Killed[$i]{count}]),
- "list");
- $total += $monsters_Killed[$i]{count};
- }
- message("----------------------------------------------n" .
- TF("Total number of killed monsters: %sn", $total) .
- "----------------------------------------------n",
- "list");
- }
- if (($arg1 eq "item") || ($arg1 eq "report")) {
- $knownArg = 1;
- message T("-[Item Change Count]--------------------------n" .
- "Name Countn"), "list";
- for my $item (sort keys %itemChange) {
- next unless $itemChange{$item};
- message(sprintf("%-40s %5dn", $item, $itemChange{$item}), "list");
- }
- message("----------------------------------------------n", "list");
- }
-
- if (!$knownArg) {
- error T("Syntax error in function 'exp' (Exp Report)n" .
- "Usage: exp [<report | monster | item | reset>]n");
- }
- }
- sub cmdFalcon {
- my (undef, $arg1) = @_;
- my $hasFalcon;
- if ($char) {
- foreach my $ID (keys %{$char->{statuses}}) {
- if ($ID eq "Falcon") {
- $hasFalcon = 1;
- last;
- }
- }
- }
- if ($arg1 eq "") {
- if ($hasFalcon) {
- message T("Your falcon is activen");
- } else {
- message T("Your falcon is inactiven");
- }
- } elsif ($arg1 eq "release") {
- if (!$hasFalcon) {
- error T("Error in function 'falcon release' (Remove Falcon Status)n" .
- "You don't possess a falcon.n");
- } elsif (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", 'falcon release');
- return;
- } else {
- $messageSender->sendCompanionRelease();
- }
- }
- }
- sub cmdFollow {
- my (undef, $arg1) = @_;
- if ($arg1 eq "") {
- error T("Syntax Error in function 'follow' (Follow Player)n" .
- "Usage: follow <player #>n");
- } elsif ($arg1 eq "stop") {
- AI::clear("follow");
- configModify("follow", 0);
- } elsif ($arg1 =~ /^d+$/) {
- if (!$playersID[$arg1]) {
- error TF("Error in function 'follow' (Follow Player)n" .
- "Player %s either not visible or not online in party.n", $arg1);
- } else {
- AI::clear("follow");
- main::ai_follow($players{$playersID[$arg1]}->name);
- configModify("follow", 1);
- configModify("followTarget", $players{$playersID[$arg1]}{name});
- }
- } else {
- AI::clear("follow");
- main::ai_follow($arg1);
- configModify("follow", 1);
- configModify("followTarget", $arg1);
- }
- }
- sub cmdFriend {
- my (undef, $args) = @_;
- my ($arg1, $arg2) = split(' ', $args, 2);
- if ($arg1 eq "") {
- message T("------------- Friends --------------n" .
- "# Name Onlinen"), "list";
- for (my $i = 0; $i < @friendsID; $i++) {
- message(swrite(
- "@< @<<<<<<<<<<<<<<<<<<<<<<< @",
- [$i + 1, $friends{$i}{'name'}, $friends{$i}{'online'}? 'X':'']),
- "list");
- }
- message("----------------------------------n", "list");
- } elsif (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", 'friend ' . $arg1);
- return;
- } elsif ($arg1 eq "request") {
- my $player = Match::player($arg2);
- if (!$player) {
- error TF("Player %s does not existn", $arg2);
- } elsif (!defined $player->{name}) {
- error T("Player name has not been received, please try againn");
- } else {
- my $alreadyFriend = 0;
- for (my $i = 0; $i < @friendsID; $i++) {
- if ($friends{$i}{'name'} eq $player->{name}) {
- $alreadyFriend = 1;
- last;
- }
- }
- if ($alreadyFriend) {
- error TF("%s is already your friendn", $player->{name});
- } else {
- message TF("Requesting %s to be your friendn", $player->{name});
- $messageSender->sendFriendRequest($players{$playersID[$arg2]}{name});
- }
- }
- } elsif ($arg1 eq "remove") {
- if ($arg2 < 1 || $arg2 > @friendsID) {
- error TF("Friend #%s does not existn", $arg2);
- } else {
- $arg2--;
- message TF("Attempting to remove %s from your friend listn", $friends{$arg2}{'name'});
- $messageSender->sendFriendRemove($friends{$arg2}{'accountID'}, $friends{$arg2}{'charID'});
- }
- } elsif ($arg1 eq "accept") {
- if ($incomingFriend{'accountID'} eq "") {
- error T("Can't accept the friend request, no incoming requestn");
- } else {
- message TF("Accepting the friend request from %sn", $incomingFriend{'name'});
- $messageSender->sendFriendAccept($incomingFriend{'accountID'}, $incomingFriend{'charID'});
- undef %incomingFriend;
- }
- } elsif ($arg1 eq "reject") {
- if ($incomingFriend{'accountID'} eq "") {
- error T("Can't reject the friend request - no incoming requestn");
- } else {
- message TF("Rejecting the friend request from %sn", $incomingFriend{'name'});
- $messageSender->sendFriendReject($incomingFriend{'accountID'}, $incomingFriend{'charID'});
- undef %incomingFriend;
- }
- } elsif ($arg1 eq "pm") {
- if ($arg2 < 1 || $arg2 > @friendsID) {
- error TF("Friend #%s does not existn", $arg2);
- } else {
- $arg2--;
- if (binFind(@privMsgUsers, $friends{$arg2}{'name'}) eq "") {
- message TF("Friend %s has been added to the PM list as %sn", $friends{$arg2}{'name'}, @privMsgUsers);
- $privMsgUsers[@privMsgUsers] = $friends{$arg2}{'name'};
- } else {
- message TF("Friend %s is already in the PM listn", $friends{$arg2}{'name'});
- }
- }
- } else {
- error T("Syntax Error in function 'friend' (Manage Friends List)n" .
- "Usage: friend [request|remove|accept|reject|pm]n");
- }
- }
- sub cmdSlave {
- my ($cmd, $subcmd) = @_;
- my @args = parseArgs($subcmd);
-
- if (!$char) {
- error T("Error: Can't detect slaves - character is not yet readyn");
- return;
- }
-
- my $slave;
- if ($cmd eq 'homun') {
- $slave = $char->{homunculus};
- } elsif ($cmd eq 'merc') {
- $slave = $char->{mercenary};
- } else {
- error T("Error: Unknown command in cmdSlaven");
- }
-
- if (
- !$slave || !$slave->{appear_time} || (
- $slave->{actorType} eq 'Homunculus' and $slave->{state} & 2 || $slave->{state} & 4
- )
- ) {
- error T("Error: No slave detected.n");
- } elsif ($subcmd eq "s" || $subcmd eq "status") {
- my $hp_string = $slave->{'hp'}. '/' .$slave->{'hp_max'} . ' (' . sprintf("%.2f",$slave->{'hpPercent'}) . '%)';
- my $sp_string = $slave->{'sp'}."/".$slave->{'sp_max'}." (".sprintf("%.2f",$slave->{'spPercent'})."%)";
- my $exp_string = (
- defined $slave->{'exp'}
- ? formatNumber($slave->{'exp'})."/".formatNumber($slave->{'exp_max'})." (".sprintf("%.2f",$slave->{'expPercent'})."%)"
- : (
- defined $slave->{kills}
- ? formatNumber($slave->{kills})
- : ''
- )
- );
-
- my ($intimacy_label, $intimacy_string) = (
- defined $slave->{intimacy}
- ? ('Intimacy:', $slave->{intimacy})
- : (
- defined $slave->{faith}
- ? ('Faith:', $slave->{faith})
- : ('', '')
- )
- );
-
- my $hunger_string = defined $slave->{hunger} ? $slave->{hunger} : 'N/A';
- my $accessory_string = defined $slave->{accessory} ? $slave->{accessory} : 'N/A';
- my $faith_string = defined $slave->{faith} ? $slave->{faith} : 'N/A';
- my $summons_string = defined $slave->{summons} ? $slave->{summons} : 'N/A';
-
- my $msg = swrite(
- T("-------------------- Slave Status ----------------------n" .
- "Name: @<<<<<<<<<<<<<<<<<<<<<<<<< HP: @>>>>>>>>>>>>>>>>>>n" .
- "Type: @<<<<<<<<<<<<<<<<<<<<<<<<< SP: @>>>>>>>>>>>>>>>>>>n" .
- "Level: @<< @>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>n" .
- "--------------------------------------------------------n" .
- "Atk: @>>> Matk: @>>> Hunger: @>>>n" .
- "Hit: @>>> Critical: @>>> @<<<<<<<<< @>>>n" .
- "Def: @>>> Mdef: @>>> Accessory: @>>>n" .
- "Flee:@>>> Aspd: @>>> Summons: @>>>n"),
- [$slave->{'name'}, $hp_string,
- $slave->{actorType}, $sp_string,
- $slave->{'level'}, $exp_string, $slave->{'atk'}, $slave->{'matk'}, $hunger_string,
- $slave->{'hit'}, $slave->{'critical'}, $intimacy_label, $intimacy_string,
- $slave->{'def'}, $slave->{'mdef'}, $accessory_string,
- $slave->{'flee'}, $slave->{'aspdDisp'}, $summons_string]);
-
- #############################################################
- #Statuses
- #############################################################
- my $statuses = 'none';
- if (defined $slave->{statuses} && %{$slave->{statuses}}) {
- $statuses = join(", ", keys %{$slave->{statuses}});
- }
- $msg .= TF("Statuses: %s n", $statuses);
- $msg .= "-------------------------------------------------n";
-
- message $msg, "info";
- } elsif ($subcmd eq "feed") {
- unless (defined $slave->{hunger}) {
- error T("This slave can not be feededn");
- return;
- }
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", $cmd . ' ' . $subcmd);
- return;
- }
- if ($slave->{hunger} >= 76) {
- message T("Your homunculus is not yet hungry. Feeding it now will lower intimacy.n"), "homunculus";
- } else {
- $messageSender->sendHomunculusFeed();
- message T("Feeding your homunculus.n"), "homunculus";
- }
- } elsif ($subcmd eq "fire") {
- unless ($slave->{actorType} eq 'Mercenary') {
- error T("This slave can not be firedn");
- return;
- }
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", $cmd . ' ' . $subcmd);
- return;
- }
- $messageSender->sendMercenaryCommand (2);
- } elsif ($args[0] eq "move") {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", $cmd . ' ' . $subcmd);
- return;
- }
- if (!($args[1] =~ /^d+$/) || !($args[2] =~ /^d+$/)) {
- error TF("Error in function '%s move' (Slave Move)n" .
- "Invalid coordinates (%s, %s) specified.n", $cmd, $args[1], $args[2]);
- return;
- } else {
- # max distance that homunculus can follow: 17
- $messageSender->sendHomunculusMove($slave->{ID}, $args[1], $args[2]);
- }
- } elsif ($subcmd eq "standby") {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", $cmd . ' ' . $subcmd);
- return;
- }
- $messageSender->sendHomunculusStandBy($slave->{ID});
- } elsif ($args[0] eq 'ai') {
- if ($args[1] eq 'clear') {
- $slave->clear();
- message T("Slave AI sequences clearedn"), "success";
- } elsif ($args[1] eq 'print') {
- # Display detailed info about current AI sequence
- message T("--------- Slave AI Sequence ------------n"), "list";
- my $index = 0;
- foreach (@{$slave->{slave_ai_seq}}) {
- message("$index: $_ " . dumpHash(%{$slave->{slave_ai_seq_args}[$index]}) . "nn", "list");
- $index++;
- }
- message T("--------- Slave AI Sequence ------------n"), "list";
- } elsif ($args[1] eq 'on' || $args[1] eq 'auto') {
- # Set AI to auto mode
- if ($slave->{slave_AI} == 2) {
- message T("Slave AI is already set to auto moden"), "success";
- } else {
- $slave->{slave_AI} = 2;
- undef $slave->{slave_AI_forcedOff};
- message T("Slave AI set to auto moden"), "success";
- }
- } elsif ($args[1] eq 'manual') {
- # Set AI to manual mode
- if ($slave->{slave_AI} == 1) {
- message T("Slave AI is already set to manual moden"), "success";
- } else {
- $slave->{slave_AI} = 1;
- $slave->{slave_AI_forcedOff} = 1;
- message T("Slave AI set to manual moden"), "success";
- }
- } elsif ($args[1] eq 'off') {
- # Turn AI off
- if ($slave->{slave_AI}) {
- undef $slave->{slave_AI};
- $slave->{slave_AI_forcedOff} = 1;
- message T("Slave AI turned offn"), "success";
- } else {
- message T("Slave AI is already offn"), "success";
- }
- } elsif ($args[1] eq '') {
- # Toggle AI
- if ($slave->{slave_AI} == 2) {
- undef $slave->{slave_AI};
- $slave->{slave_AI_forcedOff} = 1;
- message T("Slave AI turned offn"), "success";
- } elsif (!$slave->{slave_AI}) {
- $slave->{slave_AI} = 1;
- $slave->{slave_AI_forcedOff} = 1;
- message T("Slave AI set to manual moden"), "success";
- } elsif ($slave->{slave_AI} == 1) {
- $slave->{slave_AI} = 2;
- undef $slave->{slave_AI_forcedOff};
- message T("Slave AI set to auto moden"), "success";
- }
- } else {
- error T("Syntax Error in function 'slave ai' (Slave AI Commands)n" .
- "Usage: homun ai [ clear | print | auto | manual | off ]n");
- }
- } elsif ($subcmd eq "aiv") {
- if (!$slave->{slave_AI}) {
- message TF("ai_seq (off) = %sn", "@{$slave->{slave_ai_seq}}"), "list";
- } elsif ($slave->{slave_AI} == 1) {
- message TF("ai_seq (manual) = %sn", "@{$slave->{slave_ai_seq}}"), "list";
- } elsif ($slave->{slave_AI} == 2) {
- message TF("ai_seq (auto) = %sn", "@{$slave->{slave_ai_seq}}"), "list";
- }
- message T("solutionn"), "list" if ($slave->args()->{'solution'});
- } elsif ($args[0] eq "skills") {
- if ($args[1] eq '') {
- my $msg = T("--------Slave Skill List-------n" .
- " # Skill Name Lv SPn");
- foreach my $handle (@{$slave->{slave_skillsID}}) {
- my $skill = new Skill(handle => $handle);
- my $sp = $char->{skills}{$handle}{sp} || '';
- $msg .= swrite(
- "@>>> @<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>> @>>>",
- [$skill->getIDN(), $skill->getName(), $char->getSkillLevel($skill), $sp]);
- }
- $msg .= TF("nSkill Points: %dn", $slave->{points_skill}) if defined $slave->{points_skill};
- $msg .= "-------------------------------n";
- message($msg, "list");
- } elsif ($args[1] eq "add" && $args[2] =~ /d+/) {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", $cmd . ' ' . $subcmd);
- return;
- }
- my $skill = new Skill(idn => $args[2]);
- if (!$skill->getIDN() || !$char->{skills}{$skill->getHandle()}) {
- error TF("Error in function '%s skills add' (Add Skill Point)n" .
- "Skill %s does not exist.n", $cmd, $args[2]);
- } elsif ($slave->{points_skill} < 1) {
- error TF("Error in function '%s skills add' (Add Skill Point)n" .
- "Not enough skill points to increase %sn", $cmd, $skill->getName());
- } else {
- $messageSender->sendAddSkillPoint($skill->getIDN());
- }
- } elsif ($args[1] eq "desc" && $args[2] =~ /d+/) {
- my $skill = new Skill(idn => $args[2]);
- if (!$skill->getIDN()) {
- error TF("Error in function '%s skills desc' (Skill Description)n" .
- "Skill %s does not exist.n", $cmd, $args[2]);
- } else {
- my $description = $skillsDesc_lut{$skill->getHandle()} || T("Error: No description available.n");
- message TF("===============Skill Description===============n" .
- "Skill: %snn", $skill->getName()), "info";
- message $description, "info";
- message "==============================================n", "info";
- }
- } else {
- error T("Syntax Error in function 'slave skills' (Slave Skills Functions)n" .
- "Usage: homun skills [(<add | desc>) [<skill #>]]n");
- }
- } else {
- error T("Usage: slave < feed | s | status | move | standby | ai | aiv | skills>n");
- }
- }
- sub cmdGetPlayerInfo {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- $messageSender->sendGetPlayerInfo(pack("V", $args));
- }
- sub cmdGmb {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- return unless ($char);
- if ($args eq '') {
- error "Usage: gmb <MESSAGE>n";
- return;
- }
- my $msg = "$char->{name}: $args" . chr(0);
- my $packet = pack("C*", 0x99, 0x00) . pack("v", length($msg) + 4) . stringToBytes($msg);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmbb {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- return unless ($char);
- if ($args eq '') {
- error "Usage: gmbb <MESSAGE>n";
- return;
- }
- my $msg = "blue$args" . chr(0);
- my $packet = pack("C*", 0x99, 0x00) . pack("v", length($msg) + 4) . stringToBytes($msg);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmnb {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- return unless ($char);
- if ($args eq '') {
- error "Usage: gmnb <MESSAGE>n";
- return;
- }
- my $msg = $args . chr(0);
- my $packet = pack("C*", 0x99, 0x00) . pack("v", length($msg) + 4) . stringToBytes($msg);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmlb {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- return unless ($char);
- if ($args eq '') {
- error "Usage: gmlb <MESSAGE>n";
- return;
- }
- my $msg = "$char->{name}: $args" . chr(0);
- my $packet = pack("C*", 0x9c, 0x01) . pack("v", length($msg) + 4) . stringToBytes($msg);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmlbb {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- return unless ($char);
- if ($args eq '') {
- error "Usage: gmlbb <MESSAGE>n";
- return;
- }
- my $msg = "blue$args" . chr(0);
- my $packet = pack("C*", 0x9c, 0x01) . pack("v", length($msg) + 4) . stringToBytes($msg);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmnlb {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- return unless ($char);
- if ($args eq '') {
- error "Usage: gmnlb <MESSAGE>n";
- return;
- }
- my $msg = $args . chr(0);
- my $packet = pack("C*", 0x9c, 0x01) . pack("v", length($msg) + 4) . stringToBytes($msg);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmmapmove {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- my ($map_name) = $args =~ /(S+)/;
- # this will pack as 0 if it fails to match
- my ($x, $y) = $args =~ /w+ (d+) (d+)/;
- if ($map_name eq '') {
- error "Usage: gmmapmove <FIELD>n";
- error "FIELD is a field name including .gat extension, like: gef_fild01.gatn";
- return;
- }
- my $packet = pack("C*", 0x40, 0x01) . pack("a16", $map_name) . pack("v1 v1", $x, $y);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmsummon {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- if ($args eq '') {
- error "Usage: gmsummon <player name>n" .
- "Summon a player.n";
- } else {
- $messageSender->sendGmSummon($args);
- }
- }
- sub cmdGmdc {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- if ($args !~ /^d+$/) {
- error "Usage: gmdc <player_AID>n";
- return;
- }
- my $packet = pack("C*", 0xCC, 0x00).pack("V1", $args);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmkillall {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my $packet = pack("C*", 0xCE, 0x00);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmcreate {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- if ($args eq '') {
- error "Usage: gmcreate (<MONSTER_NAME> || <Item_Name>) n";
- return;
- }
- my $packet = pack("C*", 0x3F, 0x01).pack("a24", $args);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmhide {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my $packet = pack("C*", 0x9D, 0x01, 0x40, 0x00, 0x00, 0x00);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmresetstate {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my $packet = pack("C1 C1 v1", 0x97, 0x01, 0);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmresetskill {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my $packet = pack("C1 C1 v1", 0x97, 0x01, 1);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmmute {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- my ($ID, $time) = $args =~ /^(d+) (d+)/;
- if (!$ID) {
- error "Usage: gmmute <ID> <minutes>n";
- return;
- }
- my $packet = pack("C1 C1 V1 C1 v1", 0x49, 0x01, $ID, 1, $time);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmunmute {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- my ($ID, $time) = $args =~ /^(d+) (d+)/;
- if (!$ID) {
- error "Usage: gmunmute <ID> <minutes>n";
- return;
- }
- my $packet = pack("C1 C1 V1 C1 v1", 0x49, 0x01, $ID, 0, $time);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmwarpto {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- if ($args eq '') {
- error "Usage: gmwarpto <Player Name>n";
- return;
- }
- my $packet = pack("C*", 0xBB, 0x01).pack("a24", $args);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmrecall {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- if ($args eq '') {
- error "Usage: gmrecall [<Character Name> | <User Name>]n";
- return;
- }
- my $packet = pack("C*", 0xBC, 0x01).pack("a24", $args);
- $messageSender->sendToServer($packet);
- }
- sub cmdGmremove {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $args) = @_;
- if ($args eq '') {
- error "Usage: gmremove [<Character Name> | <User Name>]n";
- return;
- }
- my $packet = pack("C*", 0xBA, 0x01).pack("a24", $args);
- $messageSender->sendToServer($packet);
- }
- sub cmdGuild {
- my (undef, $args) = @_;
- my ($arg1, $arg2) = split(' ', $args, 2);
- if ($arg1 eq "" || (!%guild && ($arg1 eq "info" || $arg1 eq "member" || $arg1 eq "kick"))) {
- if (!$net || $net->getState() != Network::IN_GAME) {
- if ($arg1 eq "") {
- error T("You must be logged in the game to request guild informationn");
- } else {
- error TF("Guild information is not yet available. You must login to the game and use the '%s' command firstn", 'guild');
- }
- return;
- }
- message T("Requesting guild information...n"), "info";
- $messageSender->sendGuildInfoRequest();
- # Replies 01B6 (Guild Info) and 014C (Guild Ally/Enemy List)
- $messageSender->sendGuildRequest(0);
- # Replies 0166 (Guild Member Titles List) and 0154 (Guild Members List)
- $messageSender->sendGuildRequest(1);
- if ($arg1 eq "") {
- message T("Enter command to view guild information: guild <info | member>n"), "info";
- } else {
- message TF("Type 'guild %s' again to view the information.n", $args), "info";
- }
- } elsif ($arg1 eq "info") {
- message swrite(T("---------- Guild Information ----------n" .
- "Name : @<<<<<<<<<<<<<<<<<<<<<<<<n" .
- "Lv : @<<n" .
- "Exp : @>>>>>>>>>/@<<<<<<<<<<n" .
- "Master : @<<<<<<<<<<<<<<<<<<<<<<<<n" .
- "Connect : @>>/@<<"),
- [$guild{name}, $guild{lvl}, $guild{exp}, $guild{next_exp}, $guild{master},
- $guild{conMember}, $guild{maxMember}]), "info";
- for my $ally (keys %{$guild{ally}}) {
- # Translation Comment: List of allies. Keep the same spaces of the - Guild Information - tag.
- message TF("Ally : %s (%s)n", $guild{ally}{$ally}, $ally), "info";
- }
- message("---------------------------------------n", "info");
- } elsif ($arg1 eq "member") {
- if (!$guild{member}) {
- error T("No guild member information available.n");
- return;
- }
- my $msg = T("------------ Guild Member ------------n" .
- "# Name Job Lv Title Onlinen");
- my ($i, $name, $job, $lvl, $title, $online, $ID, $charID);
- my $count = @{$guild{member}};
- for ($i = 0; $i < $count; $i++) {
- $name = $guild{member}[$i]{name};
- next if (!defined $name);
- $job = $jobs_lut{$guild{member}[$i]{jobID}};
- $lvl = $guild{member}[$i]{lvl};
- $title = $guild{member}[$i]{title};
- # Translation Comment: Guild member online
- $online = $guild{member}[$i]{online} ? T("Yes") : T("No");
- $ID = unpack("V",$guild{member}[$i]{ID});
- $charID = unpack("V",$guild{member}[$i]{charID});
- $msg .= swrite("@< @<<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<< @> @<<<<<<<<<<<<<<<<<<<<<<< @<<",
- [$i, $name, $job, $lvl, $title, $online, $ID, $charID]);
- }
- $msg .= "---------------------------------------n";
- message $msg, "list";
-
- } elsif (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", 'guild ' . $arg1);
- return;
- } elsif ($arg1 eq "join") {
- if ($arg2 ne "1" && $arg2 ne "0") {
- error T("Syntax Error in function 'guild join' (Accept/Deny Guild Join Request)n" .
- "Usage: guild join <flag>n");
- return;
- } elsif ($incomingGuild{'ID'} eq "") {
- error T("Error in function 'guild join' (Join/Request to Join Guild)n" .
- "Can't accept/deny guild request - no incoming request.n");
- return;
- }
- $messageSender->sendGuildJoin($incomingGuild{ID}, $arg2);
- undef %incomingGuild;
- if ($arg2) {
- message T("You accepted the guild join request.n"), "success";
- } else {
- message T("You denied the guild join request.n"), "info";
- }
- } elsif ($arg1 eq "create") {
- if (!$arg2) {
- error T("Syntax Error in function 'guild create' (Create Guild)n" .
- "Usage: guild create <name>n");
- } else {
- $messageSender->sendGuildCreate($arg2);
- }
- } elsif (!defined $char->{guild}) {
- error T("You are not in a guild.n");
- } elsif ($arg1 eq "request") {
- my $player = Match::player($arg2);
- if (!$player) {
- error TF("Player %s does not exist.n", $arg2);
- } else {
- $messageSender->sendGuildJoinRequest($player->{ID});
- message TF("Sent guild join request to %sn", $player->{name});
- }
- } elsif ($arg1 eq "ally") {
- if (!$guild{master}) {
- error T("No guild information available. Type guild to refresh and then try again.n");
- return;
- }
- my $player = Match::player($arg2);
- if (!$player) {
- error TF("Player %s does not exist.n", $arg2);
- } elsif (!$char->{name} eq $guild{master}) {
- error T("You must be guildmaster to set an alliancen");
- return;
- } else {
- $messageSender->sendGuildSetAlly($net,$player->{ID},$accountID,$charID);
- message TF("Sent guild alliance request to %sn", $player->{name});
- }
- } elsif ($arg1 eq "leave") {
- $messageSender->sendGuildLeave($arg2);
- message TF("Sending guild leave: %sn", $arg2);
- } elsif ($arg1 eq "break") {
- if (!$arg2) {
- error T("Syntax Error in function 'guild break' (Break Guild)n" .
- "Usage: guild break <guild name>n");
- } else {
- $messageSender->sendGuildBreak($arg2);
- message TF("Sending guild break: %sn", $arg2);
- }
- } elsif ($arg1 eq "kick") {
- if (!$guild{member}) {
- error T("No guild member information available.n");
- return;
- }
- my @params = split(' ', $arg2, 2);
- if ($params[0] =~ /^d+$/) {
- if ($guild{'member'}[$params[0]]) {
- $messageSender->sendGuildMemberKick($char->{guildID},
- $guild{member}[$params[0]]{ID},
- $guild{member}[$params[0]]{charID},
- $params[1]);
- } else {
- error TF("Error in function 'guild kick' (Kick Guild Member)n" .
- "Invalid guild member '%s' specified.n", $params[0]);
- }
- } else {
- error T("Syntax Error in function 'guild kick' (Kick Guild Member)n" .
- "Usage: guild kick <number> <reason>n");
- }
- }
- }
- sub cmdGuildChat {
- if (!$net || $net->getState() != Network::IN_GAME) {
- error TF("You must be logged in the game to use this command (%s)n", shift);
- return;
- }
- my (undef, $arg1) = @_;
- if ($arg1 eq "") {
- error T("Syntax Error in function 'g' (Guild Chat)n" .
- "Usage: g <message>n");
- } else {
- sendMessage($messageSender, "g", $arg1);
- }
- }
- sub cmdHelp {
- # Display help message
- my (undef, $args) = @_;
- my @commands_req = split(/ +/, $args);
- my @unknown;
- my @found;
- my @commands = (@commands_req)? @commands_req : (sort keys %descriptions);
- my ($message,$cmd);
- $message .= T("--------------- Available commands ---------------n") unless @commands_req;
- foreach my $switch (@commands) {
- if ($descriptions{$switch}) {
- if (ref($descriptions{$switch}) eq 'ARRAY') {
- if (@commands_req) {
- helpIndent($switch,$descriptions{$switch});
- } else {
- $message .= sprintf("%-11s %sn",$switch, $descriptions{$switch}->[0]);
- }
- }
- push @found, $switch;
- } else {
- push @unknown, $switch;
- }
- }
- @commands = (@commands_req)? @commands_req : (sort keys %customCommands);
- foreach my $switch (@commands) {
- if ($customCommands{$switch}) {
- if (ref($customCommands{$switch}{desc}) eq 'ARRAY') {
- if (@commands_req) {
- helpIndent($switch,$customCommands{$switch}{desc});
- } else {
- $message .= sprintf("%-11s %sn",$switch, $customCommands{$switch}{desc}->[0]);
- }
- }
- push @found, $switch;
- } else {
- push @unknown, $switch unless defined binFind(@unknown,$switch);
- }
- }
- foreach (@found) {
- binRemoveAndShift(@unknown,$_);
- }
- if (@unknown) {
- if (@unknown == 1) {
- error TF("The command "%s" doesn't exist.n", $unknown[0]);
- } else {
- error TF("These commands don't exist: %sn", join(', ', @unknown));
- }
- error T("Type 'help' to see a list of all available commands.n");
- }
- $message .= "--------------------------------------------------n"unless @commands_req;
- message $message, "list" unless @commands_req;
- }
- sub helpIndent {
- my $cmd = shift;
- my $desc = shift;
- my @tmp = @{$desc};
- my $message;
- my $messageTmp;
- my @words;
- my $length = 0;
- $message = TF("------------ Help for '%s' ------------n", $cmd);