1: <?php
2: /**
3: * ManiaLive - TrackMania dedicated server manager in PHP
4: *
5: * @copyright Copyright (c) 2009-2011 NADEO (http://www.nadeo.com)
6: * @license http://www.gnu.org/licenses/lgpl.html LGPL License 3
7: * @version $Revision: 455 $:
8: * @author $Author: martin.gwendal $:
9: * @date $Date: 2012-12-19 10:48:30 +0100 (mer., 19 déc. 2012) $:
10: */
11:
12: namespace DedicatedApi;
13:
14: /**
15: * Dedicated Server Connection Instance
16: * Methods returns nothing if $multicall = true
17: */
18: class Connection
19: {
20: /**
21: * @var Connection[]
22: */
23: static protected $instances = array();
24:
25: /**
26: * XML-RPC client instance
27: * @var Xmlrpc\ClientMulticall
28: */
29: protected $xmlrpcClient;
30:
31: /**
32: * @param string $host
33: * @param int $port
34: * @param int $timeout
35: * @param string $user
36: * @param string $password
37: * @return Connection
38: */
39: static function factory($host = '127.0.0.1', $port = 5000, $timeout = 5, $user = 'SuperAdmin', $password = 'SuperAdmin')
40: {
41: $key = $host.':'.$port;
42: if(!isset(self::$instances[$key]))
43: {
44: self::$instances[$key] = new self($host, $port, $timeout, $user, $password);
45: }
46: return self::$instances[$key];
47: }
48:
49: /**
50: * @param string $host
51: * @param int $port
52: */
53: static function delete($host, $port)
54: {
55: $key = $host.':'.$port;
56: if(isset(self::$instances[$key]))
57: {
58: self::$instances[$key]->terminate();
59: unset(self::$instances[$key]);
60: }
61: }
62:
63: /**
64: * @param string $host
65: * @param int $port
66: * @param int $timeout
67: * @param string $user
68: * @param string $password
69: */
70: protected function __construct($host, $port, $timeout, $user, $password)
71: {
72: $this->xmlrpcClient = new Xmlrpc\ClientMulticall($host, $port, $timeout);
73: $this->authenticate($user, $password);
74: $this->setApiVersion('2012-06-19');
75: }
76:
77: /**
78: * Close the current socket connexion
79: * Never call this method, use instead DedicatedApi::delete($host, $port)
80: */
81: protected function terminate()
82: {
83: $this->xmlrpcClient->terminate();
84: }
85:
86: /**
87: *
88: * Read a Call back on the DedicatedServer and call the method if handle
89: * @param array $methods if empty, every methods will be called on call back, otherwise only the method declared inside. The metho name must be the name of the interface's method
90: */
91: function executeCallbacks()
92: {
93: $this->xmlrpcClient->readCallbacks();
94: $calls = $this->xmlrpcClient->getCallbackResponses();
95: return $calls;
96: }
97:
98: /**
99: * Execute the calls in queue and return the result
100: * TODO Prendre en compte les retours du mutliQuery (via un handler ?)
101: */
102: function executeMulticall()
103: {
104: $this->xmlrpcClient->multiqueryIgnoreResult();
105: }
106:
107: /**
108: * Add a call in queur. It will be executed by the next Call from the user to executemulticall
109: * @param string $methodName
110: * @param string $authLevel
111: * @param array $params
112: */
113: protected function execute($methodName, $params = array(), $multicall = false)
114: {
115: if($multicall)
116: {
117: $this->xmlrpcClient->addCall($methodName, $params);
118: }
119: else
120: {
121: array_unshift($params, $methodName);
122: call_user_func_array(array($this->xmlrpcClient, 'query'), $params);
123: return $this->xmlrpcClient->getResponse();
124: }
125: }
126:
127: /**
128: * Given the name of a method, return an array of legal signatures.
129: * Each signature is an array of strings.
130: * The first item of each signature is the return type, and any others items are parameter types.
131: * @param string $methodName
132: * @return array
133: */
134: function methodSignature($methodName)
135: {
136: return $this->execute('system.methodSignature', array($methodName));
137: }
138:
139: /**
140: * Change the password for the specified login/user.
141: * @param string $username
142: * @param string $password
143: * @return bool
144: * @throws InvalidArgumentException
145: */
146: function changeAuthPassword($username, $password)
147: {
148: if(!is_string($password))
149: {
150: throw new InvalidArgumentException('password = '.print_r($password, true));
151: }
152: if($username != 'User' && $username != 'Admin' && $username != 'SuperAdmin')
153: {
154: throw new InvalidArgumentException('username = '.print_r($username, true));
155: }
156:
157: return $this->execute(ucfirst(__FUNCTION__), array($username, $password), false);
158: }
159:
160: /**
161: * Allow the GameServer to call you back.
162: * @param bool $enable
163: * @param bool $multicall
164: * @return bool
165: */
166: function enableCallbacks($enable, $multicall = false)
167: {
168: return $this->execute(ucfirst(__FUNCTION__), array((bool) $enable), $multicall);
169: }
170:
171: /**
172: * Define the wanted api.
173: * @param string $version
174: * @param bool $multicall
175: * @return bool
176: */
177: function setApiVersion($version, $multicall = false)
178: {
179: return $this->execute(ucfirst(__FUNCTION__), array((string) $version), $multicall);
180: }
181:
182: /**
183: * Returns a struct with the Name, Version, Build and ApiVersion of the application remotely controled.
184: * @return Structures\Version
185: * @throws InvalidArgumentException
186: */
187: function getVersion()
188: {
189: $result = $this->execute(ucfirst(__FUNCTION__));
190: return Structures\Version::fromArray($result);
191: }
192:
193: function authenticate($username, $password)
194: {
195: return $this->execute(ucfirst(__FUNCTION__), array($username, $password), false);
196: }
197:
198: /**
199: * Call a vote for a cmd. The command is a XML string corresponding to an XmlRpc request.
200: * You can additionally specifiy specific parameters for this vote: a ratio, a time out
201: * and who is voting. Special timeout values: a timeout of '0' means default, '1' means
202: * indefinite; a ratio of '-1' means default; Voters values: '0' means only active players,
203: * '1' means any player, '2' is for everybody, pure spectators included.
204: * @param Structures\Vote $vote
205: * @param double $ratio -1 means default, else ration should be between 0 and 1
206: * @param int $timeout time to vote in millisecondes, '0' means default
207: * @param int $voters Voters values: '0' means only active players, '1' means any player, '2' is for everybody, pure spectators included
208: * @param bool $multicall
209: * @throws InvalidArgumentException
210: */
211: function callVote(Structures\Vote $vote, $ratio = 0.5, $timeout = 0, $voters = 1, $multicall = false)
212: {
213: if(is_null($vote))
214: {
215: throw new InvalidArgumentException('vote must be set');
216: }
217: if(!is_float($ratio))
218: {
219: throw new InvalidArgumentException('ratio = '.print_r($ratio, true));
220: }
221: if(!is_int($timeout))
222: {
223: throw new InvalidArgumentException('timeout = '.print_r($timeout, true));
224: }
225: if(!is_int($voters))
226: {
227: throw new InvalidArgumentException('voters = '.print_r($voters, true));
228: }
229: if(!is_array($vote->cmdParam))
230: {
231: throw new InvalidArgumentException('vote->cmdParam = '.print_r($vote->cmdParam, true));
232: }
233:
234: $tmpCmd = new Xmlrpc\Request($vote->cmdName, $vote->cmdParam);
235:
236: return $this->execute(ucfirst(__FUNCTION__).'Ex', array($tmpCmd->getXml(), $ratio, $timeout, $voters), $multicall);
237: }
238:
239: /**
240: * Call a vote to kick a player.
241: * You can additionally specifiy specific parameters for this vote: a ratio, a time out
242: * and who is voting. Special timeout values: a timeout of '0' means default, '1' means
243: * indefinite; a ratio of '-1' means default; Voters values: '0' means only active players,
244: * '1' means any player, '2' is for everybody, pure spectators included.
245: * @param Structures\Player|string $player Structures\Player or string
246: * @param double $ratio -1 means default, else ration should be between 0 and 1
247: * @param int $timeout time to vote in millisecondes, '0' means default
248: * @param int $voters Voters values: '0' means only active players, '1' means any player, '2' is for everybody, pure spectators included
249: * @param bool $multicall
250: * @throws InvalidArgumentException
251: */
252: function callVoteKick($player, $ratio = 0.5, $timeout = 0, $voters = 1, $multicall = false)
253: {
254: if(!($login = $this->getLogin($player)))
255: {
256: throw new InvalidArgumentException('player must be set');
257: }
258: if(!is_float($ratio))
259: {
260: throw new InvalidArgumentException('ratio = '.print_r($ratio, true));
261: }
262: if(!is_int($timeout))
263: {
264: throw new InvalidArgumentException('timeout = '.print_r($timeout, true));
265: }
266: if(!is_int($voters))
267: {
268: throw new InvalidArgumentException('voters = '.print_r($voters, true));
269: }
270:
271: $tmpCmd = new Xmlrpc\Request('Kick', array($login));
272:
273: return $this->execute('CallVoteEx', array($tmpCmd->getXml(), $ratio, $timeout, $voters), $multicall);
274: }
275:
276: /**
277: * Call a vote to ban a player.
278: * You can additionally specifiy specific parameters for this vote: a ratio, a time out
279: * and who is voting. Special timeout values: a timeout of '0' means default, '1' means
280: * indefinite; a ratio of '-1' means default; Voters values: '0' means only active players,
281: * '1' means any player, '2' is for everybody, pure spectators included.
282: * @param Structures\Player|string $player
283: * @param double $ratio -1 means default, else ration should be between 0 and 1
284: * @param int $timeout time to vote in millisecondes, '0' means default
285: * @param int $voters Voters values: '0' means only active players, '1' means any player, '2' is for everybody, pure spectators included
286: * @param bool $multicall
287: * @throws InvalidArgumentException
288: */
289: function callVoteBan($player, $ratio = 0.6, $timeout = 0, $voters = 1, $multicall = false)
290: {
291: if(!($login = $this->getLogin($player)))
292: {
293: throw new InvalidArgumentException('player must be set');
294: }
295: if(!is_float($ratio))
296: {
297: throw new InvalidArgumentException('ratio = '.print_r($ratio, true));
298: }
299: if(!is_int($timeout))
300: {
301: throw new InvalidArgumentException('timeout = '.print_r($timeout, true));
302: }
303: if(!is_int($voters))
304: {
305: throw new InvalidArgumentException('voters = '.print_r($voters, true));
306: }
307:
308: $tmpCmd = new Xmlrpc\Request('Ban', array($login));
309:
310: return $this->execute('CallVoteEx', array($tmpCmd->getXml(), $ratio, $timeout, $voters), $multicall);
311: }
312:
313: /**
314: * Call a vote to restart the current Map.
315: * You can additionally specifiy specific parameters for this vote: a ratio, a time out
316: * and who is voting. Special timeout values: a timeout of '0' means default, '1' means
317: * indefinite; a ratio of '-1' means default; Voters values: '0' means only active players,
318: * '1' means any player, '2' is for everybody, pure spectators included.
319: * @param double $ratio -1 means default, else ration should be between 0 and 1
320: * @param int $timeout time to vote in millisecondes, '0' means default
321: * @param int $voters Voters values: '0' means only active players, '1' means any player, '2' is for everybody, pure spectators included
322: * @param bool $multicall
323: * @throws InvalidArgumentException
324: */
325: function callVoteRestartMap($ratio = 0.5, $timeout = 0, $voters = 1, $multicall = false)
326: {
327: if(!is_float($ratio))
328: {
329: throw new InvalidArgumentException('ratio = '.print_r($ratio, true));
330: }
331: if(!is_int($timeout))
332: {
333: throw new InvalidArgumentException('timeout = '.print_r($timeout, true));
334: }
335: if(!is_int($voters))
336: {
337: throw new InvalidArgumentException('voters = '.print_r($voters, true));
338: }
339:
340: $tmpCmd = new Xmlrpc\Request('MapRestart', array());
341:
342: return $this->execute('CallVoteEx', array($tmpCmd->getXml(), $ratio, $timeout, $voters), $multicall);
343: }
344:
345: /**
346: * Call a vote to go to the next Map.
347: * You can additionally specifiy specific parameters for this vote: a ratio, a time out
348: * and who is voting. Special timeout values: a timeout of '0' means default, '1' means
349: * indefinite; a ratio of '-1' means default; Voters values: '0' means only active players,
350: * '1' means any player, '2' is for everybody, pure spectators included.
351: * @param double $ratio -1 means default, else ration should be between 0 and 1
352: * @param int $timeout time to vote in millisecondes, '0' means default
353: * @param int $voters Voters values: '0' means only active players, '1' means any player, '2' is for everybody, pure spectators included
354: * @param bool $multicall
355: * @throws InvalidArgumentException
356: */
357: function callVoteNextMap($ratio = 0.5, $timeout = 0, $voters = 1, $multicall = false)
358: {
359: if(!is_float($ratio))
360: {
361: throw new InvalidArgumentException('ratio = '.print_r($ratio, true));
362: }
363: if(!is_int($timeout))
364: {
365: throw new InvalidArgumentException('timeout = '.print_r($timeout, true));
366: }
367: if(!is_int($voters))
368: {
369: throw new InvalidArgumentException('voters = '.print_r($voters, true));
370: }
371:
372: $tmpCmd = new Xmlrpc\Request('NextMap', array());
373:
374: return $this->execute('CallVoteEx', array($tmpCmd->getXml(), $ratio, $timeout, $voters), $multicall);
375: }
376:
377: /**
378: * Used internaly by game.
379: * @param bool $multicall
380: * @return bool
381: */
382: protected function internalCallVote($multicall = false)
383: {
384: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
385: }
386:
387: /**
388: * Cancel the current vote.
389: * @param bool $multicall
390: * @return bool
391: */
392: function cancelVote($multicall = false)
393: {
394: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
395: }
396:
397: /**
398: * Returns the vote currently in progress.
399: * The returned structure is { CallerLogin, CmdName, CmdParam }.
400: * @return Structures\Vote
401: */
402: function getCurrentCallVote()
403: {
404: return Structures\Vote::fromArray($this->execute(ucfirst(__FUNCTION__)));
405: }
406:
407: /**
408: * Set a new timeout for waiting for votes. A zero value disables callvote.
409: * Requires a map restart to be taken into account
410: * @param int $timeout time to vote in millisecondes, '0' disables callvote
411: * @param bool $multicall
412: * @return bool
413: * @throws InvalidArgumentException
414: */
415: function setCallVoteTimeOut($timeout, $multicall = false)
416: {
417: if(!is_int($timeout))
418: {
419: throw new InvalidArgumentException('timeout = '.print_r($timeout, true));
420: }
421:
422: return $this->execute(ucfirst(__FUNCTION__), array($timeout), $multicall);
423: }
424:
425: /**
426: * Get the current and next timeout for waiting for votes.
427: * The struct returned contains two fields 'CurrentValue' and 'NextValue'.
428: * @return array
429: */
430: function getCallVoteTimeOut()
431: {
432: return $this->execute(ucfirst(__FUNCTION__));
433: }
434:
435: /**
436: * Set a new default ratio for passing a vote.
437: * Must lie between 0 and 1.
438: * @param double $ratio
439: * @param bool $multicall
440: * @return bool
441: * @throws InvalidArgumentException
442: */
443: function setCallVoteRatio($ratio, $multicall = false)
444: {
445: if($ratio !== -1 && !(is_float($ratio) && $ratio >= 0 && $ratio <= 1))
446: {
447: throw new InvalidArgumentException('ratio = '.print_r($ratio, true));
448: }
449:
450: return $this->execute(ucfirst(__FUNCTION__), array($ratio), $multicall);
451: }
452:
453: /**
454: * Get the current default ratio for passing a vote.
455: * This value lies between 0 and 1.
456: * @return double
457: */
458: function getCallVoteRatio()
459: {
460: return $this->execute(ucfirst(__FUNCTION__));
461: }
462:
463: /**
464: * Set new ratios for passing specific votes.
465: * The parameter is an array of struct
466: * {string votecommand, double ratio}, ratio is in [0,1] or -1 for vote disabled.
467: * @param array $ratios
468: * @param bool $multicall
469: * @return bool
470: * @throws InvalidArgumentException
471: */
472: function setCallVoteRatios(array $ratios, $multicall = false)
473: {
474: if(!is_array($ratios))
475: {
476: throw new InvalidArgumentException('ratios = '.print_r($ratios, true));
477: }
478:
479: foreach($ratios as $i => $ratio)
480: {
481: if(!is_array($ratio) && !array_key_exists('Command', $ratio) && !array_key_exists('Ratio', $ratio))
482: {
483: throw new InvalidArgumentException('ratios['.$i.'] = '.print_r($ratio, true));
484: }
485: if(!is_string($ratio['Command']))
486: {
487: throw new InvalidArgumentException('ratios['.$i.'][Command] = '.print_r($ratios['Command'], true));
488: }
489: if($ratio['Ratio'] !== -1 && !(is_float($ratio['Ratio']) && $ratio['Ratio'] >= 0 || $ratio['Ratio'] <= 1))
490: {
491: throw new InvalidArgumentException('ratios['.$i.'][Ratio] = '.print_r($ratio['Ratio'], true));
492: }
493: }
494:
495: return $this->execute(ucfirst(__FUNCTION__), array($ratios), $multicall);
496: }
497:
498: /**
499: * Get the current ratios for passing votes.
500: * @return array
501: */
502: function getCallVoteRatios()
503: {
504: return $this->execute(ucfirst(__FUNCTION__));
505: }
506:
507: /**
508: * Send a localised text message to specied clients.
509: * The parameter is an array of structures {Lang='??', Text='...'}.
510: * If no matching language is found, the last text in the array is used.
511: * @param array $messages
512: * @param Structures\Player|string|mixed[] $receiver Structures\Player(s) who will receive the message, put null to send the message to everyone
513: * @param bool $multicall
514: * @return bool
515: * @throws InvalidArgumentException
516: */
517: function chatSendServerMessageToLanguage(array $messages, $receiver = null, $multicall = false)
518: {
519: if(!is_array($messages))
520: {
521: throw new InvalidArgumentException('messages = '.print_r($messages, true));
522: }
523: if(is_null($receiver))
524: {
525: $receiverString = '';
526: }
527: else if(!($receiverString = $this->getLogins($receiver)))
528: {
529: throw new InvalidArgumentException('receiver = '.print_r($receiver, true));
530: }
531:
532: return $this->execute(ucfirst(__FUNCTION__), array($messages, $receiverString), $multicall);
533: }
534:
535: /**
536: * Send a text message without the server login to everyone if players is null.
537: * Players can be a Structures\Player object or an array of Structures\Player
538: * @param string $message
539: * @param Structures\Player|string|mixed[] $receiver Structures\Player(s) who will receive the message, put null to send the message to everyone
540: * @param bool $multicall
541: * @return bool
542: * @throws InvalidArgumentException
543: */
544: function chatSendServerMessage($message, $receiver = null, $multicall = false)
545: {
546: if(!is_string($message))
547: {
548: throw new InvalidArgumentException('message = '.print_r($message, true));
549: }
550:
551: $params = array($message);
552: $method = 'ChatSendServerMessage';
553: if(!is_null($receiver))
554: {
555: if(!($logins = $this->getLogins($receiver)))
556: {
557: throw new InvalidArgumentException('receiver = '.print_r($receiver, true));
558: }
559: $params[] = $logins;
560: $method .= 'ToLogin';
561: }
562:
563: return $this->execute($method, $params, $multicall);
564: }
565:
566: /**
567: * Send a localised text message to selected clients.
568: * The parameter is an array of structures {Lang='??', Text='...'}.
569: * If no matching language is found, the last text in the array is used.
570: * @param array $messages
571: * @param Structures\Player|string|mixed[] $receiver Structures\Player(s) who will receive the message, put null to send the message to everyone
572: * @param bool $multicall
573: * @return bool
574: * @throws InvalidArgumentException
575: */
576: function chatSendToLanguage(array $messages, $receiver = null, $multicall = false)
577: {
578: if(!is_array($messages)) throw new InvalidArgumentException('messages = '.print_r($messages, true));
579:
580: if($receiver == null)
581: {
582: $receiverString = '';
583: }
584: else if(!($receiverString = $this->getLogins($receiver)))
585: {
586: throw new InvalidArgumentException('receiver = '.print_r($receiver, true));
587: }
588:
589: return $this->execute(ucfirst(__FUNCTION__), array($messages, $receiverString), $multicall);
590: }
591:
592: /**
593: * Send a text message to every Structures\Player or the a specified player(s).
594: * If Structures\Player is null, the message will be delivered to every Structures\Player
595: * @param string $message
596: * @param Structures\Player|string|mixed[] $receiver Structures\Player(s) who will receive the message, put null to send the message to everyone
597: * @param bool $multicall
598: * @return bool
599: * @throws InvalidArgumentException
600: */
601: function chatSend($message, $receiver, $multicall = false)
602: {
603: if(!is_string($message)) throw new InvalidArgumentException('message = '.print_r($message, true));
604:
605: $params = array($message);
606: $method = 'ChatSend';
607: if(!is_null($receiver))
608: {
609: if(!($logins = $this->getLogins($receiver)))
610: {
611: throw new InvalidArgumentException('players = '.print_r($receiver, true));
612: }
613: $params[] = $logins;
614: $method .= 'ToLogin';
615: }
616:
617: return $this->execute($method, $params, $multicall);
618: }
619:
620: /**
621: * Returns the last chat lines. Maximum of 40 lines.
622: * @return array
623: */
624: function getChatLines()
625: {
626: return $this->execute(ucfirst(__FUNCTION__));
627: }
628:
629: /**
630: * The chat messages are no longer dispatched to the players, they only go to the rpc callback
631: * and the controller has to manually forward them. The second (optional) parameter allows all
632: * messages from the server to be automatically forwarded.
633: * @param bool $enable
634: * @param bool $serverAutomaticForward
635: * @param bool $multicall
636: * @return bool
637: * @throws InvalidArgumentException
638: */
639: function chatEnableManualRouting($enable, $serverAutomaticForward = false, $multicall = false)
640: {
641: if(!is_bool($enable))
642: {
643: throw new InvalidArgumentException('enable = '.print_r($enable, true));
644: }
645: if(!is_bool($serverAutomaticForward))
646: {
647: throw new InvalidArgumentException('serverAutomaticForward = '.print_r($serverAutomaticForward, true));
648: }
649:
650: return $this->execute(ucfirst(__FUNCTION__), array($enable, $serverAutomaticForward), $multicall);
651: }
652:
653: /**
654: * (Text, SenderLogin, DestLogin) Send a text message to the specified DestLogin (or everybody if empty)
655: * on behalf of SenderLogin. DestLogin can be a single login or a list of comma-separated logins.
656: * Only available if manual routing is enabled.
657: * @param string $message
658: * @param Structures\Player|string $sender
659: * @param Structures\Player|string $receiver
660: * @param bool $multicall
661: * @return bool
662: * @throws InvalidArgumentException
663: */
664: function chatForwardToLogin($message, $sender, $receiver = null, $multicall = false)
665: {
666: if(!is_string($message))
667: {
668: throw new InvalidArgumentException('message = '.print_r($message, true));
669: }
670: if(!($senderLogin = $this->getLogin($sender)))
671: {
672: throw new InvalidArgumentException('sender must be set');
673: }
674: $receiverLogin = $this->getLogin($receiver) ? : '';
675:
676: return $this->execute(ucfirst(__FUNCTION__), array($message, $senderLogin, $receiverLogin), $multicall);
677: }
678:
679: /**
680: * Display a notice on the client with the specified UId.
681: * The parameters are :
682: * the Uid of the client to whom the notice is sent,
683: * the text message to display,
684: * the UId of the avatar to display next to it (or '255' for no avatar),
685: * an optional 'max duration' in seconds (default: 3).
686: * @param string $message
687: * @param Structures\Player|string|mixed[] $receiver
688: * @param Structures\Player|string $player
689: * @param int $variant 0, 1 or 2
690: * @param bool $multicall
691: * @return bool
692: * @throws InvalidArgumentException
693: */
694: function sendNotice($receiver, $message, $player = null, $variant = 0, $multicall = false)
695: {
696: if(!is_string($message))
697: {
698: throw new InvalidArgumentException('message = '.print_r($message, true));
699: }
700:
701: $params = array();
702: $method = 'SendNotice';
703: if(!is_null($receiver))
704: {
705: if(!($login = $this->getLogins($receiver)))
706: throw new InvalidArgumentException('receiver = '.print_r($receiver, true));
707: else $params[] = $login;
708:
709: $method .= 'ToLogin';
710: }
711:
712: $params[] = $message;
713: $params[] = $this->getLogin($player) ? : '';
714: $params[] = $variant;
715: return $this->execute($method, $params, $multicall);
716: }
717:
718: /**
719: * Display a manialink page on the client of the specified Structures\Player(s).
720: * The first parameter is the login of the player,
721: * the other are identical to 'SendDisplayManialinkPage'.
722: * The players can be an object of player Type or an array of Structures\Player object
723: * @param null|Structures\Player|string|mixed[] $playerLogin
724: * @param string $manialink
725: * @param int $timeout
726: * @param bool $hideOnClick
727: * @param bool $multicall
728: * @return bool
729: * @throws InvalidArgumentException
730: */
731: function sendDisplayManialinkPage($players, $manialink, $timeout, $hideOnClick, $multicall = false)
732: {
733: $params = array();
734: $method = 'SendDisplayManialinkPage';
735: if(!is_null($players))
736: {
737: if(!($login = $this->getLogins($players))) throw new InvalidArgumentException('players = '.print_r($players, true));
738: else $params[] = $login;
739:
740: $method .= 'ToLogin';
741: }
742:
743: if(!is_string($manialink))
744: {
745: throw new InvalidArgumentException('manialink = '.print_r($manialink, true));
746: }
747: if(!is_int($timeout))
748: {
749: throw new InvalidArgumentException('timeout = '.print_r($timeout, true));
750: }
751: if(!is_bool($hideOnClick))
752: {
753: throw new InvalidArgumentException('hideOnClick = '.print_r($hideOnClick, true));
754: }
755: $params[] = $manialink;
756: $params[] = $timeout;
757: $params[] = $hideOnClick;
758:
759: return $this->execute($method, $params, $multicall);
760: }
761:
762: /**
763: * Hide the displayed manialink page on the client with the specified login.
764: * Login can be a single login or a list of comma-separated logins.
765: * @param null|Structures\Player|string|mixed[] $players
766: * @param bool $multicall
767: * @return bool
768: * @throws InvalidArgumentException
769: */
770: function sendHideManialinkPage($players = null, $multicall = false)
771: {
772: $params = array();
773: $method = 'SendHideManialinkPage';
774: if(!is_null($players))
775: {
776: if(!($login = $this->getLogins($players))) throw new InvalidArgumentException('players = '.print_r($players, true));
777: else $params[] = $login;
778:
779: $method .= 'ToLogin';
780: }
781:
782: return $this->execute($method, $params, $multicall);
783: }
784:
785: /**
786: * Returns the latest results from the current manialink page,
787: * as an array of structs {string Login, int PlayerId, int Result}
788: * Result==0 -> no answer, Result>0.... -> answer from the player.
789: * @return array
790: */
791: function getManialinkPageAnswers()
792: {
793: return $this->execute(ucfirst(__FUNCTION__));
794: }
795:
796: /**
797: * Kick the player with an optional message.
798: * @param Structures\Player|string $playerLogin
799: * @param string $message
800: * @param bool $multicall
801: * @return bool
802: * @throws InvalidArgumentException
803: */
804: function kick($player, $message = '', $multicall = false)
805: {
806: if(!($login = $this->getLogin($player)))
807: {
808: throw new InvalidArgumentException('player must be set');
809: }
810: if(!is_string($message))
811: {
812: throw new InvalidArgumentException('message = '.print_r($message, true));
813: }
814:
815: return $this->execute('Kick', array($login, $message), $multicall);
816: }
817:
818: /**
819: * Ban the player with an optional message.
820: * @param Structures\Player|string $player
821: * @param string $message
822: * @param bool $multicall
823: * @return bool
824: * @throws InvalidArgumentException
825: */
826: function ban($player, $message = '', $multicall = false)
827: {
828: if(!($login = $this->getLogin($player)))
829: {
830: throw new InvalidArgumentException('player must be set');
831: }
832: if(!is_string($message))
833: {
834: throw new InvalidArgumentException('message = '.print_r($message, true));
835: }
836:
837: return $this->execute('Ban', array($login, $message), $multicall);
838: }
839:
840: /**
841: * Ban the player with a message.
842: * Add it to the black list, and optionally save the new list.
843: * @param Structures\Player|string $player
844: * @param string $message
845: * @param bool $saveList
846: * @param bool $multicall
847: * @return bool
848: * @throws InvalidArgumentException
849: */
850: function banAndBlackList($player, $message, $saveList = false, $multicall = false)
851: {
852: if(!($login = $this->getLogin($player)))
853: {
854: throw new InvalidArgumentException('player must be set');
855: }
856: if(!is_string($message) || !$message)
857: {
858: throw new InvalidArgumentException('message = '.print_r($message, true));
859: }
860: if(!is_bool($saveList))
861: {
862: throw new InvalidArgumentException('saveList = '.print_r($saveList, true));
863: }
864:
865: return $this->execute(ucfirst(__FUNCTION__), array($login, $message, $saveList), $multicall);
866: }
867:
868: /**
869: * Unban the player
870: * @param Structures\Player|string $player
871: * @param bool $multicall
872: * @return bool
873: * @throws InvalidArgumentException
874: */
875: function unBan($player, $multicall = false)
876: {
877: if(!($login = $this->getLogin($player)))
878: {
879: throw new InvalidArgumentException('player must be set');
880: }
881:
882: return $this->execute(ucfirst(__FUNCTION__), array($login), $multicall);
883: }
884:
885: /**
886: * Clean the ban list of the server.
887: * @param bool $multicall
888: * @return bool
889: */
890: function cleanBanList($multicall = false)
891: {
892: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
893: }
894:
895: /**
896: * Returns the list of banned players. This method takes two parameters.
897: * The first parameter specifies the maximum number of infos to be returned,
898: * the second one the starting index in the list. The list is an array of structures.
899: * Each structure contains the following fields : Login, ClientName and IPAddress.
900: * @param int $length specifies the maximum number of infos to be returned
901: * @param int $offset specifies the starting index in the list
902: * @return Structures\Player[] The list is an array of Structures\Player
903: * @throws InvalidArgumentException
904: */
905: function getBanList($length, $offset)
906: {
907: if(!is_int($length)) throw new InvalidArgumentException('length = '.print_r($length, true));
908: if(!is_int($offset)) throw new InvalidArgumentException('offset = '.print_r($offset, true));
909:
910: $result = $this->execute(ucfirst(__FUNCTION__), array($length, $offset));
911: return Structures\Player::fromArrayOfArray($result);
912: }
913:
914: /**
915: * Blacklist the player
916: * @param Structures\Player|string $player
917: * @param bool $multicall
918: * @return bool
919: * @throws InvalidArgumentException
920: */
921: function blackList($player, $multicall = false)
922: {
923: if(!($login = $this->getLogin($player)))
924: {
925: throw new InvalidArgumentException('player must be set');
926: }
927: return $this->execute(ucfirst(__FUNCTION__), array($login), $multicall);
928: }
929:
930: /**
931: * UnBlackList the player
932: * @param Structures\Player|string $player
933: * @param bool $multicall
934: * @return bool
935: * @throws InvalidArgumentException
936: */
937: function unBlackList($player, $multicall = false)
938: {
939: if(!($login = $this->getLogin($player)))
940: {
941: throw new InvalidArgumentException('player must be set');
942: }
943: return $this->execute(ucfirst(__FUNCTION__), array($login), $multicall);
944: }
945:
946: /**
947: * Clean the blacklist of the server.
948: * @param bool $multicall
949: * @return bool
950: */
951: function cleanBlackList($multicall = false)
952: {
953: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
954: }
955:
956: /**
957: * Returns the list of blacklisted players.
958: * This method takes two parameters.
959: * The first parameter specifies the maximum number of infos to be returned,
960: * the second one the starting index in the list. The list is an array of structures.
961: * Each structure contains the following fields : Login.
962: * @param int $length specifies the maximum number of infos to be returned
963: * @param int $offset specifies the starting index in the list
964: * @return Structures\Player[] The list is an array of structures. Each structure contains the following fields : Login.
965: * @throws InvalidArgumentException
966: */
967: function getBlackList($length, $offset)
968: {
969: if(!is_int($length)) throw new InvalidArgumentException('length = '.print_r($length, true));
970: if(!is_int($offset)) throw new InvalidArgumentException('offset = '.print_r($offset, true));
971:
972: $result = $this->execute(ucfirst(__FUNCTION__), array($length, $offset));
973: return Structures\Player::fromArrayOfArray($result);
974: }
975:
976: /**
977: * Load the black list file with the specified file name.
978: * @param string $filename blackList file name
979: * @param bool $multicall
980: * @return bool
981: * @throws InvalidArgumentException
982: */
983: function loadBlackList($filename, $multicall = false)
984: {
985: if(!is_string($filename)) throw new InvalidArgumentException('filename = '.print_r($filename, true));
986:
987: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
988: }
989:
990: /**
991: * Save the black list in the file with specified file name.
992: * @param string $filename blackList filename
993: * @param bool $multicall
994: * @return bool
995: * @throws InvalidArgumentException
996: */
997: function saveBlackList($filename, $multicall = false)
998: {
999: if(!is_string($filename)) throw new InvalidArgumentException('filename = '.print_r($filename, true));
1000:
1001: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
1002: }
1003:
1004: /**
1005: * Add the player to the guest list.
1006: * @param Structures\Player|string $player
1007: * @param bool $multicall
1008: * @return bool
1009: * @throws InvalidArgumentException
1010: */
1011: function addGuest($player, $multicall = false)
1012: {
1013: if(!($login = $this->getLogin($player)))
1014: {
1015: throw new InvalidArgumentException('player must be set');
1016: }
1017: return $this->execute(ucfirst(__FUNCTION__), array($login), $multicall);
1018: }
1019:
1020: /**
1021: * Remove the player from the guest list.
1022: * @param Structures\Player|string $player
1023: * @param bool $multicall
1024: * @return bool
1025: * @throws InvalidArgumentException
1026: */
1027: function removeGuest($player, $multicall = false)
1028: {
1029: if(!($login = $this->getLogin($player)))
1030: {
1031: throw new InvalidArgumentException('player must be set');
1032: }
1033: return $this->execute(ucfirst(__FUNCTION__), array($login), $multicall);
1034: }
1035:
1036: /**
1037: * Clean the guest list of the server.
1038: * @param bool $multicall
1039: * @return bool
1040: */
1041: function cleanGuestList($multicall = false)
1042: {
1043: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
1044: }
1045:
1046: /**
1047: * Returns the list of players on the guest list.
1048: * This method takes two parameters.
1049: * The first parameter specifies the maximum number of infos to be returned,
1050: * the second one the starting index in the list. The list is an array of structures.
1051: * Each structure contains the following fields : Login.
1052: * @param int $length specifies the maximum number of infos to be returned
1053: * @param int $offset specifies the starting index in the list
1054: * @return Structures\Player[] The list is an array of structures. Each structure contains the following fields : Login.
1055: * @throws InvalidArgumentException
1056: */
1057: function getGuestList($length, $offset)
1058: {
1059: if(!is_int($length))
1060: {
1061: throw new InvalidArgumentException('length = '.print_r($length, true));
1062: }
1063: if(!is_int($offset))
1064: {
1065: throw new InvalidArgumentException('offset = '.print_r($offset, true));
1066: }
1067:
1068: $result = $this->execute(ucfirst(__FUNCTION__), array($length, $offset));
1069: return Structures\Player::fromArrayOfArray($result);
1070: }
1071:
1072: /**
1073: *
1074: * Load the guest list file with the specified file name.
1075: * @param string $filename blackList file name
1076: * @param bool $multicall
1077: * @return bool
1078: * @throws InvalidArgumentException
1079: */
1080: function loadGuestList($filename, $multicall = false)
1081: {
1082: if(!is_string($filename))
1083: {
1084: throw new InvalidArgumentException('filename = '.print_r($filename, true));
1085: }
1086:
1087: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
1088: }
1089:
1090: /**
1091: * Save the guest list in the file with specified file name.
1092: * @param string $filename blackList file name
1093: * @param bool $multicall
1094: * @return bool
1095: * @throws InvalidArgumentException
1096: */
1097: function saveGuestList($filename, $multicall = false)
1098: {
1099: if(!is_string($filename))
1100: {
1101: throw new InvalidArgumentException('filename = '.print_r($filename, true));
1102: }
1103:
1104: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
1105: }
1106:
1107: /**
1108: * Sets whether buddy notifications should be sent in the chat.
1109: * login is the login of the player, or '' for global setting,
1110: * enabled is the value.
1111: * @param null|Structures\Player|string $player the player, or null for global setting
1112: * @param bool $enable the value.
1113: * @param bool $multicall
1114: * @return bool
1115: * @throws InvalidArgumentException
1116: */
1117: function setBuddyNotification($player, $enable, $multicall = false)
1118: {
1119: if(!is_bool($enable))
1120: {
1121: throw new InvalidArgumentException('enable = '.print_r($enable, true));
1122: }
1123:
1124: $player = $this->getLogin($player) ? : '';
1125:
1126: return $this->execute(ucfirst(__FUNCTION__), array($player, $enable), $multicall);
1127: }
1128:
1129: /**
1130: * Gets whether buddy notifications are enabled for login, or '' to get the global setting.
1131: * @param null|Structures\Player|string $player the player, or null for global setting
1132: * @return bool
1133: * @throws InvalidArgumentException
1134: */
1135: function getBuddyNotification($player)
1136: {
1137: $player = $this->getLogin($player) ? : '';
1138:
1139: return $this->execute(ucfirst(__FUNCTION__), $params);
1140: }
1141:
1142: /**
1143: * Write the data to the specified file. The filename is relative to the Tracks path
1144: * @param string $filename The file to be written
1145: * @param string $localFilename The file to be read to obtain the data
1146: * @param bool $multicall
1147: * @return bool
1148: * @throws InvalidArgumentException
1149: */
1150: function writeFile($filename, $localFilename, $multicall = false)
1151: {
1152: if(!is_string($filename))
1153: {
1154: throw new InvalidArgumentException('filename = '.print_r($filename, true));
1155: }
1156: if(!file_exists($localFilename))
1157: {
1158: throw new InvalidArgumentException('localFilename = '.print_r($localFilename, true));
1159: }
1160:
1161: $inputData = file_get_contents($localFilename);
1162:
1163: $data = new Xmlrpc\Base64($inputData);
1164:
1165: if(strlen($data->getXml()) > 1024 * 1024 - 15)
1166: {
1167: throw new InvalidArgumentException('file is too big');
1168: }
1169:
1170: return $this->execute(ucfirst(__FUNCTION__), array($filename, $data), $multicall);
1171: }
1172:
1173: /**
1174: * Write the data to the specified file. The filename is relative to the Tracks path
1175: * @param string $filename The file to be written
1176: * @param string $data the data to be written
1177: * @param bool $multicall
1178: * @return bool
1179: * @throws InvalidArgumentException
1180: */
1181: function writeFileFromString($filename, $data, $multicall = false)
1182: {
1183: if(!is_string($filename))
1184: {
1185: throw new InvalidArgumentException('filename = '.print_r($filename, true));
1186: }
1187:
1188: $data = new Xmlrpc\Base64($data);
1189:
1190: if(strlen($data->getXml()) > 1024 * 1024 - 15)
1191: {
1192: throw new InvalidArgumentException('data are too big');
1193: }
1194:
1195: return $this->execute('WriteFile', array($filename, $data), $multicall);
1196: }
1197:
1198: /**
1199: * Send the data to the specified player.
1200: * Login can be a single login or a list of comma-separated logins.
1201: * @param Structures\Player|string|mixed[] $players
1202: * @param string $filename
1203: * @param bool $multicall
1204: * @return bool
1205: * @throws InvalidArgumentException
1206: */
1207: function tunnelSendData($players, $filename, $multicall = false)
1208: {
1209: if(!($login = $this->getLogins($players)))
1210: {
1211: throw new InvalidArgumentException('players = '.print_r($players, true));
1212: }
1213: if(!file_exists($filename))
1214: {
1215: throw new InvalidArgumentException('filename = '.print_r($filename, true));
1216: }
1217: if(filesize($filename) > 4 * 1024)
1218: {
1219: throw new InvalidArgumentException('file is too big');
1220: }
1221:
1222: $inputData = file_get_contents($filename);
1223:
1224: $data = new Xmlrpc\Base64($inputData);
1225:
1226: return $this->execute('TunnelSendDataToLogin', array($login, $data), $multicall);
1227: }
1228:
1229: /**
1230: * Send the data to the specified player.
1231: * Login can be a single login or a list of comma-separated logins.
1232: * @param Structures\Player|string|mixed[] $players
1233: * @param string $data
1234: * @param bool $multicall
1235: * @return bool
1236: * @throws InvalidArgumentException
1237: */
1238: function tunnelSendDataFromString($players, $data, $multicall = false)
1239: {
1240: if(!($login = $this->getLogins($players)))
1241: {
1242: throw new InvalidArgumentException('players = '.print_r($players, true));
1243: }
1244:
1245: $data = new Xmlrpc\Base64($data);
1246:
1247: return $this->execute('TunnelSendDataToLogin', array($login, $data), $multicall);
1248: }
1249:
1250: /**
1251: * Just log the parameters and invoke a callback.
1252: * Can be used to talk to other xmlrpc clients connected, or to make custom votes.
1253: * If used in a callvote, the first parameter will be used as the vote message on the clients.
1254: * @param string $message the message to log
1255: * @param string $callback optionnal callback name
1256: * @param bool $multicall
1257: * @return bool
1258: * @throws InvalidArgumentException
1259: */
1260: function dedicatedEcho($message, $callback = '', $multicall = false)
1261: {
1262: if(!is_string($message))
1263: {
1264: throw new InvalidArgumentException('message = '.print_r($message, true));
1265: }
1266: if(!is_string($callback))
1267: {
1268: throw new InvalidArgumentException('callback = '.print_r($callback, true));
1269: }
1270:
1271: return $this->execute('Echo', array($message, $callback), $multicall);
1272: }
1273:
1274: /**
1275: * Ignore the specified Structures\Player.
1276: * @param Structures\Player|string $player
1277: * @param bool $multicall
1278: * @return bool
1279: * @throws InvalidArgumentException
1280: */
1281: function ignore($player, $multicall = false)
1282: {
1283: if(!($login = $this->getLogin($player)))
1284: {
1285: throw new InvalidArgumentException('player must be set');
1286: }
1287: return $this->execute(ucfirst(__FUNCTION__), array($login), $multicall);
1288: }
1289:
1290: /**
1291: * Unignore the specified player.
1292: * @param Structures\Player|string $player
1293: * @param bool $multicall
1294: * @return bool
1295: * @throws InvalidArgumentException
1296: */
1297: function unIgnore($player, $multicall = false)
1298: {
1299: if(!($login = $this->getLogin($player)))
1300: {
1301: throw new InvalidArgumentException('player must be set');
1302: }
1303: return $this->execute(ucfirst(__FUNCTION__), array($login), $multicall);
1304: }
1305:
1306: /**
1307: * Clean the ignore list of the server.
1308: * @param bool $multicall
1309: * @return bool
1310: */
1311: function cleanIgnoreList($multicall = false)
1312: {
1313: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
1314: }
1315:
1316: /**
1317: * Returns the list of ignored players. This method takes two parameters.
1318: * The first parameter specifies the maximum number of infos to be returned,
1319: * the second one the starting index in the list. The list is an array of structures.
1320: * Each structure contains the following fields : Login.
1321: * @param int $length specifies the maximum number of infos to be returned
1322: * @param int $offset specifies the starting index in the list
1323: * @return Structures\Player[] The list is an array of structures. Each structure contains the following fields : Login.
1324: * @throws InvalidArgumentException
1325: */
1326: function getIgnoreList($length, $offset)
1327: {
1328: if(!is_int($length))
1329: {
1330: throw new InvalidArgumentException('length = '.print_r($length, true));
1331: }
1332: if(!is_int($offset))
1333: {
1334: throw new InvalidArgumentException('offset = '.print_r($offset, true));
1335: }
1336:
1337: $result = $this->execute(ucfirst(__FUNCTION__), array($length, $offset));
1338: return Structures\Player::fromArrayOfArray($result);
1339: }
1340:
1341: /**
1342: * Pay coppers from the server account to a player, returns the BillId.
1343: * This method takes three parameters:
1344: * Login of the payee,
1345: * Coppers to pay and
1346: * Label to send with the payment.
1347: * The creation of the transaction itself may cost coppers,
1348: * so you need to have coppers on the server account.
1349: * @param Structures\Player|string $player
1350: * @param int $amount
1351: * @param string $label
1352: * @param bool $multicall
1353: * @return int The Bill Id
1354: * @throws InvalidArgumentException
1355: */
1356: function pay($player, $amount, $label, $multicall = false)
1357: {
1358: if(!($login = $this->getLogin($player)))
1359: {
1360: throw new InvalidArgumentException('player must be set');
1361: }
1362: if(!is_int($amount) || $amount < 1)
1363: {
1364: throw new InvalidArgumentException('amount = '.print_r($amount, true));
1365: }
1366: if(!is_string($label))
1367: {
1368: throw new InvalidArgumentException('label = '.print_r($label, true));
1369: }
1370:
1371: return $this->execute(ucfirst(__FUNCTION__), array($login, $amount, $label), $multicall);
1372: }
1373:
1374: /**
1375: * Create a bill, send it to a player, and return the BillId.
1376: * This method takes four parameters:
1377: * LoginFrom of the payer,
1378: * Coppers the player has to pay,
1379: * Label of the transaction and
1380: * optional LoginTo of the payee (if empty string, then the server account is used).
1381: * The creation of the transaction itself may cost coppers,
1382: * so you need to have coppers on the server account.
1383: * @param Structures\Player|string $fromPlayer
1384: * @param int $amount
1385: * @param string $label
1386: * @param Structures\Player|string|null $toPlayer
1387: * @param bool $multicall
1388: * @return int
1389: * @throws InvalidArgumentException
1390: */
1391: function sendBill($fromPlayer, $amount, $label, $toPlayer = null, $multicall = false)
1392: {
1393:
1394: if(!is_int($amount) || $amount < 1)
1395: {
1396: throw new InvalidArgumentException('amount = '.print_r($amount, true));
1397: }
1398: if(!is_string($label))
1399: {
1400: throw new InvalidArgumentException('label = '.print_r($label, true));
1401: }
1402: if(!($from = $this->getLogin($fromPlayer)))
1403: {
1404: throw new InvalidArgumentException('fromPlayer must be set');
1405: }
1406:
1407: $to = $this->getLogin($toPlayer) ? : '';
1408:
1409: return $this->execute(ucfirst(__FUNCTION__), array($from, $amount, $label, $to), $multicall);
1410: }
1411:
1412: /**
1413: * Returns the current state of a bill.
1414: * This method takes one parameter, the BillId.
1415: * Returns a struct containing
1416: * State, StateName and TransactionId.
1417: * Possible enum values are: CreatingTransaction, Issued, ValidatingPayement, Payed, Refused, Error.
1418: * @param int $billId
1419: * @return Structures\Bill
1420: * @throws InvalidArgumentException
1421: */
1422: function getBillState($billId)
1423: {
1424: if(!is_int($billId))
1425: {
1426: throw new InvalidArgumentException('billId = '.print_r($billId, true));
1427: }
1428:
1429: $result = $this->execute(ucfirst(__FUNCTION__), array($billId));
1430: return Structures\Bill::fromArray($result);
1431: }
1432:
1433: /**
1434: * Returns the current number of planets on the server account.
1435: * @return int
1436: */
1437: function getServerPlanets()
1438: {
1439: return $this->execute('GetServerPlanets');
1440: }
1441:
1442: /**
1443: * Get some system infos.
1444: * Return a struct containing:
1445: * PublishedIp, Port, P2PPort, ServerLogin, ServerPlayerId
1446: * @return Structures\SystemInfos
1447: */
1448: function getSystemInfo()
1449: {
1450: $result = $this->execute(ucfirst(__FUNCTION__));
1451: return Structures\SystemInfos::fromArray($result);
1452: }
1453:
1454: /**
1455: * Sets up- and download speed for the server in kbps.
1456: * @param int $downloadRate the download rate in kbps
1457: * @param int $uploadRate the upload rate in kbps
1458: * @param bool $multicall
1459: * @return bool
1460: */
1461: function setConnectionRates($downloadRate, $uploadRate, $multicall = false)
1462: {
1463: if(!is_int($downloadRate))
1464: {
1465: throw new InvalidArgumentException('downloadRate = '.print_r($downloadRate, true));
1466: }
1467: if(!is_int($uploadRate))
1468: {
1469: throw new InvalidArgumentException('uploadRate = '.print_r($uploadRate, true));
1470: }
1471:
1472: return $this->execute(ucfirst(__FUNCTION__), array($downloadRate, $uploadRate), $multicall);
1473: }
1474:
1475: /**
1476: * Set a new server name in utf8 format.
1477: * @param string $serverName
1478: * @param bool $multicall
1479: * @return bool
1480: * @throws InvalidArgumentException
1481: */
1482: function setServerName($serverName, $multicall = false)
1483: {
1484: if(!is_string($serverName))
1485: {
1486: throw new InvalidArgumentException('serverName = '.print_r($serverName, true));
1487: }
1488:
1489: return $this->execute(ucfirst(__FUNCTION__), array($serverName), $multicall);
1490: }
1491:
1492: /**
1493: * Get the server name in utf8 format.
1494: * @return string
1495: */
1496: function getServerName()
1497: {
1498: return $this->execute(ucfirst(__FUNCTION__));
1499: }
1500:
1501: /**
1502: * Set a new server comment in utf8 format.
1503: * @param string $serverComment
1504: * @param bool $multicall
1505: * @return bool
1506: * @throws InvalidArgumentException
1507: */
1508: function setServerComment($serverComment, $multicall = false)
1509: {
1510: if(!is_string($serverComment))
1511: {
1512: throw new InvalidArgumentException('serverComment = '.print_r($serverComment, true));
1513: }
1514:
1515: return $this->execute(ucfirst(__FUNCTION__), array($serverComment), $multicall);
1516: }
1517:
1518: /**
1519: * Get the server comment in utf8 format.
1520: * @return string
1521: */
1522: function getServerComment()
1523: {
1524: return $this->execute(ucfirst(__FUNCTION__));
1525: }
1526:
1527: /**
1528: * Set whether the server should be hidden from the public server list
1529: * (0 = visible, 1 = always hidden, 2 = hidden from nations).
1530: * @param int $visibility
1531: * @param bool $multicall
1532: * @return bool
1533: * @throws InvalidArgumentException
1534: */
1535: function setHideServer($visibility, $multicall = false)
1536: {
1537: if($visibility !== 0 && $visibility !== 1 && $visibility !== 2)
1538: {
1539: throw new InvalidArgumentException('visibility = '.print_r($visibility, true));
1540: }
1541:
1542: return $this->execute(ucfirst(__FUNCTION__), array($visibility), $multicall);
1543: }
1544:
1545: /**
1546: * Get whether the server wants to be hidden from the public server list.
1547: * @return string
1548: */
1549: function getHideServer()
1550: {
1551: return $this->execute(ucfirst(__FUNCTION__));
1552: }
1553:
1554: /**
1555: * Returns true if this is a relay server.
1556: * @return bool
1557: */
1558: function isRelayServer()
1559: {
1560: return $this->execute(ucfirst(__FUNCTION__));
1561: }
1562:
1563: /**
1564: * Set a new password for the server.
1565: * @param string $serverPassword
1566: * @param bool $multicall
1567: * @return bool
1568: * @throws InvalidArgumentException
1569: */
1570: function setServerPassword($serverPassword, $multicall = false)
1571: {
1572: if(!is_string($serverPassword))
1573: {
1574: throw new InvalidArgumentException('serverPassword = '.print_r($serverPassword, true));
1575: }
1576:
1577: return $this->execute(ucfirst(__FUNCTION__), array($serverPassword), $multicall);
1578: }
1579:
1580: /**
1581: * Get the server password if called as Admin or Super Admin, else returns if a password is needed or not.
1582: * Get the server name in utf8 format.
1583: * @return bool|string
1584: */
1585: function getServerPassword()
1586: {
1587: return $this->execute(ucfirst(__FUNCTION__));
1588: }
1589:
1590: /**
1591: * Set a new password for the spectator mode.
1592: * @param string $serverPassword
1593: * @param bool $multicall
1594: * @return bool
1595: * @throws InvalidArgumentException
1596: */
1597: function setServerPasswordForSpectator($serverPassword, $multicall = false)
1598: {
1599: if(!is_string($serverPassword))
1600: {
1601: throw new InvalidArgumentException('serverPassword = '.print_r($serverPassword, true));
1602: }
1603:
1604: return $this->execute(ucfirst(__FUNCTION__), array($serverPassword), $multicall);
1605: }
1606:
1607: /**
1608: * Get the password for spectator mode if called as Admin or Super Admin, else returns if a password is needed or not.
1609: * @return bool|string
1610: */
1611: function getServerPasswordForSpectator()
1612: {
1613: return $this->execute(ucfirst(__FUNCTION__));
1614: }
1615:
1616: /**
1617: * Set a new maximum number of players.
1618: * Requires a map restart to be taken into account.
1619: * @param int $maxPlayers
1620: * @param bool $multicall
1621: * @return bool
1622: * @throws InvalidArgumentException
1623: */
1624: function setMaxPlayers($maxPlayers, $multicall = false)
1625: {
1626: if(!is_int($maxPlayers))
1627: {
1628: throw new InvalidArgumentException('maxPlayers = '.print_r($maxPlayers, true));
1629: }
1630:
1631: return $this->execute(ucfirst(__FUNCTION__), array($maxPlayers), $multicall);
1632: }
1633:
1634: /**
1635: * Get the current and next maximum number of players allowed on server.
1636: * The struct returned contains two fields CurrentValue and NextValue.
1637: * @return array
1638: */
1639: function getMaxPlayers()
1640: {
1641: return $this->execute(ucfirst(__FUNCTION__));
1642: }
1643:
1644: /**
1645: * Set a new maximum number of spectators.
1646: * Requires a map restart to be taken into account.
1647: * @param int $maxSpectators
1648: * @param bool $multicall
1649: * @return bool
1650: * @throws InvalidArgumentException
1651: */
1652: function setMaxSpectators($maxSpectators, $multicall = false)
1653: {
1654: if(!is_int($maxSpectators))
1655: {
1656: throw new InvalidArgumentException('maxPlayers = '.print_r($maxSpectators, true));
1657: }
1658:
1659: return $this->execute(ucfirst(__FUNCTION__), array($maxSpectators), $multicall);
1660: }
1661:
1662: /**
1663: * Get the current and next maximum number of spectators allowed on server.
1664: * The struct returned contains two fields CurrentValue and NextValue.
1665: * @return array
1666: */
1667: function getMaxSpectators()
1668: {
1669: return $this->execute(ucfirst(__FUNCTION__));
1670: }
1671:
1672: /**
1673: * Enable or disable peer-to-peer upload from server.
1674: * @param bool $enable
1675: * @param bool $multicall
1676: * @return bool
1677: * @throws InvalidArgumentException
1678: */
1679: function enableP2PUpload($enable, $multicall = false)
1680: {
1681: if(!is_bool($enable))
1682: {
1683: throw new InvalidArgumentException('enable = '.print_r($enable, true));
1684: }
1685:
1686: return $this->execute(ucfirst(__FUNCTION__), array($enable), $multicall);
1687: }
1688:
1689: /**
1690: * Returns if the peer-to-peer upload from server is enabled.
1691: * @return bool
1692: */
1693: function isP2PUpload()
1694: {
1695: return $this->execute(ucfirst(__FUNCTION__));
1696: }
1697:
1698: /**
1699: * Enable or disable peer-to-peer download from server.
1700: * @param bool $enable
1701: * @param bool $multicall
1702: * @return bool
1703: * @throws InvalidArgumentException
1704: */
1705: function enableP2PDownload($enable, $multicall = false)
1706: {
1707: if(!is_bool($enable))
1708: {
1709: throw new InvalidArgumentException('enable = '.print_r($enable, true));
1710: }
1711:
1712: return $this->execute(ucfirst(__FUNCTION__), array($enable), $multicall);
1713: }
1714:
1715: /**
1716: * Returns if the peer-to-peer download from server is enabled.
1717: * @return bool
1718: */
1719: function isP2PDownload()
1720: {
1721: return $this->execute(ucfirst(__FUNCTION__));
1722: }
1723:
1724: /**
1725: * Allow clients to download maps from the server.
1726: * @param bool $allow
1727: * @param bool $multicall
1728: * @return bool
1729: * @throws InvalidArgumentException
1730: */
1731: function allowMapDownload($allow, $multicall = false)
1732: {
1733: if(!is_bool($allow))
1734: {
1735: throw new InvalidArgumentException('allow = '.print_r($allow, true));
1736: }
1737:
1738: return $this->execute(ucfirst(__FUNCTION__), array($allow), $multicall);
1739: }
1740:
1741: /**
1742: * Returns if clients can download maps from the server.
1743: * @return bool
1744: */
1745: function isMapDownloadAllowed()
1746: {
1747: return $this->execute(ucfirst(__FUNCTION__));
1748: }
1749:
1750: /**
1751: * Enable the autosaving of all replays (vizualisable replays with all players,
1752: * but not validable) on the server.
1753: * @param bool $enable
1754: * @param bool $multicall
1755: * @return bool
1756: * @throws InvalidArgumentException
1757: */
1758: function autoSaveReplays($enable, $multicall = false)
1759: {
1760: if(!is_bool($enable))
1761: {
1762: throw new InvalidArgumentException('enable = '.print_r($enable, true));
1763: }
1764:
1765: return $this->execute(ucfirst(__FUNCTION__), array($enable), $multicall);
1766: }
1767:
1768: /**
1769: * Returns if autosaving of all replays is enabled on the server.
1770: * @return bool
1771: */
1772: function isAutoSaveReplaysEnabled()
1773: {
1774: return $this->execute(ucfirst(__FUNCTION__));
1775: }
1776:
1777: /**
1778: * Enable the autosaving on the server of validation replays, every time a player makes a new time.
1779: * @param bool $enable
1780: * @param bool $multicall
1781: * @return bool
1782: * @throws InvalidArgumentException
1783: */
1784: function autoSaveValidationReplays($enable, $multicall = false)
1785: {
1786: if(!is_bool($enable))
1787: {
1788: throw new InvalidArgumentException('enable = '.print_r($enable, true));
1789: }
1790:
1791: return $this->execute(ucfirst(__FUNCTION__), array($enable), $multicall);
1792: }
1793:
1794: /**
1795: * Returns if autosaving of validation replays is enabled on the server.
1796: * @return bool
1797: */
1798: function isAutoSaveValidationReplaysEnabled()
1799: {
1800: return $this->execute(ucfirst(__FUNCTION__));
1801: }
1802:
1803: /**
1804: * Saves the current replay (vizualisable replays with all players, but not validable).
1805: * Pass a filename, or '' for an automatic filename.
1806: * @param string $filename
1807: * @param bool $multicall
1808: * @return bool
1809: * @throws InvalidArgumentException
1810: */
1811: function saveCurrentReplay($filename = '', $multicall = false)
1812: {
1813: if(!is_string($filename))
1814: {
1815: throw new InvalidArgumentException('filename = '.$print_r($filename, true));
1816: }
1817:
1818: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
1819: }
1820:
1821: /**
1822: * Saves a replay with the ghost of all the players' best race.
1823: * First parameter is the player object(or null for all players),
1824: * Second parameter is the filename, or '' for an automatic filename.
1825: * @param null|Structures\Player|string $player the player (or null for all players)
1826: * @param string $filename is the filename, or '' for an automatic filename
1827: * @param bool $multicall
1828: * @return bool
1829: * @throws InvalidArgumentException
1830: */
1831: function saveBestGhostsReplay($player = null, $filename = '', $multicall = false)
1832: {
1833: if(!is_string($filename))
1834: {
1835: throw new InvalidArgumentException('filename = '.$print_r($filename, true));
1836: }
1837:
1838: $playerLogin = $this->getLogin($player) ? : '';
1839:
1840: return $this->execute(ucfirst(__FUNCTION__), array($playerLogin, $filename), $multicall);
1841: }
1842:
1843: /**
1844: * Returns a replay containing the data needed to validate the current best time of the player.
1845: * The parameter is the login of the player.
1846: * @param Structures\Player|string $player
1847: * @return string base64 encoded
1848: * @throws InvalidArgumentException
1849: */
1850: function getValidationReplay($player)
1851: {
1852: if(!($login = $this->getLogin($player)))
1853: {
1854: throw new InvalidArgumentException('player must be set');
1855: }
1856: return $this->execute(ucfirst(__FUNCTION__), array($login));
1857: }
1858:
1859: /**
1860: * Set a new ladder mode between ladder disabled (0) and forced (1).
1861: * Requires a map restart to be taken into account.
1862: * @param int $mode
1863: * @param bool $multicall
1864: * @return bool
1865: * @throws InvalidArgumentException
1866: */
1867: function setLadderMode($mode, $multicall = false)
1868: {
1869: if($mode !== 0 && $mode !== 1)
1870: {
1871: throw new InvalidArgumentException('mode = '.print_r($mode, true));
1872: }
1873:
1874: return $this->execute(ucfirst(__FUNCTION__), array($mode), $multicall);
1875: }
1876:
1877: /**
1878: * Get the current and next ladder mode on server.
1879: * The struct returned contains two fields CurrentValue and NextValue.
1880: * @return array
1881: */
1882: function getLadderMode()
1883: {
1884: return $this->execute(ucfirst(__FUNCTION__));
1885: }
1886:
1887: /**
1888: * Get the ladder points limit for the players allowed on this server.
1889: * The struct returned contains two fields LadderServerLimitMin and LadderServerLimitMax.
1890: * @return array
1891: */
1892: function getLadderServerLimits()
1893: {
1894: return $this->execute(ucfirst(__FUNCTION__));
1895: }
1896:
1897: /**
1898: * Set the network vehicle quality to Fast (0) or High (1).
1899: * Requires a map restart to be taken into account.
1900: * @param int $quality
1901: * @param bool $multicall
1902: * @return bool
1903: * @throws InvalidArgumentException
1904: */
1905: function setVehicleNetQuality($quality, $multicall = false)
1906: {
1907: if($quality !== 0 && $quality !== 1)
1908: {
1909: throw new InvalidArgumentException('quality = '.print_r($quality, true));
1910: }
1911:
1912: return $this->execute(ucfirst(__FUNCTION__), array($quality), $multicall);
1913: }
1914:
1915: /**
1916: * Get the current and next network vehicle quality on server.
1917: * The struct returned contains two fields CurrentValue and NextValue.
1918: * @return array
1919: */
1920: function getVehicleNetQuality($multicall = false)
1921: {
1922: return $this->execute(ucfirst(__FUNCTION__));
1923: }
1924:
1925: /**
1926: * Set new server options using the struct passed as parameters.
1927: * This struct must contain the following fields :
1928: * Name, Comment, Password, PasswordForSpectator, NextMaxPlayers,
1929: * NextMaxSpectators, IsP2PUpload, IsP2PDownload, NextLadderMode,
1930: * NextVehicleNetQuality, NextCallVoteTimeOut, CallVoteRatio,
1931: * AllowMapDownload, AutoSaveReplays,
1932: *
1933: * optionally for forever:
1934: * RefereePassword, RefereeMode, AutoSaveValidationReplays,
1935: * HideServer, UseChangingValidationSeed.
1936: *
1937: * A change of :
1938: * NextMaxPlayers, NextMaxSpectators, NextLadderMode, NextVehicleNetQuality,
1939: * NextCallVoteTimeOut or UseChangingValidationSeed
1940: * requires a map restart to be taken into account.
1941: * @param array $options
1942: * @param bool $multicall
1943: * @return bool
1944: * @throws InvalidArgumentException
1945: */
1946: function setServerOptions(array $options, $multicall = false)
1947: {
1948: if(!is_array($options) || !array_key_exists('Name', $options) || !array_key_exists('Comment', $options)
1949: || !array_key_exists('Password', $options) || !array_key_exists('PasswordForSpectator', $options)
1950: || !array_key_exists('NextCallVoteTimeOut', $options) || !array_key_exists('CallVoteRatio', $options)
1951: || (array_key_exists('IsP2PUpload', $options) xor array_key_exists('IsP2PDownload', $options))
1952: || (array_key_exists('NextMaxPlayer', $options) xor array_key_exists('NextMaxSpectator', $options))
1953: || (array_key_exists('RefereePassword', $options) xor array_key_exists('RefereeMode', $options)))
1954: {
1955: throw new InvalidArgumentException('options = '.print_r($options, true));
1956: }
1957:
1958: return $this->execute(ucfirst(__FUNCTION__), array($options), $multicall);
1959: }
1960:
1961: /**
1962: * Optional parameter for compatibility: struct version (0 = united, 1 = forever).
1963: * Returns a struct containing the server options:
1964: * Name, Comment, Password, PasswordForSpectator, CurrentMaxPlayers, NextMaxPlayers,
1965: * CurrentMaxSpectators, NextMaxSpectators, IsP2PUpload, IsP2PDownload, CurrentLadderMode,
1966: * NextLadderMode, CurrentVehicleNetQuality, NextVehicleNetQuality, CurrentCallVoteTimeOut,
1967: * NextCallVoteTimeOut, CallVoteRatio, AllowMapDownload and AutoSaveReplays,
1968: *
1969: * and additionally for forever:
1970: * RefereePassword, RefereeMode, AutoSaveValidationReplays, HideServer,
1971: * CurrentUseChangingValidationSeed, NextUseChangingValidationSeed.
1972: * @param int $compability
1973: * @return Structures\ServerOptions
1974: * @throws InvalidArgumentException
1975: */
1976: function getServerOptions($compatibility = 1)
1977: {
1978: if($compatibility !== 0 && $compatibility !== 1)
1979: {
1980: throw new InvalidArgumentException('compatibility = '.print_r($compatibility, true));
1981: }
1982: return Structures\ServerOptions::fromArray($this->execute(ucfirst(__FUNCTION__), array($compatibility)));
1983: }
1984:
1985: /**
1986: * Defines the packmask of the server. Can be 'United', 'Nations', 'Sunrise', 'Original',
1987: * or any of the environment names. (Only maps matching the packmask will be
1988: * allowed on the server, so that player connecting to it know what to expect.)
1989: * Only available when the server is stopped.
1990: * @param string $packMask
1991: * @param bool $multicall
1992: * @return bool
1993: * @throws InvalidArgumentException
1994: */
1995: function setServerPackMask($packMask, $multicall = false)
1996: {
1997: if(!is_string($packMask))
1998: {
1999: throw new InvalidArgumentException('packMask = '.print_r($packMask, true));
2000: }
2001:
2002: return $this->execute(ucfirst(__FUNCTION__), array($packMask), $multicall);
2003: }
2004:
2005: /**
2006: * Get the packmask of the server.
2007: * @return string
2008: */
2009: function getServerPackMask()
2010: {
2011: return $this->execute(ucfirst(__FUNCTION__));
2012: }
2013:
2014: /**
2015: * Set the mods to apply on the clients. Parameters:
2016: * Override, if true even the maps with a mod will be overridden by the server setting;
2017: * Mods, an array of structures [{EnvName, Url}, ...].
2018: * Requires a map restart to be taken into account.
2019: * @param bool $override
2020: * @param array $mods
2021: * @param bool $multicall
2022: * @return bool
2023: * @throws InvalidArgumentException
2024: */
2025: function setForcedMods($override, $mods, $multicall = false)
2026: {
2027: if(!is_bool($override))
2028: {
2029: throw new InvalidArgumentException('override = '.print_r($override, true));
2030: }
2031: if(is_array($mods))
2032: {
2033: $modList = array();
2034: foreach($mods as $mod)
2035: {
2036: if(!($mod instanceof Structures\Mod)) throw new InvalidArgumentException('mods = '.print_r($mods, true));
2037: else $modList[] = $mod->toArray();
2038: }
2039: }
2040: elseif($mods instanceof Structures\Mod) $modList = array($mods->toArray());
2041: else throw new InvalidArgumentException('mods = '.print_r($mods, true));
2042:
2043: return $this->execute(ucfirst(__FUNCTION__), array($override, $modList), $multicall);
2044: }
2045:
2046: /**
2047: * Get the mods settings.
2048: * @return array the first value is a boolean which indicate if the mods override existing mods, the second is an array of objet of Structures\Mod type
2049: */
2050: function getForcedMods()
2051: {
2052: $result = $this->execute(ucfirst(__FUNCTION__));
2053: $result['Mods'] = Structures\Mod::fromArrayOfArray($result['Mods']);
2054: return $result;
2055: }
2056:
2057: /**
2058: * Set the music to play on the clients. Parameters:
2059: * Override, if true even the maps with a custom music will be overridden by the server setting,
2060: * UrlOrFileName for the music.
2061: * Requires a map restart to be taken into account
2062: * @param bool $override
2063: * @param string $music
2064: * @param bool $multicall
2065: * @throws InvalidArgumentException
2066: */
2067: function setForcedMusic($override, $music, $multicall = false)
2068: {
2069: if(!is_bool($override))
2070: {
2071: throw new InvalidArgumentException('override = '.print_r($override, true));
2072: }
2073: if(!is_string($music))
2074: {
2075: throw new InvalidArgumentException('music = '.print_r($music, true));
2076: }
2077:
2078: return $this->execute(ucfirst(__FUNCTION__), array($override, $music), $multicall);
2079: }
2080:
2081: /**
2082: * Get the music setting.
2083: * @return Structures\Music
2084: */
2085: function getForcedMusic()
2086: {
2087: return Structures\Music::fromArray($this->execute(ucfirst(__FUNCTION__)));
2088: }
2089:
2090: /**
2091: * Defines a list of remappings for player skins. It expects a list of structs Orig, Name, Checksum, Url.
2092: * Orig is the name of the skin to remap, or '*' for any other. Name, Checksum, Url define the skin to use.
2093: * (They are optional, you may set value '' for any of those. All 3 null means same as Orig).
2094: * Will only affect players connecting after the value is set.
2095: * @param Structures\Skin[] $skins
2096: * @param bool $multicall
2097: * @return bool
2098: * @throws InvalidArgumentException
2099: */
2100: function setForcedSkins(array $skins, $multicall = false)
2101: {
2102: if(!is_array($skins))
2103: {
2104: throw new InvalidArgumentException('skins = '.print_r($skins, true));
2105: }
2106:
2107: $skinParameter = array();
2108: foreach($skins as $key => $skin)
2109: {
2110: if($skin instanceof Structures\Skin)
2111: {
2112: $skinParameter[$key] = array();
2113: $skinParameter[$key]['Orig'] = $skin->orig;
2114: $skinParameter[$key]['Name'] = $skin->name;
2115: $skinParameter[$key]['Checksum'] = $skin->checksum;
2116: $skinParameter[$key]['Url'] = $skin->url;
2117: }
2118: elseif(!is_array($skin) || !array_key_exists('Orig', $skin) && !array_key_exists('Name', $skin) && !array_key_exists('Checksum',
2119: $skin) && !array_key_exists('Url', $skin))
2120: {
2121: throw new InvalidArgumentException('skins['.$key.'] = '.print_r($skins[$key], true));
2122: }
2123: else
2124: {
2125: $skinParameter[$key] = $skin;
2126: }
2127: }
2128:
2129: return $this->execute(ucfirst(__FUNCTION__), array($skinParameter), $multicall);
2130: }
2131:
2132: /**
2133: * Get the current forced skins.
2134: * @return Structures\Skin[]
2135: */
2136: function getForcedSkins()
2137: {
2138: return Structures\Skin::fromArrayOfArray($this->execute(ucfirst(__FUNCTION__)));
2139: }
2140:
2141: /**
2142: * Returns the last error message for an internet connection.
2143: * @return string
2144: */
2145: function getLastConnectionErrorMessage()
2146: {
2147: return $this->execute(ucfirst(__FUNCTION__));
2148: }
2149:
2150: /**
2151: * Set a new password for the referee mode.
2152: * @param string $refereePassword
2153: * @param bool $multicall
2154: * @return bool
2155: * @throws InvalidArgumentException
2156: */
2157: function setRefereePassword($refereePassword, $multicall = false)
2158: {
2159: if(!is_string($refereePassword))
2160: {
2161: throw new InvalidArgumentException('refereePassword = '.print_r($refereePassword, true));
2162: }
2163:
2164: return $this->execute(ucfirst(__FUNCTION__), array($refereePassword), $multicall);
2165: }
2166:
2167: /**
2168: * Get the password for referee mode if called as Admin or Super Admin,
2169: * else returns if a password is needed or not.
2170: * @return bool|string
2171: */
2172: function getRefereePassword()
2173: {
2174: return $this->execute(ucfirst(__FUNCTION__));
2175: }
2176:
2177: /**
2178: * Set the referee validation mode. 0 = validate the top3 players, 1 = validate all players. Only available to Admin.
2179: * @param int $refereeMode
2180: * @param bool $multicall
2181: * @return bool
2182: * @throws InvalidArgumentException
2183: */
2184: function setRefereeMode($refereeMode, $multicall = false)
2185: {
2186: if($refereeMode !== 0 && $refereeMode !== 1)
2187: {
2188: throw new InvalidArgumentException('refereeMode = '.print_r($refereeMode, true));
2189: }
2190:
2191: return $this->execute(ucfirst(__FUNCTION__), array($refereeMode), $multicall);
2192: }
2193:
2194: /**
2195: * Get the referee validation mode.
2196: * @return bool|string
2197: */
2198: function getRefereeMode()
2199: {
2200: return $this->execute(ucfirst(__FUNCTION__));
2201: }
2202:
2203: /**
2204: * Set whether the game should use a variable validation seed or not.
2205: * Requires a map restart to be taken into account.
2206: * @param bool $enable
2207: * @param bool $multicall
2208: * @return bool
2209: * @throws InvalidArgumentException
2210: */
2211: function setUseChangingValidationSeed($enable, $multicall = false)
2212: {
2213: if(!is_bool($enable))
2214: {
2215: throw new InvalidArgumentException('enable = '.print_r($enable, true));
2216: }
2217:
2218: return $this->execute(ucfirst(__FUNCTION__), array($enable), $multicall);
2219: }
2220:
2221: /**
2222: * Get the current and next value of UseChangingValidationSeed.
2223: * The struct returned contains two fields CurrentValue and NextValue.
2224: * @return array
2225: */
2226: function getUseChangingValidationSeed()
2227: {
2228: return $this->execute(ucfirst(__FUNCTION__));
2229: }
2230:
2231: /**
2232: * Set the maximum time the server must wait for inputs from the clients before dropping data, or '0' for auto-adaptation.
2233: * Only used by ShootMania. Only available to Admin.
2234: * @param int $latency
2235: * @param bool $multicall
2236: * @return bool
2237: */
2238: function setClientInputsMaxLatency($latency, $multicall = false)
2239: {
2240: if(!is_int($latency))
2241: {
2242: throw new InvalidArgumentException('latency = '.print_r($latency, true));
2243: }
2244:
2245: return $this->execute(ucfirst(__FUNCTION__), array($latency), $multicall);
2246: }
2247:
2248: /**
2249: * Get the current ClientInputsMaxLatency. Only used by ShootMania.
2250: * @return int
2251: */
2252: function getClientInputsMaxLatency()
2253: {
2254: return $this->execute(ucfirst(__FUNCTION__));
2255: }
2256:
2257: /**
2258: * Sets whether the server is in warm-up phase or not.
2259: * @param bool $enable
2260: * @param bool $multicall
2261: * @return bool
2262: * @throws InvalidArgumentException
2263: */
2264: function setWarmUp($enable, $multicall = false)
2265: {
2266: if(!is_bool($enable))
2267: {
2268: throw new InvalidArgumentException('enable = '.print_r($enable, true));
2269: }
2270:
2271: return $this->execute(ucfirst(__FUNCTION__), array($enable), $multicall);
2272: }
2273:
2274: /**
2275: * Returns whether the server is in warm-up phase.
2276: * @return bool
2277: */
2278: function getWarmUp()
2279: {
2280: return $this->execute(ucfirst(__FUNCTION__));
2281: }
2282:
2283: /**
2284: * Get the current rules script.
2285: * TODO Check if correct
2286: * @return string
2287: */
2288: function getModeScriptText()
2289: {
2290: return $this->execute(ucfirst(__FUNCTION__));
2291: }
2292:
2293: /**
2294: * Set the rules script and restart.
2295: * Only available to Admin.
2296: * TODO Check if correct
2297: * @param string $script
2298: * @param bool $multicall
2299: * @return bool
2300: */
2301: function setModeScriptText($script, $multicall = false)
2302: {
2303: return $this->execute(ucfirst(__FUNCTION__), array($script), $multicall);
2304: }
2305:
2306: /**
2307: * Get the xml-rpc variables of the mode script.
2308: * Only available to Admin.
2309: * @return array
2310: */
2311: function getModeScriptVariables()
2312: {
2313: return $this->execute(ucfirst(__FUNCTION__));
2314: }
2315:
2316: /**
2317: * Set the variables of the rules script. Only available to Admin.
2318: * @param array $variables
2319: * @param bool $multicall
2320: */
2321: function setModeScriptVariables($variables, $multicall = false)
2322: {
2323: return $this->execute(ucfirst(__FUNCTION__), array($variables), $multicall);
2324: }
2325:
2326: /**
2327: * Send an event to the rules script. Only available to Admin.
2328: * @param string $param1
2329: * @param srting $param2
2330: * @param bool $multicall
2331: * @return bool
2332: */
2333: function triggerModeScriptEvent($param1, $param2, $multicall = false)
2334: {
2335: if(!is_string($param1))
2336: {
2337: throw new InvalidArgumentException('param1 = '.print_r($param1, true));
2338: }
2339: if(!is_string($param2))
2340: {
2341: throw new InvalidArgumentException('param2 = '.print_r($param2, true));
2342: }
2343: return $this->execute(ucfirst(__FUNCTION__), array($param1, $param2), $multicall);
2344: }
2345:
2346: /**
2347: * Returns the description of the current rules script,
2348: * as a structure containing: Name, CompatibleTypes,
2349: * Description and the settings available.
2350: * @return Structures\ScriptInfo
2351: */
2352: function getModeScriptInfo()
2353: {
2354: return Structures\ScriptInfo::fromArray($this->execute(ucfirst(__FUNCTION__)));
2355: }
2356:
2357: /**
2358: * Returns the current parameters of the mode script.
2359: * @return array
2360: */
2361: function getModeScriptSettings()
2362: {
2363: return $this->execute(ucfirst(__FUNCTION__));
2364: }
2365:
2366: /**
2367: * Set the parameters of the rules script. Only available to Admin.
2368: * @param array $rules
2369: * @param bool $multicall
2370: * @return bool
2371: */
2372: function setModeScriptSettings($rules, $multicall = false)
2373: {
2374: return $this->execute(ucfirst(__FUNCTION__), array($rules), $multicall);
2375: }
2376:
2377: /**
2378: * Restarts the map, with an optional boolean parameter DontClearCupScores (only available in cup mode).
2379: * @param bool $dontClearCupScores
2380: * @param bool $multicall
2381: * @return bool
2382: * @throws InvalidArgumentException
2383: */
2384: function restartMap($dontClearCupScores = false, $multicall = false)
2385: {
2386: if(!is_bool($dontClearCupScores))
2387: {
2388: throw new InvalidArgumentException('dontClearCupScores = '.print_r($dontClearCupScores, true));
2389: }
2390:
2391: return $this->execute(ucfirst(__FUNCTION__), array($dontClearCupScores), $multicall);
2392: }
2393:
2394: /**
2395: * Switch to next map, with an optional boolean parameter DontClearCupScores (only available in cup mode).
2396: * @param bool $dontClearCupScores
2397: * @param bool $multicall
2398: * @return bool
2399: * @throws InvalidArgumentException
2400: */
2401: function nextMap($dontClearCupScores = false, $multicall = false)
2402: {
2403: if(!is_bool($dontClearCupScores))
2404: {
2405: throw new InvalidArgumentException('dontClearCupScores = '.print_r($dontClearCupScores, true));
2406: }
2407:
2408: return $this->execute(ucfirst(__FUNCTION__), array($dontClearCupScores), $multicall);
2409: }
2410:
2411: /**
2412: * Attempt to balance teams. Only available to Admin.
2413: * @return bool
2414: */
2415: function autoTeamBalance()
2416: {
2417: return $this->execute(ucfirst(__FUNCTION__));
2418: }
2419:
2420: /**
2421: * Stop the server.
2422: * @param bool $multicall
2423: * @return bool
2424: */
2425: function stopServer($multicall = false)
2426: {
2427: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
2428: }
2429:
2430: /**
2431: * In Rounds or Laps mode, force the end of round without waiting for all players to giveup/finish.
2432: * @param bool $multicall
2433: * @return bool
2434: */
2435: function forceEndRound($multicall = false)
2436: {
2437: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
2438: }
2439:
2440: /**
2441: * Set new game settings using the struct passed as parameters.
2442: * This struct must contain the following fields :
2443: * GameMode, ChatTime, RoundsPointsLimit, RoundsUseNewRules, RoundsForcedLaps, TimeAttackLimit,
2444: * TimeAttackSynchStartPeriod, TeamPointsLimit, TeamMaxPoints, TeamUseNewRules, LapsNbLaps, LapsTimeLimit,
2445: * FinishTimeout, and optionally: AllWarmUpDuration, DisableRespawn, ForceShowAllOpponents, RoundsPointsLimitNewRules,
2446: * TeamPointsLimitNewRules, CupPointsLimit, CupRoundsPerMap, CupNbWinners, CupWarmUpDuration.
2447: * Requires a map restart to be taken into account.
2448: * @param Structures\GameInfos $gameInfos
2449: * @param bool $multicall
2450: * @return bool
2451: * @throws InvalidArgumentException
2452: */
2453: function setGameInfos(Structures\GameInfos $gameInfos, $multicall = false)
2454: {
2455: return $this->execute(ucfirst(__FUNCTION__), array($gameInfos->toArray()), $multicall);
2456: }
2457:
2458: /**
2459: * Optional parameter for compatibility:
2460: * struct version (0 = united, 1 = forever).
2461: * Returns a struct containing the current game settings, ie:
2462: * GameMode, ChatTime, NbMap, RoundsPointsLimit, RoundsUseNewRules, RoundsForcedLaps,
2463: * TimeAttackLimit, TimeAttackSynchStartPeriod, TeamPointsLimit, TeamMaxPoints, TeamUseNewRules,
2464: * LapsNbLaps, LapsTimeLimit, FinishTimeout,
2465: * additionally for version 1: AllWarmUpDuration, DisableRespawn, ForceShowAllOpponents, RoundsPointsLimitNewRules,
2466: * TeamPointsLimitNewRules, CupPointsLimit, CupRoundsPerMap, CupNbWinners, CupWarmUpDuration.
2467: * @param int $compatibility
2468: * @return Structures\GameInfos
2469: * @throws InvalidArgumentException
2470: */
2471: function getCurrentGameInfo($compatibility = 1)
2472: {
2473: if($compatibility !== 1 && $compatibility != 0)
2474: {
2475: throw new InvalidArgumentException('compatibility = '.print_r($compatibility, true));
2476: }
2477:
2478: return Structures\GameInfos::fromArray($this->execute(ucfirst(__FUNCTION__), array($compatibility)));
2479: }
2480:
2481: /**
2482: * Optional parameter for compatibility:
2483: * struct version (0 = united, 1 = forever).
2484: * Returns a struct containing the game settings for the next map, ie:
2485: * GameMode, ChatTime, NbMap, RoundsPointsLimit, RoundsUseNewRules, RoundsForcedLaps,
2486: * TimeAttackLimit, TimeAttackSynchStartPeriod, TeamPointsLimit, TeamMaxPoints, TeamUseNewRules,
2487: * LapsNbLaps, LapsTimeLimit, FinishTimeout,
2488: * additionally for version 1: AllWarmUpDuration, DisableRespawn, ForceShowAllOpponents, RoundsPointsLimitNewRules,
2489: * TeamPointsLimitNewRules, CupPointsLimit, CupRoundsPerMap, CupNbWinners, CupWarmUpDuration.
2490: * @param int $compatibility
2491: * @return Structures\GameInfos
2492: * @throws InvalidArgumentException
2493: */
2494: function getNextGameInfo($compatibility = 1)
2495: {
2496: if($compatibility !== 1 && $compatibility != 0)
2497: {
2498: throw new InvalidArgumentException('compatibility = '.print_r($compatibility, true));
2499: }
2500:
2501: return Structures\GameInfos::fromArray($this->execute(ucfirst(__FUNCTION__), array($compatibility)));
2502: }
2503:
2504: /**
2505: * Optional parameter for compatibility: struct version (0 = united, 1 = forever).
2506: * Returns a struct containing two other structures,
2507: * the first containing the current game settings and the second the game settings for next map.
2508: * The first structure is named CurrentGameInfos and the second NextGameInfos.
2509: * @param int $compatibility
2510: * @return Structures\GameInfos[]
2511: * @throws InvalidArgumentException
2512: */
2513: function getGameInfos($compatibility = 1)
2514: {
2515: if($compatibility !== 1 && $compatibility != 0)
2516: {
2517: throw new InvalidArgumentException('compatibility = '.print_r($compatibility, true));
2518: }
2519:
2520: return Structures\GameInfos::fromArrayOfArray($this->execute(ucfirst(__FUNCTION__), array($compatibility)));
2521: }
2522:
2523: /**
2524: * Set a new game mode between Rounds (0), TimeAttack (1), Team (2), Laps (3), Stunts (4) and Cup (5).
2525: * Requires a map restart to be taken into account.
2526: * @param int $gameMode
2527: * @param bool $multicall
2528: * @throws InvalidArgumentException
2529: * @return bool
2530: */
2531: function setGameMode($gameMode, $multicall = false)
2532: {
2533: if(!is_int($gameMode) && ($gameMode < 0 || $gameMode > 5))
2534: {
2535: throw new InvalidArgumentException('gameMode = '.print_r($gameMode, true));
2536: }
2537:
2538: return $this->execute(ucfirst(__FUNCTION__), array($gameMode), $multicall);
2539: }
2540:
2541: /**
2542: * Get the current game mode.
2543: * @return int
2544: */
2545: function getGameMode()
2546: {
2547: return $this->execute(ucfirst(__FUNCTION__));
2548: }
2549:
2550: /**
2551: * Set a new chat time value in milliseconds (actually 'chat time' is the duration of the end race podium, 0 means no podium displayed.).
2552: * @param int $chatTime
2553: * @param bool $multicall
2554: * @throws InvalidArgumentException
2555: * @return bool
2556: */
2557: function setChatTime($chatTime, $multicall = false)
2558: {
2559: if(!is_int($chatTime))
2560: {
2561: throw new InvalidArgumentException('chatTime = '.print_r($chatTime, true));
2562: }
2563:
2564: return $this->execute(ucfirst(__FUNCTION__), array($chatTime), $multicall);
2565: }
2566:
2567: /**
2568: * Get the current and next chat time. The struct returned contains two fields CurrentValue and NextValue.
2569: * @return array
2570: */
2571: function getChatTime()
2572: {
2573: return $this->execute(ucfirst(__FUNCTION__));
2574: }
2575:
2576: /**
2577: * Set a new finish timeout (for rounds/laps mode) value in milliseconds.
2578: * 0 means default. 1 means adaptative to the duration of the map.
2579: * Requires a map restart to be taken into account.
2580: * @param int $finishTimeout
2581: * @param bool $multicall
2582: * @throws InvalidArgumentException
2583: * @return bool
2584: */
2585: function setFinishTimeout($finishTimeout, $multicall = false)
2586: {
2587: if(!is_int($finishTimeout))
2588: {
2589: throw new InvalidArgumentException('chatTime = '.print_r($finishTimeout, true));
2590: }
2591:
2592: return $this->execute(ucfirst(__FUNCTION__), array($finishTimeout), $multicall);
2593: }
2594:
2595: /**
2596: * Get the current and next FinishTimeout. The struct returned contains two fields CurrentValue and NextValue.
2597: * @return array
2598: */
2599: function getFinishTimeout()
2600: {
2601: return $this->execute(ucfirst(__FUNCTION__));
2602: }
2603:
2604: /**
2605: * Set whether to enable the automatic warm-up phase in all modes.
2606: * 0 = no, otherwise it's the duration of the phase, expressed in number of rounds (in rounds/team mode),
2607: * or in number of times the gold medal time (other modes).
2608: * Requires a map restart to be taken into account.
2609: * @param int $warmUpDuration
2610: * @param bool $multicall
2611: * @throws InvalidArgumentException
2612: * @return bool
2613: */
2614: function setAllWarmUpDuration($warmUpDuration, $multicall = false)
2615: {
2616: if(!is_int($warmUpDuration))
2617: {
2618: throw new InvalidArgumentException('warmUpDuration = '.print_r($warmUpDuration, true));
2619: }
2620:
2621: return $this->execute(ucfirst(__FUNCTION__), array($warmUpDuration), $multicall);
2622: }
2623:
2624: /**
2625: * Get whether the automatic warm-up phase is enabled in all modes. The struct returned contains two fields CurrentValue and NextValue.
2626: * @return array
2627: */
2628: function getAllWarmUpDuration()
2629: {
2630: return $this->execute(ucfirst(__FUNCTION__));
2631: }
2632:
2633: /**
2634: * Set whether to disallow players to respawn.
2635: * Requires a map restart to be taken into account.
2636: * @param bool $disableRespawn
2637: * @param bool $multicall
2638: * @throws InvalidArgumentException
2639: * @return bool
2640: */
2641: function setDisableRespawn($disableRespawn, $multicall = false)
2642: {
2643: if(!is_bool($disableRespawn))
2644: {
2645: throw new InvalidArgumentException('disableRespawn = '.print_r($disableRespawn, true));
2646: }
2647:
2648: return $this->execute(ucfirst(__FUNCTION__), array($disableRespawn), $multicall);
2649: }
2650:
2651: /**
2652: * Get whether players are disallowed to respawn. The struct returned contains two fields CurrentValue and NextValue.
2653: * @return array
2654: */
2655: function getDisableRespawn()
2656: {
2657: return $this->execute(ucfirst(__FUNCTION__));
2658: }
2659:
2660: /**
2661: * Set whether to override the players preferences and always display all opponents
2662: * 0=no override, 1=show all, other value=minimum number of opponents.
2663: * Requires a map restart to be taken into account.
2664: * @param int $forceShowAllOpponents
2665: * @param bool $multicall
2666: * @throws InvalidArgumentException
2667: * @return bool
2668: */
2669: function setForceShowAllOpponents($forceShowAllOpponents, $multicall = false)
2670: {
2671: if(!is_int($forceShowAllOpponents))
2672: {
2673: throw new InvalidArgumentException('forceShowAllOpponents = '.print_r($forceShowAllOpponents, true));
2674: }
2675:
2676: return $this->execute(ucfirst(__FUNCTION__), array($forceShowAllOpponents), $multicall);
2677: }
2678:
2679: /**
2680: * Get whether players are forced to show all opponents. The struct returned contains two fields CurrentValue and NextValue.
2681: * @return array
2682: */
2683: function getForceShowAllOpponents()
2684: {
2685: return $this->execute(ucfirst(__FUNCTION__));
2686: }
2687:
2688: /**
2689: * Set a new rules script name for script mode. Only available to Admin.
2690: * Requires a map restart to be taken into account.
2691: * @param string $scriptName
2692: * @param bool $multicall
2693: * @return bool
2694: */
2695: function setScriptName($scriptName, $multicall = false)
2696: {
2697: return $this->execute(ucfirst(__FUNCTION__), array($scriptName), $multicall);
2698: }
2699:
2700: /**
2701: * Get the current and next rules script name for script mode.
2702: * The struct returned contains two fields CurrentValue and NextValue.
2703: * @return array
2704: */
2705: function getScriptName()
2706: {
2707: return $this->execute(ucfirst(__FUNCTION__));
2708: }
2709:
2710: /**
2711: * Set a new time limit for time attack mode.
2712: * Requires a map restart to be taken into account.
2713: * @param int $timeAttackLimit
2714: * @param bool $multicall
2715: * @throws InvalidArgumentException
2716: * @return bool
2717: */
2718: function setTimeAttackLimit($timeAttackLimit, $multicall = false)
2719: {
2720: if(!is_int($timeAttackLimit))
2721: {
2722: throw new InvalidArgumentException('timeAttackLimit = '.print_r($timeAttackLimit, true));
2723: }
2724:
2725: return $this->execute(ucfirst(__FUNCTION__), array($timeAttackLimit), $multicall);
2726: }
2727:
2728: /**
2729: * Get the current and next time limit for time attack mode. The struct returned contains two fields CurrentValue and NextValue.
2730: * @return array
2731: */
2732: function getTimeAttackLimit()
2733: {
2734: return $this->execute(ucfirst(__FUNCTION__));
2735: }
2736:
2737: /**
2738: * Set a new synchronized start period for time attack mode.
2739: * Requires a map restart to be taken into account.
2740: * @param int $timeAttackSynchPeriod
2741: * @param bool $multicall
2742: * @throws InvalidArgumentException
2743: * @return bool
2744: */
2745: function setTimeAttackSynchStartPeriod($timeAttackSynchPeriod, $multicall = false)
2746: {
2747: if(!is_int($timeAttackSynchPeriod))
2748: {
2749: throw new InvalidArgumentException('timeAttackSynchPeriod = '.print_r($timeAttackSynchPeriod, true));
2750: }
2751:
2752: return $this->execute(ucfirst(__FUNCTION__), array($timeAttackSynchPeriod), $multicall);
2753: }
2754:
2755: /**
2756: * Get the current and synchronized start period for time attack mode.
2757: * The struct returned contains two fields CurrentValue and NextValue.
2758: * @return array
2759: */
2760: function getTimeAttackSynchStartPeriod()
2761: {
2762: return $this->execute(ucfirst(__FUNCTION__));
2763: }
2764:
2765: /**
2766: * Set a new time limit for laps mode.
2767: * Requires a map restart to be taken into account.
2768: * @param int $lapsTimeLimit
2769: * @param bool $multicall
2770: * @throws InvalidArgumentException
2771: * @return bool
2772: */
2773: function setLapsTimeLimit($lapsTimeLimit, $multicall = false)
2774: {
2775: if(!is_int($lapsTimeLimit))
2776: {
2777: throw new InvalidArgumentException('lapsTimeLimit = '.print_r($lapsTimeLimit, true));
2778: }
2779:
2780: return $this->execute(ucfirst(__FUNCTION__), array($lapsTimeLimit), $multicall);
2781: }
2782:
2783: /**
2784: * Get the current and next time limit for laps mode.
2785: * The struct returned contains two fields CurrentValue and NextValue.
2786: * @return array
2787: */
2788: function getLapsTimeLimit()
2789: {
2790: return $this->execute(ucfirst(__FUNCTION__));
2791: }
2792:
2793: /**
2794: * Set a new number of laps for laps mode.
2795: * Requires a map restart to be taken into account.
2796: * @param int $nbLaps
2797: * @param bool $multicall
2798: * @throws InvalidArgumentException
2799: * @return bool
2800: */
2801: function setNbLaps($nbLaps, $multicall = false)
2802: {
2803: if(!is_int($nbLaps))
2804: {
2805: throw new InvalidArgumentException('nbLaps = '.print_r($nbLaps, true));
2806: }
2807:
2808: return $this->execute(ucfirst(__FUNCTION__), array($nbLaps), $multicall);
2809: }
2810:
2811: /**
2812: * Get the current and next number of laps for laps mode.
2813: * The struct returned contains two fields CurrentValue and NextValue.
2814: * @return array
2815: */
2816: function getNbLaps()
2817: {
2818: return $this->execute(ucfirst(__FUNCTION__));
2819: }
2820:
2821: /**
2822: * Set a new number of laps for rounds mode
2823: * 0 = default, use the number of laps from the maps,
2824: * otherwise forces the number of rounds for multilaps maps.
2825: * Requires a map restart to be taken into account.
2826: * @param int $roundForcedLaps
2827: * @param bool $multicall
2828: * @throws InvalidArgumentException
2829: * @return bool
2830: */
2831: function setRoundForcedLaps($roundForcedLaps, $multicall = false)
2832: {
2833: if(!is_int($roundForcedLaps))
2834: {
2835: throw new InvalidArgumentException('roundForcedLaps = '.print_r($roundForcedLaps, true));
2836: }
2837:
2838: return $this->execute(ucfirst(__FUNCTION__), array($roundForcedLaps), $multicall);
2839: }
2840:
2841: /**
2842: * Get the current and next number of laps for rounds mode.
2843: * The struct returned contains two fields CurrentValue and NextValue.
2844: * @return array
2845: */
2846: function getRoundForcedLaps()
2847: {
2848: return $this->execute(ucfirst(__FUNCTION__));
2849: }
2850:
2851: /**
2852: * Set a new points limit for rounds mode (value set depends on UseNewRulesRound).
2853: * Requires a map restart to be taken into account.
2854: * @param int $roundPointsLimit
2855: * @param bool $multicall
2856: * @throws InvalidArgumentException
2857: * @return bool
2858: */
2859: function setRoundPointsLimit($roundPointsLimit, $multicall = false)
2860: {
2861: if(!is_int($roundPointsLimit))
2862: {
2863: throw new InvalidArgumentException('roundPointsLimit = '.print_r($roundPointsLimit, true));
2864: }
2865:
2866: return $this->execute(ucfirst(__FUNCTION__), array($roundPointsLimit), $multicall);
2867: }
2868:
2869: /**
2870: * Get the current and next points limit for rounds mode (values returned depend on UseNewRulesRound).
2871: * The struct returned contains two fields CurrentValue and NextValue.
2872: * @return array
2873: */
2874: function getRoundPointsLimit()
2875: {
2876: return $this->execute(ucfirst(__FUNCTION__));
2877: }
2878:
2879: /**
2880: * Set the points used for the scores in rounds mode.
2881: * Points is an array of decreasing integers for the players from the first to last.
2882: * And you can add an optional boolean to relax the constraint checking on the scores.
2883: * @param array $roundCustomPoints
2884: * @param bool $relaxChecking
2885: * @param bool $multicall
2886: * @throws InvalidArgumentException
2887: * @return bool
2888: */
2889: function setRoundCustomPoints(array $roundCustomPoints, $relaxChecking = false, $multicall = false)
2890: {
2891: if(!is_array($roundCustomPoints))
2892: {
2893: throw new InvalidArgumentException('roundCustomPoints = '.print_r($roundCustomPoints, true));
2894: }
2895: if(!is_bool($relaxChecking))
2896: {
2897: throw new InvalidArgumentException('relaxChecking = '.print_r($relaxChecking, true));
2898: }
2899:
2900: return $this->execute(ucfirst(__FUNCTION__), array($roundCustomPoints, $relaxChecking), $multicall);
2901: }
2902:
2903: /**
2904: * Gets the points used for the scores in rounds mode.
2905: * @param bool $multicall
2906: * @return array
2907: */
2908: function getRoundCustomPoints($multicall = false)
2909: {
2910: return $this->execute(ucfirst(__FUNCTION__));
2911: }
2912:
2913: /**
2914: * Set the points used for the scores in rounds mode.
2915: * Points is an array of decreasing integers for the players from the first to last.
2916: * And you can add an optional boolean to relax the constraint checking on the scores.
2917: * @param bool $useNewRulesRound
2918: * @param bool $multicall
2919: * @throws InvalidArgumentException
2920: * @return bool
2921: */
2922: function setUseNewRulesRound($useNewRulesRound, $multicall = false)
2923: {
2924: if(!is_bool($useNewRulesRound))
2925: {
2926: throw new InvalidArgumentException('useNewRulesRound = '.print_r($useNewRulesRound, true));
2927: }
2928:
2929: return $this->execute(ucfirst(__FUNCTION__), array($useNewRulesRound), $multicall);
2930: }
2931:
2932: /**
2933: * Gets the points used for the scores in rounds mode.
2934: * @return array
2935: */
2936: function getUseNewRulesRound()
2937: {
2938: return $this->execute(ucfirst(__FUNCTION__));
2939: }
2940:
2941: /**
2942: * Set a new points limit for team mode (value set depends on UseNewRulesTeam).
2943: * Requires a map restart to be taken into account.
2944: * @param int $teamPointsLimit
2945: * @param bool $multicall
2946: * @throws InvalidArgumentException
2947: * @return bool
2948: */
2949: function setTeamPointsLimit($teamPointsLimit, $multicall = false)
2950: {
2951: if(!is_int($teamPointsLimit))
2952: {
2953: throw new InvalidArgumentException('teamPointsLimit = '.print_r($teamPointsLimit, true));
2954: }
2955:
2956: return $this->execute(ucfirst(__FUNCTION__), array($teamPointsLimit), $multicall);
2957: }
2958:
2959: /**
2960: * Get the current and next points limit for team mode (values returned depend on UseNewRulesTeam).
2961: * The struct returned contains two fields CurrentValue and NextValue.
2962: * @return array
2963: */
2964: function getTeamPointsLimit()
2965: {
2966: return $this->execute(ucfirst(__FUNCTION__));
2967: }
2968:
2969: /**
2970: * Set a new number of maximum points per round for team mode.
2971: * Requires a map restart to be taken into account.
2972: * @param int $maxPointsTeam
2973: * @param bool $multicall
2974: * @throws InvalidArgumentException
2975: * @return bool
2976: */
2977: function setMaxPointsTeam($maxPointsTeam, $multicall = false)
2978: {
2979: if(!is_int($maxPointsTeam))
2980: {
2981: throw new InvalidArgumentException('maxPointsTeam = '.print_r($maxPointsTeam, true));
2982: }
2983:
2984: return $this->execute(ucfirst(__FUNCTION__), array($maxPointsTeam), $multicall);
2985: }
2986:
2987: /**
2988: * Get the current and next number of maximum points per round for team mode.
2989: * The struct returned contains two fields CurrentValue and NextValue.
2990: * @return array
2991: */
2992: function getMaxPointsTeam()
2993: {
2994: return $this->execute(ucfirst(__FUNCTION__));
2995: }
2996:
2997: /**
2998: * Set if new rules are used for team mode.
2999: * Requires a map restart to be taken into account.
3000: * @param bool $useNewRulesTeam
3001: * @param bool $multicall
3002: * @throws InvalidArgumentException
3003: * @return bool
3004: */
3005: function setUseNewRulesTeam($useNewRulesTeam, $multicall = false)
3006: {
3007: if(!is_bool($useNewRulesTeam))
3008: {
3009: throw new InvalidArgumentException('useNewRulesTeam = '.print_r($useNewRulesTeam, true));
3010: }
3011:
3012: return $this->execute(ucfirst(__FUNCTION__), array($useNewRulesTeam), $multicall);
3013: }
3014:
3015: /**
3016: * Get if the new rules are used for team mode (Current and next values).
3017: * The struct returned contains two fields CurrentValue and NextValue.
3018: * @return array
3019: */
3020: function getUseNewRulesTeam()
3021: {
3022: return $this->execute(ucfirst(__FUNCTION__));
3023: }
3024:
3025: /**
3026: * Set the points needed for victory in Cup mode.
3027: * Requires a map restart to be taken into account.
3028: * @param int $pointsLimit
3029: * @param bool $multicall
3030: * @throws InvalidArgumentException
3031: * @return bool
3032: */
3033: function setCupPointsLimit($pointsLimit, $multicall = false)
3034: {
3035: if(!is_int($pointsLimit))
3036: {
3037: throw new InvalidArgumentException('pointsLimit = '.print_r($pointsLimit, true));
3038: }
3039:
3040: return $this->execute(ucfirst(__FUNCTION__), array($pointsLimit), $multicall);
3041: }
3042:
3043: /**
3044: * Get the points needed for victory in Cup mode.
3045: * The struct returned contains two fields CurrentValue and NextValue.
3046: * @return array
3047: */
3048: function getCupPointsLimit()
3049: {
3050: return $this->execute(ucfirst(__FUNCTION__));
3051: }
3052:
3053: /**
3054: * Sets the number of rounds before going to next map in Cup mode.
3055: * Requires a map restart to be taken into account.
3056: * @param int $roundsPerMap
3057: * @param bool $multicall
3058: * @throws InvalidArgumentException
3059: * @return bool
3060: */
3061: function setCupRoundsPerMap($roundsPerMap, $multicall = false)
3062: {
3063: if(!is_int($roundsPerMap))
3064: {
3065: throw new InvalidArgumentException('roundsPerMap = '.print_r($roundsPerMap, true));
3066: }
3067:
3068: return $this->execute(ucfirst(__FUNCTION__), array($roundsPerMap), $multicall);
3069: }
3070:
3071: /**
3072: * Get the number of rounds before going to next map in Cup mode.
3073: * The struct returned contains two fields CurrentValue and NextValue.
3074: * @param bool $multicall
3075: * @return array
3076: */
3077: function getCupRoundsPerMap()
3078: {
3079: return $this->execute(ucfirst(__FUNCTION__));
3080: }
3081:
3082: /**
3083: * Set whether to enable the automatic warm-up phase in Cup mode.
3084: * 0 = no, otherwise it's the duration of the phase, expressed in number of rounds.
3085: * Requires a map restart to be taken into account.
3086: * @param int $warmUpDuration
3087: * @param bool $multicall
3088: * @throws InvalidArgumentException
3089: * @return bool
3090: */
3091: function setCupWarmUpDuration($warmUpDuration, $multicall = false)
3092: {
3093: if(!is_int($warmUpDuration))
3094: {
3095: throw new InvalidArgumentException('warmUpDuration = '.print_r($warmUpDuration, true));
3096: }
3097:
3098: return $this->execute(ucfirst(__FUNCTION__), array($warmUpDuration), $multicall);
3099: }
3100:
3101: /**
3102: * Get whether the automatic warm-up phase is enabled in Cup mode.
3103: * The struct returned contains two fields CurrentValue and NextValue.
3104: * @return array
3105: */
3106: function getCupWarmUpDuration()
3107: {
3108: return $this->execute(ucfirst(__FUNCTION__));
3109: }
3110:
3111: /**
3112: * Set the number of winners to determine before the match is considered over.
3113: * Requires a map restart to be taken into account.
3114: * @param int $nbWinners
3115: * @param bool $multicall
3116: * @throws InvalidArgumentException
3117: * @return bool
3118: */
3119: function setCupNbWinners($nbWinners, $multicall = false)
3120: {
3121: if(!is_int($nbWinners))
3122: {
3123: throw new InvalidArgumentException('nbWinners = '.print_r($nbWinners, true));
3124: }
3125:
3126: return $this->execute(ucfirst(__FUNCTION__), array($nbWinners), $multicall);
3127: }
3128:
3129: /**
3130: * Get the number of winners to determine before the match is considered over.
3131: * The struct returned contains two fields CurrentValue and NextValue.
3132: * @return array
3133: */
3134: function getCupNbWinners()
3135: {
3136: return $this->execute(ucfirst(__FUNCTION__));
3137: }
3138:
3139: /**
3140: * Returns the current map index in the selection, or -1 if the map is no longer in the selection.
3141: * @return int
3142: */
3143: function getCurrentMapIndex()
3144: {
3145: return $this->execute(ucfirst(__FUNCTION__));
3146: }
3147:
3148: /**
3149: * Returns the map index in the selection that will be played next (unless the current one is restarted...)
3150: * @return int
3151: */
3152: function getNextMapIndex()
3153: {
3154: return $this->execute(ucfirst(__FUNCTION__));
3155: }
3156:
3157: /**
3158: * Sets the map index in the selection that will be played next (unless the current one is restarted...)
3159: * @param int $nextMapIndex
3160: * @param bool $multicall
3161: * @throws InvalidArgumentException
3162: * @return bool
3163: */
3164: function setNextMapIndex($nextMapIndex, $multicall = false)
3165: {
3166: if(!is_int($nextMapIndex))
3167: {
3168: throw new InvalidArgumentException('nextMapIndex = '.print_r($nextMapIndex, true));
3169: }
3170:
3171: return $this->execute(ucfirst(__FUNCTION__), array($nextMapIndex), $multicall);
3172: }
3173:
3174: /**
3175: * Immediately jumps to the map designated by the index in the selection
3176: * @param int $nextMapIndex
3177: * @param bool $multicall
3178: * @throws InvalidArgumentException
3179: * @return bool
3180: */
3181: function jumpToMapIndex($mapIndex, $multicall = false)
3182: {
3183: if(!is_int($mapIndex))
3184: {
3185: throw new InvalidArgumentException('mapIndex = '.print_r($mapIndex, true));
3186: }
3187:
3188: return $this->execute(ucfirst(__FUNCTION__), array($mapIndex), $multicall);
3189: }
3190:
3191: /**
3192: * Set Team names and colors. Only available to Admin.
3193: * @param string $teamName1
3194: * @param float $teamColor1
3195: * @param string $team1Country
3196: * @param string $teamName2
3197: * @param float $teamColor2
3198: * @param string $team2Country
3199: * @param bool $multicall
3200: * @return bool
3201: * @throws InvalidArgumentException
3202: */
3203: function setTeamInfo($teamName1, $teamColor1, $team1Country, $teamName2, $teamColor2, $team2Country, $multicall = false)
3204: {
3205: if(!is_float($teamColor1))
3206: {
3207: throw new InvalidArgumentException('teamColor1 = '.print_r($teamColor1, true));
3208: }
3209: if(!is_float($teamColor2))
3210: {
3211: throw new InvalidArgumentException('teamColor2 = '.print_r($teamColor2, true));
3212: }
3213: if(!is_string($teamName1))
3214: {
3215: throw new InvalidArgumentException('teamName1 = '.print_r($teamName1, true));
3216: }
3217: if(!is_string($teamName2))
3218: {
3219: throw new InvalidArgumentException('teamName2 = '.print_r($teamName2, true));
3220: }
3221: return $this->execute(ucfirst(__FUNCTION__),
3222: array('unused', 0., 'World', $teamName1, $teamColor1, $team1Country, $teamName2, $teamColor2, $team2Country),
3223: $multicall);
3224: }
3225:
3226: /**
3227: * Disable player horns. Only available to Admin.
3228: * @param bool $disable
3229: * @param bool $multicall
3230: * @return bool
3231: * @throws InvalidArgumentException
3232: */
3233: function disableHorns($disable, $multicall = false)
3234: {
3235: if(!is_bool($disable))
3236: {
3237: throw new InvalidArgumentException('disable = '.print_r($disable, true));
3238: }
3239:
3240: return $this->execute(ucfirst(__FUNCTION__), array($disable), $multicall);
3241: }
3242:
3243: /**
3244: * Returns whether the horns are disabled.
3245: * @return bool
3246: */
3247: function areHornsDisabled()
3248: {
3249: return $this->execute(ucfirst(__FUNCTION__));
3250: }
3251:
3252: /**
3253: * Returns a struct containing the infos for the current map.
3254: * The struct contains the following fields : Name, UId, FileName,
3255: * Author, Environnement, Mood, BronzeTime, SilverTime, GoldTime,
3256: * AuthorTime, CopperPrice, LapRace, NbLaps and NbCheckpoints.
3257: * @return Structures\Map
3258: */
3259: function getCurrentMapInfo()
3260: {
3261: return Structures\Map::fromArray($this->execute(ucfirst(__FUNCTION__)));
3262: }
3263:
3264: /**
3265: * Returns a struct containing the infos for the next map.
3266: * The struct contains the following fields : Name, UId, FileName,
3267: * Author, Environnement, Mood, BronzeTime, SilverTime, GoldTime,
3268: * AuthorTime, CopperPrice, LapRace, NbLaps and NbCheckpoints.
3269: * (NbLaps and NbCheckpoints are also present but always set to -1)
3270: * @return Structures\Map
3271: */
3272: function getNextMapInfo()
3273: {
3274: return Structures\Map::fromArray($this->execute(ucfirst(__FUNCTION__)));
3275: }
3276:
3277: /**
3278: * Returns a struct containing the infos for the map with the specified filename.
3279: * The struct contains the following fields : Name, UId, FileName,
3280: * Author, Environnement, Mood, BronzeTime, SilverTime, GoldTime,
3281: * AuthorTime, CopperPrice, LapRace, NbLaps and NbCheckpoints.
3282: * (NbLaps and NbCheckpoints are also present but always set to -1)
3283: * @param string $filename
3284: * @return Structures\Map
3285: * @throws InvalidArgumentException
3286: */
3287: function getMapInfo($filename)
3288: {
3289: if(!is_string($filename))
3290: {
3291: throw new InvalidArgumentException('filename = '.print_r($filename, true));
3292: }
3293:
3294: $temp = $this->execute(ucfirst(__FUNCTION__), array($filename));
3295: return Structures\Map::fromArray($temp);
3296: }
3297:
3298: /**
3299: * Returns a boolean if the map with the specified filename matches the current server settings.
3300: * @param string $filename
3301: * @return bool
3302: */
3303: function checkMapForCurrentServerParams($filename)
3304: {
3305: if(!is_string($filename))
3306: {
3307: throw new InvalidArgumentException('filename = '.print_r($filename, true));
3308: }
3309:
3310: return $this->execute(ucfirst(__FUNCTION__), array($filename));
3311: }
3312:
3313: /**
3314: * Returns a list of maps among the current selection of the server.
3315: * This method take two parameters.
3316: * The first parameter specifies the maximum number of infos to be returned,
3317: * the second one the starting index in the selection.
3318: * The list is an array of structures. Each structure contains the following fields : Name, UId, FileName, Environnement, Author, GoldTime and CopperPrice.
3319: * @param int $length specifies the maximum number of infos to be returned
3320: * @param int $offset specifies the starting index in the list
3321: * @return Structures\Map[] The list is an array of Map
3322: * @throws InvalidArgumentException
3323: */
3324: function getMapList($length, $offset)
3325: {
3326: if(!is_int($length))
3327: {
3328: throw new InvalidArgumentException('length = '.print_r($length, true));
3329: }
3330: if(!is_int($offset))
3331: {
3332: throw new InvalidArgumentException('offset = '.print_r($offset, true));
3333: }
3334:
3335: return Structures\Map::fromArrayOfArray($this->execute(ucfirst(__FUNCTION__), array($length, $offset)));
3336: }
3337:
3338: /**
3339: * Add the map with the specified filename at the end of the current selection.
3340: * @param string $filename
3341: * @param bool $multicall
3342: * @throws InvalidArgumentException
3343: * @return bool
3344: */
3345: function addMap($filename, $multicall = false)
3346: {
3347: if(!is_string($filename))
3348: {
3349: throw new InvalidArgumentException('filename = '.print_r($filename, true));
3350: }
3351:
3352: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
3353: }
3354:
3355: /**
3356: * Add the list of maps with the specified filename at the end of the current selection.
3357: * @param array $filenames
3358: * @param bool $multicall
3359: * @throws InvalidArgumentException
3360: * @return int
3361: */
3362: function addMapList(array $filenames, $multicall = false)
3363: {
3364: if(!is_array($filenames))
3365: {
3366: throw new InvalidArgumentException('filenames = '.print_r($filenames, true));
3367: }
3368:
3369: return $this->execute(ucfirst(__FUNCTION__), array($filenames), $multicall);
3370: }
3371:
3372: /**
3373: * Remove the map with the specified filename from the current selection.
3374: * @param string $filename
3375: * @param bool $multicall
3376: * @throws InvalidArgumentException
3377: * @return bool
3378: */
3379: function removeMap($filename, $multicall = false)
3380: {
3381: if(!is_string($filename))
3382: {
3383: throw new InvalidArgumentException('filename = '.print_r($filename, true));
3384: }
3385:
3386: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
3387: }
3388:
3389: /**
3390: * Remove the list of maps with the specified filenames from the current selection.
3391: * The list of maps to remove is an array of strings.
3392: * @param array $filenames
3393: * @param bool $multicall
3394: * @throws InvalidArgumentException
3395: * @return int
3396: */
3397: function removeMapList(array $filenames, $multicall = false)
3398: {
3399: if(!is_array($filenames))
3400: {
3401: throw new InvalidArgumentException('filenames = '.print_r($filenames, true));
3402: }
3403:
3404: return $this->execute(ucfirst(__FUNCTION__), array($filenames), $multicall);
3405: }
3406:
3407: /**
3408: * Insert the map with the specified filename after the current map.
3409: * @param string $filename
3410: * @throws InvalidArgumentException
3411: * @return bool
3412: */
3413: function insertMap($filename, $multicall = false)
3414: {
3415: if(!is_string($filename))
3416: {
3417: throw new InvalidArgumentException('filename = '.print_r($filename, true));
3418: }
3419:
3420: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
3421: }
3422:
3423: /**
3424: * Insert the list of maps with the specified filenames after the current map.
3425: * The list of maps to remove is an array of strings.
3426: * @param array $filenames
3427: * @throws InvalidArgumentException
3428: * @return int
3429: */
3430: function insertMapList(array $filenames, $multicall = false)
3431: {
3432: if(!is_array($filenames))
3433: {
3434: throw new InvalidArgumentException('filenames = '.print_r($filenames, true));
3435: }
3436:
3437: return $this->execute(ucfirst(__FUNCTION__), array($filenames), $multicall);
3438: }
3439:
3440: /**
3441: * Set as next map the one with the specified filename, if it is present in the selection.
3442: * @param string $filename
3443: * @param bool $multicall
3444: * @throws InvalidArgumentException
3445: * @return bool
3446: */
3447: function chooseNextMap($filename, $multicall = false)
3448: {
3449: if(!is_string($filename))
3450: {
3451: throw new InvalidArgumentException('filename = '.print_r($filename, true));
3452: }
3453:
3454: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
3455: }
3456:
3457: /**
3458: * Set as next maps the list of maps with the specified filenames, if they are present in the selection.
3459: * The list of maps to remove is an array of strings.
3460: * @param array $filenames
3461: * @param bool $multicall
3462: * @throws InvalidArgumentException
3463: * @return int
3464: */
3465: function chooseNextMapList(array $filenames, $multicall = false)
3466: {
3467: if(!is_array($filenames))
3468: {
3469: throw new InvalidArgumentException('filenames = '.print_r($filenames, true));
3470: }
3471:
3472: return $this->execute(ucfirst(__FUNCTION__), array($filenames), $multicall);
3473: }
3474:
3475: /**
3476: * Set a list of maps defined in the playlist with the specified filename
3477: * as the current selection of the server, and load the gameinfos from the same file.
3478: * @param string $filename
3479: * @throws InvalidArgumentException
3480: * @return int
3481: */
3482: function loadMatchSettings($filename, $multicall = false)
3483: {
3484: if(!is_string($filename))
3485: {
3486: throw new InvalidArgumentException('filename = '.print_r($filename, true));
3487: }
3488:
3489: return $this->execute(ucfirst(__FUNCTION__), array($filename));
3490: }
3491:
3492: /**
3493: * Add a list of maps defined in the playlist with the specified filename at the end of the current selection.
3494: * @param string $filename
3495: * @throws InvalidArgumentException
3496: * @return int
3497: */
3498: function appendPlaylistFromMatchSettings($filename, $multicall = false)
3499: {
3500: if(!is_string($filename))
3501: {
3502: throw new InvalidArgumentException('filename = '.print_r($filename, true));
3503: }
3504:
3505: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
3506: }
3507:
3508: /**
3509: * Save the current selection of map in the playlist with the specified filename, as well as the current gameinfos.
3510: * @param string $filename
3511: * @param bool $multicall
3512: * @throws InvalidArgumentException
3513: * @return int
3514: */
3515: function saveMatchSettings($filename, $multicall = false)
3516: {
3517: if(!is_string($filename))
3518: {
3519: throw new InvalidArgumentException('filename = '.print_r($filename, true));
3520: }
3521:
3522: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
3523: }
3524:
3525: /**
3526: * Insert a list of maps defined in the playlist with the specified filename after the current map.
3527: * @param string $filename
3528: * @throws InvalidArgumentException
3529: * @return int
3530: */
3531: function insertPlaylistFromMatchSettings($filename, $multicall = false)
3532: {
3533: if(!is_string($filename))
3534: {
3535: throw new InvalidArgumentException('filename = '.print_r($filename, true));
3536: }
3537:
3538: return $this->execute(ucfirst(__FUNCTION__), array($filename), $multicall);
3539: }
3540:
3541: /**
3542: * Returns the list of players on the server. This method take two parameters.
3543: * The first parameter specifies the maximum number of infos to be returned,
3544: * the second one the starting index in the list,
3545: * an optional 3rd parameter is used for compatibility: struct version (0 = united, 1 = forever, 2 = forever, including the servers).
3546: * The list is an array of Structures\Player.
3547: * LadderRanking is 0 when not in official mode,
3548: * Flags = ForceSpectator(0,1,2) + IsReferee * 10 + IsPodiumReady * 100 + IsUsingStereoscopy * 1000 +
3549: * IsManagedByAnOtherServer * 10000 + IsServer * 100000 + HasPlayerSlot * 1000000
3550: * SpectatorStatus = Spectator + TemporarySpectator * 10 + PureSpectator * 100 + AutoTarget * 1000 + CurrentTargetId * 10000
3551: * @param int $length specifies the maximum number of infos to be returned
3552: * @param int $offset specifies the starting index in the list
3553: * @param int $compatibility
3554: * @return Structures\Player[] The list is an array of Structures\Player
3555: * @throws InvalidArgumentException
3556: */
3557: function getPlayerList($length, $offset, $compatibility = 1)
3558: {
3559: if(!is_int($length))
3560: {
3561: throw new InvalidArgumentException('length = '.print_r($length, true));
3562: }
3563: if(!is_int($offset))
3564: {
3565: throw new InvalidArgumentException('offset = '.print_r($offset, true));
3566: }
3567: if(!is_int($compatibility))
3568: {
3569: throw new InvalidArgumentException('compatibility = '.print_r($compatibility, true));
3570: }
3571:
3572: return Structures\Player::fromArrayOfArray($this->execute(ucfirst(__FUNCTION__), array($length, $offset, $compatibility)));
3573: }
3574:
3575: /**
3576: * Returns a object of type Structures\Player containing the infos on the player with the specified login,
3577: * with an optional parameter for compatibility: struct version (0 = united, 1 = forever).
3578: * The structure is identical to the ones from GetPlayerList. Forever PlayerInfo struct is:
3579: * Login, NickName, PlayerId, TeamId, SpectatorStatus, LadderRanking, and Flags.
3580: * LadderRanking is 0 when not in official mode,
3581: * Flags = ForceSpectator(0,1,2) + IsReferee * 10 + IsPodiumReady * 100 + IsUsingStereoscopy * 1000 +
3582: * IsManagedByAnOtherServer * 10000 + IsServer * 100000 + HasPlayerSlot * 1000000
3583: * SpectatorStatus = Spectator + TemporarySpectator * 10 + PureSpectator * 100 + AutoTarget * 1000 + CurrentTargetId * 10000
3584: * @param int $playerLogin
3585: * @param int $compatibility
3586: * @return Structures\Player
3587: * @throws InvalidArgumentException
3588: */
3589: function getPlayerInfo($playerLogin, $compatibility = 1)
3590: {
3591: if(!is_string($playerLogin))
3592: {
3593: throw new InvalidArgumentException('playerLogin = '.print_r($playerLogin, true));
3594: }
3595: if(!is_int($compatibility))
3596: {
3597: throw new InvalidArgumentException('compatibility = '.print_r($compatibility, true));
3598: }
3599:
3600: return Structures\Player::fromArray($this->execute(ucfirst(__FUNCTION__), array($playerLogin, $compatibility)));
3601: }
3602:
3603: /**
3604: * Returns an object of type Structures\Player containing the infos on the player with the specified login.
3605: * The structure contains the following fields :
3606: * Login, NickName, PlayerId, TeamId, IPAddress, DownloadRate, UploadRate, Language, IsSpectator,
3607: * IsInOfficialMode, a structure named Avatar, an array of structures named Skins, a structure named LadderStats,
3608: * HoursSinceZoneInscription and OnlineRights (0: nations account, 3: united account).
3609: * Each structure of the array Skins contains two fields Environnement and a struct PackDesc.
3610: * Each structure PackDesc, as well as the struct Avatar, contains two fields FileName and Checksum.
3611: * @param int $playerLogin
3612: * @return Structures\Player
3613: * @throws InvalidArgumentException
3614: */
3615: function getDetailedPlayerInfo($playerLogin)
3616: {
3617: if(!is_string($playerLogin))
3618: {
3619: throw new InvalidArgumentException('playerLogin = '.print_r($playerLogin, true));
3620: }
3621:
3622: return Structures\Player::fromArray($this->execute(ucfirst(__FUNCTION__), array($playerLogin)));
3623: }
3624:
3625: /**
3626: * Returns an object of Structures\Player type containing the infos on the player with the specified login.
3627: * The structure contains the following fields : Login, NickName, PlayerId, TeamId, IPAddress, DownloadRate, UploadRate,
3628: * Language, IsSpectator, IsInOfficialMode, a structure named Avatar, an array of structures named Skins, a structure named LadderStats,
3629: * HoursSinceZoneInscription and OnlineRights (0: nations account, 3: united account).
3630: * Each structure of the array Skins contains two fields Environnement and a struct PackDesc.
3631: * Each structure PackDesc, as well as the struct Avatar, contains two fields FileName and Checksum.
3632: * @param int $compatibility
3633: * @return Structures\Player
3634: * @throws InvalidArgumentException
3635: */
3636: function getMainServerPlayerInfo($compatibility = 1)
3637: {
3638: if(!is_int($compatibility))
3639: {
3640: throw new InvalidArgumentException('compatibility = '.print_r($compatibility, true));
3641: }
3642:
3643: return Structures\Player::fromArray($this->execute(ucfirst(__FUNCTION__), array($compatibility)));
3644: }
3645:
3646: /**
3647: * Returns the current rankings for the race in progress.
3648: * (in team mode, the scores for the two teams are returned.
3649: * In other modes, it's the individual players' scores) This method take two parameters.
3650: * The first parameter specifies the maximum number of infos to be returned,
3651: * the second one the starting index in the ranking.
3652: * The ranking returned is a list of Structures\Player.
3653: * It also contains an array BestCheckpoints that contains the checkpoint times for the best race.
3654: * @param int $length specifies the maximum number of infos to be returned
3655: * @param int $offset specifies the starting index in the list
3656: * @return Structures\Player[] The list is an array of Structures\Player.
3657: * @throws InvalidArgumentException
3658: */
3659: function getCurrentRanking($length, $offset)
3660: {
3661: if(!is_int($length))
3662: {
3663: throw new InvalidArgumentException('length = '.print_r($length, true));
3664: }
3665: if(!is_int($offset))
3666: {
3667: throw new InvalidArgumentException('offset = '.print_r($offset, true));
3668: }
3669:
3670: return Structures\Player::fromArrayOfArray($this->execute(ucfirst(__FUNCTION__), array($length, $offset)));
3671: }
3672:
3673: /**
3674: * Returns the current ranking for the race in progressof the player with the specified login (or list of comma-separated logins).
3675: * The ranking returned is a list of structures that contains the following fields :
3676: * Login, NickName, PlayerId, Rank, BestTime, Score, NbrLapsFinished and LadderScore.
3677: * It also contains an array BestCheckpoints that contains the checkpoint times for the best race.
3678: * @param Structures\Player|Structures\Player[] $player
3679: * @throws InvalidArgumentException
3680: * @return Structures\Player[] The list is an array of Structures\Player.
3681: */
3682: function getCurrentRankingForLogin($player = null)
3683: {
3684: $login = $this->getLogin($player) ? : '';
3685:
3686: return Structures\Player::fromArrayOfArray($this->execute(ucfirst(__FUNCTION__), array($login)));
3687: }
3688:
3689: /**
3690: * Returns the current winning team for the race in progress. (-1: if not in team mode, or draw match)
3691: * @return int -1, 0 or 1
3692: */
3693: function getCurrentWinnerTeam()
3694: {
3695: return $this->execute(ucfirst(__FUNCTION__));
3696: }
3697:
3698: /**
3699: * Force the scores of the current game. Only available in rounds and team mode.
3700: * You have to pass an array of structs {int PlayerId, int Score}. And a boolean SilentMode -
3701: * if true, the scores are silently updated (only available for SuperAdmin), allowing an external controller to do its custom counting...
3702: * @param array $scores
3703: * @param bool $multicall
3704: * @return bool
3705: * @throws InvalidArgumentException
3706: */
3707: function forceScores(array $scores, $silentMode = false, $multicall = false)
3708: {
3709: if(!is_array($scores))
3710: {
3711: throw new InvalidArgumentException('scores = '.print_r($scores, true));
3712: }
3713:
3714: for($i = 0; $i < count($scores); $i++)
3715: {
3716: if(!is_int($scores[$i]['PlayerId']))
3717: {
3718: throw new InvalidArgumentException('score['.$i.'][\'PlayerId\'] = '.print_r($scores[$i]['PlayerId'], true));
3719: }
3720: if(!is_int($scores[$i]['Score']))
3721: {
3722: throw new InvalidArgumentException('score['.$i.'][\'Score\'] = '.print_r($scores[$i]['Score'], true));
3723: }
3724: }
3725:
3726: return $this->execute(ucfirst(__FUNCTION__), array($scores, $silentMode), $multicall);
3727: }
3728:
3729: /**
3730: * Force the team of the player. Only available in team mode. You have to pass the login and the team number (0 or 1).
3731: * @param Structures\Player|string $player
3732: * @param int $teamNumber
3733: * @param bool $multicall
3734: * @return bool
3735: */
3736: function forcePlayerTeam($player, $teamNumber, $multicall = false)
3737: {
3738: if(!($login = $this->getLogin($player)))
3739: {
3740: throw new InvalidArgumentException('player must be set');
3741: }
3742: if($teamNumber !== 0 && $teamNumber !== 1)
3743: {
3744: throw new InvalidArgumentException('teamNumber = '.print_r($teamNumber, true));
3745: }
3746:
3747: return $this->execute('ForcePlayerTeam', array($login, $teamNumber), $multicall);
3748: }
3749:
3750: /**
3751: * Force the spectating status of the player. You have to pass the login and the spectator mode (0: user selectable, 1: spectator, 2: player).
3752: * @param Structures\Player|string $player
3753: * @param int $spectatorMode
3754: * @param bool $multicall
3755: * @return bool
3756: */
3757: function forceSpectator($player, $spectatorMode, $multicall = false)
3758: {
3759: if(!($login = $this->getLogin($player)))
3760: {
3761: throw new InvalidArgumentException('player must be set');
3762: }
3763: if($spectatorMode !== 0 && $spectatorMode !== 1 && $spectatorMode !== 2)
3764: {
3765: throw new InvalidArgumentException('spectatorMode = '.print_r($spectatorMode, true));
3766: }
3767:
3768: return $this->execute('ForceSpectator', array($login, $spectatorMode), $multicall);
3769: }
3770:
3771: /**
3772: * Force spectators to look at a specific player. You have to pass the login of the spectator (or '' for all) and
3773: * the login of the target (or '' for automatic), and an integer for the camera type to use (-1 = leave unchanged, 0 = replay, 1 = follow, 2 = free).
3774: * @param Structures\Player|string $player
3775: * @param Structures\Player|string $target
3776: * @param int $cameraType
3777: * @param bool $multicall
3778: * @return bool
3779: */
3780: function forceSpectatorTarget($player, $target, $cameraType, $multicall = false)
3781: {
3782: if(!($playerLogin = $this->getLogin($player)))
3783: {
3784: throw new InvalidArgumentException('player must be set');
3785: }
3786: if(!($targetLogin = $this->getLogin($target)))
3787: {
3788: throw new InvalidArgumentException('target must be set');
3789: }
3790: if($cameraType !== -1 && $cameraType !== 0 && $cameraType !== 1 && $cameraType !== 2)
3791: {
3792: throw new InvalidArgumentException('cameraType = '.print_r($cameraType, true));
3793: }
3794:
3795: return $this->execute('ForceSpectatorTarget', array($playerLogin, $targetLogin, $cameraType), $multicall);
3796: }
3797:
3798: /**
3799: * Pass the login of the spectator. A spectator that once was a player keeps his player slot, so that he can go back to race mode.
3800: * Calling this function frees this slot for another player to connect.
3801: * @param Structures\Player|string $player
3802: * @param bool $multicall
3803: * @return bool
3804: */
3805: function spectatorReleasePlayerSlot($player, $multicall = false)
3806: {
3807: if(!($login = $this->getLogin($player)))
3808: {
3809: throw new InvalidArgumentException('player must be set');
3810: }
3811: return $this->execute('SpectatorReleasePlayerSlot', array($login), $multicall);
3812: }
3813:
3814: /**
3815: * Enable control of the game flow: the game will wait for the caller to validate state transitions.
3816: * @param bool $flowControlEnable
3817: * @param bool $multicall
3818: * @return bool
3819: * @throws InvalidArgumentException
3820: */
3821: function manualFlowControlEnable($flowControlEnable, $multicall = false)
3822: {
3823: if(!is_bool($flowControlEnable))
3824: {
3825: throw new InvalidArgumentException('flowControlEnable = '.print_r($flowControlEnable, true));
3826: }
3827:
3828: return $this->execute(ucfirst(__FUNCTION__), array($flowControlEnable), $multicall);
3829: }
3830:
3831: /**
3832: * Allows the game to proceed.
3833: * @param bool $multicall
3834: * @return bool
3835: */
3836: function manualFlowControlProceed($multicall = false)
3837: {
3838: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
3839: }
3840:
3841: /**
3842: * Returns whether the manual control of the game flow is enabled. 0 = no, 1 = yes by the xml-rpc client making the call, 2 = yes, by some other xml-rpc client.
3843: * @return int
3844: */
3845: function manualFlowControlIsEnabled()
3846: {
3847: return $this->execute(ucfirst(__FUNCTION__));
3848: }
3849:
3850: /**
3851: * Returns the transition that is currently blocked, or '' if none. (That's exactly the value last received by the callback.)
3852: * @return string
3853: */
3854: function manualFlowControlGetCurTransition()
3855: {
3856: return $this->execute(ucfirst(__FUNCTION__));
3857: }
3858:
3859: /**
3860: * Returns the current match ending condition.
3861: * Return values are: 'Playing', 'ChangeMap' or 'Finished'.
3862: * @param bool $multicall
3863: * @return string
3864: */
3865: function checkEndMatchCondition()
3866: {
3867: return $this->execute(ucfirst(__FUNCTION__));
3868: }
3869:
3870: /**
3871: * Returns an object Structures\NetworkStats.
3872: * The structure contains the following fields : Uptime, NbrConnection, MeanConnectionTime, MeanNbrPlayer,
3873: * RecvNetRate, SendNetRate, TotalReceivingSize, TotalSendingSize and an array of structures named PlayerNetInfos.
3874: * Each structure of the array PlayerNetInfos is a Structures\Player object contains the following fields : Login, IPAddress, LastTransferTime, DeltaBetweenTwoLastNetState, PacketLossRate.
3875: * @return Structures\NetworkStats
3876: */
3877: function getNetworkStats()
3878: {
3879: return Structures\NetworkStats::fromArray($this->execute(ucfirst(__FUNCTION__)));
3880: }
3881:
3882: /**
3883: * Start a server on lan, using the current configuration.
3884: * @param bool $multicall
3885: * @return bool
3886: */
3887: function startServerLan($multicall = false)
3888: {
3889: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
3890: }
3891:
3892: /**
3893: * Start a server on internet using the 'Login' and 'Password' specified in the struct passed as parameters.
3894: * @param array $ids
3895: * @param bool $multicall
3896: * @return bool
3897: * @throws InvalidArgumentException
3898: */
3899: function startServerInternet($multicall = false)
3900: {
3901: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
3902: }
3903:
3904: /**
3905: * Returns the current status of the server.
3906: * @return Structures\Status
3907: */
3908: function getStatus()
3909: {
3910: return Structures\Status::fromArray($this->execute(ucfirst(__FUNCTION__)));
3911: }
3912:
3913: /**
3914: * Quit the application.
3915: * @param bool $multicall
3916: * @return bool
3917: */
3918: function quitGame($multicall = false)
3919: {
3920: return $this->execute(ucfirst(__FUNCTION__), array(), $multicall);
3921: }
3922:
3923: /**
3924: * Returns the path of the game datas directory.
3925: * @return string
3926: */
3927: function gameDataDirectory()
3928: {
3929: return $this->execute(ucfirst(__FUNCTION__));
3930: }
3931:
3932: /**
3933: * Returns the path of the maps directory.
3934: * @return string
3935: */
3936: function getMapsDirectory()
3937: {
3938: return $this->execute(ucfirst(__FUNCTION__));
3939: }
3940:
3941: /**
3942: * Returns the path of the skins directory.
3943: * @return string
3944: */
3945: function getSkinsDirectory()
3946: {
3947: return $this->execute(ucfirst(__FUNCTION__));
3948: }
3949:
3950: /**
3951: * Returns the login of the given player
3952: * @param mixed $player Structures\Player or string
3953: * @return string
3954: */
3955: private function getLogin($player)
3956: {
3957: if(is_string($player)) return $player;
3958: if($player instanceof Structures\Player) return $player->login;
3959: return null;
3960: }
3961:
3962: /**
3963: * Returns logins of given players
3964: * @param mixed $player Structures\Player or string or array
3965: * @return string
3966: */
3967: private function getLogins($players)
3968: {
3969: if(is_array($players))
3970: {
3971: $logins = array();
3972: foreach($players as $player)
3973: {
3974: if(($login = $this->getLogin($player))) $logins[] = $login;
3975: else return null;
3976: }
3977:
3978: return implode(',', $logins);
3979: }
3980: return $this->getLogin($players);
3981: }
3982:
3983: }
3984:
3985: /**
3986: * Exception Dedicated to Query Error
3987: */
3988: class QueryException extends \Exception
3989: {
3990:
3991: }
3992:
3993: /**
3994: * Exception Dedicated to Connection Error
3995: */
3996: class ConnectionException extends \Exception
3997: {
3998:
3999: }
4000:
4001: /**
4002: * Exception Dedicated to Invalid Argument Error on Request Call
4003: */
4004: class InvalidArgumentException extends \Exception
4005: {
4006:
4007: }
4008:
4009: ?>
4010: