Importing SVN archives - Trunk

This commit is contained in:
Emmanuel BENOîT 2018-10-23 09:43:42 +02:00
parent fc4c6bd340
commit ff53af6668
507 changed files with 8866 additions and 2450 deletions
legacyworlds-server/legacyworlds-server-beans/legacyworlds-server-beans-updates

View file

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java"/>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources"/>
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
<classpathentry excluding="**" kind="src" output="target/test-classes" path="src/test/resources"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>legacyworlds-server-beans-updates</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.maven.ide.eclipse.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.maven.ide.eclipse.maven2Nature</nature>
</natures>
</projectDescription>

View file

@ -0,0 +1,6 @@
#Tue Mar 29 13:49:47 CEST 2011
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.source=1.6

View file

@ -0,0 +1,9 @@
#Tue Mar 29 13:49:47 CEST 2011
activeProfiles=
eclipse.preferences.version=1
fullBuildGoals=process-test-resources
includeModules=false
resolveWorkspaceProjects=true
resourceFilterGoals=process-resources resources\:testResources
skipCompilerPlugin=true
version=1

View file

@ -0,0 +1,13 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>legacyworlds-server-beans</artifactId>
<groupId>com.deepclone.lw</groupId>
<version>5.99.2</version>
</parent>
<groupId>com.deepclone.lw</groupId>
<artifactId>legacyworlds-server-beans-updates</artifactId>
<version>5.99.2</version>
<name>Legacy Worlds updates and pre-computation management</name>
<description>This Maven module contains the components which implement both the game's "standard", per-minute update system as well as the pre-computation manager.</description>
</project>

View file

@ -0,0 +1,367 @@
package com.deepclone.lw.beans.updates;
import java.util.ArrayList;
import java.util.EnumMap;
import java.util.List;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.cmd.admin.logs.LogLevel;
import com.deepclone.lw.interfaces.eventlog.Logger;
import com.deepclone.lw.interfaces.eventlog.SystemLogger;
import com.deepclone.lw.interfaces.game.updates.DuplicateUpdateHandler;
import com.deepclone.lw.interfaces.game.updates.GameUpdate;
import com.deepclone.lw.interfaces.game.updates.GameUpdatePhase;
import com.deepclone.lw.interfaces.game.updates.GameUpdatePhaseHandler;
import com.deepclone.lw.interfaces.game.updates.UpdatesDAO;
import com.deepclone.lw.interfaces.sys.ConstantDefinition;
import com.deepclone.lw.interfaces.sys.ConstantsManager;
import com.deepclone.lw.interfaces.sys.MaintenanceStatusException;
import com.deepclone.lw.interfaces.sys.SystemStatus;
import com.deepclone.lw.interfaces.sys.TickStatusException;
import com.deepclone.lw.interfaces.sys.Ticker;
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
/**
* Implementation of the game update management component.
*
* @author tseeker
*/
public class GameUpdateBean
implements GameUpdate , InitializingBean , Runnable , ApplicationContextAware
{
/** The event scheduling component */
private Ticker ticker;
/** The system status access and update component */
private SystemStatus systemStatus;
/** The game update component's logger */
private SystemLogger logger;
/** Transaction template */
private TransactionTemplate tTemplate;
/** Game updates data access component */
private UpdatesDAO updatesDao;
/** Amount of registered, non-default handlers */
private int nRegisteredHandlers = 0;
/** Amount of handler components */
private int nHandlerComponents = -1;
/** Registered game update phase handlers */
private final EnumMap< GameUpdatePhase , GameUpdatePhaseHandler > handlers;
public GameUpdateBean( )
{
this.handlers = new EnumMap< GameUpdatePhase , GameUpdatePhaseHandler >( GameUpdatePhase.class );
}
/**
* Dependency injector for the event scheduling component
*
* @param ticker
* the event scheduling component
*/
@Autowired( required = true )
public void setTicker( Ticker ticker )
{
this.ticker = ticker;
}
/**
* Dependency injector for the system status access component
*
* @param systemStatus
* the system status access component
*/
@Autowired( required = true )
public void setSystemStatus( SystemStatus systemStatus )
{
this.systemStatus = systemStatus;
}
/**
* Dependency injector that initialises the game update component's logger.
*
* @param logger
* the system logging component
*/
@Autowired( required = true )
public void setLogger( Logger logger )
{
this.logger = logger.getSystemLogger( "GameUpdate" );
}
/**
* Dependency injector that initialises the transaction template.
*
* @param transactionManager
* the application's transaction manager
*/
@Autowired( required = true )
public void setTransactionManager( PlatformTransactionManager transactionManager )
{
this.tTemplate = new TransactionTemplate( transactionManager );
}
/**
* Dependency injector for the game updates data access component
*
* @param updatesDao
* the game updates data access component
*/
@Autowired( required = true )
public void setUpdatesDAO( UpdatesDAO updatesDao )
{
this.updatesDao = updatesDao;
}
/**
* Dependency injector which registers the game.updatesPerDay constant.
*
* @param constantsManager
* the constants manager
*/
@Autowired( required = true )
public void setConstantsManager( ConstantsManager constantsManager )
{
List< ConstantDefinition > definitions;
ConstantDefinition constant;
definitions = new ArrayList< ConstantDefinition >( 1 );
constant = new ConstantDefinition(
"game.updatesPerDay" ,
"Game (misc)" ,
"Game updates per day from the computations's point of view. "
+ "This does not affect the actual amount of updates, but changes the computations. "
+ "Can be used to speed things up or slow them down without actually changing ticker.interval." ,
1440.0 , 0.05 , 5760.0 );
definitions.add( 0 , constant );
constantsManager.registerConstants( definitions );
}
/**
* Read the amount of update phase handlers from the application context.
*
* @param context
* the application context
*/
@Override
public void setApplicationContext( ApplicationContext context )
throws BeansException
{
this.nHandlerComponents = context.getBeansOfType( GameUpdatePhaseHandler.class ).size( );
if ( this.nRegisteredHandlers == this.nHandlerComponents ) {
this.initialise( );
}
}
/* Documentation in GameUpdate interface */
@Override
public void registerHandler( GameUpdatePhaseHandler handler )
throws DuplicateUpdateHandler
{
GameUpdatePhase phase = handler.getPhase( );
synchronized ( this.handlers ) {
if ( this.handlers.containsKey( phase ) ) {
throw new DuplicateUpdateHandler( phase );
}
this.handlers.put( phase , handler );
}
this.logger.log( LogLevel.DEBUG , "Registered game update handler for phase " + phase.toString( ) ).flush( );
this.nRegisteredHandlers++;
if ( this.nRegisteredHandlers == this.nHandlerComponents ) {
this.initialise( );
}
}
/**
* Initialise the component if it is ready.
*/
@Override
public void afterPropertiesSet( )
{
if ( this.nRegisteredHandlers == this.nHandlerComponents ) {
this.initialise( );
}
}
/**
* Finish any pending computations (unless maintenance mode is active), then register the game
* update task into the {@link #ticker}.
*/
private void initialise( )
{
// Finish previous tick if possible
try {
this.endPreviousTick( );
} catch ( MaintenanceStatusException e ) {
// EMPTY
}
// Register ticker task
this.ticker.registerTask( Frequency.MINUTE , "Game update" , this );
// Make sure initialisation only occurs once
this.nHandlerComponents = -1;
}
/**
* When the game update event is triggered by the system's scheduling component, attempt to run
* a game update.
*
* First, check if there is already a game update in progress, and attempt to finish running it
* if necessary. Otherwise start a new update though the system status manager, and execute it.
*/
@Override
public void run( )
{
// Attempt to end the previous tick, if e.g. maintenance mode was initiated while it was
// being processed
try {
if ( this.endPreviousTick( ) ) {
return;
}
} catch ( MaintenanceStatusException e ) {
return;
}
// Initiate next tick
long tickId;
try {
tickId = this.systemStatus.startTick( );
} catch ( TickStatusException e ) {
throw new RuntimeException( "tick initiated while previous tick still being processed" , e );
} catch ( MaintenanceStatusException e ) {
return;
}
// Execute tick
this.logger.log( LogLevel.DEBUG , "Tick " + tickId + " started" ).flush( );
this.executeUpdate( tickId );
}
/**
* Check if a game update was in progress and finish running it if necessary.
*
* @return <code>true</code> if a game update was already being executed, <code>false</code>
* otherwise.
*
* @throws MaintenanceStatusException
* if the game is under maintenance.
*/
private boolean endPreviousTick( )
throws MaintenanceStatusException
{
Long currentTick = this.systemStatus.checkStuckTick( );
if ( currentTick == null ) {
return false;
}
this.logger.log( LogLevel.WARNING , "Tick " + currentTick + " restarted" ).flush( );
this.executeUpdate( currentTick.longValue( ) );
return true;
}
/**
* Execute all phase handlers for a game update, then mark the update as completed.
*
* @param updateId
* the identifier of the current update
*/
private void executeUpdate( long updateId )
{
for ( GameUpdatePhase phase : GameUpdatePhase.values( ) ) {
this.executeUpdatePhase( updateId , phase );
}
try {
this.systemStatus.endTick( );
} catch ( TickStatusException e ) {
throw new RuntimeException( "Game update completed but status error reported" , e );
} catch ( MaintenanceStatusException e ) {
return;
}
this.logger.log( LogLevel.TRACE , "Tick " + updateId + " completed" ).flush( );
}
/**
* Execute a phase of the game update.
*
* @param updateId
* the identifier of the current update
* @param phase
* the phase of the update to execute
*/
private void executeUpdatePhase( final long updateId , GameUpdatePhase phase )
{
final GameUpdatePhaseHandler handler = this.getHandlerForPhase( phase );
handler.onPhaseStart( updateId );
boolean hasMore;
do {
hasMore = this.tTemplate.execute( new TransactionCallback< Boolean >( ) {
@Override
public Boolean doInTransaction( TransactionStatus status )
{
return handler.updateGame( updateId );
}
} );
} while ( hasMore );
}
/**
* Access the handler for an update phase. If no handler has been registered, create a default
* {@link ProceduralGameUpdate} handler.
*
* @param phase
* the update phase whose handler is to be retrieved
* @return the game update handler
*/
private GameUpdatePhaseHandler getHandlerForPhase( GameUpdatePhase phase )
{
GameUpdatePhaseHandler handler;
synchronized ( this.handlers ) {
handler = this.handlers.get( phase );
if ( handler == null ) {
this.logger.log( LogLevel.DEBUG , "Creating default handler for phase " + phase.toString( ) ).flush( );
handler = new ProceduralGameUpdate( this.updatesDao , phase );
this.handlers.put( phase , handler );
}
}
return handler;
}
}

View file

@ -0,0 +1,52 @@
package com.deepclone.lw.beans.updates;
import com.deepclone.lw.interfaces.game.updates.GameUpdatePhase;
import com.deepclone.lw.interfaces.game.updates.GameUpdatePhaseHandler;
import com.deepclone.lw.interfaces.game.updates.UpdatesDAO;
class ProceduralGameUpdate
implements GameUpdatePhaseHandler
{
private final GameUpdatePhase phase;
private final UpdatesDAO updatesDao;
ProceduralGameUpdate( UpdatesDAO updatesDao , GameUpdatePhase phase )
{
this.updatesDao = updatesDao;
this.phase = phase;
}
@Override
public GameUpdatePhase getPhase( )
{
return this.phase;
}
@Override
public boolean updateGame( long updateId )
{
if ( !this.updatesDao.prepareUpdates( updateId , this.phase ) ) {
return false;
}
this.updatesDao.executeProceduralUpdate( updateId , this.phase );
this.updatesDao.validateUpdatedRecords( updateId , this.phase );
return true;
}
@Override
public void onPhaseStart( long updateId )
{
// EMPTY
}
}

View file

@ -0,0 +1,85 @@
package com.deepclone.lw.beans.updates;
import java.sql.Types;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import com.deepclone.lw.interfaces.game.updates.GameUpdatePhase;
import com.deepclone.lw.interfaces.game.updates.UpdatesDAO;
import com.deepclone.lw.utils.StoredProc;
/**
* Implementation of the game update data access component.
*
* @author tseeker
*/
public class UpdatesDAOBean
implements UpdatesDAO
{
/** Wrapper for the stored procedure that prepares updates */
private StoredProc fPrepareUpdates;
/** Wrapper for the stored procedure that executes a procedural game update */
private StoredProc fExecuteProcedural;
/** Wrapper for the stored procedure that marks update records as processed */
private StoredProc fUpdatesProcessed;
/**
* Dependency injector that initialises stored procedure call handlers.
*
* @param dataSource
* the data source
*/
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
// Stored procedure that prepares updates
this.fPrepareUpdates = new StoredProc( dataSource , "sys" , "prepare_updates" );
this.fPrepareUpdates.addParameter( "u_id" , Types.BIGINT );
this.fPrepareUpdates.addParameter( "u_type" , "update_type" );
this.fPrepareUpdates.addOutput( "has_more" , Types.BOOLEAN );
// Stored procedure that executes a procedural game update
this.fExecuteProcedural = new StoredProc( dataSource , "sys" , "exec_update_proc" );
this.fExecuteProcedural.addParameter( "u_id" , Types.BIGINT );
this.fExecuteProcedural.addParameter( "u_type" , "update_type" );
// Stored procedure that marks update records as processed
this.fUpdatesProcessed = new StoredProc( dataSource , "sys" , "updates_processed" );
this.fUpdatesProcessed.addParameter( "u_id" , Types.BIGINT );
this.fUpdatesProcessed.addParameter( "u_type" , "update_type" );
}
/* Documentation in UpdatesDAO interface */
@Override
public boolean prepareUpdates( long updateId , GameUpdatePhase phase )
{
return (Boolean) this.fPrepareUpdates.execute( updateId , phase.toString( ) ).get( "has_more" );
}
/* Documentation in UpdatesDAO interface */
@Override
public void executeProceduralUpdate( long updateId , GameUpdatePhase phase )
{
this.fExecuteProcedural.execute( updateId , phase.toString( ) );
}
/* Documentation in UpdatesDAO interface */
@Override
public void validateUpdatedRecords( long updateId , GameUpdatePhase phase )
{
this.fUpdatesProcessed.execute( updateId , phase );
}
}

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<import resource="updates/game-update-bean.xml" />
<import resource="updates/updates-dao-bean.xml" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- Game update bean -->
<bean id="gameUpdate" class="com.deepclone.lw.beans.updates.GameUpdateBean" />
</beans>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="updatesDAO" class="com.deepclone.lw.beans.updates.UpdatesDAOBean" />
</beans>