MainController.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 16 use Doctrine\ORM\EntityManagerInterface; 17 18 class MainController extends AbstractController 19 { 20 #[Route( 21 '/', 22 name: 'main_index', 23 methods: 24 [ 25 'GET' 26 ] 27 )] 28 public function index( 29 ?Request $request, 30 TranslatorInterface $translatorInterface, 31 EntityManagerInterface $entityManagerInterface 32 ): Response 33 { 34 // Init memory 35 $memory = new \Yggverse\Cache\Memory( 36 $this->getParameter('app.memcached.host'), 37 $this->getParameter('app.memcached.port'), 38 $this->getParameter('app.memcached.namespace'), 39 $this->getParameter('app.memcached.timeout') + time(), 40 ); 41 42 // Collect servers info 43 $servers = []; 44 45 foreach ((array) $entityManagerInterface->getRepository(Server::class)->findAll() as $server) 46 { 47 // Init defaults 48 $status = false; 49 50 $info = 51 [ 52 'Protocol' => null, 53 'HostName' => null, 54 'Map' => null, 55 'ModDir' => null, 56 'ModDesc' => null, 57 'AppID' => null, 58 'Players' => null, 59 'MaxPlayers' => null, 60 'Bots' => null, 61 'Dedicated' => null, 62 'Os' => null, 63 'Password' => null, 64 'Secure' => null, 65 'Version' => null 66 ]; 67 68 // Request server info 69 try 70 { 71 $node = new \xPaw\SourceQuery\SourceQuery(); 72 73 $node->Connect( 74 false === filter_var($server->getHost(), FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ? $server->getHost() : "[{$server->getHost()}]", 75 $server->getPort(), 76 1 77 ); 78 79 if ($node->Ping()) 80 { 81 $status = true; 82 83 foreach ((array) $node->GetInfo() as $key => $value) 84 { 85 $info[$key] = $value; 86 } 87 } 88 } 89 90 catch (Exception $error) 91 { 92 throw $this->createNotFoundException(); 93 } 94 95 catch (\Throwable $error) 96 { 97 $status = false; 98 } 99 100 finally 101 { 102 $node->Disconnect(); 103 } 104 105 // Add server 106 $servers[] = [ 107 'crc32server' => $server->getCrc32server(), 108 'name' => $server->getName(), 109 'host' => $server->getHost(), 110 'port' => $server->getPort(), 111 'added' => $server->getAdded(), 112 'updated' => $server->getUpdated(), 113 'online' => $server->getOnline(), 114 'info' => $info, 115 'status' => $status, 116 'connections' => empty($info['Players']) || $info['Players'] < 0 || empty($info['Bots']) || $info['Bots'] < 0 117 ? 0 118 : (int) $info['Players'] - (int) $info['Bots'] 119 ]; 120 } 121 122 // Sort by players 123 array_multisort( 124 array_column( 125 $servers, 126 'connections' 127 ), 128 SORT_DESC, 129 $servers 130 ); 131 132 // Online calendar 133 $time = time(); 134 135 $month = new \Yggverse\Graph\Calendar\Month($time); 136 137 foreach ($month->getNodes() as $day => $node) 138 { 139 // Skip future days processing 140 if ($day > date('j')) 141 { 142 break; 143 } 144 145 // Add daily stats 146 $total = $memory->getByMethodCallback( 147 $entityManagerInterface->getRepository(Online::class), 148 'getMaxPlayersByTimeInterval', 149 [ 150 strtotime( 151 sprintf( 152 '%s-%s-%s 00:00', 153 date('Y', $time), 154 date('n', $time), 155 $day 156 ) 157 ), 158 strtotime( 159 '+1 day', 160 strtotime( 161 sprintf( 162 '%s-%s-%s 00:00', 163 date('Y', $time), 164 date('n', $time), 165 $day 166 ) 167 ) 168 ) 169 ], 170 time() + ($day == date('j') ? 60 : 2592000) 171 ); 172 173 $month->addNode( 174 $day, 175 $total, 176 sprintf( 177 $translatorInterface->trans('online %d'), 178 $total 179 ), 180 null, 181 0 182 ); 183 184 // Add hourly stats 185 for ($hour = 0; $hour < 24; $hour++) 186 { 187 $total = $memory->getByMethodCallback( 188 $entityManagerInterface->getRepository(Online::class), 189 'getMaxPlayersByTimeInterval', 190 [ 191 strtotime( 192 sprintf( 193 '%s-%s-%s %s:00', 194 date('Y', $time), 195 date('n', $time), 196 $day, 197 $hour 198 ) 199 ), 200 strtotime( 201 sprintf( 202 '%s-%s-%s %s:00', 203 date('Y', $time), 204 date('n', $time), 205 $day, 206 $hour + 1 207 ) 208 ) 209 ], 210 time() + ($day == date('j') ? 60 : 2592000) 211 ); 212 213 $month->addNode( 214 $day, 215 $total, 216 sprintf( 217 $translatorInterface->trans('%s:00-%s:00 %s online %s'), 218 $hour, 219 $hour + 1, 220 date('e'), 221 $total 222 ), 223 'background-color-default', 224 1 225 ); 226 } 227 } 228 229 return $this->render( 230 'default/main/index.html.twig', 231 [ 232 'request' => $request, 233 'servers' => $servers, 234 'month' => 235 [ 236 'online' => (array) $month->getNodes() 237 ] 238 ] 239 ); 240 } 241 }