/ src / Controller / MainController.php
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  }