From 8e3807e07944a81e7700b2d60ff5743b9cf06e66 Mon Sep 17 00:00:00 2001 From: Frank Date: Mon, 5 Jan 2026 23:37:36 +0100 Subject: [PATCH] Toevoeging van meer responses op messages --- src/Game/Entity/Game.php | 74 +++++++++++ src/Game/Entity/GameSetting.php | 9 +- src/Game/Entity/Session.php | 72 ++++++++++- src/Game/Entity/SessionSetting.php | 9 +- src/Game/Enum/GameSettingType.php | 8 ++ src/Game/Enum/SessionSettingType.php | 13 ++ src/Game/Repository/GameSettingRepository.php | 10 ++ .../Repository/SessionSettingRepository.php | 5 +- src/Game/Service/GameResponseService.php | 121 ++++++++++++++++-- src/Game/Service/PlayerService.php | 41 ++++++ 10 files changed, 340 insertions(+), 22 deletions(-) create mode 100644 src/Game/Enum/GameSettingType.php create mode 100644 src/Game/Enum/SessionSettingType.php diff --git a/src/Game/Entity/Game.php b/src/Game/Entity/Game.php index 19d5b72..99f3464 100644 --- a/src/Game/Entity/Game.php +++ b/src/Game/Entity/Game.php @@ -4,6 +4,8 @@ namespace App\Game\Entity; use App\Game\Enum\GameStatus; use App\Game\Repository\GameRepository; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity(repositoryClass: GameRepository::class)] @@ -24,6 +26,18 @@ class Game #[ORM\Column(type: 'string', length: 20, enumType: GameStatus::class)] private ?GameStatus $status = null; + #[ORM\OneToMany(mappedBy: 'game', targetEntity: Session::class)] + private Collection $sessions; + + #[ORM\OneToMany(mappedBy: 'game', targetEntity: GameSetting::class)] + private Collection $settings; + + public function __construct() + { + $this->sessions = new ArrayCollection(); + $this->settings = new ArrayCollection(); + } + public function getId(): ?int { return $this->id; @@ -64,4 +78,64 @@ class Game return $this; } + + /** + * @return Collection + */ + public function getSessions(): Collection + { + return $this->sessions; + } + + public function addSession(Session $session): static + { + if (!$this->sessions->contains($session)) { + $this->sessions->add($session); + $session->setGame($this); + } + + return $this; + } + + public function removeSession(Session $session): static + { + if ($this->sessions->removeElement($session)) { + // set the owning side to null (unless already changed) + if ($session->getGame() === $this) { + $session->setGame(null); + } + } + + return $this; + } + + /** + * @return Collection + */ + public function getSettings(): Collection + { + return $this->settings; + } + + public function addSetting(GameSetting $setting): static + { + if (!$this->settings->contains($setting)) { + $this->settings->add($setting); + $setting->setGame($this); + } + + return $this; + } + + public function removeSetting(GameSetting $setting): static + { + if ($this->settings->removeElement($setting)) { + // set the owning side to null (unless already changed) + if ($setting->getGame() === $this) { + $setting->setGame(null); + } + } + + return $this; + } } diff --git a/src/Game/Entity/GameSetting.php b/src/Game/Entity/GameSetting.php index e008b15..47bdbee 100644 --- a/src/Game/Entity/GameSetting.php +++ b/src/Game/Entity/GameSetting.php @@ -2,6 +2,7 @@ namespace App\Game\Entity; +use App\Game\Enum\GameSettingType; use App\Game\Repository\GameSettingRepository; use Doctrine\ORM\Mapping as ORM; @@ -18,8 +19,8 @@ class GameSetting #[ORM\JoinColumn(nullable: false)] private ?Game $game = null; - #[ORM\Column(length: 255)] - private ?string $name = null; + #[ORM\Column(type: 'string', length: 255, enumType: GameSettingType::class)] + private ?GameSettingType $name = null; #[ORM\Column(type: 'text', nullable: true)] private ?string $value = null; @@ -41,12 +42,12 @@ class GameSetting return $this; } - public function getName(): ?string + public function getName(): ?GameSettingType { return $this->name; } - public function setName(string $name): static + public function setName(GameSettingType $name): static { $this->name = $name; diff --git a/src/Game/Entity/Session.php b/src/Game/Entity/Session.php index a2afc58..2659ad6 100644 --- a/src/Game/Entity/Session.php +++ b/src/Game/Entity/Session.php @@ -4,6 +4,8 @@ namespace App\Game\Entity; use App\Game\Enum\SessionStatus; use App\Game\Repository\SessionRepository; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\DBAL\Types\Types; use Doctrine\ORM\Mapping as ORM; @@ -16,7 +18,7 @@ class Session #[ORM\Column] private ?int $id = null; - #[ORM\ManyToOne(targetEntity: Game::class)] + #[ORM\ManyToOne(targetEntity: Game::class, inversedBy: 'sessions')] #[ORM\JoinColumn(nullable: false)] private ?Game $game = null; @@ -29,9 +31,17 @@ class Session #[ORM\Column(type: Types::DATETIME_MUTABLE)] private ?\DateTimeInterface $created = null; + #[ORM\OneToMany(mappedBy: 'session', targetEntity: Player::class)] + private Collection $players; + + #[ORM\OneToMany(mappedBy: 'session', targetEntity: SessionSetting::class)] + private Collection $settings; + public function __construct() { $this->created = new \DateTime(); + $this->players = new ArrayCollection(); + $this->settings = new ArrayCollection(); } public function getId(): ?int @@ -86,4 +96,64 @@ class Session return $this; } + + /** + * @return Collection + */ + public function getPlayers(): Collection + { + return $this->players; + } + + public function addPlayer(Player $player): static + { + if (!$this->players->contains($player)) { + $this->players->add($player); + $player->setSession($this); + } + + return $this; + } + + public function removePlayer(Player $player): static + { + if ($this->players->removeElement($player)) { + // set the owning side to null (unless already changed) + if ($player->getSession() === $this) { + $player->setSession(null); + } + } + + return $this; + } + + /** + * @return Collection + */ + public function getSettings(): Collection + { + return $this->settings; + } + + public function addSetting(SessionSetting $setting): static + { + if (!$this->settings->contains($setting)) { + $this->settings->add($setting); + $setting->setSession($this); + } + + return $this; + } + + public function removeSetting(SessionSetting $setting): static + { + if ($this->settings->removeElement($setting)) { + // set the owning side to null (unless already changed) + if ($setting->getSession() === $this) { + $setting->setSession(null); + } + } + + return $this; + } } diff --git a/src/Game/Entity/SessionSetting.php b/src/Game/Entity/SessionSetting.php index 9328c4f..215a53f 100644 --- a/src/Game/Entity/SessionSetting.php +++ b/src/Game/Entity/SessionSetting.php @@ -2,6 +2,7 @@ namespace App\Game\Entity; +use App\Game\Enum\SessionSettingType; use App\Game\Repository\SessionSettingRepository; use Doctrine\ORM\Mapping as ORM; @@ -22,8 +23,8 @@ class SessionSetting #[ORM\JoinColumn(nullable: true)] private ?Player $player = null; - #[ORM\Column(length: 255)] - private ?string $name = null; + #[ORM\Column(type: 'string', length: 255, enumType: SessionSettingType::class)] + private ?SessionSettingType $name = null; #[ORM\Column(type: 'text', nullable: true)] private ?string $value = null; @@ -57,12 +58,12 @@ class SessionSetting return $this; } - public function getName(): ?string + public function getName(): ?SessionSettingType { return $this->name; } - public function setName(string $name): static + public function setName(SessionSettingType $name): static { $this->name = $name; diff --git a/src/Game/Enum/GameSettingType.php b/src/Game/Enum/GameSettingType.php new file mode 100644 index 0000000..7b86da2 --- /dev/null +++ b/src/Game/Enum/GameSettingType.php @@ -0,0 +1,8 @@ +findOneBy([ + 'game' => $game, + 'name' => $name, + ]); + } } diff --git a/src/Game/Repository/SessionSettingRepository.php b/src/Game/Repository/SessionSettingRepository.php index 2b6df09..45b788a 100644 --- a/src/Game/Repository/SessionSettingRepository.php +++ b/src/Game/Repository/SessionSettingRepository.php @@ -2,6 +2,7 @@ namespace App\Game\Repository; +use App\Game\Enum\SessionSettingType; use App\Game\Entity\Player; use App\Game\Entity\Session; use App\Game\Entity\SessionSetting; @@ -18,13 +19,13 @@ class SessionSettingRepository extends ServiceEntityRepository parent::__construct($registry, SessionSetting::class); } - public function getSetting(Session $session, string $name, ?Player $player = null): ?SessionSetting + public function getSetting(Session $session, SessionSettingType $name, ?Player $player = null): ?SessionSetting { $qb = $this->createQueryBuilder('s') ->where('s.session = :session') ->andWhere('s.name = :name') ->setParameter('session', $session) - ->setParameter('name', $name); + ->setParameter('name', $name->value); if ($player) { $qb->andWhere('s.player = :player') diff --git a/src/Game/Service/GameResponseService.php b/src/Game/Service/GameResponseService.php index cd31eac..057b31d 100644 --- a/src/Game/Service/GameResponseService.php +++ b/src/Game/Service/GameResponseService.php @@ -3,6 +3,7 @@ namespace App\Game\Service; use App\Game\Enum\DecodeMessage; +use App\Game\Enum\SessionSettingType; use App\Game\Entity\Player; use App\Game\Repository\SessionSettingRepository; use App\Tech\Entity\User; @@ -52,7 +53,18 @@ class GameResponseService private function getRechten(Player $player): array { - $setting = $this->sessionSettingRepository->getSetting($player->getSession(), 'level', $player); + $settingName = match($player->getScreen()) { + 1 => SessionSettingType::RIGHTS_FOR_PLAYER1, + 2 => SessionSettingType::RIGHTS_FOR_PLAYER2, + 3 => SessionSettingType::RIGHTS_FOR_PLAYER3, + default => null, + }; + + if (!$settingName) { + return []; + } + + $setting = $this->sessionSettingRepository->getSetting($player->getSession(), $settingName, $player); if (!$setting || !$setting->getValue()) { return []; } @@ -69,7 +81,7 @@ class GameResponseService switch($messagePart[0]) { case '/chat': if(!in_array('chat', $rechten)) - return ['result' => ['Unknown command.']]; + return ['result' => ['Unknown command']]; $this->handleChatMessage($message); break; @@ -77,22 +89,22 @@ class GameResponseService return ['result' => $this->getHelpCommand($rechten)]; case '/decode': if(!in_array('decode', $rechten)) - return ['result' => ['Unknown command.']]; + return ['result' => ['Unknown command']]; return ['result' => [$this->handleDecodeMessage($messagePart[1], $player)]]; case '/verify': if(!in_array('verify', $rechten)) - return ['result' => ['Unknown command.']]; + return ['result' => ['Unknown command']]; - $this->handleVerifyMessage($message); - break; + $result = $this->handleVerifyMessage($message); + return ['result' => [$result]]; default: - return ['result' => ['Unknown command.']]; + return ['result' => ['Unknown command']]; } return []; } - private function checkConsoleCommando(string $message, Player $player) : array + private function checkConsoleCommando(string $message, Player $player, bool $sudo = false) : array { $messagePart = explode(' ', $message); $rechten = $this->getRechten($player); @@ -102,14 +114,22 @@ class GameResponseService case 'ls': break; case 'cd': + $pwd = $this->playerService->getCurrentPwdOfPlayer($player); + if(!$pwd) + return ['result' => ['Unknown command']]; + $newLocation = $this->goToNewDir($pwd, $messagePart[1], $player); - break; + if($newLocation === false) + return ['result' => ['Unknown path']]; + + $this->playerService->saveCurrentPwdOfPlayer($player, $newLocation); + return ['result' => ['Path: ' . $newLocation]]; case 'rm': break; case 'sudo': break; default: - return ['result' => ['Unknown command.']]; + return ['result' => ['Unknown command']]; } return []; } @@ -227,7 +247,86 @@ class GameResponseService return $randomString; } - private function handleVerifyMessage(string $message) + private function handleVerifyMessage(string $message) : string { + return ''; + } + + private function goToNewDir(string $pwd, string $newPwd, Player $player) : string|bool + { + $allPossiblePaths = $this->getAllPossiblePaths($player); + + $dirParts = explode('/', $newPwd); + + $int = count($dirParts); + + if($dirParts[0] == '') { + $newDir = ''; + $startPart = 1; + } else { + $newDir = $pwd; + $startPart = 0; + } + + for($i = $startPart; $i < $int; $i++) { + if($dirParts[$i] == '..') + $newDir = $this->getPrevPath($newDir); + else + $newDir .= '/' . $dirParts[$i]; + + if(!in_array($newDir, $allPossiblePaths)) + return false; + } + + return $newDir; + } + + private function getPrevPath(string $pwd) : string + { + $pwdParts = explode('/', $pwd); + array_pop($pwdParts); + $pwd = implode('/', $pwdParts); + return $pwd; + } + + private function getAllPossiblePaths(Player $player) : array + { + $paths = []; + + $paths[] = '/'; + $paths[] = '/var'; + $paths[] = '/var/arrest'; + $paths[] = '/var/www'; + $paths[] = '/var/marriage'; + $paths[] = '/var/rapports'; + $paths[] = '/var/linking'; + + $paths[] = '/etc'; + $paths[] = '/etc/short'; + $paths[] = '/etc/long'; + $paths[] = '/etc/arrest'; + $paths[] = '/etc/power'; + $paths[] = '/etc/break'; + $paths[] = '/etc/handle'; + $paths[] = '/etc/freak'; + $paths[] = '/etc/host'; + + $paths[] = '/home'; + + $playerNames = ['root', 'Luke', 'Charles', 'William', 'Peter']; + + $players = $player->getSession()->getPlayers(); + + foreach($players as $player) { + $playerNames[] = $player->getUser()->getUsername(); + } + + $playerNames = array_unique($playerNames); + + foreach($playerNames as $name) { + $paths[] = '/home/' . $name; + } + + return $paths; } } diff --git a/src/Game/Service/PlayerService.php b/src/Game/Service/PlayerService.php index e691d8b..23e8f5c 100644 --- a/src/Game/Service/PlayerService.php +++ b/src/Game/Service/PlayerService.php @@ -4,14 +4,19 @@ namespace App\Game\Service; use App\Game\Entity\Game; use App\Game\Entity\Player; +use App\Game\Enum\SessionSettingType; use App\Game\Enum\SessionStatus; use App\Game\Repository\PlayerRepository; +use App\Game\Repository\SessionSettingRepository; use App\Tech\Entity\User; +use Doctrine\ORM\EntityManagerInterface; class PlayerService { public function __construct( private PlayerRepository $playerRepository, + private SessionSettingRepository $sessionSettingRepository, + private EntityManagerInterface $entityManager, ) { } @@ -32,4 +37,40 @@ class PlayerService return $player; } + + public function getCurrentPwdOfPlayer(Player $player) : ?string { + $settingName = match($player->getScreen()) { + 1 => SessionSettingType::PWD_FOR_PLAYER1, + 2 => SessionSettingType::PWD_FOR_PLAYER2, + 3 => SessionSettingType::PWD_FOR_PLAYER3, + default => null, + }; + + if (!$settingName) { + return null; + } + + $setting = $this->sessionSettingRepository->getSetting($player->getSession(), $settingName, $player); + return $setting?->getValue(); + } + + public function saveCurrentPwdOfPlayer(Player $player, string $newLocation) + { + $settingName = match($player->getScreen()) { + 1 => SessionSettingType::PWD_FOR_PLAYER1, + 2 => SessionSettingType::PWD_FOR_PLAYER2, + 3 => SessionSettingType::PWD_FOR_PLAYER3, + default => null, + }; + + if (!$settingName) { + return; + } + + $setting = $this->sessionSettingRepository->getSetting($player->getSession(), $settingName, $player); + $setting->setValue($newLocation); + + $this->entityManager->persist($setting); + $this->entityManager->flush(); + } }