Browse Source

implement basic features

main
ghost 4 months ago
parent
commit
2071796a07
  1. 14
      .env
  2. 5
      .gitignore
  3. 9
      assets/app.js
  4. 5
      assets/bootstrap.js
  5. 15
      assets/controllers.json
  6. 16
      assets/controllers/hello_controller.js
  7. 3
      assets/styles/app.css
  8. 10
      composer.json
  9. 294
      composer.lock
  10. 5
      config/packages/asset_mapper.yaml
  11. 6
      config/packages/twig.yaml
  12. 5
      config/services.yaml
  13. 30
      importmap.php
  14. 124
      public/css/default.css
  15. 86
      src/Controller/MainController.php
  16. 15
      symfony.lock
  17. 17
      templates/base.html.twig
  18. 38
      templates/default/layout.html.twig
  19. 57
      templates/default/main/index.html.twig

14
.env

@ -43,12 +43,14 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0 @@ -43,12 +43,14 @@ MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
# HLState
# Application version, used for API and media cache
APP_VERSION=1.0.0
APP_VERSION="1.0.0"
# Application name
APP_NAME=HLState
APP_NAME="HLState"
# Game server
APP_SERVER_HOST=localhost
APP_SERVER_PORT=27015
APP_SERVER_TIMEOUT=3
# Application template
APP_THEME="default"
# Servers registry, URL or filepath
# https://github.com/YGGverse/HLServers
APP_HLSERVERS="https://raw.githubusercontent.com/YGGverse/HLServers/main/config.json"

5
.gitignore vendored

@ -17,8 +17,3 @@ @@ -17,8 +17,3 @@
.phpunit.result.cache
/phpunit.xml
###< symfony/phpunit-bridge ###
###> symfony/asset-mapper ###
/public/assets/
/assets/vendor
###< symfony/asset-mapper ###

9
assets/app.js

@ -1,9 +0,0 @@ @@ -1,9 +0,0 @@
/*
* Welcome to your app's main JavaScript file!
*
* This file will be included onto the page via the importmap() Twig function,
* which should already be in your base.html.twig.
*/
import './styles/app.css'
console.log('This log comes from assets/app.js - welcome to AssetMapper! 🎉')

5
assets/bootstrap.js vendored

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
import { startStimulusApp } from '@symfony/stimulus-bundle';
const app = startStimulusApp();
// register any custom, 3rd party controllers here
// app.register('some_controller_name', SomeImportedController);

15
assets/controllers.json

@ -1,15 +0,0 @@ @@ -1,15 +0,0 @@
{
"controllers": {
"@symfony/ux-turbo": {
"turbo-core": {
"enabled": true,
"fetch": "eager"
},
"mercure-turbo-stream": {
"enabled": false,
"fetch": "eager"
}
}
},
"entrypoints": []
}

16
assets/controllers/hello_controller.js

@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
import { Controller } from '@hotwired/stimulus';
/*
* This is an example Stimulus controller!
*
* Any element with a data-controller="hello" attribute will cause
* this controller to be executed. The name "hello" comes from the filename:
* hello_controller.js -> "hello"
*
* Delete this file or adapt it for your use!
*/
export default class extends Controller {
connect() {
this.element.textContent = 'Hello Stimulus! Edit me in assets/controllers/hello_controller.js';
}
}

3
assets/styles/app.css

@ -1,3 +0,0 @@ @@ -1,3 +0,0 @@
body {
background-color: skyblue;
}

10
composer.json

@ -14,8 +14,6 @@ @@ -14,8 +14,6 @@
"doctrine/orm": "^2.17",
"phpdocumentor/reflection-docblock": "^5.3",
"phpstan/phpdoc-parser": "^1.25",
"symfony/asset": "7.0.*",
"symfony/asset-mapper": "7.0.*",
"symfony/console": "7.0.*",
"symfony/doctrine-messenger": "7.0.*",
"symfony/dotenv": "7.0.*",
@ -43,8 +41,9 @@ @@ -43,8 +41,9 @@
"symfony/validator": "7.0.*",
"symfony/web-link": "7.0.*",
"symfony/yaml": "7.0.*",
"twig/extra-bundle": "^2.12|^3.0",
"twig/twig": "^2.12|^3.0",
"twig/extra-bundle": "^3.8",
"twig/intl-extra": "^3.8",
"twig/twig": "^3.8",
"xpaw/php-source-query-class": "^2.1"
},
"config": {
@ -78,8 +77,7 @@ @@ -78,8 +77,7 @@
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd",
"importmap:install": "symfony-cmd"
"assets:install %PUBLIC_DIR%": "symfony-cmd"
},
"post-install-cmd": [
"@auto-scripts"

294
composer.lock generated

@ -4,89 +4,8 @@ @@ -4,89 +4,8 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "66ab47b04c6a49df812afba2a57a75bc",
"content-hash": "b88a8a873f067191119676f1b8833846",
"packages": [
{
"name": "composer/semver",
"version": "3.4.0",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32",
"reference": "35e8d0af4486141bc745f23a29cc2091eb624a32",
"shasum": ""
},
"require": {
"php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
"phpstan/phpstan": "^1.4",
"symfony/phpunit-bridge": "^4.2 || ^5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-main": "3.x-dev"
}
},
"autoload": {
"psr-4": {
"Composer\\Semver\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Nils Adermann",
"email": "naderman@naderman.de",
"homepage": "http://www.naderman.de"
},
{
"name": "Jordi Boggiano",
"email": "j.boggiano@seld.be",
"homepage": "http://seld.be"
},
{
"name": "Rob Bast",
"email": "rob.bast@gmail.com",
"homepage": "http://robbast.nl"
}
],
"description": "Semver library that offers utilities, version constraint parsing and validation.",
"keywords": [
"semantic",
"semver",
"validation",
"versioning"
],
"support": {
"irc": "ircs://irc.libera.chat:6697/composer",
"issues": "https://github.com/composer/semver/issues",
"source": "https://github.com/composer/semver/tree/3.4.0"
},
"funding": [
{
"url": "https://packagist.com",
"type": "custom"
},
{
"url": "https://github.com/composer",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
"type": "tidelift"
}
],
"time": "2023-08-31T09:50:34+00:00"
},
{
"name": "doctrine/cache",
"version": "2.2.0",
@ -2099,153 +2018,6 @@ @@ -2099,153 +2018,6 @@
},
"time": "2021-07-14T16:46:02+00:00"
},
{
"name": "symfony/asset",
"version": "v7.0.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/asset.git",
"reference": "82cd3961bc7fc1b3c3f85e8f2b9a287a1dfd6f2f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/asset/zipball/82cd3961bc7fc1b3c3f85e8f2b9a287a1dfd6f2f",
"reference": "82cd3961bc7fc1b3c3f85e8f2b9a287a1dfd6f2f",
"shasum": ""
},
"require": {
"php": ">=8.2"
},
"conflict": {
"symfony/http-foundation": "<6.4"
},
"require-dev": {
"symfony/http-client": "^6.4|^7.0",
"symfony/http-foundation": "^6.4|^7.0",
"symfony/http-kernel": "^6.4|^7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\Asset\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Manages URL generation and versioning of web assets such as CSS stylesheets, JavaScript files and image files",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/asset/tree/v7.0.0"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-10-31T17:59:56+00:00"
},
{
"name": "symfony/asset-mapper",
"version": "v7.0.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/asset-mapper.git",
"reference": "e4e3a98dc279cb0d266f50c7c73bd42cb9c3a0c3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/asset-mapper/zipball/e4e3a98dc279cb0d266f50c7c73bd42cb9c3a0c3",
"reference": "e4e3a98dc279cb0d266f50c7c73bd42cb9c3a0c3",
"shasum": ""
},
"require": {
"composer/semver": "^3.0",
"php": ">=8.2",
"symfony/filesystem": "^6.4|^7.0",
"symfony/http-client": "^6.4|^7.0"
},
"conflict": {
"symfony/framework-bundle": "<6.4"
},
"require-dev": {
"symfony/asset": "^6.4|^7.0",
"symfony/browser-kit": "^6.4|^7.0",
"symfony/console": "^6.4|^7.0",
"symfony/event-dispatcher-contracts": "^3.0",
"symfony/finder": "^6.4|^7.0",
"symfony/framework-bundle": "^6.4|^7.0",
"symfony/http-foundation": "^6.4|^7.0",
"symfony/http-kernel": "^6.4|^7.0",
"symfony/web-link": "^6.4|^7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Symfony\\Component\\AssetMapper\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Maps directories of assets & makes them available in a public directory with versioned filenames.",
"homepage": "https://symfony.com",
"support": {
"source": "https://github.com/symfony/asset-mapper/tree/v7.0.2"
},
"funding": [
{
"url": "https://symfony.com/sponsor",
"type": "custom"
},
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
"type": "tidelift"
}
],
"time": "2023-12-27T08:42:13+00:00"
},
{
"name": "symfony/cache",
"version": "v7.0.2",
@ -7417,6 +7189,70 @@ @@ -7417,6 +7189,70 @@
],
"time": "2023-11-21T14:02:01+00:00"
},
{
"name": "twig/intl-extra",
"version": "v3.8.0",
"source": {
"type": "git",
"url": "https://github.com/twigphp/intl-extra.git",
"reference": "7b3db67c700735f473a265a97e1adaeba3e6ca0c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/twigphp/intl-extra/zipball/7b3db67c700735f473a265a97e1adaeba3e6ca0c",
"reference": "7b3db67c700735f473a265a97e1adaeba3e6ca0c",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/intl": "^5.4|^6.0|^7.0",
"twig/twig": "^3.0"
},
"require-dev": {
"symfony/phpunit-bridge": "^6.4|^7.0"
},
"type": "library",
"autoload": {
"psr-4": {
"Twig\\Extra\\Intl\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
}
],
"description": "A Twig extension for Intl",
"homepage": "https://twig.symfony.com",
"keywords": [
"intl",
"twig"
],
"support": {
"source": "https://github.com/twigphp/intl-extra/tree/v3.8.0"
},
"funding": [
{
"url": "https://github.com/fabpot",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/twig/twig",
"type": "tidelift"
}
],
"time": "2023-11-21T17:27:48+00:00"
},
{
"name": "twig/twig",
"version": "v3.8.0",

5
config/packages/asset_mapper.yaml

@ -1,5 +0,0 @@ @@ -1,5 +0,0 @@
framework:
asset_mapper:
# The paths to make available to the asset mapper.
paths:
- assets/

6
config/packages/twig.yaml

@ -1,6 +1,10 @@ @@ -1,6 +1,10 @@
twig:
default_path: '%kernel.project_dir%/templates'
globals:
app:
version: '%app.version%'
name: '%app.name%'
theme: '%app.theme%'
when@test:
twig:
strict_variables: true

5
config/services.yaml

@ -6,9 +6,8 @@ @@ -6,9 +6,8 @@
parameters:
app.version: '%env(APP_VERSION)%'
app.name: '%env(APP_NAME)%'
app.server.host: '%env(APP_SERVER_HOST)%'
app.server.port: '%env(APP_SERVER_PORT)%'
app.server.timeout: '%env(APP_SERVER_TIMEOUT)%'
app.theme: '%env(APP_THEME)%'
app.hlservers: '%env(APP_HLSERVERS)%'
services:
# default configuration for services in *this* file

30
importmap.php

@ -1,30 +0,0 @@ @@ -1,30 +0,0 @@
<?php
/**
* Returns the importmap for this application.
*
* - "path" is a path inside the asset mapper system. Use the
* "debug:asset-map" command to see the full list of paths.
*
* - "entrypoint" (JavaScript only) set to true for any module that will
* be used as an "entrypoint" (and passed to the importmap() Twig function).
*
* The "importmap:require" command can be used to add new entries to this file.
*
* This file has been auto-generated by the importmap commands.
*/
return [
'app' => [
'path' => './assets/app.js',
'entrypoint' => true,
],
'@hotwired/stimulus' => [
'version' => '3.2.2',
],
'@symfony/stimulus-bundle' => [
'path' => './vendor/symfony/stimulus-bundle/assets/dist/loader.js',
],
'@hotwired/turbo' => [
'version' => '7.3.0',
],
];

124
public/css/default.css

@ -0,0 +1,124 @@ @@ -0,0 +1,124 @@
*
{
/* apply defaults */
margin: 0;
padding: 0;
/* allow draw */
font-family: monospace;
/* adaptive */
color-scheme: light dark;
/* vars */
--container-max-width: 768px;
--color-warning: #ee784e;
--color-error: #ff6363;
--color-default: #999;
}
*::placeholder
{
font-size: 12px;
}
hr {
background-color: var(--color-default);
border: none;
color: var(--color-default);
height: 1px;
margin: 8px 0;
}
h1
{
font-size: 16px;
}
h2
{
font-size: 14px;
}
h3
{
font-size: 13px;
}
a, a:active, a:visited
{
color: var(--color-warning);
}
table
{
width: 100%;
border-collapse: collapse;
border: 1px solid var(--color-default);
}
table th,
table td
{
border: 1px solid var(--color-default);
padding: 4px;
}
header
{
display: block;
margin: 16px auto;
max-width: var(--container-max-width);
}
main
{
display: block;
margin: 16px auto;
max-width: var(--container-max-width);
}
footer
{
display: block;
margin: 16px auto;
max-width: var(--container-max-width);
}
/* framework */
.text-align-left
{
text-align: left;
}
.text-align-center
{
text-align: center;
}
.text-align-right
{
text-align: right;
}
.border-default
{
border: 1px var(--color-default) solid;
}
.padding-8-px
{
padding: 8px;
}
.padding-y-8-px
{
padding-bottom: 8px;
padding-top: 8px;
}
.margin-y-8-px
{
margin-bottom: 8px;
margin-top: 8px;
}

86
src/Controller/MainController.php

@ -0,0 +1,86 @@ @@ -0,0 +1,86 @@
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Request;
class MainController extends AbstractController
{
#[Route(
'/',
name: 'main_index',
methods:
[
'GET'
]
)]
public function index(
?Request $request
): Response
{
// Get HLServers config
if ($hlservers = file_get_contents($this->getParameter('app.hlservers')))
{
$hlservers = json_decode($hlservers);
}
else
{
$hlservers = [];
}
// Collect servers info
$servers = [];
foreach ($hlservers as $hlserver)
{
try
{
$server = new \xPaw\SourceQuery\SourceQuery();
$server->Connect(
$hlserver->host,
$hlserver->port
);
if ($server->Ping())
{
if ($info = (array) $server->GetInfo())
{
$servers[] = [
'host' => $hlserver->host,
'port' => $hlserver->port,
'alias' => $hlserver->alias,
'info' => $info,
'online' => empty($info['Players']) ? [] : (array) $server->GetPlayers()
];
}
}
}
catch (Exception $error)
{
continue;
}
finally
{
$server->Disconnect();
}
}
return $this->render(
'default/main/index.html.twig',
[
'request' => $request,
'servers' => $servers
]
);
}
}

15
symfony.lock

@ -40,21 +40,6 @@ @@ -40,21 +40,6 @@
"tests/bootstrap.php"
]
},
"symfony/asset-mapper": {
"version": "7.0",
"recipe": {
"repo": "github.com/symfony/recipes",
"branch": "main",
"version": "6.4",
"ref": "8a0d17c04c791b3d7bdd083e1e2b2a53439dc3b0"
},
"files": [
"assets/app.js",
"assets/styles/app.css",
"config/packages/asset_mapper.yaml",
"importmap.php"
]
},
"symfony/console": {
"version": "7.0",
"recipe": {

17
templates/base.html.twig

@ -1,17 +0,0 @@ @@ -1,17 +0,0 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block title %}Welcome!{% endblock %}</title>
<link rel="icon" href="data:image/svg+xml,<svg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 128 128%22><text y=%221.2em%22 font-size=%2296%22>⚫</text></svg>">
{% block stylesheets %}
{% endblock %}
{% block javascripts %}
{% block importmap %}{{ importmap('app') }}{% endblock %}
{% endblock %}
</head>
<body>
{% block body %}{% endblock %}
</body>
</html>

38
templates/default/layout.html.twig

@ -0,0 +1,38 @@ @@ -0,0 +1,38 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>{% block head_title_content %}{{ app.name }}{% endblock %}</title>
<link rel="stylesheet" type="text/css" href="{{ url('main_index') }}css/default.css?{{ app.version }}"/>
</head>
<body>
{% block header_container %}
<header>
{% block header_content %}
<div class="text-align-right">
<strong>
{{ app.name }}
</strong>
</div>
{% endblock %}
</header>
{% endblock %}
{% block main_container %}
<main>
{% block main_content %}{% endblock %}
</main>
{% endblock %}
{% block footer_container %}
<footer>
{% block footer_content %}
<div class="text-align-right">
<small>
{{ 'Powered by' | trans }}
<a href="https://github.com/YGGverse/HLState" target="_blank">HLState</a>
</small>
</div>
{% endblock %}
</footer>
{% endblock %}
</body>
</html>

57
templates/default/main/index.html.twig

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
{% extends 'default/layout.html.twig' %}
{% block main_content %}
{% for server in servers %}
<div class="border-default padding-8-px margin-y-8-px">
<h2>{{ server.info.HostName }}</h2>
<hr />
<h3 class="padding-y-8-px text-align-right">{{ 'Address' | trans }}</h3>
<div>
{{ server.host }}:{{ server.port }}
</div>
{% if server.alias %}
<h3 class="padding-y-8-px text-align-right">{{ 'Aliases' | trans }}</h3>
{% for alias in server.alias %}
<div>
{{ alias.host }}:{{ alias.port }}
</div>
{% endfor %}
{% endif %}
{% if server.info %}
<h3 class="padding-y-8-px text-align-right">{{ 'Info' | trans }}</h3>
<table>
{% for key, value in server.info %}
<tr>
<td class="text-align-left">{{ key }}</td>
<td class="text-align-left">{{ value }}</td>
</tr>
{% endfor %}
</table>
{% endif %}
{% if server.online %}
<h3 class="padding-y-8-px text-align-right">{{ 'Online' | trans }}</h3>
<table>
<tr>
<th class="text-align-left">{{ 'Name' | trans }}</th>
<th class="text-align-center">{{ 'Frags' | trans }}</th>
<th class="text-align-center">{{ 'Time' | trans }}</th>
</tr>
{% for player in server.online %}
<tr>
<td class="text-align-left">{{ player.Name }}</td>
<td class="text-align-center">{{ player.Frags }}</td>
<td class="text-align-center">
{% if player.TimeF == '59:59' %}
<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" viewBox="0 0 16 16">
<path d="M5.68 5.792 7.345 7.75 5.681 9.708a2.75 2.75 0 1 1 0-3.916ZM8 6.978 6.416 5.113l-.014-.015a3.75 3.75 0 1 0 0 5.304l.014-.015L8 8.522l1.584 1.865.014.015a3.75 3.75 0 1 0 0-5.304l-.014.015zm.656.772 1.663-1.958a2.75 2.75 0 1 1 0 3.916z"/>
</svg>
{% else %}
{{ player.TimeF }}
{% endif %}
</td>
</tr>
{% endfor %}
</table>
{% endif %}
</div>
{% endfor %}
{% endblock %}
Loading…
Cancel
Save