Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix backend for create game #182

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 0 additions & 13 deletions .vscode/settings.json

This file was deleted.

318 changes: 153 additions & 165 deletions api.php
Original file line number Diff line number Diff line change
Expand Up @@ -1405,7 +1405,7 @@ public function __construct() {
}

public function run($userID, $permissionIsExplicit) {
global $DB, $MC, $Misc;
global $DB, $MC, $Misc, $Game;
$User = new User($userID);

$args = $this->getArgs();
Expand Down Expand Up @@ -1440,191 +1440,179 @@ public function run($userID, $permissionIsExplicit) {
// $input['botFill'] = 'Yes';
// }

try {
if ($Misc->Panic) {
throw new Exception(l_t("Game creation has been temporarily disabled while we take care of an unexpected problem. Please try again later, sorry for the inconvenience"));
}
if ($Misc->Panic) {
throw new Exception(l_t("Game creation has been temporarily disabled while we take care of an unexpected problem. Please try again later, sorry for the inconvenience"));
}

$variantID = (int)$variantID;
if (!isset(Config::$variants[$variantID])) {
throw new Exception(l_t("Variant ID given (%s) doesn't represent a real variant.", $variantID));
}
$variantID = (int)$variantID;
if (!isset(Config::$variants[$variantID])) {
throw new Exception(l_t("Variant ID given (%s) doesn't represent a real variant.", $variantID));
}

// If the name isn't unique or is too long the database will stop it
$name = $DB->escape($name);
if ( !$name ) { throw new Exception(l_t("No name entered.")); }
// If the name isn't unique or is too long the database will stop it
$name = $DB->escape($name);
if ( !$name ) { throw new Exception(l_t("No name entered.")); }

// This is hashed, so doesn't need validation
if ( $inviteCode != $inviteCodeConfirmation ) {
throw new Exception(l_t("The two invite codes entered don't match."));
}
// This is hashed, so doesn't need validation
if ( $inviteCode != $inviteCodeConfirmation ) {
throw new Exception(l_t("The two invite codes entered don't match."));
}

$bet = (int)$bet;
if ($bet < 5 or $bet > $User->points){
throw new Exception(l_t("%s is an invalid bet size.",(string)$bet));
}
$bet = (int)$bet;
if ($bet < 5 or $bet > $User->points){
throw new Exception(l_t("%s is an invalid bet size.",(string)$bet));
}

if ($potType != 'Winner-takes-all' and $potType != 'Points-per-supply-center' and $potType != 'Unranked' and $potType != 'Sum-of-squares') {
throw new Exception(l_t('Invalid potType input given.'));
}
if ($potType != 'Winner-takes-all' and $potType != 'Points-per-supply-center' and $potType != 'Unranked' and $potType != 'Sum-of-squares') {
throw new Exception(l_t('Invalid potType input given.'));
}

$phaseMinutes = (int)$phaseMinutes;
if ($phaseMinutes < 5 or $phaseMinutes > 1440*10) {
throw new Exception(l_t("The phase value is too large or small; it must be between 5 minutes and 10 days."));
}
$phaseMinutesRB = (int)$phaseMinutesRB;
if ($phaseMinutesRB != -1 && ($phaseMinutesRB < 1 or $phaseMinutesRB > 1440*10)) {
throw new Exception(l_t("The phase value for retreats and builds is too large or small; it must be between 1 minute and 10 days."));
}
if ($phaseMinutesRB != -1 && ($phaseMinutesRB > $phaseMinutes || $phaseMinutesRB < $phaseMinutes / 10)) {
throw new Exception(l_t("The phase length for retreats and builds must be within 10% and 100% of the regular phase length."));
}
$phaseMinutes = (int)$phaseMinutes;
if ($phaseMinutes < 5 or $phaseMinutes > 1440*10) {
throw new Exception(l_t("The phase value is too large or small; it must be between 5 minutes and 10 days."));
}
$phaseMinutesRB = (int)$phaseMinutesRB;
if ($phaseMinutesRB != -1 && ($phaseMinutesRB < 1 or $phaseMinutesRB > 1440*10)) {
throw new Exception(l_t("The phase value for retreats and builds is too large or small; it must be between 1 minute and 10 days."));
}
if ($phaseMinutesRB != -1 && ($phaseMinutesRB > $phaseMinutes || $phaseMinutesRB < $phaseMinutes / 10)) {
throw new Exception(l_t("The phase length for retreats and builds must be within 10% and 100% of the regular phase length."));
}

$nextPhaseMinutes = (int)$nextPhaseMinutes;
$phaseSwitchPeriod = (int)$phaseSwitchPeriod;
$nextPhaseMinutes = (int)$nextPhaseMinutes;
$phaseSwitchPeriod = (int)$phaseSwitchPeriod;

// If a game is not live, set the next phase minutes to match the phase.
if ($phaseMinutes > 60) {
$nextPhaseMinutes = $phaseMinutes;
$phaseSwitchPeriod = -1;
// If a game is not live, set the next phase minutes to match the phase.
if ($phaseMinutes > 60) {
$nextPhaseMinutes = $phaseMinutes;
$phaseSwitchPeriod = -1;
}

if ($phaseMinutes < 61 and $phaseSwitchPeriod != -1) {
// If the next phase minutes is less than 1 day or more than 10 because someone is messing around with the console, default to 2 days if the game is live.
if (($nextPhaseMinutes < 1440 or $nextPhaseMinutes > 1440*10)) {
$nextPhaseMinutes = 2880;
}

if ($phaseMinutes < 61 and $phaseSwitchPeriod != -1) {
// If the next phase minutes is less than 1 day or more than 10 because someone is messing around with the console, default to 2 days if the game is live.
if (($nextPhaseMinutes < 1440 or $nextPhaseMinutes > 1440*10)) {
$nextPhaseMinutes = 2880;
}

// If the phase Switch period is outside the allowed range default it to 3 hours.
if (($phaseSwitchPeriod > 360 or $phaseSwitchPeriod < $phaseMinutes)) {
$phaseSwitchPeriod = 180;
}
// If the phase Switch period is outside the allowed range default it to 3 hours.
if (($phaseSwitchPeriod > 360 or $phaseSwitchPeriod < $phaseMinutes)) {
$phaseSwitchPeriod = 180;
}
}

$joinPeriod = (int)$joinPeriod;
if ($joinPeriod < 5 or $joinPeriod > 1440*14) {
throw new Exception(l_t("Joining period value out of range."));
}
$anon = ((strtolower($anon) == 'yes') ? 'Yes' : 'No');
// Force 1 vs 1 variants to be unranked to prevent point farming.
if ($variantID == 15 or $variantID == 23 or $variantID == 91) {
$bet = 5;
$potType = 'Unranked';
}
$joinPeriod = (int)$joinPeriod;
if ($joinPeriod < 5 or $joinPeriod > 1440*14) {
throw new Exception(l_t("Joining period value out of range."));
}

$anon = ((strtolower($anon) == 'yes') ? 'Yes' : 'No');

// Force 1 vs 1 variants to be unranked to prevent point farming.
if ($variantID == 15 or $variantID == 23 or $variantID == 91) {
$bet = 5;
$potType = 'Unranked';
}

// Only classic, no press can support fill with bots.
if (($variantID != 1) || ($pressType != 'NoPress')) {
$botFill = 'No';
}
// Only classic, no press can support fill with bots.
if (($variantID != 1) || ($pressType != 'NoPress')) {
$botFill = 'No';
}

// If no press is selected, force the game to anon to prevent cheating via out of game messaging.
switch($pressType) {
case 'PublicPressOnly':
$pressType = 'PublicPressOnly';
break;
case 'NoPress':
$pressType = 'NoPress';
$anon = 'Yes';
break;
case 'RulebookPress':
$pressType = 'RulebookPress';
break;
case 'Regular': // Regular is the default
default:
$pressType = 'Regular';
}

// Force bot games to be no press and unranked.
if($botFill == 'Yes') {
// If no press is selected, force the game to anon to prevent cheating via out of game messaging.
switch($pressType) {
case 'PublicPressOnly':
$pressType = 'PublicPressOnly';
break;
case 'NoPress':
$pressType = 'NoPress';
$potType = 'Unranked';
$bet = 5;
$playerTypes = 'Mixed';
}

switch($missingPlayerPolicy) {
case 'Wait':
$missingPlayerPolicy = 'Wait';
break;
default:
$missingPlayerPolicy = 'Normal';
} switch($drawType) {
case 'draw-votes-hidden':
$drawType = 'draw-votes-hidden';
break;
default:
$drawType = 'draw-votes-public';
break;
}
$anon = 'Yes';
break;
case 'RulebookPress':
$pressType = 'RulebookPress';
break;
case 'Regular': // Regular is the default
default:
$pressType = 'Regular';
}

// Force bot games to be no press and unranked.
if($botFill == 'Yes') {
$pressType = 'NoPress';
$potType = 'Unranked';
$bet = 5;
$playerTypes = 'Mixed';
}

$minimumReliabilityRating = (int)$minimumReliabilityRating;
if ($minimumReliabilityRating < 0 or $minimumReliabilityRating > 100) {
throw new RequestException(l_t("The reliability rating threshold must range from 0-100"));
}
switch($missingPlayerPolicy) {
case 'Wait':
$missingPlayerPolicy = 'Wait';
break;
default:
$missingPlayerPolicy = 'Normal';
} switch($drawType) {
case 'draw-votes-hidden':
$drawType = 'draw-votes-hidden';
break;
default:
$drawType = 'draw-votes-public';
break;
}

if ($minimumReliabilityRating > $User->reliabilityRating) {
throw new Exception(l_t("Your reliability rating is %s%%, so you can't create a game which requires players to have a RR of %s%% or greater.",$User->reliabilityRating, $minimumReliabilityRating));
}
$minimumReliabilityRating = (int)$minimumReliabilityRating;
if ($minimumReliabilityRating < 0 or $minimumReliabilityRating > 100) {
throw new RequestException(l_t("The reliability rating threshold must range from 0-100"));
}

$excusedMissedTurns = (int)$excusedMissedTurns;
if ($excusedMissedTurns < 0 || $excusedMissedTurns > 4) {
throw new Exception(l_t("The excused missed turn number is too large or small; it must be between 0 and 4."));
}
// if ($minimumReliabilityRating > $User->reliabilityRating) {
// throw new Exception(l_t("Your reliability rating is %s%%, so you can't create a game which requires players to have a RR of %s%% or greater.",$User->reliabilityRating, $minimumReliabilityRating));
// }

// Prevent temp banned players from making new games.
if ($User->userIsTempBanned()) {
throw new Exception(l_t("You are blocked from creating new games.', 'You are blocked from creating new games."));
}
$excusedMissedTurns = (int)$excusedMissedTurns;
if ($excusedMissedTurns < 0 || $excusedMissedTurns > 4) {
throw new Exception(l_t("The excused missed turn number is too large or small; it must be between 0 and 4."));
}

// Create Game record & object
// require_once(l_r('gamemaster/game.php'));
// $Game = processGame::create(
// $variantID,
// $name,
// $inviteCode,
// $bet,
// $potType,
// $phaseMinutes,
// $phaseMinutesRB,
// $nextPhaseMinutes,
// $phaseSwitchPeriod,
// $joinPeriod,
// $anon,
// $pressType,
// $missingPlayerPolicy,
// $drawType,
// $minimumReliabilityRating,
// $excusedMissedTurns,
// $playerTypes);

// file_put_contents('php://stdout', 'Enter here');
// file_put_contents('php://stdout', $User->id);
// // Create first Member record & object
// processMember::create($User->id, $bet);
// $Game->Members->joinedRedirect();

// $responseStr = $game ? 'Game successfully created.' : 'Game was not created';
$responseStr = "";

return $this->JSONResponse(
$responseStr,
'',
true,
$payload
);
} catch(Exception $e) {
// return $this->JSONResponse(
// $e->getMessage(),
// '',
// false,
// $payload
// );
throw new RequestException(
$this->JSONResponse('A gameID is required.', '', false, [])
);
Comment on lines -1617 to -1626
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if you remove the try | catch, and if the API has an error, the error will not be returned in JSON format.
I use Insomnia to test my API endpoints, you can test with this endpoint.

image

Try changing the bet to 3, and the correct JSON error should be returned. With the change you made, an HTML error is returned.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you can get your wrapper to return a proper error message with stack trace as JSON, that would be awesome.

// Prevent temp banned players from making new games.
if ($User->userIsTempBanned()) {
throw new Exception(l_t("You are blocked from creating new games.', 'You are blocked from creating new games."));
}

// Create Game record & object
require_once(l_r('gamemaster/game.php'));
$Game = processGame::create(
$variantID,
$name,
$inviteCode,
$bet,
$potType,
$phaseMinutes,
$phaseMinutesRB,
$nextPhaseMinutes,
$phaseSwitchPeriod,
$joinPeriod,
$anon,
$pressType,
$missingPlayerPolicy,
$drawType,
$minimumReliabilityRating,
$excusedMissedTurns,
$playerTypes);

file_put_contents('php://stdout', 'Enter here');
file_put_contents('php://stdout', $User->id);
// Create first Member record & object
processMember::create($User->id, $bet);
// $Game->Members->joinedRedirect();

// $responseStr = $game ? 'Game successfully created.' : 'Game was not created';
return $this->JSONResponse(
'Successfully created game.',
'',
true,
[
'gameID' => $Game->id
]
);
}
}
// return json_encode([
Expand Down
2 changes: 1 addition & 1 deletion beta-src/src/components/ui/new/CreateGameForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ const CreateGameForm: FunctionComponent<CreateGameFormProps> = function ({
validationSchema,
onSubmit: async (values) => {
console.log("values", values);
// dispatch(createGame(values));
dispatch(createGame(values));
showSuccess({
title: "Game created",
description: "The game was successfully created",
Expand Down
3 changes: 3 additions & 0 deletions beta-src/src/state/game/game-api-slice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,8 @@ const gameApiSlice = createSlice({
if (action.payload) {
handlePostSucceeded(state);
console.log({ action });
const { gameID } = action.payload;
// redirect to gameID

// const { messages } = action.payload;
// const allMessages = mergeMessageArrays(
Expand All @@ -452,6 +454,7 @@ const gameApiSlice = createSlice({
}
})
.addCase(createGame.rejected, (state, action) => {
console.log({ state, action });
handlePostFailed(
state,
"Error sending message, network connection issue",
Expand Down