Empire mining settings
* Modified mining settings stored procedures to use text identifiers instead of numeric identifiers * Added DAO for mining settings and controller for resource operations * Added UpdateEmpireMiningSettingsCommand and associated command delegate. The command always returns NullResponse. * Overview page templates split into multiple files for clarity, added priority update form to the empire economy view and associated web server handler
This commit is contained in:
parent
92dd01ffce
commit
d38576a5cf
24 changed files with 1024 additions and 160 deletions
|
@ -0,0 +1,83 @@
|
|||
package com.deepclone.lw.beans.game.resources;
|
||||
|
||||
|
||||
import java.sql.Types;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.deepclone.lw.interfaces.game.resources.MiningSettingsDAO;
|
||||
import com.deepclone.lw.utils.StoredProc;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Data access component for mining settings
|
||||
*
|
||||
* <p>
|
||||
* This component implements the methods which allow mining settings to be updated by calling the
|
||||
* appropriate stored procedures.
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
class MiningSettingsDAOBean
|
||||
implements MiningSettingsDAO
|
||||
{
|
||||
/** <code>emp.mset_update_start(INT)</code> stored procedure */
|
||||
private StoredProc pStartEmpireUpdate;
|
||||
|
||||
/** <code>emp.mset_update_set(TEXT,INT)</code> stored procedure */
|
||||
private StoredProc pSetMiningPriority;
|
||||
|
||||
/** <code>emp.mset_update_apply()</code> stored procedure */
|
||||
private StoredProc pApplyUpdate;
|
||||
|
||||
|
||||
/**
|
||||
* Dependency injector that sets the data source
|
||||
*
|
||||
* @param dataSource
|
||||
* the data source
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setDataSource( DataSource dataSource )
|
||||
{
|
||||
this.pStartEmpireUpdate = new StoredProc( dataSource , "emp" , "mset_update_start" );
|
||||
this.pStartEmpireUpdate.addParameter( "_empire" , Types.INTEGER );
|
||||
this.pStartEmpireUpdate.addOutput( "_success" , Types.BOOLEAN );
|
||||
|
||||
this.pSetMiningPriority = new StoredProc( dataSource , "emp" , "mset_update_set" );
|
||||
this.pSetMiningPriority.addParameter( "_resource" , Types.VARCHAR );
|
||||
this.pSetMiningPriority.addParameter( "_priority" , Types.INTEGER );
|
||||
this.pSetMiningPriority.addOutput( "_success" , Types.BOOLEAN );
|
||||
|
||||
this.pApplyUpdate = new StoredProc( dataSource , "emp" , "mset_update_apply" );
|
||||
this.pApplyUpdate.addOutput( "_success" , Types.BOOLEAN );
|
||||
}
|
||||
|
||||
|
||||
/* Documented in interface */
|
||||
@Override
|
||||
public boolean startUpdate( int empireId )
|
||||
{
|
||||
return (Boolean) this.pStartEmpireUpdate.execute( empireId ).get( "_success" );
|
||||
}
|
||||
|
||||
|
||||
/* Documented in interface */
|
||||
@Override
|
||||
public boolean setNewPriority( String resource , int priority )
|
||||
{
|
||||
return (Boolean) this.pSetMiningPriority.execute( resource , priority ).get( "_success" );
|
||||
}
|
||||
|
||||
|
||||
/* Documented in interface */
|
||||
@Override
|
||||
public boolean applyUpdate( )
|
||||
{
|
||||
return (Boolean) this.pApplyUpdate.execute( ).get( "_success" );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package com.deepclone.lw.beans.game.resources;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import com.deepclone.lw.interfaces.game.resources.MiningSettingsDAO;
|
||||
import com.deepclone.lw.interfaces.game.resources.ResourcesController;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resources controller component
|
||||
*
|
||||
* <p>
|
||||
* This component implements all game actions that affect resources or resource-related information,
|
||||
* such as mining priorities.
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@Transactional
|
||||
class ResourcesControllerBean
|
||||
implements ResourcesController
|
||||
{
|
||||
|
||||
/** The mining settings access interface */
|
||||
private MiningSettingsDAO settings;
|
||||
|
||||
|
||||
/**
|
||||
* Dependency injector that sets the mining settings access interface
|
||||
*
|
||||
* @param settings
|
||||
* the mining settings access interface
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setMiningSettingsDAO( MiningSettingsDAO settings )
|
||||
{
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Update an empire's mining settings
|
||||
*
|
||||
* <p>
|
||||
* Start a mining settings update for the specified empire, then set each resource-specific
|
||||
* priority, then apply the update. Exit whenever something goes wrong.
|
||||
*/
|
||||
@Override
|
||||
public void updateEmpireSettings( int empireId , Map< String , Integer > settings )
|
||||
{
|
||||
if ( !this.settings.startUpdate( empireId ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
for ( Map.Entry< String , Integer > entry : settings.entrySet( ) ) {
|
||||
if ( ! this.settings.setNewPriority( entry.getKey( ) , entry.getValue( ) ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.settings.applyUpdate( );
|
||||
}
|
||||
|
||||
}
|
|
@ -3,6 +3,8 @@
|
|||
xsi:schemaLocation="
|
||||
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
|
||||
|
||||
<bean id="miningSettingsDAO" class="com.deepclone.lw.beans.game.resources.MiningSettingsDAOBean" />
|
||||
<bean id="resourcesController" class="com.deepclone.lw.beans.game.resources.ResourcesControllerBean" />
|
||||
<bean id="resourcesInformationDAO" class="com.deepclone.lw.beans.game.resources.ResourcesInformationDAOBean" />
|
||||
|
||||
</beans>
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
package com.deepclone.lw.beans.user.player.game;
|
||||
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate;
|
||||
import com.deepclone.lw.beans.user.abst.SessionCommandHandler;
|
||||
import com.deepclone.lw.beans.user.player.GameSubTypeBean;
|
||||
import com.deepclone.lw.cmd.player.UpdateEmpireMiningSettingsCommand;
|
||||
import com.deepclone.lw.interfaces.game.resources.ResourcesController;
|
||||
import com.deepclone.lw.interfaces.session.ServerSession;
|
||||
import com.deepclone.lw.session.Command;
|
||||
import com.deepclone.lw.session.CommandResponse;
|
||||
import com.deepclone.lw.session.NullResponse;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Command handler for empire mining settings updates
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
class UpdateEmpireMiningSettingsCommandDelegateBean
|
||||
implements AutowiredCommandDelegate
|
||||
{
|
||||
|
||||
/** The resources controller */
|
||||
private ResourcesController resourcesController;
|
||||
|
||||
|
||||
/**
|
||||
* Dependency injector that sets the resources controller
|
||||
*
|
||||
* @param resourcesController
|
||||
* the resources controller
|
||||
*/
|
||||
@Autowired( required = true )
|
||||
public void setResourcesController( ResourcesController resourcesController )
|
||||
{
|
||||
this.resourcesController = resourcesController;
|
||||
}
|
||||
|
||||
|
||||
/** This class handles {@link UpdateEmpireMiningSettingsCommand} instances */
|
||||
@Override
|
||||
public Class< ? extends Command > getType( )
|
||||
{
|
||||
return UpdateEmpireMiningSettingsCommand.class;
|
||||
}
|
||||
|
||||
|
||||
/** This class is enabled for the {@link GameSubTypeBean} session type */
|
||||
@Override
|
||||
public Class< ? extends SessionCommandHandler > getCommandHandler( )
|
||||
{
|
||||
return GameSubTypeBean.class;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If the account is not in vacation mode, update mining settings. Always return a
|
||||
* {@link NullResponse}.
|
||||
*/
|
||||
@Override
|
||||
public CommandResponse execute( ServerSession session , Command command )
|
||||
{
|
||||
if ( !session.get( "vacation" , Boolean.class ) ) {
|
||||
int empireId = session.get( "empireId" , Integer.class );
|
||||
this.resourcesController.updateEmpireSettings( empireId ,
|
||||
( (UpdateEmpireMiningSettingsCommand) command ).getSettings( ) );
|
||||
}
|
||||
return new NullResponse( );
|
||||
}
|
||||
}
|
|
@ -45,6 +45,7 @@
|
|||
<!-- Game: empire -->
|
||||
<bean class="com.deepclone.lw.beans.user.player.game.OverviewCommandDelegateBean" />
|
||||
<bean class="com.deepclone.lw.beans.user.player.game.ImplementTechCommandDelegateBean" />
|
||||
<bean class="com.deepclone.lw.beans.user.player.game.UpdateEmpireMiningSettingsCommandDelegateBean" />
|
||||
<bean class="com.deepclone.lw.beans.user.player.game.GetNewPlanetCommandDelegateBean" />
|
||||
|
||||
<!-- Game: planet list -->
|
||||
|
|
|
@ -29,15 +29,17 @@ BEGIN
|
|||
|
||||
CREATE TEMPORARY TABLE mset_update(
|
||||
empire_id INT ,
|
||||
resource_name_id INT ,
|
||||
resource_name TEXT ,
|
||||
empmset_weight INT
|
||||
) ON COMMIT DROP;
|
||||
|
||||
INSERT INTO mset_update
|
||||
SELECT _mset.empire_id , _mset.resource_name_id , 2
|
||||
SELECT _mset.empire_id , _str.name , 2
|
||||
FROM emp.empires _empire
|
||||
INNER JOIN emp.mining_settings _mset
|
||||
ON _empire.name_id = _mset.empire_id
|
||||
INNER JOIN defs.strings _str
|
||||
ON _str.id = _mset.resource_name_id
|
||||
WHERE _empire.name_id = _empire_id
|
||||
FOR SHARE OF _empire
|
||||
FOR UPDATE OF _mset;
|
||||
|
@ -81,7 +83,7 @@ BEGIN
|
|||
CREATE TEMPORARY TABLE mset_update(
|
||||
empire_id INT ,
|
||||
planet_id INT ,
|
||||
resource_name_id INT ,
|
||||
resource_name TEXT ,
|
||||
empmset_weight INT
|
||||
) ON COMMIT DROP;
|
||||
|
||||
|
@ -106,8 +108,10 @@ BEGIN
|
|||
FOR UPDATE;
|
||||
|
||||
INSERT INTO mset_update
|
||||
SELECT _empire_id , _planet_id , resource_name_id , 2
|
||||
SELECT _empire_id , _planet_id , _str.name , 2
|
||||
FROM verse.resource_providers
|
||||
INNER JOIN defs.strings _str
|
||||
ON _str.id = resource_name_id
|
||||
WHERE planet_id = _planet_id;
|
||||
|
||||
RETURN TRUE;
|
||||
|
@ -131,14 +135,14 @@ GRANT EXECUTE
|
|||
* must be called after emp.mset_update_start() has initialised the table.
|
||||
*
|
||||
* Parameters:
|
||||
* _resource_id The resource's identifier
|
||||
* _resource The resource's text identifier
|
||||
* _weight The setting's new value
|
||||
*
|
||||
* Returns:
|
||||
* ? True if the resource exists, false otherwise.
|
||||
*/
|
||||
DROP FUNCTION IF EXISTS emp.mset_update_set( INT , INT );
|
||||
CREATE FUNCTION emp.mset_update_set( _resource_id INT , _weight INT )
|
||||
DROP FUNCTION IF EXISTS emp.mset_update_set( TEXT , INT );
|
||||
CREATE FUNCTION emp.mset_update_set( _resource TEXT , _weight INT )
|
||||
RETURNS BOOLEAN
|
||||
STRICT VOLATILE
|
||||
SECURITY DEFINER
|
||||
|
@ -147,7 +151,7 @@ BEGIN
|
|||
|
||||
UPDATE mset_update
|
||||
SET empmset_weight = _weight
|
||||
WHERE resource_name_id = _resource_id;
|
||||
WHERE resource_name = _resource;
|
||||
RETURN FOUND;
|
||||
|
||||
END;
|
||||
|
@ -155,10 +159,10 @@ $mset_update_set$ LANGUAGE PLPGSQL;
|
|||
|
||||
|
||||
REVOKE EXECUTE
|
||||
ON FUNCTION emp.mset_update_set( INT , INT )
|
||||
ON FUNCTION emp.mset_update_set( TEXT , INT )
|
||||
FROM PUBLIC;
|
||||
GRANT EXECUTE
|
||||
ON FUNCTION emp.mset_update_set( INT , INT )
|
||||
ON FUNCTION emp.mset_update_set( TEXT , INT )
|
||||
TO :dbuser;
|
||||
|
||||
|
||||
|
@ -201,8 +205,10 @@ BEGIN
|
|||
empire_id , planet_id , resource_name_id ,
|
||||
emppmset_weight
|
||||
) SELECT empire_id , planet_id ,
|
||||
resource_name_id , empmset_weight
|
||||
FROM mset_update;
|
||||
_str.id , empmset_weight
|
||||
FROM mset_update
|
||||
INNER JOIN defs.strings _str
|
||||
ON _str.name = resource_name;
|
||||
|
||||
EXCEPTION
|
||||
|
||||
|
@ -211,8 +217,10 @@ BEGIN
|
|||
UPDATE emp.mining_settings _settings
|
||||
SET empmset_weight = _update.empmset_weight
|
||||
FROM mset_update _update
|
||||
INNER JOIN defs.strings _str
|
||||
ON _str.name = _update.resource_name
|
||||
WHERE _update.empire_id = _settings.empire_id
|
||||
AND _update.resource_name_id = _settings.resource_name_id;
|
||||
AND _str.id = _settings.resource_name_id;
|
||||
END;
|
||||
RETURN TRUE;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ BEGIN;
|
|||
SELECT ok( NOT emp.mset_update_start( _get_bad_emp_name( ) ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT ) - Temporary table exists despite bad empire identifier' );
|
||||
SELECT has_table( 'mset_update' );
|
||||
DROP TABLE mset_update;
|
||||
DROP TABLE IF EXISTS mset_update;
|
||||
|
||||
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT ) - Return value on valid empire identifier' );
|
||||
|
|
|
@ -28,31 +28,31 @@ BEGIN;
|
|||
SELECT ok( NOT emp.mset_update_start( _get_bad_emp_name( ) , _get_map_name( 'testPlanet1' ) ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Temporary table exists despite bad empire identifier' );
|
||||
SELECT has_table( 'mset_update' );
|
||||
DROP TABLE mset_update;
|
||||
DROP TABLE IF EXISTS mset_update;
|
||||
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Return value on bad planet identifier' );
|
||||
SELECT ok( NOT emp.mset_update_start( _get_emp_name( 'testEmp1' ) , _get_bad_map_name( ) ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Temporary table exists despite bad planet identifier' );
|
||||
SELECT has_table( 'mset_update' );
|
||||
DROP TABLE mset_update;
|
||||
DROP TABLE IF EXISTS mset_update;
|
||||
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Return value on unowned planet identifier' );
|
||||
SELECT ok( NOT emp.mset_update_start( _get_emp_name( 'testEmp1' ) , _get_map_name( 'testPlanet2' ) ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Temporary table exists despite unowned planet identifier' );
|
||||
SELECT has_table( 'mset_update' );
|
||||
DROP TABLE mset_update;
|
||||
DROP TABLE IF EXISTS mset_update;
|
||||
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Return value on unowned planet identifier' );
|
||||
SELECT ok( NOT emp.mset_update_start( _get_emp_name( 'testEmp1' ) , _get_map_name( 'testPlanet2' ) ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Temporary table exists despite unowned planet identifier' );
|
||||
SELECT has_table( 'mset_update' );
|
||||
DROP TABLE mset_update;
|
||||
DROP TABLE IF EXISTS mset_update;
|
||||
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Return value on planet with no resource providers' );
|
||||
SELECT ok( NOT emp.mset_update_start( _get_emp_name( 'testEmp1' ) , _get_map_name( 'testPlanet3' ) ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Temporary table exists despite planet with no resource providers' );
|
||||
SELECT has_table( 'mset_update' );
|
||||
DROP TABLE mset_update;
|
||||
DROP TABLE IF EXISTS mset_update;
|
||||
|
||||
|
||||
SELECT diag_test_name( 'emp.mset_update_start( INT , INT ) - Return value on valid identifiers' );
|
||||
|
|
|
@ -4,34 +4,34 @@
|
|||
BEGIN;
|
||||
CREATE TEMPORARY TABLE mset_update(
|
||||
empire_id INT ,
|
||||
resource_name_id INT ,
|
||||
resource_name TEXT ,
|
||||
empmset_weight INT
|
||||
) ON COMMIT DROP;
|
||||
INSERT INTO mset_update VALUES ( 1 , 1 , 0 ) , ( 1 , 2 , 0 );
|
||||
INSERT INTO mset_update VALUES ( 1 , 'a' , 0 ) , ( 1 , 'b' , 0 );
|
||||
|
||||
/***** TESTS BEGIN HERE *****/
|
||||
SELECT plan( 7 );
|
||||
|
||||
SELECT diag_test_name( 'emp.mset_update_set( ) - Valid update' );
|
||||
SELECT ok( emp.mset_update_set( 1 , 1 ) );
|
||||
SELECT ok( emp.mset_update_set( 'a' , 1 ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_set( ) - Valid update results (1/2)' );
|
||||
SELECT is( empmset_weight , 1 ) FROM mset_update WHERE resource_name_id = 1;
|
||||
SELECT is( empmset_weight , 1 ) FROM mset_update WHERE resource_name = 'a';
|
||||
SELECT diag_test_name( 'emp.mset_update_set( ) - Valid update results (2/2)' );
|
||||
SELECT is( empmset_weight , 0 ) FROM mset_update WHERE resource_name_id = 2;
|
||||
SELECT is( empmset_weight , 0 ) FROM mset_update WHERE resource_name = 'b';
|
||||
DELETE FROM mset_update;
|
||||
|
||||
INSERT INTO mset_update VALUES ( 1 , 1 , 0 ) , ( 1 , 2 , 0 );
|
||||
INSERT INTO mset_update VALUES ( 1 , 'a' , 0 ) , ( 1 , 'b' , 0 );
|
||||
SELECT diag_test_name( 'emp.mset_update_set( ) - Update on unknown resource' );
|
||||
SELECT ok( NOT emp.mset_update_set( 12 , 1 ) );
|
||||
SELECT ok( NOT emp.mset_update_set( 'c' , 1 ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_set( ) - Unknown resource update results (1/2)' );
|
||||
SELECT is( empmset_weight , 0 ) FROM mset_update WHERE resource_name_id = 1;
|
||||
SELECT is( empmset_weight , 0 ) FROM mset_update WHERE resource_name = 'a';
|
||||
SELECT diag_test_name( 'emp.mset_update_set( ) - Unknown resource update results (2/2)' );
|
||||
SELECT is( empmset_weight , 0 ) FROM mset_update WHERE resource_name_id = 2;
|
||||
SELECT is( empmset_weight , 0 ) FROM mset_update WHERE resource_name = 'b';
|
||||
DELETE FROM mset_update;
|
||||
|
||||
INSERT INTO mset_update VALUES ( 1 , 1 , 0 ) , ( 1 , 2 , 0 );
|
||||
INSERT INTO mset_update VALUES ( 1 , 'a' , 0 ) , ( 1 , 'b' , 0 );
|
||||
SELECT diag_test_name( 'emp.mset_update_set( ) - Update with invalid weight' );
|
||||
SELECT ok( emp.mset_update_set( 1 , -1 ) );
|
||||
SELECT ok( emp.mset_update_set( 'a' , -1 ) );
|
||||
|
||||
SELECT * FROM finish( );
|
||||
ROLLBACK;
|
|
@ -2,6 +2,11 @@
|
|||
* Test the emp.mset_update_apply() function
|
||||
*/
|
||||
BEGIN;
|
||||
/*
|
||||
* Create a pair of strings
|
||||
*/
|
||||
INSERT INTO defs.strings (name) VALUES ( 'a' ) , ( 'b' );
|
||||
|
||||
/*
|
||||
* Remove foreign keys from the empire mining settings table, insert some
|
||||
* data into it.
|
||||
|
@ -10,15 +15,17 @@ BEGIN;
|
|||
DROP CONSTRAINT fk_empmset_empire ,
|
||||
DROP CONSTRAINT fk_empmset_resource;
|
||||
INSERT INTO emp.mining_settings ( empire_id , resource_name_id )
|
||||
VALUES ( 1 , 1 ) , ( 1 , 2 );
|
||||
SELECT 1 , id
|
||||
FROM defs.strings
|
||||
WHERE name IN ( 'a' , 'b' );
|
||||
|
||||
/* Create the temporary table */
|
||||
CREATE TEMPORARY TABLE mset_update(
|
||||
empire_id INT ,
|
||||
resource_name_id INT ,
|
||||
resource_name TEXT ,
|
||||
empmset_weight INT
|
||||
) ON COMMIT DROP;
|
||||
INSERT INTO mset_update VALUES ( 1 , 1 , 0 ) , ( 1 , 2 , 4 );
|
||||
INSERT INTO mset_update VALUES ( 1 , 'a' , 0 ) , ( 1 , 'b' , 4 );
|
||||
|
||||
/***** TESTS BEGIN HERE *****/
|
||||
SELECT plan( 8 );
|
||||
|
@ -27,23 +34,31 @@ BEGIN;
|
|||
SELECT ok( emp.mset_update_apply( ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_apply() - Empire update results' );
|
||||
SELECT set_eq(
|
||||
$$ SELECT resource_name_id , empmset_weight FROM emp.mining_settings $$ ,
|
||||
$$ VALUES ( 1 , 0 ) , ( 2 , 4 ) $$
|
||||
$$ SELECT name , empmset_weight
|
||||
FROM emp.mining_settings
|
||||
INNER JOIN defs.strings
|
||||
ON resource_name_id = id $$ ,
|
||||
$$ VALUES ( 'a' , 0 ) , ( 'b' , 4 ) $$
|
||||
);
|
||||
|
||||
/* Reset temporary table and settings */
|
||||
DELETE FROM mset_update;
|
||||
DELETE FROM emp.mining_settings;
|
||||
INSERT INTO emp.mining_settings ( empire_id , resource_name_id )
|
||||
VALUES ( 1 , 1 ) , ( 1 , 2 );
|
||||
SELECT 1 , id
|
||||
FROM defs.strings
|
||||
WHERE name IN ( 'a' , 'b' );
|
||||
|
||||
INSERT INTO mset_update VALUES ( 1 , 1 , -1 ) , ( 1 , 2 , 4 );
|
||||
INSERT INTO mset_update VALUES ( 1 , 'a' , -1 ) , ( 1 , 'b' , 4 );
|
||||
SELECT diag_test_name( 'emp.mset_update_apply() - Applying invalid empire update' );
|
||||
SELECT ok( NOT emp.mset_update_apply( ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_apply() - Invalid empire update results' );
|
||||
SELECT set_eq(
|
||||
$$ SELECT resource_name_id , empmset_weight FROM emp.mining_settings $$ ,
|
||||
$$ VALUES ( 1 , 2 ) , ( 2 , 2 ) $$
|
||||
$$ SELECT name , empmset_weight
|
||||
FROM emp.mining_settings
|
||||
INNER JOIN defs.strings
|
||||
ON resource_name_id = id $$ ,
|
||||
$$ VALUES ( 'a' , 2 ) , ( 'b' , 2 ) $$
|
||||
);
|
||||
|
||||
|
||||
|
@ -55,38 +70,48 @@ BEGIN;
|
|||
DROP CONSTRAINT fk_emppmset_empire ,
|
||||
DROP CONSTRAINT fk_emppmset_resource;
|
||||
INSERT INTO emp.planet_mining_settings ( empire_id , planet_id , resource_name_id )
|
||||
VALUES ( 1 , 1 , 1 ) , ( 1 , 1 , 2 );
|
||||
SELECT 1 , 1 , id
|
||||
FROM defs.strings
|
||||
WHERE name IN ( 'a' , 'b' );
|
||||
|
||||
DROP TABLE mset_update;
|
||||
CREATE TEMPORARY TABLE mset_update(
|
||||
empire_id INT ,
|
||||
planet_id INT ,
|
||||
resource_name_id INT ,
|
||||
resource_name TEXT ,
|
||||
empmset_weight INT
|
||||
) ON COMMIT DROP;
|
||||
INSERT INTO mset_update VALUES ( 1 , 1 , 1 , 0 ) , ( 1 , 1 , 2 , 4 );
|
||||
INSERT INTO mset_update VALUES ( 1 , 1 , 'a' , 0 ) , ( 1 , 1 , 'b' , 4 );
|
||||
|
||||
SELECT diag_test_name( 'emp.mset_update_apply() - Applying valid planet update' );
|
||||
SELECT ok( emp.mset_update_apply( ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_apply() - Planet update results' );
|
||||
SELECT set_eq(
|
||||
$$ SELECT resource_name_id , emppmset_weight FROM emp.planet_mining_settings $$ ,
|
||||
$$ VALUES ( 1 , 0 ) , ( 2 , 4 ) $$
|
||||
$$ SELECT name , emppmset_weight
|
||||
FROM emp.planet_mining_settings
|
||||
INNER JOIN defs.strings
|
||||
ON resource_name_id = id $$ ,
|
||||
$$ VALUES ( 'a' , 0 ) , ( 'b' , 4 ) $$
|
||||
);
|
||||
|
||||
/* Reset temporary table and settings */
|
||||
DELETE FROM mset_update;
|
||||
DELETE FROM emp.planet_mining_settings;
|
||||
INSERT INTO emp.planet_mining_settings ( empire_id , planet_id , resource_name_id )
|
||||
VALUES ( 1 , 1 , 1 ) , ( 1 , 1 , 2 );
|
||||
SELECT 1 , 1 , id
|
||||
FROM defs.strings
|
||||
WHERE name IN ( 'a' , 'b' );
|
||||
|
||||
INSERT INTO mset_update VALUES ( 1 , 1 , 1 , -1 ) , ( 1 , 1 , 2 , 4 );
|
||||
INSERT INTO mset_update VALUES ( 1 , 1 , 'a' , -1 ) , ( 1 , 1 , 'b' , 4 );
|
||||
SELECT diag_test_name( 'emp.mset_update_apply() - Applying invalid planet update' );
|
||||
SELECT ok( NOT emp.mset_update_apply( ) );
|
||||
SELECT diag_test_name( 'emp.mset_update_apply() - Invalid planet update results' );
|
||||
SELECT set_eq(
|
||||
$$ SELECT resource_name_id , emppmset_weight FROM emp.planet_mining_settings $$ ,
|
||||
$$ VALUES ( 1 , 2 ) , ( 2 , 2 ) $$
|
||||
$$ SELECT name , emppmset_weight
|
||||
FROM emp.planet_mining_settings
|
||||
INNER JOIN defs.strings
|
||||
ON resource_name_id = id $$ ,
|
||||
$$ VALUES ( 'a' , 2 ) , ( 'b' , 2 ) $$
|
||||
);
|
||||
|
||||
SELECT * FROM finish( );
|
||||
|
|
|
@ -7,7 +7,7 @@ BEGIN;
|
|||
|
||||
SELECT diag_test_name( 'emp.mset_update_set() - Privileges' );
|
||||
SELECT lives_ok( $$
|
||||
SELECT emp.mset_update_set( 1 , -1 )
|
||||
SELECT emp.mset_update_set( 'a' , -1 )
|
||||
$$ );
|
||||
|
||||
SELECT * FROM finish( );
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package com.deepclone.lw.interfaces.game.resources;
|
||||
|
||||
|
||||
/**
|
||||
* Data access object for mining settings
|
||||
*
|
||||
* <p>
|
||||
* This interface provides methods which call stored procedures that control mining settings for
|
||||
* both empires and planets.
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
public interface MiningSettingsDAO
|
||||
{
|
||||
|
||||
/**
|
||||
* Start an empire settings update
|
||||
*
|
||||
* <p>
|
||||
* Start an empire settings update by calling the <code>emp.mset_update_start(INT)</code> stored
|
||||
* procedure.
|
||||
*
|
||||
* @param empireId
|
||||
* the identifier of the empire whose settings will be updated
|
||||
*
|
||||
* @return <code>true</code> on success, <code>false</code> on failure
|
||||
*/
|
||||
public boolean startUpdate( int empireId );
|
||||
|
||||
|
||||
/**
|
||||
* Set the new extraction priority of a resource
|
||||
*
|
||||
* <p>
|
||||
* Call the <code>emp.mset_update_set(TEXT,INT)</code> stored procedure to set the new
|
||||
* extraction priority for some type of resources. An mining settings update (empire- or
|
||||
* planet-wide) must have been initiated before this method is called.
|
||||
*
|
||||
* @param resource
|
||||
* the identifier of the resource
|
||||
* @param priority
|
||||
* the new extraction priority for the resource
|
||||
*
|
||||
* @return <code>true</code> on success, <code>false</code> if the resource did not exist.
|
||||
*/
|
||||
public boolean setNewPriority( String resource , int priority );
|
||||
|
||||
|
||||
/**
|
||||
* Apply the current settings update
|
||||
*
|
||||
* <p>
|
||||
* This method applies a previously initiated mining settings update by calling the
|
||||
* <code>emp.mset_update_apply()</code> stored procedure.
|
||||
*
|
||||
* @return <code>true</code> on success, <code>false</code> if one of the priorities was
|
||||
* invalid.
|
||||
*/
|
||||
public boolean applyUpdate( );
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package com.deepclone.lw.interfaces.game.resources;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Resources control interface
|
||||
*
|
||||
* <p>
|
||||
* This interface corresponds to the component which controls resources from the game's point of
|
||||
* view. It contains methods that update mining settings.
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
public interface ResourcesController
|
||||
{
|
||||
|
||||
/**
|
||||
* Update an empire's mining settings
|
||||
*
|
||||
* @param empireId
|
||||
* the empire's identifier
|
||||
* @param settings
|
||||
* the new settings
|
||||
*/
|
||||
public void updateEmpireSettings( int empireId , Map< String , Integer > settings );
|
||||
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package com.deepclone.lw.beans.game.resources;
|
||||
|
||||
|
||||
import com.deepclone.lw.interfaces.game.resources.MiningSettingsDAO;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Mock mining settings DAO which can be used to simulate failures and trace which methods were
|
||||
* called.
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*
|
||||
*/
|
||||
public class MockMiningSettingsDAO
|
||||
implements MiningSettingsDAO
|
||||
{
|
||||
/** The empire identifier with which {@link #startUpdate(int)} was called */
|
||||
private Integer updateEmpire = null;
|
||||
|
||||
/** The amount of calls to {@link #setNewPriority(String, int)} */
|
||||
private int callsToSet = 0;
|
||||
|
||||
/** Whether {@link #applyUpdate()} was called */
|
||||
private boolean applyCalled = false;
|
||||
|
||||
/** Whether {@link #startUpdate(int)} will succeed or fail */
|
||||
private boolean startUpdateSucceeds = true;
|
||||
|
||||
/** Whether applyUpdate will succeed */
|
||||
private boolean applyUpdateSucceeds = true;
|
||||
|
||||
/**
|
||||
* Amount of calls to {@link #setNewPriority(String, int)} that will succeed, or
|
||||
* <code>null</code> if they will all succeed.
|
||||
*/
|
||||
private Integer maxSetCalls = null;
|
||||
|
||||
|
||||
/** @return the empire identifier to update */
|
||||
public Integer getUpdateEmpire( )
|
||||
{
|
||||
return this.updateEmpire;
|
||||
}
|
||||
|
||||
|
||||
/** @return the amount of calls to {@link #setNewPriority(String, int)} */
|
||||
public int getCallsToSet( )
|
||||
{
|
||||
return this.callsToSet;
|
||||
}
|
||||
|
||||
|
||||
/** @return <code>true</code> if {@link #applyUpdate()} was called */
|
||||
public boolean wasApplyCalled( )
|
||||
{
|
||||
return this.applyCalled;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether calls to {@link #startUpdate(int)} will succeed
|
||||
*
|
||||
* @param startUpdateSucceeds
|
||||
* <code>true</code> if the call is to succeed, <code>false</code> if it is to fail
|
||||
*/
|
||||
public void setStartUpdateSucceeds( boolean startUpdateSucceeds )
|
||||
{
|
||||
this.startUpdateSucceeds = startUpdateSucceeds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether calls to {@link #applyUpdate()} will succeed
|
||||
*
|
||||
* @param applyUpdateSucceeds
|
||||
* <code>true</code> if the call is to succeed, <code>false</code> if it is to fail
|
||||
*/
|
||||
public void setApplyUpdateSucceeds( boolean applyUpdateSucceeds )
|
||||
{
|
||||
this.applyUpdateSucceeds = applyUpdateSucceeds;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the amount of calls to {@link #setNewPriority(String, int)} that will succeed
|
||||
*
|
||||
* @param maxSetCalls
|
||||
* the amount of calls that will succeed, or <code>null</code> if the method must
|
||||
* always succeed
|
||||
*/
|
||||
public void setMaxSetCalls( Integer maxSetCalls )
|
||||
{
|
||||
this.maxSetCalls = maxSetCalls;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean startUpdate( int empireId )
|
||||
{
|
||||
this.updateEmpire = empireId;
|
||||
return this.startUpdateSucceeds;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean setNewPriority( String resource , int priority )
|
||||
{
|
||||
this.callsToSet++;
|
||||
return ( this.maxSetCalls == null || this.maxSetCalls > this.callsToSet - 1 );
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean applyUpdate( )
|
||||
{
|
||||
this.applyCalled = true;
|
||||
return this.applyUpdateSucceeds;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,121 @@
|
|||
package com.deepclone.lw.beans.game.resources;
|
||||
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.deepclone.lw.interfaces.game.resources.MiningSettingsDAO;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Tests for {@link ResourcesControllerBean}
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*
|
||||
*/
|
||||
public class TestResourcesControllerBean
|
||||
{
|
||||
|
||||
/** Empire identifier used in the tests */
|
||||
private static final Integer EMPIRE_ID = 42;
|
||||
|
||||
/** Mining settings used in the tests */
|
||||
private static final Map< String , Integer > MINING_SETTINGS;
|
||||
|
||||
/**
|
||||
* Initialise the mining settings map
|
||||
*/
|
||||
static {
|
||||
HashMap< String , Integer > tempMap = new HashMap< String , Integer >( );
|
||||
tempMap.put( "test 1" , 1 );
|
||||
tempMap.put( "test 2" , 2 );
|
||||
tempMap.put( "test 3" , 3 );
|
||||
tempMap.put( "test 4" , 4 );
|
||||
MINING_SETTINGS = Collections.unmodifiableMap( tempMap );
|
||||
}
|
||||
|
||||
/** The mock database access object */
|
||||
private MockMiningSettingsDAO miningSettingsDAO;
|
||||
|
||||
/** The instance to test on */
|
||||
private ResourcesControllerBean ctrl;
|
||||
|
||||
|
||||
/**
|
||||
* Create the resource controller that will be used in the tests and its various (usually fake)
|
||||
* dependencies
|
||||
*/
|
||||
@Before
|
||||
public void setUp( )
|
||||
{
|
||||
this.miningSettingsDAO = new MockMiningSettingsDAO( );
|
||||
this.ctrl = new ResourcesControllerBean( );
|
||||
this.ctrl.setMiningSettingsDAO( this.miningSettingsDAO );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When calling {@link MiningSettingsDAO#startUpdate(int)} fails, the empire settings update is
|
||||
* interrupted.
|
||||
*/
|
||||
@Test
|
||||
public void testEmpireStartUpdateFails( )
|
||||
{
|
||||
this.miningSettingsDAO.setStartUpdateSucceeds( false );
|
||||
this.ctrl.updateEmpireSettings( EMPIRE_ID , MINING_SETTINGS );
|
||||
assertEquals( EMPIRE_ID , this.miningSettingsDAO.getUpdateEmpire( ) );
|
||||
assertEquals( 0 , this.miningSettingsDAO.getCallsToSet( ) );
|
||||
assertFalse( this.miningSettingsDAO.wasApplyCalled( ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* When calling {@link MiningSettingsDAO#startUpdate(int)} succeeds but one of the calls to
|
||||
* {@link MiningSettingsDAO#setNewPriority(String, int)} fails, the update is interrupted.
|
||||
*/
|
||||
@Test
|
||||
public void testSetMiningPriorityFails( )
|
||||
{
|
||||
this.miningSettingsDAO.setMaxSetCalls( 2 );
|
||||
this.ctrl.updateEmpireSettings( EMPIRE_ID , MINING_SETTINGS );
|
||||
assertEquals( EMPIRE_ID , this.miningSettingsDAO.getUpdateEmpire( ) );
|
||||
assertEquals( 3 , this.miningSettingsDAO.getCallsToSet( ) );
|
||||
assertFalse( this.miningSettingsDAO.wasApplyCalled( ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* If both {@link MiningSettingsDAO#startUpdate(int)} and
|
||||
* {@link MiningSettingsDAO#setNewPriority(String, int)} succeed,
|
||||
* {@link MiningSettingsDAO#applyUpdate()} is called.
|
||||
*/
|
||||
@Test
|
||||
public void testSettingsSuccess( )
|
||||
{
|
||||
this.ctrl.updateEmpireSettings( EMPIRE_ID , MINING_SETTINGS );
|
||||
assertEquals( EMPIRE_ID , this.miningSettingsDAO.getUpdateEmpire( ) );
|
||||
assertEquals( 4 , this.miningSettingsDAO.getCallsToSet( ) );
|
||||
assertTrue( this.miningSettingsDAO.wasApplyCalled( ) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A failure of {@link MiningSettingsDAO#applyUpdate()} has no influence on the call.
|
||||
*/
|
||||
@Test
|
||||
public void testSettingsApplyFail( )
|
||||
{
|
||||
this.miningSettingsDAO.setApplyUpdateSucceeds( false );
|
||||
this.ctrl.updateEmpireSettings( EMPIRE_ID , MINING_SETTINGS );
|
||||
assertEquals( EMPIRE_ID , this.miningSettingsDAO.getUpdateEmpire( ) );
|
||||
assertEquals( 4 , this.miningSettingsDAO.getCallsToSet( ) );
|
||||
assertTrue( this.miningSettingsDAO.wasApplyCalled( ) );
|
||||
}
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
package com.deepclone.lw.cmd.player;
|
||||
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import com.deepclone.lw.session.Command;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Command that updates empire mining settings
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
public class UpdateEmpireMiningSettingsCommand
|
||||
extends Command
|
||||
{
|
||||
|
||||
/**
|
||||
* Serialisation version identifier
|
||||
*
|
||||
* <ul>
|
||||
* <li>Introduced in B6M2
|
||||
* </ul>
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** The new empire mining settings */
|
||||
private final Map< String , Integer > settings;
|
||||
|
||||
|
||||
/**
|
||||
* Initialise the command using mining settings
|
||||
*
|
||||
* @param settings
|
||||
* a map that associates resource identifiers to priorities
|
||||
*/
|
||||
public UpdateEmpireMiningSettingsCommand( Map< String , Integer > settings )
|
||||
{
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
|
||||
/** @return the mining settings to apply */
|
||||
public Map< String , Integer > getSettings( )
|
||||
{
|
||||
return this.settings;
|
||||
}
|
||||
|
||||
}
|
|
@ -85,6 +85,19 @@ public class PlayerSession
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Send an {@link UpdateEmpireMiningSettingsCommand} to the server
|
||||
*
|
||||
* @param miningSettings
|
||||
* the mining settings
|
||||
*/
|
||||
public void updateEmpireMiningSettings( Map< String , Integer > miningSettings )
|
||||
throws SessionException , SessionServerException , SessionMaintenanceException
|
||||
{
|
||||
this.execute( new UpdateEmpireMiningSettingsCommand( miningSettings ) );
|
||||
}
|
||||
|
||||
|
||||
/* Planet list */
|
||||
|
||||
public ListPlanetsResponse listPlanets( )
|
||||
|
|
|
@ -63,60 +63,8 @@
|
|||
</@tab>
|
||||
|
||||
<@tab id="economy" title="Economy">
|
||||
|
||||
<@listview>
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width=30> </@lv_column>
|
||||
<@lv_column width="x">Resource</@lv_column>
|
||||
<@lv_column width=100 centered=true><@over_time "Income" /></@lv_column>
|
||||
<@lv_column width=100 centered=true><@over_time "Upkeep" /></@lv_column>
|
||||
<@lv_column width=100 centered=true>Reserves</@lv_column>
|
||||
<@lv_column width=100 centered=true>Mining priority</@lv_column>
|
||||
</@lv_line>
|
||||
|
||||
<#list ov.economy as resource>
|
||||
|
||||
<#if previousCategory?has_content && !resource.category?has_content
|
||||
|| resource.category?has_content && !previousCategory?has_content
|
||||
|| resource.category?has_content && previousCategory?has_content
|
||||
&& resource.category != previousCategory>
|
||||
<@lv_line>
|
||||
<#if resource.category?has_content>
|
||||
<td colspan="5"><strong>${resource.category?xhtml}</strong></td>
|
||||
<#else>
|
||||
<td colspan="5"><hr /></td>
|
||||
</#if>
|
||||
</@lv_line>
|
||||
<#local previousCategory=resource.category>
|
||||
</#if>
|
||||
|
||||
<@lv_line>
|
||||
<@lv_column> </@lv_column>
|
||||
<@lv_column>${resource.title?xhtml}
|
||||
<div class="auto-hide">${resource.description?xhtml}</div>
|
||||
</@lv_column>
|
||||
<@lv_column centered=true>${resource.income?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>${resource.upkeep?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>${resource.stockpiled?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>
|
||||
<#if resource.miningPriority?has_content>
|
||||
<#switch resource.miningPriority>
|
||||
<#case 0>lowest<#break>
|
||||
<#case 1>low<#break>
|
||||
<#case 2>normal<#break>
|
||||
<#case 3>high<#break>
|
||||
<#case 4>highest<#break>
|
||||
</#switch>
|
||||
<#else>
|
||||
N/A
|
||||
</#if>
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
|
||||
</#list>
|
||||
|
||||
</@listview>
|
||||
|
||||
<#include "overview/resources.ftl" />
|
||||
<@overviewResources />
|
||||
</@tab>
|
||||
|
||||
<@tab id="research" title="Research">
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<#macro overviewResources>
|
||||
<form action="update-mining-settings.action" method="POST"><@listview>
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width=30> </@lv_column>
|
||||
<@lv_column width="x">Resource</@lv_column>
|
||||
<@lv_column width=100 centered=true><@over_time "Income" /></@lv_column>
|
||||
<@lv_column width=100 centered=true><@over_time "Upkeep" /></@lv_column>
|
||||
<@lv_column width=100 centered=true>Reserves</@lv_column>
|
||||
<@lv_column width=100 centered=true>Mining priority</@lv_column>
|
||||
</@lv_line>
|
||||
|
||||
<#list ov.economy as resource>
|
||||
|
||||
<#if previousCategory?has_content && !resource.category?has_content
|
||||
|| resource.category?has_content && !previousCategory?has_content
|
||||
|| resource.category?has_content && previousCategory?has_content
|
||||
&& resource.category != previousCategory>
|
||||
<@lv_line>
|
||||
<#if resource.category?has_content>
|
||||
<td colspan="5"><strong>${resource.category?xhtml}</strong></td>
|
||||
<#else>
|
||||
<td colspan="5"><hr /></td>
|
||||
</#if>
|
||||
</@lv_line>
|
||||
<#local previousCategory=resource.category>
|
||||
</#if>
|
||||
|
||||
<@lv_line>
|
||||
<@lv_column> </@lv_column>
|
||||
<@lv_column>${resource.title?xhtml}
|
||||
<div class="auto-hide">${resource.description?xhtml}</div>
|
||||
</@lv_column>
|
||||
<@lv_column centered=true>${resource.income?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>${resource.upkeep?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>${resource.stockpiled?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>
|
||||
<#if resource.miningPriority?has_content>
|
||||
<select name="ems-${resource.identifier?xhtml}" class="input">
|
||||
<option style="padding: 0 5px" value="0" <#if resource.miningPriority = 0>selected="selected"</#if>>lowest</option>
|
||||
<option style="padding: 0 5px" value="1" <#if resource.miningPriority = 1>selected="selected"</#if>>low</option>
|
||||
<option style="padding: 0 5px" value="2" <#if resource.miningPriority = 2>selected="selected"</#if>>normal</option>
|
||||
<option style="padding: 0 5px" value="3" <#if resource.miningPriority = 3>selected="selected"</#if>>high</option>
|
||||
<option style="padding: 0 5px" value="4" <#if resource.miningPriority = 4>selected="selected"</#if>>highest</option>
|
||||
</select>
|
||||
<#else>
|
||||
N/A
|
||||
</#if>
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
|
||||
</#list>
|
||||
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width="x" colspan=6> </@lv_column>
|
||||
</@lv_line>
|
||||
<@lv_line>
|
||||
<@lv_column colspan=4> </@lv_column>
|
||||
<@lv_column right=true colspan=2>
|
||||
<input type="submit" value="Update mining priorities" class="input" style="margin: 15px 0 0 0" />
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
|
||||
</@listview></form>
|
||||
</#macro>
|
|
@ -63,60 +63,8 @@
|
|||
</@tab>
|
||||
|
||||
<@tab id="economy" title="Économie">
|
||||
|
||||
<@listview>
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width=30> </@lv_column>
|
||||
<@lv_column width="x">Ressource</@lv_column>
|
||||
<@lv_column width=100 centered=true><@over_time "Bénéfice" /></@lv_column>
|
||||
<@lv_column width=100 centered=true><@over_time title="Charges" feminin=true pluriel=true /></@lv_column>
|
||||
<@lv_column width=100 centered=true>Réserves</@lv_column>
|
||||
<@lv_column width=100 centered=true>Priorité d'extraction</@lv_column>
|
||||
</@lv_line>
|
||||
|
||||
<#list ov.economy as resource>
|
||||
|
||||
<#if previousCategory?has_content && !resource.category?has_content
|
||||
|| resource.category?has_content && !previousCategory?has_content
|
||||
|| resource.category?has_content && previousCategory?has_content
|
||||
&& resource.category != previousCategory>
|
||||
<@lv_line>
|
||||
<#if resource.category?has_content>
|
||||
<td colspan="5"><strong>${resource.category?xhtml}</strong></td>
|
||||
<#else>
|
||||
<td colspan="5"><hr /></td>
|
||||
</#if>
|
||||
</@lv_line>
|
||||
<#local previousCategory=resource.category>
|
||||
</#if>
|
||||
|
||||
<@lv_line>
|
||||
<@lv_column> </@lv_column>
|
||||
<@lv_column>${resource.title?xhtml}
|
||||
<div class="auto-hide">${resource.description?xhtml}</div>
|
||||
</@lv_column>
|
||||
<@lv_column centered=true>${resource.income?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>${resource.upkeep?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>${resource.stockpiled?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>
|
||||
<#if resource.miningPriority?has_content>
|
||||
<#switch resource.miningPriority>
|
||||
<#case 0>très basse<#break>
|
||||
<#case 1>basse<#break>
|
||||
<#case 2>normale<#break>
|
||||
<#case 3>haute<#break>
|
||||
<#case 4>très haute<#break>
|
||||
</#switch>
|
||||
<#else>
|
||||
N/A
|
||||
</#if>
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
|
||||
</#list>
|
||||
|
||||
</@listview>
|
||||
|
||||
<#include "overview/resources.ftl" />
|
||||
<@overviewResources />
|
||||
</@tab>
|
||||
|
||||
<@tab id="research" title="Recherche">
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
<#macro overviewResources>
|
||||
<form action="update-mining-settings.action" method="POST"><@listview>
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width=30> </@lv_column>
|
||||
<@lv_column width="x">Ressource</@lv_column>
|
||||
<@lv_column width=100 centered=true><@over_time "Bénéfice" /></@lv_column>
|
||||
<@lv_column width=100 centered=true><@over_time title="Charges" feminin=true pluriel=true /></@lv_column>
|
||||
<@lv_column width=100 centered=true>Réserves</@lv_column>
|
||||
<@lv_column width=100 centered=true>Priorité d'extraction</@lv_column>
|
||||
</@lv_line>
|
||||
|
||||
<#list ov.economy as resource>
|
||||
|
||||
<#if previousCategory?has_content && !resource.category?has_content
|
||||
|| resource.category?has_content && !previousCategory?has_content
|
||||
|| resource.category?has_content && previousCategory?has_content
|
||||
&& resource.category != previousCategory>
|
||||
<@lv_line>
|
||||
<#if resource.category?has_content>
|
||||
<td colspan="5"><strong>${resource.category?xhtml}</strong></td>
|
||||
<#else>
|
||||
<td colspan="5"><hr /></td>
|
||||
</#if>
|
||||
</@lv_line>
|
||||
<#local previousCategory=resource.category>
|
||||
</#if>
|
||||
|
||||
<@lv_line>
|
||||
<@lv_column> </@lv_column>
|
||||
<@lv_column>${resource.title?xhtml}
|
||||
<div class="auto-hide">${resource.description?xhtml}</div>
|
||||
</@lv_column>
|
||||
<@lv_column centered=true>${resource.income?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>${resource.upkeep?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>${resource.stockpiled?string(",##0")}</@lv_column>
|
||||
<@lv_column centered=true>
|
||||
<#if resource.miningPriority?has_content>
|
||||
<select name="ems-${resource.identifier?xhtml}" class="input">
|
||||
<option style="padding: 0 5px" value="0" <#if resource.miningPriority = 0>selected="selected"</#if>>très basse</option>
|
||||
<option style="padding: 0 5px" value="1" <#if resource.miningPriority = 1>selected="selected"</#if>>basse</option>
|
||||
<option style="padding: 0 5px" value="2" <#if resource.miningPriority = 2>selected="selected"</#if>>normale</option>
|
||||
<option style="padding: 0 5px" value="3" <#if resource.miningPriority = 3>selected="selected"</#if>>haute</option>
|
||||
<option style="padding: 0 5px" value="4" <#if resource.miningPriority = 4>selected="selected"</#if>>très haute</option>
|
||||
</select>
|
||||
<#else>
|
||||
N/A
|
||||
</#if>
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
|
||||
</#list>
|
||||
|
||||
<@lv_line headers=true>
|
||||
<@lv_column width="x" colspan=6> </@lv_column>
|
||||
</@lv_line>
|
||||
<@lv_line>
|
||||
<@lv_column colspan=4> </@lv_column>
|
||||
<@lv_column right=true colspan=2>
|
||||
<input type="submit" value="Modifier les priorités" class="input" style="margin: 15px 0 0 0" />
|
||||
</@lv_column>
|
||||
</@lv_line>
|
||||
|
||||
</@listview></form>
|
||||
</#macro>
|
|
@ -1,6 +1,10 @@
|
|||
package com.deepclone.lw.web.main.game;
|
||||
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.stereotype.Controller;
|
||||
|
@ -20,6 +24,15 @@ import com.deepclone.lw.web.csess.PlayerSession;
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* Overview page controller
|
||||
*
|
||||
* <p>
|
||||
* This page controller implements the "Overview" page, as well as the commands it supports
|
||||
* (implement technology, update empire mining settings).
|
||||
*
|
||||
* @author <a href="mailto:tseeker@legacyworlds.com">E. Benoît</a>
|
||||
*/
|
||||
@Controller
|
||||
@SessionRequirement( value = true , redirectTo = "player-session" , subType = "game" )
|
||||
@SessionAttributes( "language" )
|
||||
|
@ -27,6 +40,29 @@ public class OverviewPage
|
|||
extends PageControllerBase
|
||||
{
|
||||
|
||||
/**
|
||||
* Main overview display
|
||||
*
|
||||
* <p>
|
||||
* This method is mapped to the overview page's URL. It will fetch the empire overview from the
|
||||
* server and display the appropriate page.
|
||||
*
|
||||
* @param request
|
||||
* the HTTP request
|
||||
* @param language
|
||||
* the language from the session
|
||||
* @param model
|
||||
* the model
|
||||
*
|
||||
* @return the overview page rendering order
|
||||
*
|
||||
* @throws SessionException
|
||||
* if some error occurs on the server
|
||||
* @throws SessionServerException
|
||||
* if the server is unreachable
|
||||
* @throws SessionMaintenanceException
|
||||
* if the game is under maintenance
|
||||
*/
|
||||
@RequestMapping( "/overview" )
|
||||
public String overview( HttpServletRequest request , @ModelAttribute( "language" ) String language , Model model )
|
||||
throws SessionException , SessionServerException , SessionMaintenanceException
|
||||
|
@ -36,6 +72,30 @@ public class OverviewPage
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* "Implement technology" command
|
||||
*
|
||||
* <p>
|
||||
* This method is mapped to the technology implementation command URL.
|
||||
*
|
||||
* @param request
|
||||
* the HTTP request
|
||||
* @param language
|
||||
* the language from the session
|
||||
* @param model
|
||||
* the model
|
||||
* @param tech
|
||||
* the technology identifier
|
||||
*
|
||||
* @return the overview page rendering order
|
||||
*
|
||||
* @throws SessionException
|
||||
* if some error occurs on the server
|
||||
* @throws SessionServerException
|
||||
* if the server is unreachable
|
||||
* @throws SessionMaintenanceException
|
||||
* if the game is under maintenance
|
||||
*/
|
||||
@RequestMapping( value = "/implement-{tech}.action" , method = RequestMethod.POST )
|
||||
public String implement( HttpServletRequest request , @ModelAttribute( "language" ) String language , Model model ,
|
||||
@PathVariable String tech )
|
||||
|
@ -52,4 +112,67 @@ public class OverviewPage
|
|||
return this.render( model , "game" , language , "overview" , pSession.implementTechnology( techId ) );
|
||||
}
|
||||
|
||||
|
||||
@RequestMapping( value = "/update-mining-settings.action" , method = RequestMethod.POST )
|
||||
public String updateMiningSettings( HttpServletRequest request , @ModelAttribute( "language" ) String language ,
|
||||
Model model )
|
||||
throws SessionException , SessionServerException , SessionMaintenanceException
|
||||
{
|
||||
Map< String , Integer > miningSettings = this.getMiningSettings( request );
|
||||
if ( miningSettings != null ) {
|
||||
this.getSession( PlayerSession.class , request ).updateEmpireMiningSettings( miningSettings );
|
||||
}
|
||||
return this.redirect( "overview#economy" );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Extract mining priorities from the HTTP request
|
||||
*
|
||||
* <p>
|
||||
* Look for all submitted fields that begin with "ems-" then try to extract their values into a
|
||||
* map that associates resource identifiers to priorities.
|
||||
*
|
||||
* @param request
|
||||
* the HTTP request
|
||||
*
|
||||
* @return the map containing the submitted mining settings, or <code>null</code> if one of the
|
||||
* values was incorrect.
|
||||
*/
|
||||
private Map< String , Integer > getMiningSettings( HttpServletRequest request )
|
||||
{
|
||||
Map< String , Object > input = this.getInput( request );
|
||||
Map< String , Integer > miningSettings = new HashMap< String , Integer >( );
|
||||
for ( Entry< String , Object > entry : input.entrySet( ) ) {
|
||||
// Ignore items which are not mining settings
|
||||
String name = entry.getKey( );
|
||||
if ( !name.startsWith( "ems-" ) ) {
|
||||
continue;
|
||||
}
|
||||
name = name.substring( 4 );
|
||||
|
||||
// Get values
|
||||
if ( ! ( entry.getValue( ) instanceof String[] ) ) {
|
||||
continue;
|
||||
}
|
||||
String[] values = (String[]) entry.getValue( );
|
||||
if ( values.length < 1 ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Pre-validate them
|
||||
int value;
|
||||
try {
|
||||
value = Integer.parseInt( values[ 0 ] );
|
||||
} catch ( NumberFormatException e ) {
|
||||
value = -1;
|
||||
}
|
||||
if ( value < 0 || value > 4 ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
miningSettings.put( name , value );
|
||||
}
|
||||
return miningSettings;
|
||||
}
|
||||
}
|
||||
|
|
61
legacyworlds/dev-tools/run-database-tests.sh
Executable file
61
legacyworlds/dev-tools/run-database-tests.sh
Executable file
|
@ -0,0 +1,61 @@
|
|||
#!/bin/sh
|
||||
|
||||
[ -z "$3" ] && {
|
||||
echo "Syntax: $0 test-database admin-user test-user [misc]" >&2
|
||||
echo
|
||||
echo "Where misc is:"
|
||||
echo " --no-create don't create the DB"
|
||||
echo " --run-name name run tests matching '*name*'"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
test_db="$1"
|
||||
admin_user="$2"
|
||||
test_user="$3"
|
||||
|
||||
create_db=1
|
||||
run_name=""
|
||||
while ! [ -z "$4" ]; do
|
||||
if [ "x$4" = "x--no-create" ]; then
|
||||
create_db=0
|
||||
elif [ "x$4" = "x--run-name" ]; then
|
||||
shift
|
||||
run_name="$4"
|
||||
fi
|
||||
|
||||
shift
|
||||
done
|
||||
|
||||
scriptdir="`dirname $0`"
|
||||
tempdir="`mktemp -d`"
|
||||
cp -Rap $scriptdir/../../legacyworlds-server-data/db-structure/* $tempdir/
|
||||
cat > $tempdir/db-config.txt <<EOF
|
||||
admin=$admin_user
|
||||
db=$test_db
|
||||
user=$test_user
|
||||
password=$test_user
|
||||
EOF
|
||||
|
||||
(
|
||||
cd $tempdir
|
||||
|
||||
if [ $create_db -eq 1 ]; then
|
||||
echo "Creating DB..."
|
||||
psql -vQUIET=1 -vON_ERROR_STOP=1 --file database.sql || exit 1
|
||||
psql -vQUIET=1 -f tests/pgtap.sql $test_db || exit 1
|
||||
fi
|
||||
|
||||
cd tests
|
||||
if [ "x$run_name" = "x" ]; then
|
||||
run_name='*.sql'
|
||||
else
|
||||
run_name='*'"$run_name"'*'
|
||||
fi
|
||||
pg_prove -d $test_db `find admin/ -type f -name "$run_name" | sort` || exit 1
|
||||
pg_prove -U $test_user -d $test_db `find user/ -type f -name "$run_name" | sort` || exit 1
|
||||
)
|
||||
result=$?
|
||||
|
||||
rm -rf $tempdir
|
||||
exit $result
|
Reference in a new issue