summaryrefslogtreecommitdiff
path: root/src/gemini/Gemini.php
blob: 41b87161de7c3953ad68a542ae3aa677937e8568 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?php

namespace App\gemini;

use App\DB;
use App\EventRunner;
use App\View;
use App\gemini\Controller\Building;
use App\gemini\Controller\Unit;
use App\gemini\Controller\User;
use App\gemini\Controller\Village;
use GeminiFoundation\Request;
use GeminiFoundation\Response;
use GeminiFoundation\Server;
use GeminiFoundation\Status;

class Gemini
{
  private array $certificate;
  private string $hostname;

  public function __construct(array $certificate, string $hostname)
  {
    $this->certificate = $certificate;
    $this->hostname = $hostname;

    global $_SESSION;
    $_SESSION = [];

    DB::init();

    View::init();
    View::addGlobal('session', $_SESSION);
  }

  public function run(): void
  {
    $server = new Server($this->certificate, $this->hostname, [
      'client_certificate_support_workaround' => true,
    ]);

    $server->onRequest(function (Response $response, Request $request) {
      new EventRunner();

      // auth
      if ($request->getClientCertificate() === null) {
        return new Response(
          statusCode: Status::CLIENT_CERTIFICATE_REQUIRED,
          meta: 'Attach a client certificate to log in'
        );
      }

      $userController = new User();
      $user = $userController->get($request);
      if (empty($user)) {
        $user = $userController->create($request);
      }

      global $_SESSION;
      $_SESSION['user'] = [
        'id' => $user['id'],
        'username' => $user['username'],
      ];
      View::addGlobal('session', $_SESSION);


      // routes
      if ($request->getPath() == '/villages') {
        $villageController = new Village();
        $response = $villageController->list($request);
      }

      else if (preg_match('@village/(\d+)/(\d+)/storage/config/?(\w+)?@', $request->getPath(), $routeMatch)) {
        $request
          ->set('x', $routeMatch[1])
          ->set('y', $routeMatch[2]);

        if (isset($routeMatch[3])) {
          $request->set('type', $routeMatch[3]);
        }

        $villageController = new Village();
        $response = $villageController->storageConfig($request);
      }

      else if (preg_match('@village/(\d+)/(\d+)/building/(\w+)/level-up@', $request->getPath(), $routeMatch)) {
        $request
          ->set('x', $routeMatch[1])
          ->set('y', $routeMatch[2])
          ->set('type', $routeMatch[3]);

        $buildingController = new Building();
        $response = $buildingController->levelUp($request);
      }

      else if (preg_match('@village/(\d+)/(\d+)/unit/(\w+)/create@', $request->getPath(), $routeMatch)) {
        $request
          ->set('x', $routeMatch[1])
          ->set('y', $routeMatch[2])
          ->set('type', $routeMatch[3]);

        $unitController = new Unit();
        $response = $unitController->train($request);
      }

      else if (preg_match('@village/(\d+)/(\d+)@', $request->getPath(), $routeMatch)) {
        $request
          ->set('x', $routeMatch[1])
          ->set('y', $routeMatch[2]);

        $villageController = new Village();
        $response = $villageController->show($request);
      }

      return $response;
    });

    $server->listen();
  }
}