Advertisement
Guest User

Untitled

a guest
Dec 18th, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.56 KB | None | 0 0
  1. <?php
  2.  
  3. class Server extends Daemon
  4. {
  5.  
  6. public $socket;
  7.  
  8. public $ip, $port;
  9.  
  10. public $clients = array();
  11.  
  12. public $salons = array();
  13.  
  14. public $commands = array();
  15.  
  16. public function __construct($ip, $port)
  17. {
  18. // Ici on souhaite gérer les signaux SIGUSR1 et SIGUSR2 en plus
  19. parent::__construct("server", array(
  20. SIGUSR1,
  21. SIGUSR2
  22. ));
  23. $this->ip = $ip;
  24. $this->port = $port;
  25.  
  26. // salon
  27. $this->salons[] = new Salon("Acceuil", - 1, 2, false);
  28. $this->salons[] = new Salon("Salon 1", 5, 7, true);
  29. $this->salons[] = new Salon("Salon 2", 5, 7, true);
  30. $this->salons[] = new Salon("Salon 3", 5, 7, true);
  31. $this->salons[] = new Salon("Sauna/Hamam", 15, 1, true);
  32. $this->salons[] = new Salon("Salon de thé", 10, 3, true);
  33. $this->salons[] = new Salon("Zoo", - 1, - 1, true);
  34. $this->salons[] = new Salon("Pour les schizophrènes", 1, 1, true);
  35. $this->salons[] = new Salon("AFK", - 1, 0, false);
  36.  
  37. // commands
  38. $this->commands[] = new HelpCommand("/help", "Affichage des commandes", 0);
  39. $this->commands[] = new PseudoCommand("/pseudo", "/pseudo <votre pseudo> - Définir un pseudo", 1);
  40. $this->commands[] = new ChannelSwitchCommand("/salon", "/salon <ID du salon>", 1);
  41. $this->commands[] = new ChannelDisplayCommand("/listsalon", "Affichage des salons disponible", 0);
  42. $this->commands[] = new RestartCommand("/restart", "Relance le serveur", 0);
  43. $this->commands[] = new StopCommand("/stop", "Stop le serveur", 0);
  44. $this->commands[] = new LeaveCommand("/leave", "Déconnexion du serveur", 0);
  45.  
  46. // Démarrage du démon
  47. parent::start();
  48. }
  49.  
  50. public function run()
  51. {
  52. // Le code qui s'exécute infiniment
  53. if ($c = socket_accept($this->socket)) {
  54. socket_set_nonblock($c);
  55. $client_ip;
  56. $client_port;
  57. @socket_getpeername($c, $client_ip, $client_port);
  58.  
  59. $clientInstance = new Client($client_ip, $client_port, $c);
  60. array_push($this->clients, $clientInstance);
  61.  
  62. $this->logs("Ajout du client " . $clientInstance->id . " sur " . $client_ip . ":" . $client_port);
  63. $this->salons[0]->moveClient($clientInstance, $this);
  64. $this->displayChannels($clientInstance);
  65. }
  66. foreach ($this->clients as $client) {
  67. $this->handleClient($client);
  68. }
  69. usleep(500);
  70. }
  71.  
  72. public function handleClient($client)
  73. {
  74. $socket = $client->socket;
  75.  
  76. if ($socket !== FALSE) {
  77. if ($buf = @socket_read($socket, 2048)) {
  78.  
  79. if (strpos($buf, '/') === 0) {
  80. $this->handleCommand($client, $buf);
  81. } else {
  82. $result = $this->onTalk($client, $buf);
  83. if ($result) {
  84. $message = new ChatMessage($buf, $client->username, $client->currentSalon);
  85.  
  86. $client->sendMessage($message->format(), false);
  87.  
  88. foreach ($this->clients as $otherClient) {
  89. if ($client->id !== $otherClient->id && $client->currentSalon->isClientIn($otherClient)) {
  90. $otherClient->sendMessage($message->format(), false);
  91. }
  92. }
  93.  
  94. $client->currentSalon->storeMessage($message);
  95. }
  96. }
  97. }
  98. } else {
  99. $clients = array_splice($this->clients, $client, 1);
  100. }
  101. }
  102.  
  103. public function handleCommand($client, $command)
  104. {
  105. $any = false;
  106. foreach ($this->commands as $commandInstance) {
  107. $startWith = (substr($command, 0, strlen($commandInstance->commandName)) === $commandInstance->commandName);
  108.  
  109. if ($startWith) {
  110. $any = true;
  111.  
  112. $argsString = substr($command, strlen($commandInstance->commandName)); // supprésion du prefix de la commande
  113. $args = explode(" ", $argsString); // sépération des arguments
  114. $formattedArgs = array();
  115.  
  116. // supprésion des éléments vides de la commande
  117. foreach ($args as $arg) {
  118. if ($arg != null && strlen($arg) > 0 && trim($arg) !== '') {
  119. $formattedArgs[] = $arg;
  120. }
  121. }
  122.  
  123. $args = $formattedArgs;
  124.  
  125. if ($commandInstance->argsLength != 0 && sizeof($args) < $commandInstance->argsLength) {
  126. $client->sendMessage("Command invalide, usage de la commande: " . $commandInstance->usage);
  127. } else {
  128. $commandInstance->execute($this, $client, $args);
  129.  
  130. $this->logs("Commande par l'utilisateur " . $client->id . " " . $command);
  131. break;
  132. }
  133. }
  134. }
  135.  
  136. if (! $any) {
  137. $client->sendMessage("Commande inconnue, /help pour afficher la liste des commandes.");
  138. }
  139. }
  140.  
  141. public function onTalk($client, $message)
  142. {
  143. if ($client->username == null) {
  144. $client->sendMessage("Vous devez avoir un pseudo pous écrire dans le tchat.");
  145. $client->sendMessage("Utiliser la commande suivante pour en définir un: /pseudo <votre pseudo>", false);
  146. return false;
  147. }
  148. $salon = $client->currentSalon;
  149. if ($salon == null) {
  150. $this->salons[0]->moveClient($client, $this);
  151. return false;
  152. }
  153. if ($salon->canTalk === FALSE) {
  154. $client->sendMessage("Vous ne pouvez pas discuter dans se salon.", false);
  155. return false;
  156. }
  157. if ($salon->cooldownCheck($client)) {
  158. $client->sendMessage("Vous ne pouvez parler que toutes les " . $salon->talk_cooldown_time . " secondes.", false);
  159. return false;
  160. }
  161.  
  162. return true;
  163. }
  164.  
  165. public function onStart()
  166. {
  167. $this->logs("Démarrage du processus avec le pid " . getmypid());
  168. if (($this->socket = @socket_create(AF_INET, SOCK_STREAM, SOL_TCP)) == FALSE) {
  169. $this->logs("socket_create_listen() a échoué : " . socket_strerror(socket_last_error($this->socket)));
  170. exit(1);
  171. }
  172. socket_set_nonblock($this->socket);
  173. // Modification de l'option SO_REUSEADDR à la valeur 1 !
  174. if (! socket_set_option($this->socket, SOL_SOCKET, SO_REUSEADDR, 1)) {
  175. $this->logs('Impossible de définir l\'option du socket : ' . socket_strerror(socket_last_error($this->socket)));
  176. exit(1);
  177. }
  178. if (@socket_bind($this->socket, $this->ip, $this->port) == FALSE) {
  179. $this->logs("socket_bind() a échoué : " . socket_strerror(socket_last_error($this->socket)));
  180. exit(1);
  181. }
  182. if (@socket_listen($this->socket) == FALSE) {
  183. $this->logs("socket_listen() a échoué : " . socket_strerror(socket_last_error($this->socket)));
  184. exit(1);
  185. }
  186. $this->logs("Serveur en écoute sur " . $this->ip . ":" . $this->port);
  187. }
  188.  
  189. public function onStop()
  190. {
  191. $this->logs("Arrêt du processus avec le pid " . getmypid());
  192. socket_close($this->socket);
  193. }
  194.  
  195. public function handleOtherSignals($signal)
  196. {
  197. $this->logs("Signal non géré par la classe Daemon : " . $signal);
  198. }
  199.  
  200. public function dcClient($client)
  201. {
  202. socket_close($client->socket);
  203. $this->logs("Déconnexion du client " . $client->id . ".");
  204. }
  205.  
  206. public function displayChannels($client)
  207. {
  208. $client->sendMessage("ID - Nom du salon - Nombre de client en ligne / Slots", false);
  209.  
  210. $id = 0;
  211.  
  212. foreach ($this->salons as $salon) {
  213. $client->sendMessage($id ++ . " - " . $salon->nom . " - " . $salon->countClients($this) . "/" . ($salon->max_clients == - 1 ? "Infini" : $salon->max_clients), false);
  214. }
  215. }
  216.  
  217. public function logs($message)
  218. {
  219. file_put_contents("/var/log/" . $this->name . ".log", $message . "\n", FILE_APPEND);
  220. }
  221. }
  222. ?>
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement