-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdaemon.php
More file actions
executable file
·102 lines (97 loc) · 2.6 KB
/
Copy pathdaemon.php
File metadata and controls
executable file
·102 lines (97 loc) · 2.6 KB
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
#!/usr/bin/php
<?php
require 'vendor/autoload.php';
require 'lib/game.php';
require 'lib/net.php';
define("DIR", getenv("C2K48_DATA") ?: __DIR__ . "/tmp");
$path = DIR;
$path = implode('/', [realpath(dirname($path)), basename($path)]);
$path = "$path/daemon.sock";
ignore_user_abort(true);
use Amp\ByteStream\BufferedReader;
use Amp\Socket;
use function Amp\async;
use function Amp\delay;
if (file_exists($path)) {
unlink($path);
}
$server = Socket\listen("unix://$path");
$games = [];
function close_game($client, string $name) {
if (!isset($client->games[$name])) {
return;
}
$viewer = $client->games[$name];
$viewer->game->users--;
$viewer->game->viewers -= (int) !$viewer->isplayer;
unset($client->games[$name]);
}
while (($client = $server->accept()) !== null) {
(function () use ($client, &$games) {
$client = (object) [
"rpc" => new ObjectRPC(
new JsonMsgReader(new BufferedReader($client)),
new JsonMsgWriter($client)
),
"games" => [],
];
$client->rpc->handler("new_game", function (...$arg) use (&$games) {
do {
$id = bin2hex(random_bytes(8));
} while (isset($games[$id]));
$games[$id] = (object) [];
error_log("creating game {$id}");
$game = $games[$id];
$game->game = new x1p11local(...$arg);
$game->pkey = bin2hex(random_bytes(16));
$game->users = 0;
$game->viewers = 0;
async(function () use ($game, &$games, $id) {
while (1) {
delay(10);
for ($t = 600; $t > 0 && ($kill = $game->users == 0); $t--) {
delay(1);
}
if ($kill) {
error_log("killing inactive game {$id}");
unset($games[$id]);
break;
}
}
});
return [$id, $game->pkey];
});
$client->rpc->handler("open_game", function (string $name, string $id, string $pkey = "") use (&$games, $client) {
if (!isset($games[$id])) {
error_log("game doesn't exist! {$id}");
return;
}
if (isset($client->games[$name])) {
close_game($client, $name);
}
$game = $games[$id];
$viewer = (object) [
"isplayer" => $game->pkey == $pkey,
"game" => $game,
"server" => new x1p11server($game->game, $client->rpc, $name),
];
$game->users++;
$game->viewers += (int) !$viewer->isplayer;
if (!$viewer->isplayer) {
$client->rpc->handler("{$name}/move");
}
$client->games[$name] = $viewer;
return (object) [
"writable" => $viewer->isplayer,
];
});
$client->rpc->handler("close_game", function (string $name) use ($client) {
close_game($client, $name);
});
async($client->rpc->listen(...))
->catch(function ($e) {error_log($e);})
->finally(function () use ($client) {
});
})();
unset($client);
}