Skip to content

Commit

Permalink
1.34: wait for orders mode
Browse files Browse the repository at this point in the history
  • Loading branch information
kestasjk committed Jun 2, 2013
1 parent 81a8ca1 commit 3e446c7
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 12 deletions.
27 changes: 27 additions & 0 deletions admin/adminActions.php
Expand Up @@ -121,6 +121,11 @@ class adminActions extends adminActionsForms
'description' => 'Set a game process time to now, resulting in it being processed now', 'description' => 'Set a game process time to now, resulting in it being processed now',
'params' => array('gameID'=>'Game ID'), 'params' => array('gameID'=>'Game ID'),
), ),
'toggleWaitForOrders' => array(
'name' => 'Toggle Wait for orders mode',
'description' => 'Will toggle this game between normal NMR rules and wait-for-orders mode',
'params' => array('gameID'=>'Game ID'),
),
'panic' => array( 'panic' => array(
'name' => 'Toggle panic button', 'name' => 'Toggle panic button',
'description' => 'Toggle the panic button; turning it on prevents games from being processed, users joining games, 'description' => 'Toggle the panic button; turning it on prevents games from being processed, users joining games,
Expand Down Expand Up @@ -453,6 +458,28 @@ public function changePhaseLength(array $params)
return l_t('Process time changed from %s to %s. Next process time is %s.', return l_t('Process time changed from %s to %s. Next process time is %s.',
libTime::timeLengthText($oldPhaseMinutes*60),libTime::timeLengthText($Game->phaseMinutes*60),libTime::text($Game->processTime)); libTime::timeLengthText($oldPhaseMinutes*60),libTime::timeLengthText($Game->phaseMinutes*60),libTime::text($Game->processTime));
} }
public function toggleWaitForOrders(array $params)
{
global $DB;

require_once(l_r('objects/game.php'));

$Variant=libVariant::loadFromGameID($params['gameID']);
$Game = $Variant->Game($params['gameID']);

if( $Game->missingPlayerPolicy == 'Wait' )
{
$msg = "Set game to normal mode.";
$setting = 'Normal';
}
else
{
$msg = "Set game to wait-for-orders mode.";
$setting = 'Wait';
}
$DB->sql_put("UPDATE wD_Games SET missingPlayerPolicy = '".$setting."' WHERE id = ".$Game->id);
return l_t($msg);
}


