1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace ManiaLive\PluginHandler;
13:
14: use ManiaLive\Event\Dispatcher;
15: use ManiaLive\Application\Listener as AppListener;
16: use ManiaLive\Application\Event as AppEvent;
17: use ManiaLive\Data\Listener as PlayerListener;
18: use ManiaLive\Data\Event as PlayerEvent;
19: use ManiaLive\DedicatedApi\Callback\Adapter as ServerAdapter;
20: use ManiaLive\DedicatedApi\Callback\Event as ServerEvent;
21: use ManiaLive\Features\Tick\Listener as TickListener;
22: use ManiaLive\Features\Tick\Event as TickEvent;
23: use ManiaLive\PluginHandler\Listener as PluginListener;
24: use ManiaLive\PluginHandler\Event as PluginEvent;
25: use ManiaLive\Threading\Listener as ThreadListener;
26: use ManiaLive\Threading\Event as ThreadEvent;
27:
28: use ManiaLive\Data\Storage;
29: use ManiaLive\Database\Connection as DbConnection;
30: use DedicatedApi\Connection;
31: use ManiaLive\Features\ChatCommand\Interpreter;
32: use ManiaLive\Features\ChatCommand\Command;
33: use ManiaLive\Utilities\Console;
34: use ManiaLive\Utilities\Logger;
35:
36: 37: 38: 39: 40:
41: abstract class Plugin extends ServerAdapter implements ThreadListener, TickListener, AppListener, PlayerListener, PluginListener
42: {
43:
44: private $name;
45:
46: private $author;
47:
48: private $id;
49:
50: private $version;
51:
52: private $dependencies;
53: 54: 55:
56: private $eventsApplication = 0;
57: private $eventsThreading = 0;
58: private $eventsTick = false;
59: private $eventsServer = 0;
60: private $eventsStorage = 0;
61: private $eventsPlugins = 0;
62:
63: private $pluginHandler;
64:
65: private $methods;
66:
67: private $chatCommands;
68:
69: protected $storage;
70:
71: protected $connection;
72:
73: protected $db;
74:
75: final function __construct()
76: {
77: $this->dependencies = array();
78: $this->methods = array();
79:
80: $items = explode('\\', get_class($this));
81: $this->author = $items[1];
82: $this->name = $items[2];
83: $this->id = $this->author.'\\'.$this->name;
84: $this->setVersion(1);
85:
86: $config = \ManiaLive\DedicatedApi\Config::getInstance();
87: $this->connection = Connection::factory($config->host, $config->port, $config->timeout, $config->user, $config->password);
88: $this->pluginHandler = PluginHandler::getInstance();
89: $this->storage = Storage::getInstance();
90: $this->chatCommands = array();
91: }
92:
93: 94: 95: 96: 97: 98:
99: final protected function setVersion($version)
100: {
101: $this->version = $version;
102: }
103:
104: 105: 106: 107:
108: final public function getVersion()
109: {
110: return $this->version;
111: }
112:
113: 114: 115: 116:
117: final public function getName()
118: {
119: return $this->name;
120: }
121:
122: 123: 124: 125:
126: final public function getAuthor()
127: {
128: return $this->author;
129: }
130:
131: 132: 133: 134:
135: final public function getId()
136: {
137: return $this->id;
138: }
139:
140: 141: 142: 143: 144:
145: final public function addDependency(Dependency $dependency)
146: {
147: $this->dependencies[] = $dependency;
148: }
149:
150: 151: 152: 153:
154: final public function getDependencies()
155: {
156: return $this->dependencies;
157: }
158:
159: 160: 161: 162: 163: 164:
165: final protected function setPublicMethod($name)
166: {
167: try
168: {
169: $method = new \ReflectionMethod($this, $name);
170: if(!$method->isPublic())
171: throw new Exception('The method "'.$name.'" must be declared as public!');
172: $this->methods[$name] = $method;
173: }
174: catch(\ReflectionException $ex)
175: {
176: throw new Exception('The method "'.$name.'" does not exist and therefore can not be exposed!');
177: }
178: }
179:
180: 181: 182: 183: 184: 185: 186:
187: final protected function callPublicMethod($pluginId, $method)
188: {
189: $this->restrictIfUnloaded();
190: return $this->pluginHandler->callPublicMethod($this, $pluginId, $method, array_slice(func_get_args(), 2));
191: }
192:
193: 194: 195: 196: 197: 198: 199: 200:
201: final public function getPublicMethod($method)
202: {
203: if(isset($this->methods[$method]))
204: return $this->methods[$method];
205: else
206: throw new Exception('The method "'.$method.'" does not exist or has not been set public in plugin "'.$this->id.'"!');
207: }
208:
209: 210: 211: 212:
213: final public function getPublicMethods()
214: {
215: $methods = array();
216: foreach($this->methods as $name => $method)
217: {
218: $info = array(
219: 'name' => $name,
220: 'parameter_count' => $method->getNumberOfParameters(),
221: 'parameters' => array()
222: );
223:
224: $parameters = $method->getParameters();
225: foreach($parameters as $parameter)
226: {
227: if($parameter->allowsNull())
228: {
229: $info['parameters'][] = '['.$parameter->name.']';
230: }
231: else
232: {
233: $info['parameters'][] = $parameter->name;
234: }
235: }
236:
237: $methods[] = $info;
238: }
239: return $methods;
240: }
241:
242: 243: 244: 245: 246:
247: final private function restrictIfUnloaded()
248: {
249: if(!$this->isLoaded())
250: {
251: $trace = debug_backtrace();
252: throw new \Exception("The method '{$trace[1]['function']}' can not be called before the Plugin '".$this->getId()."' has been loaded!");
253: }
254: }
255:
256: 257: 258: 259:
260: final public function isLoaded()
261: {
262: return $this->isPluginLoaded($this->getId());
263: }
264:
265: 266: 267: 268: 269:
270: final public function isPluginLoaded($pluginId, $min = Dependency::NO_LIMIT, $max = Dependency::NO_LIMIT)
271: {
272: return $this->pluginHandler->isLoaded($pluginId, $min, $max);
273: }
274:
275:
276: final protected function enableDatabase()
277: {
278: $config = \ManiaLive\Database\Config::getInstance();
279: $this->db = DbConnection::getConnection(
280: $config->host,
281: $config->username,
282: $config->password,
283: $config->database,
284: $config->type,
285: $config->port
286: );
287: }
288:
289: final protected function disableDatabase()
290: {
291: $this->db = null;
292: }
293:
294: 295: 296: 297:
298: final protected function enableApplicationEvents($events = AppEvent::ALL)
299: {
300: $this->restrictIfUnloaded();
301:
302: Dispatcher::register(AppEvent::getClass(), $this, $events & ~$this->eventsApplication);
303: $this->eventsApplication |= $events;
304: }
305:
306: 307: 308:
309: final protected function disableApplicationEvents($events = AppEvent::ALL)
310: {
311: $this->restrictIfUnloaded();
312:
313: Dispatcher::unregister(AppEvent::getClass(), $this, $events & $this->eventsApplication);
314: $this->eventsApplication &= ~$events;
315: }
316:
317: 318: 319:
320: final protected function enableTickerEvent()
321: {
322: $this->restrictIfUnloaded();
323:
324: Dispatcher::register(TickEvent::getClass(), $this);
325: $this->eventsTick = true;
326: }
327:
328: 329: 330:
331: final protected function disableTickerEvent()
332: {
333: $this->restrictIfUnloaded();
334:
335: Dispatcher::unregister(TickEvent::getClass(), $this);
336: $this->eventsTick = false;
337: }
338:
339: 340: 341: 342: 343: 344:
345: final protected function enableDedicatedEvents($events = ServerEvent::ALL)
346: {
347: $this->restrictIfUnloaded();
348:
349: Dispatcher::register(ServerEvent::getClass(), $this, $events & ~$this->eventsServer);
350: $this->eventsServer |= $events;
351: }
352:
353: 354: 355:
356: final protected function disableDedicatedEvents($events = ServerEvent::ALL)
357: {
358: $this->restrictIfUnloaded();
359:
360: Dispatcher::unregister(ServerEvent::getClass(), $this, $events & $this->eventsServer);
361: $this->eventsServer &= ~$events;
362: }
363:
364: 365: 366: 367:
368: final protected function enableStorageEvents($events = PlayerEvent::ALL)
369: {
370: $this->restrictIfUnloaded();
371:
372: Dispatcher::register(PlayerEvent::getClass(), $this, $events & ~$this->eventsStorage);
373: $this->eventsStorage |= $events;
374: }
375:
376: 377: 378:
379: final protected function disableStorageEvents($events = PlayerEvent::ALL)
380: {
381: $this->restrictIfUnloaded();
382:
383: Dispatcher::unregister(PlayerEvent::getClass(), $this, $events & $this->eventsStorage);
384: $this->eventsStorage &= ~$events;
385: }
386:
387: 388: 389: 390:
391: final protected function enableThreadingEvents($events = ThreadEvent::ALL)
392: {
393: $this->restrictIfUnloaded();
394:
395: Dispatcher::register(ThreadEvent::getClass(), $this, $events & ~$this->eventsThreading);
396: $this->eventsThreading |= $events;
397: }
398:
399: 400: 401:
402: final protected function disableThreadingEvents($events = ThreadEvent::ALL)
403: {
404: $this->restrictIfUnloaded();
405:
406: Dispatcher::unregister(ThreadEvent::getClass(), $this, $events & $this->eventsThreading);
407: $this->eventsThreading &= ~$events;
408: }
409:
410: 411: 412: 413:
414: final protected function enablePluginEvents($events = PluginEvent::ALL)
415: {
416: $this->restrictIfUnloaded();
417:
418: Dispatcher::register(PluginEvent::getClass(), $this, $events & ~$this->eventsPlugins);
419: $this->eventsPlugins |= $events;
420: }
421:
422: 423: 424:
425: final protected function disablePluginEvents($events = PluginEvent::ALL)
426: {
427: $this->restrictIfUnloaded();
428:
429: Dispatcher::unregister(PluginEvent::getClass(), $this, $events & $this->eventsPlugins);
430: $this->eventsPlugins &= ~$events;
431: }
432:
433: 434: 435: 436: 437: 438: 439: 440: 441:
442: final function registerChatCommand($name, $method, $parameterCount = 0, $addLogin = false, $authorizedLogin = array())
443: {
444: $this->restrictIfUnloaded();
445: $cmd = new Command($name, $parameterCount, $authorizedLogin);
446: $cmd->callback = array($this, $method);
447: $cmd->addLoginAsFirstParameter = $addLogin;
448: $cmd->isPublic = true;
449: Interpreter::getInstance()->register($cmd);
450: $this->chatCommands[] = $cmd;
451:
452: return $cmd;
453: }
454:
455: 456: 457: 458:
459: final public function unregisterAllChatCommands()
460: {
461: while($command = array_pop($this->chatCommands))
462: Interpreter::getInstance()->unregister($command);
463: }
464:
465: 466: 467: 468: 469:
470: final protected function writeLog($text)
471: {
472: Logger::getLog($this->author.'_'.$this->name)->write($text);
473: }
474:
475: 476: 477: 478: 479:
480: final protected function writeConsole($text)
481: {
482: Console::println('['.Console::getDatestamp().'|'.$this->name.'] '.$text);
483: }
484:
485:
486:
487: function onInit() {}
488: function onLoad() {}
489: function onReady() {}
490:
491: 492: 493: 494: 495: 496: 497: 498: 499:
500: function onUnload()
501: {
502: $this->disableApplicationEvents();
503: $this->disableDedicatedEvents();
504: $this->disableStorageEvents();
505: $this->disableThreadingEvents();
506: $this->disableTickerEvent();
507: $this->disablePluginEvents();
508:
509: $this->unregisterAllChatCommands();
510:
511: $this->methods = array();
512: }
513:
514:
515: function onRun() {}
516: function onPreLoop() {}
517: function onPostLoop() {}
518: function onTerminate() {}
519:
520:
521: function onThreadDies($threadId) {}
522: function onThreadRestart($threadId) {}
523: function onThreadStart($threadId) {}
524: function onThreadTimesOut($threadId) {}
525: function onThreadKilled($threadId) {}
526:
527:
528: function onTick() {}
529:
530:
531: function onPlayerNewBestScore($player, $oldScore, $newScore) {}
532: function onPlayerNewBestTime($player, $oldBest, $newBest) {}
533: function onPlayerNewRank($player, $oldRank, $newRank) {}
534: function onPlayerChangeSide($player, $oldSide) {}
535: function onPlayerFinishLap($player, $time, $checkpoints, $nbLap) {}
536:
537:
538: function onPluginLoaded($pluginId) {}
539: function onPluginUnloaded($pluginId) {}
540: }
541:
542: ?>
543: