ServerController.php
1 <?php 2 3 namespace App\Controller; 4 5 use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; 6 use Symfony\Contracts\Translation\TranslatorInterface; 7 8 use Symfony\Component\Routing\Annotation\Route; 9 use Symfony\Component\HttpFoundation\Response; 10 use Symfony\Component\HttpFoundation\Request; 11 12 use App\Entity\Online; 13 use App\Entity\Player; 14 use App\Entity\Server; 15 use Doctrine\ORM\EntityManagerInterface; 16 17 class ServerController extends AbstractController 18 { 19 #[Route( 20 '/server/{crc32server}', 21 name: 'server_index', 22 requirements: 23 [ 24 'crc32server' => '\d+', 25 ], 26 methods: 27 [ 28 'GET' 29 ] 30 )] 31 public function index( 32 ?Request $request, 33 EntityManagerInterface $entityManagerInterface 34 ): Response 35 { 36 // Validate server 37 $server = $entityManagerInterface->getRepository(Server::class)->findOneBy( 38 [ 39 'crc32server' => $request->get('crc32server') 40 ] 41 ); 42 43 if (!$server) 44 { 45 throw $this->createNotFoundException(); 46 } 47 48 // Prepare page request 49 if ($request->get('page') && (int) $request->get('page') > 1) 50 { 51 $page = (int) $request->get('page'); 52 } 53 54 else 55 { 56 $page = 1; 57 } 58 59 // Init defaults 60 $info = []; 61 $session = []; 62 63 // Get online 64 $online = $entityManagerInterface->getRepository(Online::class)->findBy( 65 [ 66 'crc32server' => $server->getCrc32server() 67 ], 68 [ 69 'online' == $request->get('sort') && in_array($request->get('field'), ['time','players','bots','total']) 70 ? $request->get('field') : 'time' => in_array($request->get('order'), ['asc','desc']) ? $request->get('order') : 'desc', 71 ], 72 $this->getParameter('app.server.online.limit'), 73 'online' == $request->get('sort') ? ($page - 1) * $this->getParameter('app.server.online.limit') : 0 74 ); 75 76 // Get players 77 $players = $entityManagerInterface->getRepository(Player::class)->findBy( 78 [ 79 'crc32server' => $server->getCrc32server() 80 ], 81 [ 82 'players' == $request->get('sort') && in_array($request->get('field'), ['name','frags','joined','online']) 83 ? $request->get('field') : 'frags' => in_array($request->get('order'), ['asc','desc']) ? $request->get('order') : 'desc', 84 ], 85 $this->getParameter('app.server.players.limit'), 86 'players' == $request->get('sort') ? ($page - 1) * $this->getParameter('app.server.players.limit') : 0 87 ); 88 89 // Format address 90 if (false === filter_var($server->getHost(), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) 91 { 92 $address = "{$server->getHost()}:{$server->getPort()}"; 93 } 94 95 else 96 { 97 $address = "[{$server->getHost()}]:{$server->getPort()}"; 98 } 99 100 // Request server info 101 try 102 { 103 $node = new \xPaw\SourceQuery\SourceQuery(); 104 105 $node->Connect( 106 false === filter_var($server->getHost(), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? $server->getHost() : "[{$server->getHost()}]", 107 $server->getPort(), 108 1 109 ); 110 111 if ($node->Ping()) 112 { 113 if ($info = (array) $node->GetInfo()) 114 { 115 // Get session 116 $session = empty($info['Players']) ? [] : (array) $node->GetPlayers(); 117 118 // Sort by players by frags 119 if ($session) 120 { 121 array_multisort( 122 array_column( 123 $session, 124 'Frags' 125 ), 126 SORT_DESC, 127 $session 128 ); 129 } 130 } 131 132 $status = true; 133 } 134 135 else 136 { 137 $status = false; 138 } 139 } 140 141 catch (Exception $error) 142 { 143 throw $this->createNotFoundException(); 144 } 145 146 catch (\Throwable $error) 147 { 148 $status = false; 149 } 150 151 finally 152 { 153 $node->Disconnect(); 154 } 155 156 return $this->render( 157 'default/server/index.html.twig', 158 [ 159 'request' => $request, 160 'server' => 161 [ 162 'address' => $address, 163 'crc32server' => $server->getCrc32server(), 164 'name' => $server->getName(), 165 'host' => $server->getHost(), 166 'port' => $server->getPort(), 167 'info' => $info, 168 'session' => $session, 169 'online' => $online, 170 'players' => $players, 171 'status' => $status, 172 'pagination' => 173 [ 174 'players' => ceil( 175 $entityManagerInterface->getRepository(Player::class)->getTotalByCrc32server( 176 $server->getCrc32server() 177 ) / $this->getParameter('app.server.players.limit') 178 ), 179 'online' => ceil( 180 $entityManagerInterface->getRepository(Online::class)->getTotalByCrc32server( 181 $server->getCrc32server() 182 ) / $this->getParameter('app.server.online.limit') 183 ) 184 ], 185 'connections' => empty($info['Players']) || $info['Players'] < 0 || empty($info['Bots']) || $info['Bots'] < 0 186 ? 0 187 : (int) $info['Players'] - (int) $info['Bots'] 188 ] 189 ] 190 ); 191 } 192 }