Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
173407cd26 | ||
|
|
90e5fd904f | ||
|
|
225c14124a | ||
|
|
a932161973 | ||
|
|
01b0522bd1 | ||
|
|
9c5b3fbe4e | ||
|
|
38d134bbac | ||
|
|
25664bbc4f | ||
|
|
4dfc8e7b15 | ||
|
|
bf7d1ee379 | ||
|
|
5188b6e697 | ||
|
|
812dc06988 | ||
|
|
376ed3f592 | ||
|
|
0543ed43b9 | ||
|
|
b486ca64d3 | ||
|
|
50b7300649 | ||
|
|
c9294d6df8 | ||
|
|
93f162b306 | ||
|
|
55a46a42b2 | ||
|
|
9cf04be857 | ||
|
|
654b4036b4 | ||
|
|
b58da74967 | ||
|
|
18821e2463 | ||
|
|
3b071eec9b |
@@ -1,63 +0,0 @@
|
|||||||
# In all environments, the following files are loaded if they exist,
|
|
||||||
# the latter taking precedence over the former:
|
|
||||||
#
|
|
||||||
# * .env contains default values for the environment variables needed by the app
|
|
||||||
# * .env.local uncommitted file with local overrides
|
|
||||||
# * .env.$APP_ENV committed environment-specific defaults
|
|
||||||
# * .env.$APP_ENV.local uncommitted environment-specific overrides
|
|
||||||
#
|
|
||||||
# Real environment variables win over .env files.
|
|
||||||
#
|
|
||||||
# DO NOT DEFINE PRODUCTION SECRETS IN THIS FILE NOR IN ANY OTHER COMMITTED FILES.
|
|
||||||
# https://symfony.com/doc/current/configuration/secrets.html
|
|
||||||
#
|
|
||||||
# Run "composer dump-env prod" to compile .env files for production use (requires symfony/flex >=1.2).
|
|
||||||
# https://symfony.com/doc/current/best_practices.html#use-environment-variables-for-infrastructure-configuration
|
|
||||||
|
|
||||||
###> symfony/framework-bundle ###
|
|
||||||
APP_ENV=dev
|
|
||||||
APP_SECRET=
|
|
||||||
###< symfony/framework-bundle ###
|
|
||||||
|
|
||||||
###> doctrine/doctrine-bundle ###
|
|
||||||
# Format described at https://www.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/configuration.html#connecting-using-a-url
|
|
||||||
# IMPORTANT: You MUST configure your server version, either here or in config/packages/doctrine.yaml
|
|
||||||
#
|
|
||||||
# DATABASE_URL="sqlite:///%kernel.project_dir%/var/data_%kernel.environment%.db"
|
|
||||||
# DATABASE_URL="mysql://app:!ChangeMe!@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
|
|
||||||
DATABASE_URL="mysql://escapepage:b.0nqrxJ%%2FD%%2ALuf9N@localhost:3306/escapepage?serverVersion=8.0.32&charset=utf8mb4"
|
|
||||||
###< doctrine/doctrine-bundle ###
|
|
||||||
|
|
||||||
###> symfony/messenger ###
|
|
||||||
# Choose one of the transports below
|
|
||||||
# MESSENGER_TRANSPORT_DSN=amqp://guest:guest@localhost:5672/%2f/messages
|
|
||||||
# MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
|
|
||||||
MESSENGER_TRANSPORT_DSN=doctrine://default?auto_setup=0
|
|
||||||
###< symfony/messenger ###
|
|
||||||
|
|
||||||
###> symfony/mailer ###
|
|
||||||
# Development: use Mailpit (docker compose override provides service `mailer` on port 1025)
|
|
||||||
MAILER_DSN=smtp://mailer:1025
|
|
||||||
# Production/Stage (uncomment and set SENDGRID_API_KEY in real env or secrets):
|
|
||||||
# MAILER_DSN=sendgrid+api://%env(SENDGRID_API_KEY)%
|
|
||||||
# Alternatively, via SMTP (no extra package needed):
|
|
||||||
# MAILER_DSN="smtp://apikey:%env(SENDGRID_API_KEY)%@smtp.sendgrid.net:587?encryption=tls"
|
|
||||||
# Optional default sender (used by test command if --from not passed):
|
|
||||||
# MAILER_FROM=no-reply@your-domain.tld
|
|
||||||
# SENDGRID_API_KEY=your_real_key_goes_here # Do NOT commit this; set in .env.local or deployment env
|
|
||||||
###< symfony/mailer ###
|
|
||||||
|
|
||||||
###> symfony/sendgrid-mailer ###
|
|
||||||
# MAILER_DSN=sendgrid://KEY@default
|
|
||||||
###< symfony/sendgrid-mailer ###
|
|
||||||
|
|
||||||
###> mercure ###
|
|
||||||
# Internal hub URL used by the PHP app (reachable from the php container)
|
|
||||||
MERCURE_URL=http://mercure/.well-known/mercure
|
|
||||||
# Public hub URL used by browsers
|
|
||||||
MERCURE_PUBLIC_URL=http://localhost:8090/.well-known/mercure
|
|
||||||
# Shared secret for signing JWTs (dev only). In prod, set via real env/secrets.
|
|
||||||
MERCURE_JWT_SECRET=!ChangeThisMercureJWT!
|
|
||||||
# Base URL for Mercure topics. Use .dev in development; override to .com in prod via .env.prod or real env.
|
|
||||||
MERCURE_TOPIC_BASE=https://escapepage.dev
|
|
||||||
###< mercure ###
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
|
|
||||||
###> symfony/framework-bundle ###
|
|
||||||
APP_SECRET=620e9ce5f88a714b636179eb39d5be4f
|
|
||||||
###< symfony/framework-bundle ###
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
### Compiled or real environment variables should be used in production.
|
|
||||||
### Configure MAILER_DSN to use SendGrid API transport.
|
|
||||||
### Prefer storing SENDGRID_API_KEY using Symfony Secrets or real env vars.
|
|
||||||
|
|
||||||
###> symfony/mailer ###
|
|
||||||
# Example using SendGrid API key (replace with real secret via vault/secrets):
|
|
||||||
# SENDGRID_API_KEY=SG.xxxxx
|
|
||||||
MAILER_DSN=sendgrid+api://%env(resolve:SENDGRID_API_KEY)%@default
|
|
||||||
###< symfony/mailer ###
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# define your env variables for the test env here
|
|
||||||
KERNEL_CLASS='App\Kernel'
|
|
||||||
APP_SECRET='$ecretf0rt3st'
|
|
||||||
+60
-2
@@ -1,6 +1,9 @@
|
|||||||
/* Game1 entry point built with Webpack Encore */
|
/* Game1 entry point built with Webpack Encore */
|
||||||
import './styles/game1.css';
|
import './styles/game1.css';
|
||||||
|
|
||||||
|
let sequenceFinished = false;
|
||||||
|
let stillPlayingSound = true;
|
||||||
|
|
||||||
function subscribeToMercure(mercurePublicUrl, topic) {
|
function subscribeToMercure(mercurePublicUrl, topic) {
|
||||||
try {
|
try {
|
||||||
const url = mercurePublicUrl + '?topic=' + encodeURIComponent(topic);
|
const url = mercurePublicUrl + '?topic=' + encodeURIComponent(topic);
|
||||||
@@ -10,6 +13,25 @@ function subscribeToMercure(mercurePublicUrl, topic) {
|
|||||||
try {
|
try {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
console.log('[Mercure][game1] Update:', data);
|
console.log('[Mercure][game1] Update:', data);
|
||||||
|
|
||||||
|
// data is [sendTo, message]
|
||||||
|
if (Array.isArray(data) && data.length >= 2) {
|
||||||
|
const messageContainer = document.getElementById('message-container');
|
||||||
|
if (messageContainer) {
|
||||||
|
const msgEl = document.createElement('div');
|
||||||
|
msgEl.className = 'message';
|
||||||
|
msgEl.textContent = data[1];
|
||||||
|
msgEl.style.color = '#0F0'; // Green for incoming messages
|
||||||
|
msgEl.style.marginBottom = '10px';
|
||||||
|
messageContainer.appendChild(msgEl);
|
||||||
|
if(stillPlayingSound)
|
||||||
|
playSound();
|
||||||
|
console.log('[Mercure][game1] sequenceFinished status:', sequenceFinished);
|
||||||
|
if (sequenceFinished) {
|
||||||
|
flashRed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log('[Mercure][game1] Raw event:', event.data);
|
console.log('[Mercure][game1] Raw event:', event.data);
|
||||||
}
|
}
|
||||||
@@ -25,6 +47,28 @@ function subscribeToMercure(mercurePublicUrl, topic) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function playSound() {
|
||||||
|
const sound = document.getElementById('message-sound');
|
||||||
|
if (sound) {
|
||||||
|
sound.currentTime = 0;
|
||||||
|
sound.play().catch(e => console.warn('[Audio] Playback failed:', e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function flashRed() {
|
||||||
|
console.log('[Game1] Triggering flashRed');
|
||||||
|
const body = document.body;
|
||||||
|
body.classList.remove('flash-red');
|
||||||
|
void body.offsetWidth; // Trigger reflow to restart animation
|
||||||
|
body.classList.add('flash-red');
|
||||||
|
|
||||||
|
// Also remove it after animation finishes so it's clean for inspection
|
||||||
|
setTimeout(() => {
|
||||||
|
body.classList.remove('flash-red');
|
||||||
|
console.log('[Game1] Removed flash-red class');
|
||||||
|
}, 150);
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchJson(url, options = {}) {
|
async function fetchJson(url, options = {}) {
|
||||||
const opts = { ...options };
|
const opts = { ...options };
|
||||||
const headers = new Headers(opts.headers || {});
|
const headers = new Headers(opts.headers || {});
|
||||||
@@ -125,16 +169,26 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
|
|
||||||
const printNextMessage = () => {
|
const printNextMessage = () => {
|
||||||
if (currentMessageIndex < messages.length) {
|
if (currentMessageIndex < messages.length) {
|
||||||
|
|
||||||
const msg = messages[currentMessageIndex];
|
const msg = messages[currentMessageIndex];
|
||||||
const msgEl = document.createElement('div');
|
const msgEl = document.createElement('div');
|
||||||
msgEl.className = 'message';
|
|
||||||
|
let extraClass = '';
|
||||||
|
if(msg[2])
|
||||||
|
extraClass = msg[2];
|
||||||
|
|
||||||
|
msgEl.className = 'message ' + extraClass;
|
||||||
msgEl.textContent = msg[0];
|
msgEl.textContent = msg[0];
|
||||||
msgEl.style.color = '#F00';
|
|
||||||
msgEl.style.marginBottom = '10px';
|
msgEl.style.marginBottom = '10px';
|
||||||
messageContainer.appendChild(msgEl);
|
messageContainer.appendChild(msgEl);
|
||||||
|
|
||||||
|
playSound();
|
||||||
|
|
||||||
currentMessageIndex++;
|
currentMessageIndex++;
|
||||||
setTimeout(printNextMessage, msg[1]);
|
setTimeout(printNextMessage, msg[1]);
|
||||||
|
if (sequenceFinished) {
|
||||||
|
flashRed();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// After it has printed a set of messages, it has to start a timer of 2 seconds
|
// After it has printed a set of messages, it has to start a timer of 2 seconds
|
||||||
console.log('[Game1] All messages printed. Starting 2s timer to expand message-container height...');
|
console.log('[Game1] All messages printed. Starting 2s timer to expand message-container height...');
|
||||||
@@ -146,6 +200,8 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
// Add event listener for Enter key
|
// Add event listener for Enter key
|
||||||
inputField.addEventListener('keypress', async (e) => {
|
inputField.addEventListener('keypress', async (e) => {
|
||||||
if (e.key === 'Enter') {
|
if (e.key === 'Enter') {
|
||||||
|
stillPlayingSound = false;
|
||||||
|
sequenceFinished = false;
|
||||||
const message = inputField.value.trim();
|
const message = inputField.value.trim();
|
||||||
if (message && apiEchoUrl) {
|
if (message && apiEchoUrl) {
|
||||||
inputField.value = '';
|
inputField.value = '';
|
||||||
@@ -163,6 +219,8 @@ document.addEventListener('DOMContentLoaded', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
console.log('[Game1] message-container height changed to 400vh and input enabled');
|
console.log('[Game1] message-container height changed to 400vh and input enabled');
|
||||||
|
sequenceFinished = true;
|
||||||
|
console.log('[Game1] sequenceFinished is now TRUE');
|
||||||
}, 2000);
|
}, 2000);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
+29
-3
@@ -47,6 +47,10 @@ div#message-container {
|
|||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.message {
|
||||||
|
color: #C0C0C0;
|
||||||
|
}
|
||||||
|
|
||||||
div#input {
|
div#input {
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
}
|
}
|
||||||
@@ -54,10 +58,32 @@ div#input {
|
|||||||
input#input-message {
|
input#input-message {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
background: #000;
|
background: #111;
|
||||||
border: 1px solid #F00;
|
border: 1px solid #A00000;
|
||||||
color: #F00;
|
color: #C0C0C0;
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.flash-red::after {
|
||||||
|
content: '';
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 100px;
|
||||||
|
pointer-events: none;
|
||||||
|
background: linear-gradient(to top, rgba(255, 0, 0, 0.8), transparent);
|
||||||
|
animation: flash-red-anim 0.1s linear forwards;
|
||||||
|
z-index: 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes flash-red-anim {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Binary file not shown.
@@ -11,4 +11,5 @@ enum SessionSettingType: string
|
|||||||
case RIGHTS_FOR_PLAYER2 = 'RightsForPlayer2';
|
case RIGHTS_FOR_PLAYER2 = 'RightsForPlayer2';
|
||||||
case RIGHTS_FOR_PLAYER3 = 'RightsForPlayer3';
|
case RIGHTS_FOR_PLAYER3 = 'RightsForPlayer3';
|
||||||
case INVITE_CODE = 'InviteCode';
|
case INVITE_CODE = 'InviteCode';
|
||||||
|
case SET_OF_DELETED_FILES = 'SetOfDeletedFiles';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ use App\Game\Entity\Player;
|
|||||||
use App\Game\Repository\SessionSettingRepository;
|
use App\Game\Repository\SessionSettingRepository;
|
||||||
use App\Tech\Entity\User;
|
use App\Tech\Entity\User;
|
||||||
use Symfony\Bundle\SecurityBundle\Security;
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
|
use Symfony\Component\Mercure\HubInterface;
|
||||||
|
use Symfony\Component\Mercure\Update;
|
||||||
|
|
||||||
class GameResponseService
|
class GameResponseService
|
||||||
{
|
{
|
||||||
@@ -15,10 +17,11 @@ class GameResponseService
|
|||||||
private Security $security,
|
private Security $security,
|
||||||
private PlayerService $playerService,
|
private PlayerService $playerService,
|
||||||
private SessionSettingRepository $sessionSettingRepository,
|
private SessionSettingRepository $sessionSettingRepository,
|
||||||
|
private HubInterface $hub,
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGameResponse(string $raw)
|
public function getGameResponse(string $raw) : array
|
||||||
{
|
{
|
||||||
$info = json_decode($raw, true);
|
$info = json_decode($raw, true);
|
||||||
|
|
||||||
@@ -83,8 +86,10 @@ class GameResponseService
|
|||||||
if(!in_array('chat', $rechten))
|
if(!in_array('chat', $rechten))
|
||||||
return ['result' => ['Unknown command']];
|
return ['result' => ['Unknown command']];
|
||||||
|
|
||||||
$this->handleChatMessage($message);
|
if($this->handleChatMessage($message, $player))
|
||||||
break;
|
return ['result' => ['succesfully send']];
|
||||||
|
else
|
||||||
|
return ['result' => ['Error sending']];
|
||||||
case '/help':
|
case '/help':
|
||||||
return ['result' => $this->getHelpCommand($rechten)];
|
return ['result' => $this->getHelpCommand($rechten)];
|
||||||
case '/decode':
|
case '/decode':
|
||||||
@@ -101,7 +106,6 @@ class GameResponseService
|
|||||||
default:
|
default:
|
||||||
return ['result' => ['Unknown command']];
|
return ['result' => ['Unknown command']];
|
||||||
}
|
}
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function checkConsoleCommando(string $message, Player $player, bool $sudo = false) : array
|
private function checkConsoleCommando(string $message, Player $player, bool $sudo = false) : array
|
||||||
@@ -112,8 +116,15 @@ class GameResponseService
|
|||||||
case 'help':
|
case 'help':
|
||||||
return ['result' => $this->getHelpCommand($rechten)];
|
return ['result' => $this->getHelpCommand($rechten)];
|
||||||
case 'ls':
|
case 'ls':
|
||||||
break;
|
if(!in_array('ls', $rechten))
|
||||||
|
return ['result' => ['Unknown command']];
|
||||||
|
|
||||||
|
$files = $this->getAllCurrentFilesInDirectory($player);
|
||||||
|
return ['result' => $files];
|
||||||
case 'cd':
|
case 'cd':
|
||||||
|
if(!in_array('cd', $rechten))
|
||||||
|
return ['result' => ['Unknown command']];
|
||||||
|
|
||||||
$pwd = $this->playerService->getCurrentPwdOfPlayer($player);
|
$pwd = $this->playerService->getCurrentPwdOfPlayer($player);
|
||||||
if(!$pwd)
|
if(!$pwd)
|
||||||
return ['result' => ['Unknown command']];
|
return ['result' => ['Unknown command']];
|
||||||
@@ -124,14 +135,43 @@ class GameResponseService
|
|||||||
|
|
||||||
$this->playerService->saveCurrentPwdOfPlayer($player, $newLocation);
|
$this->playerService->saveCurrentPwdOfPlayer($player, $newLocation);
|
||||||
return ['result' => ['Path: ' . $newLocation]];
|
return ['result' => ['Path: ' . $newLocation]];
|
||||||
|
case 'pwd':
|
||||||
|
if(!in_array('pwd', $rechten))
|
||||||
|
return ['result' => ['Unknown command']];
|
||||||
|
|
||||||
|
$pwd = $this->playerService->getCurrentPwdOfPlayer($player);
|
||||||
|
return ['result' => ['Path: ' . $pwd]];
|
||||||
case 'rm':
|
case 'rm':
|
||||||
break;
|
if(!in_array('rm', $rechten))
|
||||||
|
return ['result' => ['Unknown command']];
|
||||||
|
|
||||||
|
$pwd = $this->playerService->getCurrentPwdOfPlayer($player);
|
||||||
|
if(!$pwd)
|
||||||
|
return ['result' => ['Unknown command']];
|
||||||
|
|
||||||
|
if (!isset($messagePart[1])) {
|
||||||
|
return ['result' => ['Usage: rm {filename}']];
|
||||||
|
}
|
||||||
|
|
||||||
|
$filename = $messagePart[1];
|
||||||
|
$fullPath = ($pwd === '/' ? '' : $pwd) . '/' . $filename;
|
||||||
|
|
||||||
|
if(!$this->isAllowedToRemove($fullPath, $player, $sudo))
|
||||||
|
return ['result' => ['You are not allowed to remove this file.']];
|
||||||
|
|
||||||
|
$this->playerService->addDeletedFileToSession($player, $fullPath);
|
||||||
|
return ['result' => ['File removed: ' . $filename]];
|
||||||
case 'sudo':
|
case 'sudo':
|
||||||
break;
|
if(!in_array('sudo', $rechten))
|
||||||
|
return ['result' => ['Unknown command']];
|
||||||
|
|
||||||
|
$sudo = array_shift($messagePart);
|
||||||
|
$message = implode(' ', $messagePart);
|
||||||
|
|
||||||
|
return $this->checkConsoleCommando($message, $player, true);
|
||||||
default:
|
default:
|
||||||
return ['result' => ['Unknown command']];
|
return ['result' => ['Unknown command']];
|
||||||
}
|
}
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getHelpCommand(mixed $rechten) : array
|
private function getHelpCommand(mixed $rechten) : array
|
||||||
@@ -161,6 +201,13 @@ class GameResponseService
|
|||||||
$messages[] = ' USAGE: /decode {message}';
|
$messages[] = ' USAGE: /decode {message}';
|
||||||
$messages[] = '';
|
$messages[] = '';
|
||||||
break;
|
break;
|
||||||
|
case 'pwd':
|
||||||
|
$messages[] = 'pwd';
|
||||||
|
$messages[] = ' This message will let you know what your current location is.';
|
||||||
|
$messages[] = ' It will show you the folder you are in so you can continue navigating the server.';
|
||||||
|
$messages[] = ' USAGE: pwd';
|
||||||
|
$messages[] = '';
|
||||||
|
break;
|
||||||
case 'cat':
|
case 'cat':
|
||||||
$messages[] = 'cat';
|
$messages[] = 'cat';
|
||||||
$messages[] = ' To read a file, use cat {filename}.';
|
$messages[] = ' To read a file, use cat {filename}.';
|
||||||
@@ -210,9 +257,42 @@ class GameResponseService
|
|||||||
return $messages;
|
return $messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function handleChatMessage(string $message)
|
private function handleChatMessage(string $message, Player $player) : bool
|
||||||
{
|
{
|
||||||
|
$messageParts = explode(' ', $message);
|
||||||
|
$toSingle = false;
|
||||||
|
|
||||||
|
if (isset($messageParts[1]) &&
|
||||||
|
is_numeric($messageParts[1]) &&
|
||||||
|
$messageParts[1] >= 1 &&
|
||||||
|
$messageParts[1] <= 3) {
|
||||||
|
|
||||||
|
$toSingle = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$chatMessage = array_shift($messageParts);
|
||||||
|
$sendTo = 0;
|
||||||
|
|
||||||
|
if ($toSingle) {
|
||||||
|
$sendTo = array_shift($messageParts);
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = $player->getUser()->getUsername() . ': ' . $chatMessage;
|
||||||
|
foreach($messageParts as $messagePart) {
|
||||||
|
$message .= $messagePart . ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
$message = trim($message);
|
||||||
|
|
||||||
|
$activeGame = $player->getSession()?->getId();
|
||||||
|
|
||||||
|
if(is_null($activeGame))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
$topic = $_ENV['MERCURE_TOPIC_BASE'] . '/game/hub-' . $activeGame;
|
||||||
|
$this->hub->publish(new Update($topic, json_encode([$sendTo, $message])));
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function handleDecodeMessage(string $message, Player $player)
|
private function handleDecodeMessage(string $message, Player $player)
|
||||||
@@ -329,4 +409,113 @@ class GameResponseService
|
|||||||
|
|
||||||
return $paths;
|
return $paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function isAllowedToRemove(string $file, Player $player, bool $sudo) : bool
|
||||||
|
{
|
||||||
|
if(!$this->fileExists($file))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(str_starts_with($file, '/var/rapports/'))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
$rights = $this->getRechten($player);
|
||||||
|
|
||||||
|
if(in_array('sudo', $rights) || $sudo)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
$sudoFiles = [
|
||||||
|
'/var/arrest/handle.sh',
|
||||||
|
'/var/arrest/cell.sh',
|
||||||
|
'/var/marriage/divorce.sh',
|
||||||
|
];
|
||||||
|
|
||||||
|
return !in_array($file, $sudoFiles);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function fileExists(string $file)
|
||||||
|
{
|
||||||
|
$files = $this->getAllPossibleFiles();
|
||||||
|
|
||||||
|
if(in_array($file, $files))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAllPossibleFiles()
|
||||||
|
{
|
||||||
|
$files = [];
|
||||||
|
|
||||||
|
$files[] = '/var/arrest/handle.sh';
|
||||||
|
$files[] = '/var/arrest/bars.sh';
|
||||||
|
$files[] = '/var/arrest/cell.sh';
|
||||||
|
$files[] = '/var/marriage/share.sh';
|
||||||
|
$files[] = '/var/marriage/divorce.sh';
|
||||||
|
$files[] = '/var/rapports/095_07-14.txt';
|
||||||
|
$files[] = '/var/rapports/007_19-52.txt';
|
||||||
|
$files[] = '/var/rapports/083_25-39.txt';
|
||||||
|
$files[] = '/var/rapports/019_31-11.txt';
|
||||||
|
$files[] = '/var/rapports/075_46-77.txt';
|
||||||
|
$files[] = '/var/rapports/031_53-28.txt';
|
||||||
|
$files[] = '/var/rapports/072_61-05.txt';
|
||||||
|
$files[] = '/var/rapports/064_72-90.txt';
|
||||||
|
$files[] = '/var/rapports/091_81-33.txt';
|
||||||
|
$files[] = '/var/rapports/079_89-47.txt';
|
||||||
|
$files[] = '/var/rapports/098_92-14.txt';
|
||||||
|
$files[] = '/var/rapports/012_94-31.txt';
|
||||||
|
$files[] = '/var/rapports/016_98-07.txt';
|
||||||
|
$files[] = '/var/rapports/087_102-45.txt';
|
||||||
|
$files[] = '/var/rapports/094_110-19.txt';
|
||||||
|
$files[] = '/var/rapports/063_117-56.txt';
|
||||||
|
$files[] = '/var/rapports/017_123-88.txt';
|
||||||
|
$files[] = '/var/rapports/093_138-24.txt';
|
||||||
|
$files[] = '/var/rapports/001_145-93.txt';
|
||||||
|
$files[] = '/var/rapports/index.txt';
|
||||||
|
|
||||||
|
return $files;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getAllCurrentFilesInDirectory(Player $player) : array
|
||||||
|
{
|
||||||
|
$pwd = $this->playerService->getCurrentPwdOfPlayer($player);
|
||||||
|
if (!$pwd) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
$allPaths = $this->getAllPossiblePaths($player);
|
||||||
|
$allFiles = $this->getAllPossibleFiles();
|
||||||
|
$deletedFiles = $this->playerService->getDeletedFilesOfSession($player);
|
||||||
|
|
||||||
|
$entries = [];
|
||||||
|
|
||||||
|
// Find directories in current pwd
|
||||||
|
foreach ($allPaths as $path) {
|
||||||
|
if ($path === $pwd) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if $path is a direct child of $pwd
|
||||||
|
$parent = $this->getPrevPath($path);
|
||||||
|
if ($parent === $pwd) {
|
||||||
|
$parts = explode('/', $path);
|
||||||
|
$entries[] = [end($parts) . '/', 'dir'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find files in current pwd
|
||||||
|
foreach ($allFiles as $file) {
|
||||||
|
if (in_array($file, $deletedFiles)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$parent = $this->getPrevPath($file);
|
||||||
|
if ($parent === $pwd) {
|
||||||
|
$parts = explode('/', $file);
|
||||||
|
$entries[] = [end($parts), 'file'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sort($entries);
|
||||||
|
return $entries;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ namespace App\Game\Service;
|
|||||||
|
|
||||||
use App\Game\Entity\Game;
|
use App\Game\Entity\Game;
|
||||||
use App\Game\Entity\Player;
|
use App\Game\Entity\Player;
|
||||||
|
use App\Game\Entity\SessionSetting;
|
||||||
use App\Game\Enum\SessionSettingType;
|
use App\Game\Enum\SessionSettingType;
|
||||||
use App\Game\Enum\SessionStatus;
|
use App\Game\Enum\SessionStatus;
|
||||||
use App\Game\Repository\PlayerRepository;
|
use App\Game\Repository\PlayerRepository;
|
||||||
@@ -73,4 +74,33 @@ class PlayerService
|
|||||||
$this->entityManager->persist($setting);
|
$this->entityManager->persist($setting);
|
||||||
$this->entityManager->flush();
|
$this->entityManager->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getDeletedFilesOfSession(Player $player): array
|
||||||
|
{
|
||||||
|
$setting = $this->sessionSettingRepository->getSetting($player->getSession(), SessionSettingType::SET_OF_DELETED_FILES);
|
||||||
|
if (!$setting || !$setting->getValue()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return json_decode($setting->getValue(), true) ?? [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addDeletedFileToSession(Player $player, string $filename): void
|
||||||
|
{
|
||||||
|
$setting = $this->sessionSettingRepository->getSetting($player->getSession(), SessionSettingType::SET_OF_DELETED_FILES);
|
||||||
|
if (!$setting) {
|
||||||
|
$setting = new SessionSetting();
|
||||||
|
$setting->setSession($player->getSession());
|
||||||
|
$setting->setName(SessionSettingType::SET_OF_DELETED_FILES);
|
||||||
|
}
|
||||||
|
|
||||||
|
$deletedFiles = json_decode($setting->getValue() ?? '[]', true) ?? [];
|
||||||
|
if (!in_array($filename, $deletedFiles)) {
|
||||||
|
$deletedFiles[] = $filename;
|
||||||
|
$setting->setValue(json_encode($deletedFiles));
|
||||||
|
|
||||||
|
$this->entityManager->persist($setting);
|
||||||
|
$this->entityManager->flush();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,10 +15,9 @@
|
|||||||
<div id="game-container">
|
<div id="game-container">
|
||||||
<div id="mercure-config"
|
<div id="mercure-config"
|
||||||
data-mercure-public-url="{{ mercure_public_url|e('html_attr') }}"
|
data-mercure-public-url="{{ mercure_public_url|e('html_attr') }}"
|
||||||
data-topic="{{ (mercure_topic_base ~ '/game/hub')|e('html_attr') }}"
|
data-topic="{{ (mercure_topic_base ~ '/game/hub-' ~ session.id)|e('html_attr') }}"
|
||||||
data-api-ping-url="{{ path('game_api_ping')|e('html_attr') }}"
|
data-api-ping-url="{{ path('game_api_ping')|e('html_attr') }}"
|
||||||
data-api-echo-url="{{ path('game_api_message')|e('html_attr') }}"
|
data-api-echo-url="{{ path('game_api_message')|e('html_attr') }}"
|
||||||
data-user-id="{{ user_id|e('html_attr') }}"
|
|
||||||
style="display:none">
|
style="display:none">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -28,6 +27,9 @@
|
|||||||
<div id="message-container">
|
<div id="message-container">
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
<audio id="message-sound" style="display:none">
|
||||||
|
<source src="{{ asset('audio/message.mp3') }}" type="audio/mpeg">
|
||||||
|
</audio>
|
||||||
<div id="input">
|
<div id="input">
|
||||||
<input type="text" disabled id="input-message">
|
<input type="text" disabled id="input-message">
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user