Overview

Namespaces

  • Budabot
    • Core
      • Modules
    • User
      • Modules
  • None
  • Tyrence
    • Modules

Classes

  • AccessLevel
  • Budabot\Core\AccessManager
  • Budabot\Core\AdminManager
  • Budabot\Core\AOChat
  • Budabot\Core\AOChatPacket
  • Budabot\Core\AOChatQueue
  • Budabot\Core\AOExtMsg
  • Budabot\Core\AsyncHttp
  • Budabot\Core\AutoInject
  • Budabot\Core\BotRunner
  • Budabot\Core\Budabot
  • Budabot\Core\BuddylistManager
  • Budabot\Core\CacheManager
  • Budabot\Core\CacheResult
  • Budabot\Core\ClassLoader
  • Budabot\Core\ColorSettingHandler
  • Budabot\Core\CommandAlias
  • Budabot\Core\CommandManager
  • Budabot\Core\ConfigFile
  • Budabot\Core\DB
  • Budabot\Core\DBRow
  • Budabot\Core\EventLoop
  • Budabot\Core\EventManager
  • Budabot\Core\GuildChannelCommandReply
  • Budabot\Core\GuildManager
  • Budabot\Core\HelpManager
  • Budabot\Core\Http
  • Budabot\Core\HttpRequest
  • Budabot\Core\LegacyLogger
  • Budabot\Core\LimitsController
  • Budabot\Core\LoggerWrapper
  • Budabot\Core\MMDBParser
  • Budabot\Core\Modules\AdminController
  • Budabot\Core\Modules\AliasController
  • Budabot\Core\Modules\AltInfo
  • Budabot\Core\Modules\AltsController
  • Budabot\Core\Modules\BanController
  • Budabot\Core\Modules\BuddylistController
  • Budabot\Core\Modules\ColorsController
  • Budabot\Core\Modules\CommandlistController
  • Budabot\Core\Modules\CommandSearchController
  • Budabot\Core\Modules\ConfigController
  • Budabot\Core\Modules\EventlistController
  • Budabot\Core\Modules\HelpController
  • Budabot\Core\Modules\LogsController
  • Budabot\Core\Modules\PlayerLookupController
  • Budabot\Core\Modules\ProfileCommandReply
  • Budabot\Core\Modules\ProfileController
  • Budabot\Core\Modules\SettingsController
  • Budabot\Core\Modules\SQLController
  • Budabot\Core\Modules\SystemController
  • Budabot\Core\Modules\UsageController
  • Budabot\Core\Modules\WhitelistController
  • Budabot\Core\NumberSettingHandler
  • Budabot\Core\OptionsSettingHandler
  • Budabot\Core\PlayerHistory
  • Budabot\Core\PlayerHistoryManager
  • Budabot\Core\PlayerManager
  • Budabot\Core\Preferences
  • Budabot\Core\PrivateChannelCommandReply
  • Budabot\Core\PrivateMessageCommandReply
  • Budabot\Core\Registry
  • Budabot\Core\SettingHandler
  • Budabot\Core\SettingManager
  • Budabot\Core\SettingObject
  • Budabot\Core\SocketManager
  • Budabot\Core\SocketNotifier
  • Budabot\Core\SubcommandManager
  • Budabot\Core\Text
  • Budabot\Core\TextSettingHandler
  • Budabot\Core\Timer
  • Budabot\Core\TimerEvent
  • Budabot\Core\TimeSettingHandler
  • Budabot\Core\Util
  • Budabot\Core\xml
  • Budabot\User\Modules\AlienArmorController
  • Budabot\User\Modules\AlienBioController
  • Budabot\User\Modules\AlienMiscController
  • Budabot\User\Modules\AOSpeakController
  • Budabot\User\Modules\AOUController
  • Budabot\User\Modules\AXPController
  • Budabot\User\Modules\BankController
  • Budabot\User\Modules\BosslootController
  • Budabot\User\Modules\BroadcastController
  • Budabot\User\Modules\BuffPerksController
  • Budabot\User\Modules\CacheController
  • Budabot\User\Modules\ChatAssistController
  • Budabot\User\Modules\ChatCheckController
  • Budabot\User\Modules\ChatLeaderController
  • Budabot\User\Modules\ChatRallyController
  • Budabot\User\Modules\ChatSayController
  • Budabot\User\Modules\ChatTopicController
  • Budabot\User\Modules\CityWaveController
  • Budabot\User\Modules\CloakController
  • Budabot\User\Modules\ClusterController
  • Budabot\User\Modules\CountdownController
  • Budabot\User\Modules\DevController
  • Budabot\User\Modules\DingController
  • Budabot\User\Modules\EventsController
  • Budabot\User\Modules\FightController
  • Budabot\User\Modules\FindOrgController
  • Budabot\User\Modules\FindPlayerController
  • Budabot\User\Modules\FunController
  • Budabot\User\Modules\GitController
  • Budabot\User\Modules\GuideController
  • Budabot\User\Modules\GuildController
  • Budabot\User\Modules\HelpbotController
  • Budabot\User\Modules\HtmlDecodeController
  • Budabot\User\Modules\ImplantController
  • Budabot\User\Modules\ImplantDesignerController
  • Budabot\User\Modules\InactiveMemberController
  • Budabot\User\Modules\ItemsController
  • Budabot\User\Modules\KillOnSightController
  • Budabot\User\Modules\LevelController
  • Budabot\User\Modules\LinksController
  • Budabot\User\Modules\LootListsController
  • Budabot\User\Modules\MdbController
  • Budabot\User\Modules\MessageInfoCommandReply
  • Budabot\User\Modules\MockCommandReply
  • Budabot\User\Modules\NanoController
  • Budabot\User\Modules\NewsController
  • Budabot\User\Modules\NotesController
  • Budabot\User\Modules\OnlineController
  • Budabot\User\Modules\OrgHistoryController
  • Budabot\User\Modules\OrglistController
  • Budabot\User\Modules\OrgMembersController
  • Budabot\User\Modules\OSController
  • Budabot\User\Modules\PlayerHistoryController
  • Budabot\User\Modules\PlayfieldController
  • Budabot\User\Modules\PocketbossController
  • Budabot\User\Modules\PremadeImplantController
  • Budabot\User\Modules\PrivateChannelController
  • Budabot\User\Modules\QuoteController
  • Budabot\User\Modules\RaffleController
  • Budabot\User\Modules\RaidController
  • Budabot\User\Modules\RandomController
  • Budabot\User\Modules\RecipeController
  • Budabot\User\Modules\RelayController
  • Budabot\User\Modules\ReputationController
  • Budabot\User\Modules\ResearchController
  • Budabot\User\Modules\RunAsController
  • Budabot\User\Modules\SendTellController
  • Budabot\User\Modules\ShoppingController
  • Budabot\User\Modules\SilenceController
  • Budabot\User\Modules\SkillsController
  • Budabot\User\Modules\SpiritsController
  • Budabot\User\Modules\StopwatchController
  • Budabot\User\Modules\Teamspeak3
  • Budabot\User\Modules\TeamspeakController
  • Budabot\User\Modules\TestController
  • Budabot\User\Modules\TimeController
  • Budabot\User\Modules\TimerController
  • Budabot\User\Modules\TimezoneController
  • Budabot\User\Modules\TowerController
  • Budabot\User\Modules\TrackerController
  • Budabot\User\Modules\TrickleController
  • Budabot\User\Modules\UnixtimeController
  • Budabot\User\Modules\VoteController
  • Budabot\User\Modules\WeatherController
  • Budabot\User\Modules\WhatBuffsController
  • Budabot\User\Modules\WhereisController
  • Budabot\User\Modules\WhoisController
  • Budabot\User\Modules\WhoisOrgController
  • Budabot\User\Modules\WhompahController
  • Command
  • DefaultStatus
  • DefineCommand
  • Description
  • Event
  • HandlesCommand
  • Help
  • Inject
  • Instance
  • Intoptions
  • Matches
  • Options
  • Setting
  • Setup
  • Type
  • Tyrence\Modules\DemoResponseCommandReply
  • Tyrence\Modules\SameChannelResponseController
  • Visibility

Interfaces

  • Budabot\Core\CommandReply

Exceptions

  • Budabot\Core\InvalidHttpRequest
  • Budabot\Core\SQLException
  • Budabot\Core\StopExecutionException

Functions

  • Budabot\Core\isWindows
  • Budabot\Core\Modules\read_input
  • Overview
  • Namespace
  • Class
  1: <?php
  2: 
  3: namespace Budabot\Core;
  4: 
  5: use stdClass;
  6: use ReflectionAnnotatedMethod;
  7: use Exception;
  8: 
  9: /**
 10:  * @Instance
 11:  */
 12: class CommandManager {
 13: 
 14:     /** @Inject */
 15:     public $db;
 16: 
 17:     /** @Inject */
 18:     public $chatBot;
 19: 
 20:     /** @Inject */
 21:     public $settingManager;
 22: 
 23:     /** @Inject */
 24:     public $accessManager;
 25: 
 26:     /** @Inject */
 27:     public $helpManager;
 28: 
 29:     /** @Inject */
 30:     public $commandAlias;
 31: 
 32:     /** @Inject */
 33:     public $text;
 34: 
 35:     /** @Inject */
 36:     public $util;
 37: 
 38:     /** @Inject */
 39:     public $subcommandManager;
 40:     
 41:     /** @Inject */
 42:     public $commandSearchController;
 43:     
 44:     /** @Inject */
 45:     public $usageController;
 46: 
 47:     /** @Logger */
 48:     public $logger;
 49: 
 50:     public $commands;
 51: 
 52:     /**
 53:      * @name: register
 54:      * @description: Registers a command
 55:      */
 56:     public function register($module, $channel, $filename, $command, $accessLevel, $description, $help = '', $defaultStatus = null) {
 57:         $command = strtolower($command);
 58:         $module = strtoupper($module);
 59:         $accessLevel = $this->accessManager->getAccessLevel($accessLevel);
 60: 
 61:         if (!$this->chatBot->processCommandArgs($channel, $accessLevel)) {
 62:             $this->logger->log('ERROR', "Invalid args for $module:command($command). Command not registered.");
 63:             return;
 64:         }
 65: 
 66:         if (empty($filename)) {
 67:             $this->logger->log('ERROR', "Error registering $module:command($command).  Handler is blank.");
 68:             return;
 69:         }
 70: 
 71:         forEach (explode(',', $filename) as $handler) {
 72:             list($name, $method) = explode(".", $handler);
 73:             if (!Registry::instanceExists($name)) {
 74:                 $this->logger->log('ERROR', "Error registering method '$handler' for command '$command'.  Could not find instance '$name'.");
 75:                 return;
 76:             }
 77:         }
 78: 
 79:         if (!empty($help)) {
 80:             $help = $this->helpManager->checkForHelpFile($module, $help);
 81:         }
 82: 
 83:         if ($defaultStatus === null) {
 84:             if ($this->chatBot->vars['default_module_status'] == 1) {
 85:                 $status = 1;
 86:             } else {
 87:                 $status = 0;
 88:             }
 89:         } else {
 90:             $status = $defaultStatus;
 91:         }
 92: 
 93:         for ($i = 0; $i < count($channel); $i++) {
 94:             $this->logger->log('debug', "Adding Command to list:($command) File:($filename) Admin:({$accessLevel[$i]}) Channel:({$channel[$i]})");
 95:             $row = $this->db->queryRow("SELECT 1 FROM cmdcfg_<myname> WHERE cmd = ? AND type = ?", $command, $channel[$i]);
 96: 
 97:             try {
 98:                 if ($row !== null) {
 99:                     $sql = "UPDATE cmdcfg_<myname> SET `module` = ?, `verify` = ?, `file` = ?, `description` = ?, `help` = ? WHERE `cmd` = ? AND `type` = ?";
100:                     $this->db->exec($sql, $module, '1', $filename, $description, $help, $command, $channel[$i]);
101:                 } else {
102:                     $sql = "INSERT INTO cmdcfg_<myname> (`module`, `type`, `file`, `cmd`, `admin`, `description`, `verify`, `cmdevent`, `status`, `help`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
103:                     $this->db->exec($sql, $module, $channel[$i], $filename, $command, $accessLevel[$i], $description, '1', 'cmd', $status, $help);
104:                 }
105:             } catch (SQLException $e) {
106:                 $this->logger->log('ERROR', "Error registering method '$handler' for command '$command': " . $e->getMessage());
107:             }
108:         }
109:     }
110: 
111:     /**
112:      * @name: activate
113:      * @description: Activates a command
114:      */
115:     public function activate($channel, $filename, $command, $accessLevel = 'all') {
116:         $command = strtolower($command);
117:         $accessLevel = $this->accessManager->getAccessLevel($accessLevel);
118:         $channel = strtolower($channel);
119: 
120:         $this->logger->log('DEBUG', "Activate Command:($command) Admin Type:($accessLevel) File:($filename) Channel:($channel)");
121: 
122:         forEach (explode(',', $filename) as $handler) {
123:             list($name, $method) = explode(".", $handler);
124:             if (!Registry::instanceExists($name)) {
125:                 $this->logger->log('ERROR', "Error activating method $handler for command $command.  Could not find instance '$name'.");
126:                 return;
127:             }
128:         }
129: 
130:         $obj = new stdClass;
131:         $obj->file = $filename;
132:         $obj->admin = $accessLevel;
133: 
134:         $this->commands[$channel][$command] = $obj;
135:     }
136: 
137:     /**
138:      * @name: deactivate
139:      * @description: Deactivates a command
140:      */
141:     public function deactivate($channel, $filename, $command) {
142:         $command = strtolower($command);
143:         $channel = strtolower($channel);
144: 
145:         $this->logger->log('DEBUG', "Deactivate Command:($command) File:($filename) Channel:($channel)");
146: 
147:         unset($this->commands[$channel][$command]);
148:     }
149: 
150:     public function updateStatus($channel, $cmd, $module, $status, $admin) {
151:         if ($channel == 'all' || $channel == '' || $channel == null) {
152:             $type_sql = '';
153:         } else {
154:             $type_sql = "AND `type` = '$channel'";
155:         }
156: 
157:         if ($cmd == '' || $cmd == null) {
158:             $cmd_sql = '';
159:         } else {
160:             $cmd_sql = "AND `cmd` = '$cmd'";
161:         }
162: 
163:         if ($module == '' || $module == null) {
164:             $module_sql = '';
165:         } else {
166:             $module_sql = "AND `module` = '$module'";
167:         }
168: 
169:         if ($admin == '' || $admin == null) {
170:             $adminSql = '';
171:         } else {
172:             $adminSql = ", admin = '$admin'";
173:         }
174: 
175:         $data = $this->db->query("SELECT * FROM cmdcfg_<myname> WHERE `cmdevent` = 'cmd' $module_sql $cmd_sql $type_sql");
176:         if (count($data) == 0) {
177:             return 0;
178:         }
179: 
180:         forEach ($data as $row) {
181:             if ($status == 1) {
182:                 $this->activate($row->type, $row->file, $row->cmd, $admin);
183:             } else if ($status == 0) {
184:                 $this->deactivate($row->type, $row->file, $row->cmd);
185:             }
186:         }
187: 
188:         return $this->db->exec("UPDATE cmdcfg_<myname> SET status = '$status' $adminSql WHERE `cmdevent` = 'cmd' $module_sql $cmd_sql $type_sql");
189:     }
190: 
191:     /**
192:      * @name: loadCommands
193:      * @description: Loads the active commands into memory to activate them
194:      */
195:     public function loadCommands() {
196:         $this->logger->log('DEBUG', "Loading enabled commands");
197: 
198:         $data = $this->db->query("SELECT * FROM cmdcfg_<myname> WHERE `status` = '1' AND `cmdevent` = 'cmd'");
199:         forEach ($data as $row) {
200:             $this->activate($row->type, $row->file, $row->cmd, $row->admin);
201:         }
202:     }
203: 
204:     public function get($command, $channel = null) {
205:         $command = strtolower($command);
206: 
207:         if ($channel !== null) {
208:             $type_sql = "AND type = '{$channel}'";
209:         }
210: 
211:         $sql = "SELECT * FROM cmdcfg_<myname> WHERE `cmd` = ? {$type_sql}";
212:         return $this->db->query($sql, $command);
213:     }
214:     
215:     private function mapToCmd($sc) {
216:         return $sc->cmd;
217:     }
218: 
219:     function process($channel, $message, $sender, CommandReply $sendto) {
220:         list($cmd, $params) = explode(' ', $message, 2);
221:         $cmd = strtolower($cmd);
222: 
223:         $commandHandler = $this->getActiveCommandHandler($cmd, $channel, $message);
224: 
225:         // if command doesn't exist
226:         if ($commandHandler === null) {
227:             // if they've disabled feedback for guild or private channel, just return
228:             if (($channel == 'guild' && $this->settingManager->get('guild_channel_cmd_feedback') == 0) || ($channel == 'priv' && $this->settingManager->get('private_channel_cmd_feedback') == 0)) {
229:                 return;
230:             }
231: 
232:             $similarCommands = $this->commandSearchController->findSimilarCommands(array($cmd));
233:             $similarCommands = $this->commandSearchController->filterResultsByAccessLevel($sender, $similarCommands);
234:             $similarCommands = array_slice($similarCommands, 0, 5);
235:             $cmdNames = array_map(array($this, 'mapToCmd'), $similarCommands);
236: 
237:             $sendto->reply("Error! Unknown command. Did you mean..." . implode(", ", $cmdNames) . '?');
238:             return;
239:         }
240: 
241:         // if the character doesn't have access
242:         if (!$this->checkAccessLevel($channel, $message, $sender, $sendto, $cmd, $commandHandler)) {
243:             return;
244:         }
245: 
246:         try {
247:             $handler = $this->callCommandHandler($commandHandler, $message, $channel, $sender, $sendto);
248: 
249:             if ($handler === null) {
250:                 $help = $this->getHelpForCommand($cmd, $channel, $sender);
251:                 $sendto->reply($help);
252:             }
253:         } catch (StopExecutionException $e) {
254:             throw $e;
255:         } catch (SQLException $e) {
256:             $this->logger->log("ERROR", $e->getMessage(), $e);
257:             $sendto->reply("There was an SQL error executing your command.");
258:         } catch (Exception $e) {
259:             $this->logger->log("ERROR", "Error executing '$message': " . $e->getMessage(), $e);
260:             $sendto->reply("There was an error executing your command: " . $e->getMessage());
261:         }
262:         
263:         try {
264:             // record usage stats (in try/catch block in case there is an error)
265:             if ($this->settingManager->get('record_usage_stats') == 1) {
266:                 $this->usageController->record($channel, $cmd, $sender, $handler);
267:             }
268:         } catch (Exception $e) {
269:             $this->logger->log("ERROR", $e->getMessage(), $e);
270:         }
271:     }
272: 
273:     public function checkAccessLevel($channel, $message, $sender, $sendto, $cmd, $commandHandler) {
274:         if ($this->accessManager->checkAccess($sender, $commandHandler->admin) !== true) {
275:             if ($channel == 'msg') {
276:                 if ($this->settingManager->get('access_denied_notify_guild') == 1) {
277:                     $this->chatBot->sendGuild("Player <highlight>$sender<end> was denied access to command <highlight>$cmd<end>.", true);
278:                 }
279:                 if ($this->settingManager->get('access_denied_notify_priv') == 1) {
280:                     $this->chatBot->sendPrivate("Player <highlight>$sender<end> was denied access to command <highlight>$cmd<end>.", true);
281:                 }
282:             }
283:         
284:             // if they've disabled feedback for guild or private channel, just return
285:             if (($channel == 'guild' && $this->settingManager->get('guild_channel_cmd_feedback') == 0) || ($channel == 'priv' && $this->settingManager->get('private_channel_cmd_feedback') == 0)) {
286:                 return false;
287:             }
288: 
289:             $sendto->reply("Error! Access denied.");
290:             return false;
291:         }
292:         return true;
293:     }
294: 
295:     public function callCommandHandler($commandHandler, $message, $channel, $sender, CommandReply $sendto) {
296:         $successfulHandler = null;
297: 
298:         forEach (explode(',', $commandHandler->file) as $handler) {
299:             list($name, $method) = explode(".", $handler);
300:             $instance = Registry::getInstance($name);
301:             if ($instance === null) {
302:                 $this->logger->log('ERROR', "Could not find instance for name '$name'");
303:             } else {
304:                 $arr = $this->checkMatches($instance, $method, $message);
305:                 if ($arr !== false) {
306:                     // methods will return false to indicate a syntax error, so when a false is returned,
307:                     // we set $syntaxError = true, otherwise we set it to false
308:                     $syntaxError = ($instance->$method($message, $channel, $sender, $sendto, $arr) === false);
309:                     if ($syntaxError == false) {
310:                         // we can stop looking, command was handled successfully
311:                         
312:                         $successfulHandler = $handler;
313:                         break;
314:                     }
315:                 }
316:             }
317:         }
318: 
319:         return $successfulHandler;
320:     }
321: 
322:     public function getActiveCommandHandler($cmd, $channel, $message) {
323:         // Check if a subcommands for this exists
324:         if (isset($this->subcommandManager->subcommands[$cmd])) {
325:             forEach ($this->subcommandManager->subcommands[$cmd] as $row) {
326:                 if ($row->type == $channel && preg_match("/^{$row->cmd}$/i", $message)) {
327:                     return $row;
328:                 }
329:             }
330:         }
331:         return $this->commands[$channel][$cmd];
332:     }
333: 
334:     public function getHelpForCommand($cmd, $channel, $sender) {
335:         $results = $this->get($cmd, $channel);
336:         $result = $results[0];
337: 
338:         if ($result->help != '') {
339:             $blob = file_get_contents($result->help);
340:         } else {
341:             $blob = $this->helpManager->find($cmd, $sender);
342:         }
343:         if (!empty($blob)) {
344:             $msg = $this->text->makeBlob("Help ($cmd)", $blob);
345:         } else {
346:             $msg = "Error! Invalid syntax.";
347:         }
348:         return $msg;
349:     }
350: 
351:     public function checkMatches($instance, $method, $message) {
352:         try {
353:             $reflectedMethod = new ReflectionAnnotatedMethod($instance, $method);
354:         } catch (ReflectionException $e) {
355:             // method doesn't exist (probably handled dynamically)
356:             return true;
357:         }
358: 
359:         $regexes = $this->retrieveRegexes($reflectedMethod);
360: 
361:         if (count($regexes) > 0) {
362:             forEach ($regexes as $regex) {
363:                 if (preg_match($regex, $message, $arr)) {
364:                     return $arr;
365:                 }
366:             }
367:             return false;
368:         } else {
369:             return true;
370:         }
371:     }
372: 
373:     public function retrieveRegexes($reflectedMethod) {
374:         $regexes = array();
375:         if ($reflectedMethod->hasAnnotation('Matches')) {
376:             forEach ($reflectedMethod->getAllAnnotations('Matches') as $annotation) {
377:                 $regexes []= $annotation->value;
378:             }
379:         }
380:         return $regexes;
381:     }
382: }
383: 
Budabot 4 Docs API documentation generated by ApiGen