Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ARC often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ARC, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 15 | class ARC |
||
| 16 | { |
||
| 17 | /** |
||
| 18 | * @var array Options for ARC stored in an array |
||
| 19 | */ |
||
| 20 | private $options = [ |
||
| 21 | 'timeoutSec' => 1, |
||
| 22 | 'autosaveBans' => false, |
||
| 23 | 'sendHeartbeat' => false, |
||
| 24 | ]; |
||
| 25 | /** |
||
| 26 | * @var string Server IP of the BattlEye server |
||
| 27 | */ |
||
| 28 | private $serverIP; |
||
| 29 | /** |
||
| 30 | * @var int Specific port of the BattlEye server |
||
| 31 | */ |
||
| 32 | private $serverPort; |
||
| 33 | /** |
||
| 34 | * @var string Required password for authenticating |
||
| 35 | */ |
||
| 36 | private $rconPassword; |
||
| 37 | /** |
||
| 38 | * @var resource Socket for sending commands |
||
| 39 | */ |
||
| 40 | private $socket; |
||
| 41 | /** |
||
| 42 | * @var bool Status of the connection |
||
| 43 | */ |
||
| 44 | private $disconnected = true; |
||
| 45 | /** |
||
| 46 | * @var string Head of the message, which was sent to the server |
||
| 47 | */ |
||
| 48 | private $head; |
||
| 49 | /** |
||
| 50 | * Class constructor |
||
| 51 | * |
||
| 52 | * @param string $serverIP IP of the Arma server |
||
| 53 | * @param integer $serverPort Port of the Arma server |
||
| 54 | * @param string $RConPassword RCon password required by BattlEye |
||
| 55 | * @param array $options Options array of ARC |
||
| 56 | * |
||
| 57 | * @throws \Exception if wrong parameter types were passed to the function |
||
| 58 | */ |
||
| 59 | public function __construct($serverIP, $RConPassword, $serverPort = 2302, array $options = array()) |
||
| 72 | /** |
||
| 73 | * Class destructor |
||
| 74 | */ |
||
| 75 | public function __destruct() |
||
| 79 | /** |
||
| 80 | * Closes the connection |
||
| 81 | */ |
||
| 82 | public function disconnect() |
||
| 91 | /** |
||
| 92 | * Creates a connection to the server |
||
| 93 | * |
||
| 94 | * @throws \Exception if creating the socket fails |
||
| 95 | */ |
||
| 96 | private function connect() |
||
| 110 | /** |
||
| 111 | * Closes the current connection and creates a new one |
||
| 112 | */ |
||
| 113 | public function reconnect() |
||
| 121 | /** |
||
| 122 | * Checks if ARC's option array contains any deprecated options |
||
| 123 | */ |
||
| 124 | private function checkForDeprecatedOptions() |
||
| 134 | /** |
||
| 135 | * Validate all option types |
||
| 136 | */ |
||
| 137 | private function checkOptionTypes() |
||
| 155 | /** |
||
| 156 | * Sends the login data to the server in order to send commands later |
||
| 157 | * |
||
| 158 | * @throws \Exception if login fails (due to a wrong password or port) |
||
| 159 | */ |
||
| 160 | private function authorize() |
||
| 171 | /** |
||
| 172 | * Receives the answer form the server |
||
| 173 | * |
||
| 174 | * @return string Any answer from the server, except the log-in message |
||
| 175 | */ |
||
| 176 | protected function getResponse() |
||
| 192 | /** |
||
| 193 | * The heart of this class - this function actually sends the RCon command |
||
| 194 | * |
||
| 195 | * @param string $command The command sent to the server |
||
| 196 | * |
||
| 197 | * @throws \Exception if the connection is closed |
||
| 198 | * @throws \Exception if sending the command failed |
||
| 199 | * |
||
| 200 | * @return bool Whether sending the command was successful or not |
||
| 201 | */ |
||
| 202 | protected function send($command) |
||
| 215 | /** |
||
| 216 | * Writes the given message to the socket |
||
| 217 | * |
||
| 218 | * @param string $message Message which will be written to the socket |
||
| 219 | * |
||
| 220 | * @return int |
||
| 221 | */ |
||
| 222 | private function writeToSocket($message) |
||
| 226 | /** |
||
| 227 | * Generates the password's CRC32 data |
||
| 228 | * |
||
| 229 | * @return string |
||
| 230 | */ |
||
| 231 | private function getAuthCRC() |
||
| 237 | /** |
||
| 238 | * Generates the message's CRC32 data |
||
| 239 | * |
||
| 240 | * @param string $command The message which will be prepared for being sent to the server |
||
| 241 | * |
||
| 242 | * @return string Message which can be sent to the server |
||
| 243 | */ |
||
| 244 | private function getMsgCRC($command) |
||
| 250 | /** |
||
| 251 | * Generates the login message |
||
| 252 | * |
||
| 253 | * @return string The message for authenticating in, containing the RCon password |
||
| 254 | */ |
||
| 255 | private function getLoginMessage() |
||
| 262 | /** |
||
| 263 | * Returns the socket used by ARC, might be null if connection is closed |
||
| 264 | * |
||
| 265 | * @return resource |
||
| 266 | */ |
||
| 267 | public function getSocket() |
||
| 271 | /** |
||
| 272 | * Sends a custom command to the server |
||
| 273 | * |
||
| 274 | * @param string $command Command which will be sent to the server |
||
| 275 | * |
||
| 276 | * @throws \Exception if wrong parameter types were passed to the function |
||
| 277 | * |
||
| 278 | * @return string Response from the server |
||
| 279 | */ |
||
| 280 | public function command($command) |
||
| 288 | /** |
||
| 289 | * Executes multiple commands |
||
| 290 | * |
||
| 291 | * @param array $commands Commands to be executed |
||
| 292 | */ |
||
| 293 | public function commands(array $commands) |
||
| 302 | /** |
||
| 303 | * Kicks a player who is currently on the server |
||
| 304 | * |
||
| 305 | * @param string $reason Message displayed why the player is kicked |
||
| 306 | * @param integer $player The player who should be kicked |
||
| 307 | * @throws \Exception if wrong parameter types were passed to the function |
||
| 308 | * |
||
| 309 | * @return ARC |
||
| 310 | */ |
||
| 311 | public function kickPlayer($player, $reason = 'Admin Kick') |
||
| 327 | /** |
||
| 328 | * Sends a global message to all players |
||
| 329 | * |
||
| 330 | * @param string $message The message which will be shown to all players |
||
| 331 | * @throws \Exception if wrong parameter types were passed to the function |
||
| 332 | * |
||
| 333 | * @return ARC |
||
| 334 | */ |
||
| 335 | public function sayGlobal($message) |
||
| 345 | /** |
||
| 346 | * Sends a message to a specific player |
||
| 347 | * |
||
| 348 | * @param integer $player Player who will be sent the message to |
||
| 349 | * @param string $message Message for the player |
||
| 350 | * @throws \Exception if wrong parameter types were passed to the function |
||
| 351 | * |
||
| 352 | * @return ARC |
||
| 353 | */ |
||
| 354 | public function sayPlayer($player, $message) |
||
| 362 | /** |
||
| 363 | * Loads the "scripts.txt" file without the need to restart the server |
||
| 364 | * |
||
| 365 | * @return ARC |
||
| 366 | */ |
||
| 367 | public function loadScripts() |
||
| 372 | /** |
||
| 373 | * Changes the MaxPing value. If a player has a higher ping, he will be kicked from the server |
||
| 374 | * |
||
| 375 | * @param integer $ping The value for the 'MaxPing' BattlEye server setting |
||
| 376 | * |
||
| 377 | * @throws \Exception if wrong parameter types were passed to the function |
||
| 378 | * |
||
| 379 | * @return ARC |
||
| 380 | */ |
||
| 381 | public function maxPing($ping) |
||
| 391 | /** |
||
| 392 | * Changes the RCon password |
||
| 393 | * |
||
| 394 | * @param string $password The new password |
||
| 395 | * |
||
| 396 | * @throws \Exception if wrong parameter types were passed to the function |
||
| 397 | * |
||
| 398 | * @return ARC |
||
| 399 | */ |
||
| 400 | public function changePassword($password) |
||
| 410 | /** |
||
| 411 | * (Re)load the BE ban list from bans.txt |
||
| 412 | * |
||
| 413 | * @return ARC |
||
| 414 | */ |
||
| 415 | public function loadBans() |
||
| 420 | /** |
||
| 421 | * Gets a list of all players currently on the server |
||
| 422 | * |
||
| 423 | * @return string The list of all players on the server |
||
| 424 | */ |
||
| 425 | public function getPlayers() |
||
| 433 | /** |
||
| 434 | * Gets a list of all players currently on the server as an array |
||
| 435 | * |
||
| 436 | * @author nerdalertdk (https://github.com/nerdalertdk) |
||
| 437 | * @link https://github.com/Nizarii/arma-rcon-class-php/issues/4 The related GitHub Issue |
||
| 438 | * |
||
| 439 | * @throws \Exception if sending the command failed |
||
| 440 | * |
||
| 441 | * @return array The array containing all players being currently on the server |
||
| 442 | */ |
||
| 443 | public function getPlayersArray() |
||
| 451 | /** |
||
| 452 | * Gets a list of all bans |
||
| 453 | * |
||
| 454 | * @throws \Exception if sending the command failed |
||
| 455 | * |
||
| 456 | * @return string List containing the missions |
||
| 457 | */ |
||
| 458 | public function getMissions() |
||
| 463 | /** |
||
| 464 | * Ban a player's BE GUID from the server. If time is not specified or 0, the ban will be permanent;. |
||
| 465 | * If reason is not specified the player will be kicked with the message "Banned". |
||
| 466 | * |
||
| 467 | * @param integer $player Player who will be banned |
||
| 468 | * @param string $reason Reason why the player is banned |
||
| 469 | * @param integer $time How long the player is banned in minutes (0 = permanent) |
||
| 470 | * @throws \Exception if wrong parameter types were passed to the function |
||
| 471 | * |
||
| 472 | * @return ARC |
||
| 473 | */ |
||
| 474 | public function banPlayer($player, $reason = 'Banned', $time = 0) |
||
| 492 | /** |
||
| 493 | * Same as "banPlayer", but allows to ban a player that is not currently on the server |
||
| 494 | * |
||
| 495 | * @param integer $player Player who will be banned |
||
| 496 | * @param string $reason Reason why the player is banned |
||
| 497 | * @param integer $time How long the player is banned in minutes (0 = permanent) |
||
| 498 | * |
||
| 499 | * @throws \Exception if wrong parameter types were passed to the function |
||
| 500 | * |
||
| 501 | * @return ARC |
||
| 502 | */ |
||
| 503 | public function addBan($player, $reason = 'Banned', $time = 0) |
||
| 516 | /** |
||
| 517 | * Removes a ban |
||
| 518 | * |
||
| 519 | * @param integer $banId Ban who will be removed |
||
| 520 | * |
||
| 521 | * @throws \Exception if wrong parameter types were passed to the function |
||
| 522 | * |
||
| 523 | * @return ARC |
||
| 524 | */ |
||
| 525 | public function removeBan($banId) |
||
| 540 | /** |
||
| 541 | * Gets an array of all bans |
||
| 542 | * |
||
| 543 | * @author nerdalertdk (https://github.com/nerdalertdk) |
||
| 544 | * @link https://github.com/Nizarii/arma-rcon-class-php/issues/4 |
||
| 545 | * |
||
| 546 | * @return array The array containing all bans |
||
| 547 | */ |
||
| 548 | public function getBansArray() |
||
| 555 | /** |
||
| 556 | * Gets a list of all bans |
||
| 557 | * |
||
| 558 | * @return string The response from the server |
||
| 559 | */ |
||
| 560 | public function getBans() |
||
| 565 | /** |
||
| 566 | * Removes expired bans from bans file |
||
| 567 | * |
||
| 568 | * @return ARC |
||
| 569 | */ |
||
| 570 | public function writeBans() |
||
| 575 | /** |
||
| 576 | * Gets the current version of the BE server |
||
| 577 | * |
||
| 578 | * @return string The BE server version |
||
| 579 | */ |
||
| 580 | public function getBEServerVersion() |
||
| 585 | /** |
||
| 586 | * Converts BE text "array" list to array |
||
| 587 | * |
||
| 588 | * @author nerdalertdk (https://github.com/nerdalertdk) |
||
| 589 | * @link https://github.com/Nizarii/arma-rcon-class-php/issues/4 The related Github issue |
||
| 590 | * |
||
| 591 | * @param $str array |
||
| 592 | * |
||
| 593 | * @return array |
||
| 594 | */ |
||
| 595 | private function formatList($str) |
||
| 610 | /** |
||
| 611 | * Remove control characters |
||
| 612 | * |
||
| 613 | * @author nerdalertdk (https://github.com/nerdalertdk) |
||
| 614 | * @link https://github.com/Nizarii/arma-rcon-class-php/issues/4 The related GitHub issue |
||
| 615 | * |
||
| 616 | * @param $str string |
||
| 617 | * |
||
| 618 | * @return string |
||
| 619 | */ |
||
| 620 | private function cleanList($str) |
||
| 624 | } |
If you suppress an error, we recommend checking for the error condition explicitly: