MAPG-235 new challenge can be created and is prepared
This commit is contained in:
parent
99244e93d2
commit
d7147b30d6
@ -16,7 +16,7 @@ CREATE TABLE `user_in_challenge` (
|
|||||||
`round` smallint(5) signed NOT NULL DEFAULT -1,
|
`round` smallint(5) signed NOT NULL DEFAULT -1,
|
||||||
`score` int(10) unsigned NOT NULL DEFAULT 0,
|
`score` int(10) unsigned NOT NULL DEFAULT 0,
|
||||||
`time_left` int(10) unsigned,
|
`time_left` int(10) unsigned,
|
||||||
`owner` tinyint(1) NOT NULL DEFAULT 0,
|
`is_owner` tinyint(1) NOT NULL DEFAULT 0,
|
||||||
PRIMARY KEY (`id`),
|
PRIMARY KEY (`id`),
|
||||||
KEY `user_id` (`user_id`),
|
KEY `user_id` (`user_id`),
|
||||||
KEY `challenge_id` (`challenge_id`),
|
KEY `challenge_id` (`challenge_id`),
|
||||||
|
@ -75,6 +75,25 @@ div.mapItem>div.buttonContainer {
|
|||||||
grid-auto-flow: column;
|
grid-auto-flow: column;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#restrictions {
|
||||||
|
margin-top: 1em;
|
||||||
|
font-family: 'Roboto', sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
#restrictions h3 {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
#restrictions input[type=checkbox] {
|
||||||
|
height: auto;
|
||||||
|
margin: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#restrictions input[type=range] {
|
||||||
|
height: 1.5em;
|
||||||
|
margin-left: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 1504px) {
|
@media screen and (min-width: 1504px) {
|
||||||
#mapContainer {
|
#mapContainer {
|
||||||
grid-template-columns: auto auto auto auto;
|
grid-template-columns: auto auto auto auto;
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
|
const GameType = Object.freeze({'SINGLE': 0, 'MULTI': 1, 'CHALLENGE': 2});
|
||||||
|
|
||||||
(function () {
|
(function () {
|
||||||
var Game = {
|
var Game = {
|
||||||
NUMBER_OF_ROUNDS: 5,
|
NUMBER_OF_ROUNDS: 5,
|
||||||
MAX_SCORE: 1000,
|
MAX_SCORE: 1000,
|
||||||
|
|
||||||
|
type: GameType.SINGLE,
|
||||||
mapBounds: null,
|
mapBounds: null,
|
||||||
multi: { token: null, owner: false },
|
multi: { token: null, owner: false },
|
||||||
rounds: [],
|
rounds: [],
|
||||||
@ -211,6 +214,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getGameIdentifier: function() {
|
||||||
|
switch(Game.type) {
|
||||||
|
case GameType.SINGLE:
|
||||||
|
return '/game/' + mapId;
|
||||||
|
case GameType.MULTI:
|
||||||
|
return '/multiGame/' + roomId;
|
||||||
|
case GameType.CHALLENGE:
|
||||||
|
return '/challenge/' + challengeToken;
|
||||||
|
default:
|
||||||
|
return '/game/' + mapId;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
prepare: function () {
|
prepare: function () {
|
||||||
var data = new FormData();
|
var data = new FormData();
|
||||||
var userNames;
|
var userNames;
|
||||||
@ -226,7 +242,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('loading').style.visibility = 'visible';
|
document.getElementById('loading').style.visibility = 'visible';
|
||||||
var url = roomId ? '/multiGame/' + roomId + '/prepare.json' : '/game/' + mapId + '/prepare.json';
|
var url = Game.getGameIdentifier() + '/prepare.json';
|
||||||
MapGuesser.httpRequest('POST', url, function () {
|
MapGuesser.httpRequest('POST', url, function () {
|
||||||
document.getElementById('loading').style.visibility = 'hidden';
|
document.getElementById('loading').style.visibility = 'hidden';
|
||||||
|
|
||||||
@ -269,7 +285,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('loading').style.visibility = 'visible';
|
document.getElementById('loading').style.visibility = 'visible';
|
||||||
MapGuesser.httpRequest('POST', '/game/' + mapId + '/initialData.json', function () {
|
MapGuesser.httpRequest('POST', Game.getGameIdentifier() + '/initialData.json', function () {
|
||||||
document.getElementById('loading').style.visibility = 'hidden';
|
document.getElementById('loading').style.visibility = 'hidden';
|
||||||
document.getElementById('panoCover').style.visibility = 'hidden';
|
document.getElementById('panoCover').style.visibility = 'hidden';
|
||||||
|
|
||||||
@ -876,6 +892,12 @@
|
|||||||
document.getElementById("compass").style.transform = "translateY(-50%) rotate(" + heading + "deg)";
|
document.getElementById("compass").style.transform = "translateY(-50%) rotate(" + heading + "deg)";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(roomId !== null) {
|
||||||
|
Game.type = GameType.MULTI;
|
||||||
|
} else if(challengeToken !== null) {
|
||||||
|
Game.type = GameType.CHALLENGE;
|
||||||
|
}
|
||||||
|
|
||||||
if (COOKIES_CONSENT) {
|
if (COOKIES_CONSENT) {
|
||||||
Game.prepare();
|
Game.prepare();
|
||||||
}
|
}
|
||||||
|
@ -85,10 +85,40 @@
|
|||||||
window.location.href = '/multiGame/' + this.elements.roomId.value;
|
window.location.href = '/multiGame/' + this.elements.roomId.value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
document.getElementById('challengeForm').onsubmit = function (e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
var url = '/challenge/create.json';
|
||||||
|
var formData = new FormData(this);
|
||||||
|
|
||||||
|
document.getElementById('loading').style.visibility = 'visible';
|
||||||
|
MapGuesser.httpRequest('POST', url, function() {
|
||||||
|
document.getElementById('loading').style.visibility = 'hidden';
|
||||||
|
|
||||||
|
if (this.response.error) {
|
||||||
|
Game.handleErrorResponse(this.response.error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.location.href = '/challenge/' + this.response.challengeToken;
|
||||||
|
|
||||||
|
}, formData);
|
||||||
|
};
|
||||||
|
|
||||||
document.getElementById('multiButton').onclick = function () {
|
document.getElementById('multiButton').onclick = function () {
|
||||||
MapGuesser.showModal('multi');
|
MapGuesser.showModal('multi');
|
||||||
document.getElementById('createNewRoomButton').href = '/multiGame/new/' + this.dataset.mapId;
|
document.getElementById('createNewRoomButton').href = '/multiGame/new/' + this.dataset.mapId;
|
||||||
document.getElementById('multiForm').elements.roomId.select();
|
document.getElementById('multiForm').elements.roomId.select();
|
||||||
|
document.getElementById('playMode').style.visibility = 'hidden';
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('challengeButton').onclick = function () {
|
||||||
|
MapGuesser.showModal('challenge');
|
||||||
|
document.getElementById('createNewChallengeButton').href = '/challenge/new/' + this.dataset.mapId;
|
||||||
|
document.getElementById('playMode').style.visibility = 'hidden';
|
||||||
|
|
||||||
|
var timeLimit = document.getElementById('timeLimit').value;
|
||||||
|
document.getElementById('timeLimitLabel').innerText = 'Time limit of ' + timeLimit + ' seconds per round';
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('closePlayModeButton').onclick = function () {
|
document.getElementById('closePlayModeButton').onclick = function () {
|
||||||
@ -99,6 +129,10 @@
|
|||||||
MapGuesser.hideModal();
|
MapGuesser.hideModal();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
document.getElementById('closeChallengeButton').onclick = function () {
|
||||||
|
MapGuesser.hideModal();
|
||||||
|
}
|
||||||
|
|
||||||
var buttons = document.getElementById('mapContainer').getElementsByClassName('playButton');
|
var buttons = document.getElementById('mapContainer').getElementsByClassName('playButton');
|
||||||
for (var i = 0; i < buttons.length; i++) {
|
for (var i = 0; i < buttons.length; i++) {
|
||||||
var button = buttons[i];
|
var button = buttons[i];
|
||||||
@ -107,6 +141,13 @@
|
|||||||
MapGuesser.showModal('playMode');
|
MapGuesser.showModal('playMode');
|
||||||
document.getElementById('singleButton').href = '/game/' + this.dataset.mapId;
|
document.getElementById('singleButton').href = '/game/' + this.dataset.mapId;
|
||||||
document.getElementById('multiButton').dataset.mapId = this.dataset.mapId;
|
document.getElementById('multiButton').dataset.mapId = this.dataset.mapId;
|
||||||
|
document.getElementById('challengeMapId').value = this.dataset.mapId;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.getElementById('timeLimit').oninput = function () {
|
||||||
|
var timeLimit = document.getElementById('timeLimit').value;
|
||||||
|
document.getElementById('timeLimitLabel').innerText = 'Time limit of ' + timeLimit + ' seconds per round';
|
||||||
|
document.getElementById('timerEnabled').checked = true;
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
|
@ -8,14 +8,22 @@ use MapGuesser\Response\JsonContent;
|
|||||||
use MapGuesser\Interfaces\Response\IContent;
|
use MapGuesser\Interfaces\Response\IContent;
|
||||||
use MapGuesser\Interfaces\Response\IRedirect;
|
use MapGuesser\Interfaces\Response\IRedirect;
|
||||||
use MapGuesser\Multi\MultiConnector;
|
use MapGuesser\Multi\MultiConnector;
|
||||||
|
use MapGuesser\PersistentData\Model\Challenge;
|
||||||
use MapGuesser\PersistentData\Model\MultiRoom;
|
use MapGuesser\PersistentData\Model\MultiRoom;
|
||||||
|
use MapGuesser\PersistentData\Model\PlaceInChallenge;
|
||||||
|
use MapGuesser\PersistentData\Model\UserInChallenge;
|
||||||
use MapGuesser\PersistentData\PersistentDataManager;
|
use MapGuesser\PersistentData\PersistentDataManager;
|
||||||
|
use MapGuesser\Repository\ChallengeRepository;
|
||||||
use MapGuesser\Repository\MapRepository;
|
use MapGuesser\Repository\MapRepository;
|
||||||
use MapGuesser\Repository\MultiRoomRepository;
|
use MapGuesser\Repository\MultiRoomRepository;
|
||||||
|
use MapGuesser\Repository\PlaceRepository;
|
||||||
|
use MapGuesser\Repository\UserInChallengeRepository;
|
||||||
use MapGuesser\Response\Redirect;
|
use MapGuesser\Response\Redirect;
|
||||||
|
|
||||||
class GameController
|
class GameController
|
||||||
{
|
{
|
||||||
|
const NUMBER_OF_ROUNDS = 5;
|
||||||
|
|
||||||
private IRequest $request;
|
private IRequest $request;
|
||||||
|
|
||||||
private PersistentDataManager $pdm;
|
private PersistentDataManager $pdm;
|
||||||
@ -26,6 +34,12 @@ class GameController
|
|||||||
|
|
||||||
private MapRepository $mapRepository;
|
private MapRepository $mapRepository;
|
||||||
|
|
||||||
|
private PlaceRepository $placeRepository;
|
||||||
|
|
||||||
|
private ChallengeRepository $challengeRepository;
|
||||||
|
|
||||||
|
private UserInChallengeRepository $userInChallengeRepository;
|
||||||
|
|
||||||
public function __construct(IRequest $request)
|
public function __construct(IRequest $request)
|
||||||
{
|
{
|
||||||
$this->request = $request;
|
$this->request = $request;
|
||||||
@ -33,6 +47,9 @@ class GameController
|
|||||||
$this->multiConnector = new MultiConnector();
|
$this->multiConnector = new MultiConnector();
|
||||||
$this->multiRoomRepository = new MultiRoomRepository();
|
$this->multiRoomRepository = new MultiRoomRepository();
|
||||||
$this->mapRepository = new MapRepository();
|
$this->mapRepository = new MapRepository();
|
||||||
|
$this->placeRepository = new PlaceRepository();
|
||||||
|
$this->challengeRepository = new ChallengeRepository();
|
||||||
|
$this->userInChallengeRepository = new UserInChallengeRepository();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getGame(): IContent
|
public function getGame(): IContent
|
||||||
@ -79,6 +96,69 @@ class GameController
|
|||||||
return new HtmlContent('game', ['roomId' => $roomId]);
|
return new HtmlContent('game', ['roomId' => $roomId]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getChallenge(): IContent
|
||||||
|
{
|
||||||
|
$challengeToken = $this->request->query('challengeToken');
|
||||||
|
|
||||||
|
return new HtmlContent('game', ['challengeToken' => $challengeToken]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function createNewChallenge(): IContent
|
||||||
|
{
|
||||||
|
// create Challenge
|
||||||
|
$challengeToken = rand();
|
||||||
|
|
||||||
|
$challenge = new Challenge();
|
||||||
|
$challenge->setToken($challengeToken);
|
||||||
|
$challenge->setCreatedDate(new DateTime());
|
||||||
|
|
||||||
|
if($this->request->post('timerEnabled') !== null && $this->request->post('timeLimit') !== null) {
|
||||||
|
$challenge->setTimerSec($this->request->post('timeLimit'));
|
||||||
|
}
|
||||||
|
if($this->request->post('noMove') !== null) {
|
||||||
|
$challenge->setNoMove(true);
|
||||||
|
}
|
||||||
|
if($this->request->post('noPan') !== null) {
|
||||||
|
$challenge->setNoPan(true);
|
||||||
|
}
|
||||||
|
if($this->request->post('noZoom') !== null) {
|
||||||
|
$challenge->setNoZoom(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->pdm->saveToDb($challenge);
|
||||||
|
|
||||||
|
// save owner/creator
|
||||||
|
|
||||||
|
$session = $this->request->session();
|
||||||
|
$userId = $session->get('userId');
|
||||||
|
|
||||||
|
$userInChallenge = new UserInChallenge();
|
||||||
|
$userInChallenge->setUserId($userId);
|
||||||
|
$userInChallenge->setChallenge($challenge);
|
||||||
|
$userInChallenge->setTimeLeft($challenge->getTimerSec());
|
||||||
|
$userInChallenge->setIsOwner(true);
|
||||||
|
|
||||||
|
$this->pdm->saveToDb($userInChallenge);
|
||||||
|
|
||||||
|
// select places
|
||||||
|
|
||||||
|
$mapId = (int) $this->request->post('mapId');
|
||||||
|
$map = $this->mapRepository->getById($mapId);
|
||||||
|
|
||||||
|
$places = $this->placeRepository->getRandomNPlaces($mapId, static::NUMBER_OF_ROUNDS, $userId);
|
||||||
|
|
||||||
|
$order = 1;
|
||||||
|
foreach ($places as $place) {
|
||||||
|
$placeInChallenge = new PlaceInChallenge();
|
||||||
|
$placeInChallenge->setPlace($place);
|
||||||
|
$placeInChallenge->setChallenge($challenge);
|
||||||
|
$placeInChallenge->setOrder($order++);
|
||||||
|
$this->pdm->saveToDb($placeInChallenge);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JsonContent(['challengeToken' => dechex($challengeToken)]);
|
||||||
|
}
|
||||||
|
|
||||||
public function prepareGame(): IContent
|
public function prepareGame(): IContent
|
||||||
{
|
{
|
||||||
$mapId = (int) $this->request->query('mapId');
|
$mapId = (int) $this->request->query('mapId');
|
||||||
@ -154,6 +234,28 @@ class GameController
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function prepareChallenge(): IContent
|
||||||
|
{
|
||||||
|
$challengeToken_str = $this->request->query('challengeToken');
|
||||||
|
$session = $this->request->session();
|
||||||
|
$userId = $session->get('userId');
|
||||||
|
$challenge = $this->challengeRepository->getByTokenStr($challengeToken_str);
|
||||||
|
|
||||||
|
if(!$this->userInChallengeRepository->isUserParticipatingInChallenge($userId, $challenge)) {
|
||||||
|
$userInChallenge = new UserInChallenge();
|
||||||
|
$userInChallenge->setUserId($userId);
|
||||||
|
$userInChallenge->setTimeLeft($challenge->getTimerSec());
|
||||||
|
}
|
||||||
|
|
||||||
|
$map = $this->mapRepository->getByChallenge($challenge);
|
||||||
|
|
||||||
|
return new JsonContent([
|
||||||
|
'mapId' => $map->getId(),
|
||||||
|
'mapName' => $map->getName(),
|
||||||
|
'bounds' => $map->getBounds()->toArray()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
private function getMultiToken(string $roomId): string
|
private function getMultiToken(string $roomId): string
|
||||||
{
|
{
|
||||||
$session = $this->request->session();
|
$session = $this->request->session();
|
||||||
|
@ -323,6 +323,10 @@ class Select
|
|||||||
$value = $this->generateColumn($value);
|
$value = $this->generateColumn($value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if(count($columns) > 0 && $columns[0] == Utils::backtick('id')) {
|
||||||
|
$columns[0] = Utils::backtick($this->table) . '.' . Utils::backtick('id');
|
||||||
|
}
|
||||||
|
|
||||||
return implode(',', $columns);
|
return implode(',', $columns);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ use DateTime;
|
|||||||
|
|
||||||
class Challenge extends Model
|
class Challenge extends Model
|
||||||
{
|
{
|
||||||
protected static string $table = 'challenge';
|
protected static string $table = 'challenges';
|
||||||
|
|
||||||
protected static array $fields = ['token', 'timer_sec', 'no_move', 'no_pan', 'no_zoom', 'created'];
|
protected static array $fields = ['token', 'timer_sec', 'no_move', 'no_pan', 'no_zoom', 'created'];
|
||||||
|
|
||||||
@ -12,13 +12,13 @@ class Challenge extends Model
|
|||||||
|
|
||||||
private int $token;
|
private int $token;
|
||||||
|
|
||||||
private int $timerSec;
|
private ?int $timerSec = null;
|
||||||
|
|
||||||
private bool $noMove;
|
private bool $noMove = false;
|
||||||
|
|
||||||
private bool $noPan;
|
private bool $noPan = false;
|
||||||
|
|
||||||
private bool $noZoom;
|
private bool $noZoom = false;
|
||||||
|
|
||||||
private DateTime $created;
|
private DateTime $created;
|
||||||
|
|
||||||
@ -27,9 +27,11 @@ class Challenge extends Model
|
|||||||
$this->token = $token;
|
$this->token = $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setTimerSec(int $timerSec): void
|
public function setTimerSec(?int $timerSec): void
|
||||||
{
|
{
|
||||||
$this->timerSec = $timerSec;
|
if(isset($timerSec)) {
|
||||||
|
$this->timerSec = $timerSec;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setNoMove(bool $noMove): void
|
public function setNoMove(bool $noMove): void
|
||||||
@ -62,7 +64,7 @@ class Challenge extends Model
|
|||||||
return $this->token;
|
return $this->token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getTimerSec(): int
|
public function getTimerSec(): ?int
|
||||||
{
|
{
|
||||||
return $this->timerSec;
|
return $this->timerSec;
|
||||||
}
|
}
|
||||||
|
@ -16,13 +16,13 @@ class UserInChallenge extends Model
|
|||||||
|
|
||||||
private ?int $challengeId = null;
|
private ?int $challengeId = null;
|
||||||
|
|
||||||
private int $round;
|
private int $round = -1;
|
||||||
|
|
||||||
private int $score;
|
private int $score = 0;
|
||||||
|
|
||||||
private int $timeLeft;
|
private ?int $timeLeft = null;
|
||||||
|
|
||||||
private bool $isOwner;
|
private bool $isOwner = false;
|
||||||
|
|
||||||
public function setUser(User $user): void
|
public function setUser(User $user): void
|
||||||
{
|
{
|
||||||
@ -54,9 +54,11 @@ class UserInChallenge extends Model
|
|||||||
$this->score = $score;
|
$this->score = $score;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setTimeLeft(int $timeLeft): void
|
public function setTimeLeft(?int $timeLeft): void
|
||||||
{
|
{
|
||||||
$this->timeLeft = $timeLeft;
|
if(isset($timeLeft)) {
|
||||||
|
$this->timeLeft = $timeLeft;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function setIsOwner(bool $isOwner): void
|
public function setIsOwner(bool $isOwner): void
|
||||||
|
@ -28,6 +28,13 @@ class ChallengeRepository
|
|||||||
return $this->pdm->selectFromDb($select, Challenge::class);
|
return $this->pdm->selectFromDb($select, Challenge::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getByTokenStr(string $token_str): ?Challenge
|
||||||
|
{
|
||||||
|
$token = hexdec($token_str);
|
||||||
|
|
||||||
|
return $this->getByToken($token);
|
||||||
|
}
|
||||||
|
|
||||||
public function getAllByParticipant(User $user): Generator
|
public function getAllByParticipant(User $user): Generator
|
||||||
{
|
{
|
||||||
$select = new Select(\Container::$dbConnection);
|
$select = new Select(\Container::$dbConnection);
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
<?php namespace MapGuesser\Repository;
|
<?php namespace MapGuesser\Repository;
|
||||||
|
|
||||||
|
use MapGuesser\Database\Query\Select;
|
||||||
|
use MapGuesser\PersistentData\Model\Challenge;
|
||||||
use MapGuesser\PersistentData\Model\Map;
|
use MapGuesser\PersistentData\Model\Map;
|
||||||
use MapGuesser\PersistentData\PersistentDataManager;
|
use MapGuesser\PersistentData\PersistentDataManager;
|
||||||
|
|
||||||
@ -16,4 +18,15 @@ class MapRepository
|
|||||||
{
|
{
|
||||||
return $this->pdm->selectFromDbById($mapId, Map::class);
|
return $this->pdm->selectFromDbById($mapId, Map::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function getByChallenge(Challenge $challenge): ?Map
|
||||||
|
{
|
||||||
|
$select = new Select(\Container::$dbConnection);
|
||||||
|
$select->innerJoin('places', ['maps', 'id'], '=', ['places', 'map_id']);
|
||||||
|
$select->innerJoin('place_in_challenge', ['places', 'id'], '=', ['place_in_challenge', 'place_id']);
|
||||||
|
$select->where('challenge_id', '=', $challenge->getId());
|
||||||
|
$select->limit(1);
|
||||||
|
|
||||||
|
return $this->pdm->selectFromDb($select, Map::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,4 +31,13 @@ class UserInChallengeRepository
|
|||||||
|
|
||||||
yield from $this->pdm->selectMultipleFromDb($select, UserInChallenge::class);
|
yield from $this->pdm->selectMultipleFromDb($select, UserInChallenge::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isUserParticipatingInChallenge(int $userId, Challenge $challenge): bool
|
||||||
|
{
|
||||||
|
$select = new Select(\Container::$dbConnection, 'user_in_challenge');
|
||||||
|
$select->where('user_id', '=', $userId);
|
||||||
|
$select->where('challenge_id', '=', $challenge->getId());
|
||||||
|
|
||||||
|
return $select->count();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,5 +84,6 @@
|
|||||||
var multiUrl = '<?= $_ENV['MULTI_WS_URL'] ?>';
|
var multiUrl = '<?= $_ENV['MULTI_WS_URL'] ?>';
|
||||||
var roomId = <?= isset($roomId) ? '\'' . $roomId . '\'' : 'null' ?>;
|
var roomId = <?= isset($roomId) ? '\'' . $roomId . '\'' : 'null' ?>;
|
||||||
var mapId = <?= isset($mapId) ? '\'' . $mapId . '\'' : 'null' ?>;
|
var mapId = <?= isset($mapId) ? '\'' . $mapId . '\'' : 'null' ?>;
|
||||||
|
var challengeToken = <?= isset($challengeToken) ? '\'' . $challengeToken . '\'' : 'null' ?>;
|
||||||
</script>
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
@ -11,6 +11,8 @@ TODO: condition!
|
|||||||
<a id="singleButton" class="button fullWidth marginTop" href="" title="Single player">Single player</a>
|
<a id="singleButton" class="button fullWidth marginTop" href="" title="Single player">Single player</a>
|
||||||
<p class="bold center marginTop marginBottom">OR</p>
|
<p class="bold center marginTop marginBottom">OR</p>
|
||||||
<button id="multiButton" class="fullWidth green" data-map-id="">Multiplayer (beta)</button>
|
<button id="multiButton" class="fullWidth green" data-map-id="">Multiplayer (beta)</button>
|
||||||
|
<p class="bold center marginTop marginBottom">OR</p>
|
||||||
|
<button id="challengeButton" class="fullWidth yellow" data-map-id="" data-timer="">Challenge (gamma)</button>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<button id="closePlayModeButton" class="gray marginTop" type="button">Close</button>
|
<button id="closePlayModeButton" class="gray marginTop" type="button">Close</button>
|
||||||
</div>
|
</div>
|
||||||
@ -29,6 +31,47 @@ TODO: condition!
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
<div id="challenge" class="modal">
|
||||||
|
<h2>Challenge (gamma)</h2>
|
||||||
|
<form id="challengeForm" class="marginTop" method="get">
|
||||||
|
<!--
|
||||||
|
<div class="inputWithButton">
|
||||||
|
<input type="text" name="challengeToken" placeholder="Challenge to enter" required minlength="6" maxlength="6">
|
||||||
|
</div>
|
||||||
|
<p class="bold center marginTop marginBottom">OR</p>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div id="restrictions">
|
||||||
|
<h3>Optional restrictions</h3>
|
||||||
|
<div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="timerEnabled" name="timerEnabled" value="timerEnabled" />
|
||||||
|
<label id="timeLimitLabel" for="timerEnabled">Time limit measured in seconds</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="range" id="timeLimit" name="timeLimit" min="10" max="600" value="120" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="noMove" name="noMove" value="noMove" />
|
||||||
|
<label for="noMove">No movement allowed</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="noPan" name="noPan" value="noPan" />
|
||||||
|
<label for="noPan">No camera rotation allowed</label>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="checkbox" id="noZoom" name="noZoom" value="noZoom" />
|
||||||
|
<label for="noMove">No zoom allowed</label>
|
||||||
|
</div>
|
||||||
|
<input type="hidden" name="mapId" id="challengeMapId" />
|
||||||
|
</div>
|
||||||
|
<button id="createNewChallengeButton" type="submit" class="button fullWidth green" href="" title="Create new challenge">Create new challenge</button>
|
||||||
|
<div class="right">
|
||||||
|
<button id="closeChallengeButton" class="gray marginTop" type="button">Close</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section(main)
|
@section(main)
|
||||||
|
7
web.php
7
web.php
@ -62,6 +62,13 @@ Container::$routeCollection->group('multiGame', function (MapGuesser\Routing\Rou
|
|||||||
$routeCollection->post('multiGame.nextRound-json', '{roomId}/nextRound.json', [MapGuesser\Controller\GameFlowController::class, 'multiNextRound']);
|
$routeCollection->post('multiGame.nextRound-json', '{roomId}/nextRound.json', [MapGuesser\Controller\GameFlowController::class, 'multiNextRound']);
|
||||||
$routeCollection->post('multiGame.guess-json', '{roomId}/guess.json', [MapGuesser\Controller\GameFlowController::class, 'multiGuess']);
|
$routeCollection->post('multiGame.guess-json', '{roomId}/guess.json', [MapGuesser\Controller\GameFlowController::class, 'multiGuess']);
|
||||||
});
|
});
|
||||||
|
Container::$routeCollection->group('challenge', function (MapGuesser\Routing\RouteCollection $routeCollection) {
|
||||||
|
$routeCollection->post('challenge.create', 'create.json', [\MapGuesser\Controller\GameController::class, 'createNewChallenge']);
|
||||||
|
$routeCollection->get('challenge', '{challengeToken}', [MapGuesser\Controller\GameController::class, 'getChallenge']);
|
||||||
|
$routeCollection->post('challenge.prepare-json', '{challengeToken}/prepare.json', [MapGuesser\Controller\GameController::class, 'prepareChallenge']);
|
||||||
|
$routeCollection->post('challenge.initialData-json', '{challengeToken}/initialData.json', [MapGuesser\Controller\GameFlowController::class, 'challengeInitialData']);
|
||||||
|
$routeCollection->post('challenge.guess-json', '{challengeToken}/guess.json', [MapGuesser\Controller\GameFlowController::class, 'challengeGuess']);
|
||||||
|
});
|
||||||
Container::$routeCollection->group('admin', function (MapGuesser\Routing\RouteCollection $routeCollection) {
|
Container::$routeCollection->group('admin', function (MapGuesser\Routing\RouteCollection $routeCollection) {
|
||||||
$routeCollection->get('admin.mapEditor', 'mapEditor/{mapId?}', [MapGuesser\Controller\MapAdminController::class, 'getMapEditor']);
|
$routeCollection->get('admin.mapEditor', 'mapEditor/{mapId?}', [MapGuesser\Controller\MapAdminController::class, 'getMapEditor']);
|
||||||
$routeCollection->get('admin.place', 'place.json/{placeId}', [MapGuesser\Controller\MapAdminController::class, 'getPlace']);
|
$routeCollection->get('admin.place', 'place.json/{placeId}', [MapGuesser\Controller\MapAdminController::class, 'getPlace']);
|
||||||
|
Loading…
Reference in New Issue
Block a user