public function resetLastProcessTime(array $params) public function resetLastProcessTime(array $params)
{ {
Expand Down
2 changes: 1 addition & 1 deletion config.sample.php
Expand Up @@ -266,7 +266,7 @@ public static function customFooter()
* The number of minutes that gamemaster.php will detect that it hasn't been run for before it will * The number of minutes that gamemaster.php will detect that it hasn't been run for before it will
* mark itself in downtime mode. * mark itself in downtime mode.
*/ */
public static $downtimeTriggerMinutes=30; public static $downtimeTriggerMinutes=12;




// --- // ---
Expand Down
25 changes: 23 additions & 2 deletions gamecreate.php
Expand Up @@ -49,8 +49,11 @@
$form = $_REQUEST['newGame']; // This makes $form look harmless when it is unsanitized; the parameters must all be sanitized $form = $_REQUEST['newGame']; // This makes $form look harmless when it is unsanitized; the parameters must all be sanitized


$input = array(); $input = array();
$required = array('variantID', 'name', 'password', 'passwordcheck', 'bet', 'potType', 'phaseMinutes', 'joinPeriod', 'anon', 'pressType'); $required = array('variantID', 'name', 'password', 'passwordcheck', 'bet', 'potType', 'phaseMinutes', 'joinPeriod', 'anon', 'pressType', 'missingPlayerPolicy');


if ( !isset($form['missingPlayerPolicy']) )
$form['missingPlayerPolicy'] = 'Normal';

foreach($required as $requiredName) foreach($required as $requiredName)
{ {
if ( isset($form[$requiredName]) ) if ( isset($form[$requiredName]) )
Expand Down Expand Up @@ -114,11 +117,29 @@
case 'Regular': // Regular is the default case 'Regular': // Regular is the default
default: default:
$input['pressType'] = 'Regular'; $input['pressType'] = 'Regular';
}

switch($input['missingPlayerPolicy']) {
case 'Wait':
$input['missingPlayerPolicy'] = 'Wait';
break;
default:
$input['missingPlayerPolicy'] = 'Normal';
} }


// Create Game record & object // Create Game record & object
require_once(l_r('gamemaster/game.php')); require_once(l_r('gamemaster/game.php'));
$Game = processGame::create($input['variantID'], $input['name'], $input['password'], $input['bet'], $input['potType'], $input['phaseMinutes'], $input['joinPeriod'], $input['anon'], $input['pressType']); $Game = processGame::create(
$input['variantID'],
$input['name'],
$input['password'],
$input['bet'],
$input['potType'],
$input['phaseMinutes'],
$input['joinPeriod'],
$input['anon'],
$input['pressType'],
$input['missingPlayerPolicy']);


// Create first Member record & object // Create first Member record & object
processMember::create($User->id, $input['bet']); processMember::create($User->id, $input['bet']);
Expand Down
5 changes: 3 additions & 2 deletions gamemaster/game.php
Expand Up @@ -286,7 +286,7 @@ function loadMembers()
* *
* @return Game The object corresponding to the new game * @return Game The object corresponding to the new game
*/ */
public static function create($variantID, $name, $password, $bet, $potType, $phaseMinutes, $joinPeriod, $anon, $press) public static function create($variantID, $name, $password, $bet, $potType, $phaseMinutes, $joinPeriod, $anon, $press, $missingPlayerPolicy='Normal')
{ {
global $DB; global $DB;


Expand Down Expand Up @@ -324,7 +324,8 @@ public static function create($variantID, $name, $password, $bet, $potType, $pha
pressType = '".$press."', pressType = '".$press."',
".( $password ? "password = UNHEX('".md5($password)."')," : ""). ".( $password ? "password = UNHEX('".md5($password)."')," : "").
"processTime = ".$pTime.", "processTime = ".$pTime.",
phaseMinutes = ".$phaseMinutes); phaseMinutes = ".$phaseMinutes.",
missingPlayerPolicy = '".$missingPlayerPolicy."'");


$gameID = $DB->last_inserted(); $gameID = $DB->last_inserted();


Expand Down
6 changes: 4 additions & 2 deletions gamepanel/game.php
Expand Up @@ -90,8 +90,8 @@ function gameNoticeBar()
else else
return l_t('%s players joined; game will start on next process cycle', count($this->Variant->countries)); return l_t('%s players joined; game will start on next process cycle', count($this->Variant->countries));
} }
elseif( $this->missingPlayerPolicy=='Strict'&&!$this->Members->isComplete() && time()>=$this->processTime ) elseif( $this->missingPlayerPolicy=='Wait'&&!$this->Members->isCompleted() && time()>=$this->processTime )
return l_t("One or more players need to complete their orders before this strict/tournament game can go on"); return l_t("One or more players need to complete their orders before this wait-mode game can go on");
} }


/* /*
Expand Down Expand Up @@ -262,6 +262,8 @@ function gameVariants() {
$alternatives[]=l_t('Anonymous players'); $alternatives[]=l_t('Anonymous players');
if( $this->potType=='Winner-takes-all' ) if( $this->potType=='Winner-takes-all' )
$alternatives[]=l_t($this->potType); $alternatives[]=l_t($this->potType);
if( $this->missingPlayerPolicy=='Wait' )
$alternatives[]=l_t('Wait for orders');


if ( $alternatives ) if ( $alternatives )
return '<div class="titleBarLeftSide" style="float:left"> return '<div class="titleBarLeftSide" style="float:left">
Expand Down
2 changes: 1 addition & 1 deletion global/definitions.php
Expand Up @@ -24,7 +24,7 @@


defined('IN_CODE') or die('This script can not be run by itself.'); defined('IN_CODE') or die('This script can not be run by itself.');


define("VERSION", 133); define("VERSION", 134) ;


// Some integer values which are named for clarity. // Some integer values which are named for clarity.


Expand Down
16 changes: 16 additions & 0 deletions install/1.33-1.34/readme.txt
@@ -0,0 +1,16 @@
Changelog
---------
- Changed the default time that the server will go without processing before stopping processing to 12 minutes. (2 attempts)
- Added an option for NMR behavior, giving a setting that will make the game wait indefinitely for a missing player.
- Added pagination to game chat archive screens
- Fixed bug where users attempt to join a non-joinable game and get an incorrect error message

Updating
--------
- Take a backup (database and files) <-- Important!
- Set the server to maintenance mode (perhaps set an appropriate message warning users of the update in config.php first)
- Wait a minute for all active processes to finish
- Run update.sql
- Copy the new code over the old code
- View and test the updated site
- Turn off maintenance mode
2 changes: 2 additions & 0 deletions install/1.33-1.34/update.sql
@@ -0,0 +1,2 @@
ALTER TABLE `wD_Backup_Games` CHANGE `missingPlayerPolicy` `missingPlayerPolicy` ENUM( 'Normal', 'Strict', 'Wait' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'Normal';
ALTER TABLE `wD_Games` CHANGE `missingPlayerPolicy` `missingPlayerPolicy` ENUM( 'Normal', 'Strict', 'Wait' ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL DEFAULT 'Normal';
21 changes: 21 additions & 0 deletions locales/English/gamecreate.php
Expand Up @@ -224,6 +224,27 @@


<strong>Default:</strong> No password set <strong>Default:</strong> No password set
</li> </li>

<li class="formlisttitle">
No moves received options:
</li>
<li class="formlistfield">
<input type="radio" name="newGame[missingPlayerPolicy]" value="Normal" checked > Normal<br />
<input type="radio" name="newGame[missingPlayerPolicy]" value="Wait"> Wait for all players
</li>
<li class="formlistdesc">
What should happen if the end of the turn comes and a player has not submitted any orders?<br /><br />

If set to <strong>Normal</strong> the game will proceed, and after
a couple of turns they will go into civil disorder and their country can be taken over by another player.<br /><br />

If set to <strong>Wait for all players</strong> the game will not continue until all players have submitted their orders.<br />
This avoids any issues caused by
someone not submitting their orders on time, but it means that if someone becomes unavailable the game will not continue until they either
return, or a moderator manually sets them to civil disorder.<br /><br />

<strong>Default:</strong> Normal
</li>
</ul> </ul>


</div> </div>
Expand Down
8 changes: 4 additions & 4 deletions objects/game.php
Expand Up @@ -360,14 +360,14 @@ function isJoinable()
case 'Pre-game': case 'Pre-game':
if(count($this->Members->ByID)==count($this->Variant->countries)) if(count($this->Members->ByID)==count($this->Variant->countries))
return false; return false;
elseif($User->points < $this->minimumBet ) elseif(is_null($this->minimumBet) || $User->points < $this->minimumBet )
return false; return false;
else else
return true; return true;
default: default:
if(count($this->Members->ByStatus['Left'])==0) if(count($this->Members->ByStatus['Left'])==0)
return false; return false;
elseif($User->points < $this->minimumBet ) elseif(is_null($this->minimumBet) || $User->points < $this->minimumBet )
return false; return false;
else else
return true; return true;
Expand Down Expand Up @@ -480,15 +480,15 @@ function needsProcess()
* - Games are processing as normal * - Games are processing as normal
* - The game isn't finished * - The game isn't finished
* - The game isn't crashed or paused * - The game isn't crashed or paused
* - The game isn't in strict mode and missing a players completed moves * - The game isn't in wait mode and missing a players completed moves
* - The game is either: * - The game is either:
* - Out of time for the phase * - Out of time for the phase
* - Or either: * - Or either:
* - It's a normal order-related phase and everyone is ready to proceed * - It's a normal order-related phase and everyone is ready to proceed
* - Or it's a pre-game phase and enough people have joined, and it's not a live game * - Or it's a pre-game phase and enough people have joined, and it's not a live game
*/ */
if( self::gamesCanProcess() && $this->phase!='Finished' && $this->processStatus=='Not-processing' && if( self::gamesCanProcess() && $this->phase!='Finished' && $this->processStatus=='Not-processing' &&
!( $this->missingPlayerPolicy=='Strict'&&!$this->Members->isComplete() ) && ( ( $this->Members->isCompleted() || $this->missingPlayerPolicy!='Wait' ) && (
time() >= $this->processTime time() >= $this->processTime
|| ( ($this->phase!='Pre-game' && $this->Members->isReady() ) || ( ($this->phase!='Pre-game' && $this->Members->isReady() )
|| ($this->phase=='Pre-game' && count($this->Members->ByID)==count($this->Variant->countries) && !($this->isLiveGame()) ) ) || ($this->phase=='Pre-game' && count($this->Members->ByID)==count($this->Variant->countries) && !($this->isLiveGame()) ) )
Expand Down
56 changes: 56 additions & 0 deletions pager/pagerforum.php
@@ -0,0 +1,56 @@
<?php
/*
Copyright (C) 2004-2010 Kestas J. Kuliukas
This file is part of webDiplomacy.
webDiplomacy is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
webDiplomacy is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with webDiplomacy. If not, see <http://www.gnu.org/licenses/>.
*/

defined('IN_CODE') or die('This script can not be run by itself.');

/**
* @package Base
* @subpackage Pager
*/

require_once(l_r('pager/pagerthread.php'));
class PagerForum extends Pager
{
public static $defaultPostsPerPage=30;
public $type='forum';

function __construct($itemsTotal)
{
parent::__construct('forum.php',$itemsTotal,self::$defaultPostsPerPage);
}
function getCurrentPage($currentPage=1)
{
parent::getCurrentPage($this->pageCount);
if ( $this->currentPage>$this->pageCount )
$this->currentPage = $this->pageCount;
}
function currentPageNumber()
{
if( $this->currentPage != $this->pageCount )
return parent::currentPageNumber();
else
return '';
}

function SQLLimit()
{
return ' LIMIT '.($this->pageCount-$this->currentPage)*$this->itemsPerPage.', '.$this->itemsPerPage;
}
}

3 comments on commit 3e446c7

@Sleepcap
Copy link
Contributor

Choose a reason for hiding this comment

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

Hi kestas,
nice addition. We have something similar on vDip but made this a bit more complex for the following reason:

It's impossible for these games to continue without mod-support. Many experts like such a setting but also many players so not care and ruin the game for the better players. If a game gets paused by a missing player (usually a 1 SC player in a loosing position) for about 1-2 weeks usually all others loose interest.

In my solution you can set how many times the phase should be extended, and for how many turns this setting should be active. Usually the first 2 turns (with all phases included) is enough. Also it does not put the game on hostage if a 1 SC-power did not enter any orders.
Finally it puts the country in question in civil disorder. So a replacement can be found.

These is the setting from the gamecreate:

NMR-policy:
-Dropdown with 4 possible solutions:

  1. off / off
  2. 1 / 1 (Default - configurable in config.php)
  3. 5 / 2 (Commited)
  4. ∞ / ∞ (Serious)
  5. Custom (opens 2 input-boxes for custom numbers)

This rule will send a players into Civil Disorder (CD) if there are No Moves Received (NMR) from them.

Turns: How many turns this action will be in effect for. Be careful, a turn has up to three phases. Example: A two will send the country in CD for the diplomacy, retreat and build phase of the first 2 turns (usually Spring and Autumn).
Delay: How much time to advertise and find a replacement player (the current phase will be extended by the current phase length that many times). A zero will send the country in CD, but proceed with the turn as usual. Countries with 1 or less SCs will not hold back the game from processing.

Any value greater 90 will set the value to ∞, a value of 0 will set this to off.

This way the feature works quite well, but without I fear your admins need to CD quite a lot of countries on a regular basis.

@kestasjk
Copy link
Owner Author

@kestasjk kestasjk commented on 3e446c7 Jun 3, 2013 via email

Choose a reason for hiding this comment

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

@Sleepcap
Copy link
Contributor

Choose a reason for hiding this comment

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

Feel free to ask any questions.
Basically it works this way:
If a country does not submit any orders for the first X turns (this is configurable in the game-create and and we have a default setting of 1) and this country has more than 1 SC it set the Orderstatus for all other players from "Ready" to "Save", sets the process-time to now()+phase-length and CDs the countries with no moves. Now the other players can look for a replacement or just continoue without the player. It does this Y times (with a default of Y=1) till a replacement is found.

Please sign in to comment.