Importing SVN archives - Trunk
This commit is contained in:
parent
fc4c6bd340
commit
ff53af6668
507 changed files with 8866 additions and 2450 deletions
|
@ -4,12 +4,12 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server-beans</artifactId>
|
<artifactId>legacyworlds-server-beans</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-beans-accounts</artifactId>
|
<artifactId>legacyworlds-server-beans-accounts</artifactId>
|
||||||
<name>Legacy Worlds account management</name>
|
<name>Legacy Worlds account management</name>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<description>This package contains the beans responsible for managing accounts, including registration, inactivity checks, bans and authentication.</description>
|
<description>This package contains the beans responsible for managing accounts, including registration, inactivity checks, bans and authentication.</description>
|
||||||
</project>
|
</project>
|
|
@ -4,7 +4,7 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server-beans</artifactId>
|
<artifactId>legacyworlds-server-beans</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -20,6 +20,6 @@
|
||||||
|
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-beans-bt</artifactId>
|
<artifactId>legacyworlds-server-beans-bt</artifactId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<name>Legacy Worlds bug tracking system</name>
|
<name>Legacy Worlds bug tracking system</name>
|
||||||
</project>
|
</project>
|
|
@ -28,6 +28,7 @@ public class EmpireSummaryBean
|
||||||
|
|
||||||
private final RowMapper< DebugInformation > mMainInfo;
|
private final RowMapper< DebugInformation > mMainInfo;
|
||||||
private final RowMapper< ResearchInformation > mResearch;
|
private final RowMapper< ResearchInformation > mResearch;
|
||||||
|
private final RowMapper< TechnologyInformation > mTechnology;
|
||||||
private final RowMapper< PlanetInformation > mPlanet;
|
private final RowMapper< PlanetInformation > mPlanet;
|
||||||
private final RowMapper< QueueItemInformation > mQueueItem;
|
private final RowMapper< QueueItemInformation > mQueueItem;
|
||||||
private final RowMapper< BuildingsInformation > mBuildings;
|
private final RowMapper< BuildingsInformation > mBuildings;
|
||||||
|
@ -42,7 +43,8 @@ public class EmpireSummaryBean
|
||||||
AccountInformation.class , AllianceInformation.class , BuildingsInformation.class ,
|
AccountInformation.class , AllianceInformation.class , BuildingsInformation.class ,
|
||||||
DebugInformation.class , EmpireInformation.class , FleetInformation.class , MovementInformation.class ,
|
DebugInformation.class , EmpireInformation.class , FleetInformation.class , MovementInformation.class ,
|
||||||
PlanetInformation.class , QueueInformation.class , QueueItemInformation.class ,
|
PlanetInformation.class , QueueInformation.class , QueueItemInformation.class ,
|
||||||
ResearchInformation.class , ShipsInformation.class , SystemInformation.class
|
ResearchInformation.class , TechnologyInformation.class , ShipsInformation.class ,
|
||||||
|
SystemInformation.class
|
||||||
} );
|
} );
|
||||||
|
|
||||||
this.mMainInfo = new RowMapper< DebugInformation >( ) {
|
this.mMainInfo = new RowMapper< DebugInformation >( ) {
|
||||||
|
@ -83,13 +85,23 @@ public class EmpireSummaryBean
|
||||||
throws SQLException
|
throws SQLException
|
||||||
{
|
{
|
||||||
ResearchInformation ri = new ResearchInformation( );
|
ResearchInformation ri = new ResearchInformation( );
|
||||||
ri.setId( rs.getInt( "line_id" ) );
|
ri.setName( rs.getString( "name" ) );
|
||||||
ri.setCurrentLevel( rs.getInt( "level" ) );
|
|
||||||
ri.setLevelName( rs.getString( "name" ) );
|
|
||||||
ri.setAccumulated( rs.getDouble( "accumulated" ) );
|
ri.setAccumulated( rs.getDouble( "accumulated" ) );
|
||||||
|
ri.setPriority( rs.getInt( "priority" ) );
|
||||||
return ri;
|
return ri;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
this.mTechnology = new RowMapper< TechnologyInformation >( ) {
|
||||||
|
@Override
|
||||||
|
public TechnologyInformation mapRow( ResultSet rs , int rowNum )
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
TechnologyInformation ti = new TechnologyInformation( );
|
||||||
|
ti.setName( rs.getString( "name" ) );
|
||||||
|
ti.setImplemented( rs.getBoolean( "implemented" ) );
|
||||||
|
return ti;
|
||||||
|
}
|
||||||
|
};
|
||||||
this.mPlanet = new RowMapper< PlanetInformation >( ) {
|
this.mPlanet = new RowMapper< PlanetInformation >( ) {
|
||||||
@Override
|
@Override
|
||||||
public PlanetInformation mapRow( ResultSet rs , int rowNum )
|
public PlanetInformation mapRow( ResultSet rs , int rowNum )
|
||||||
|
@ -199,9 +211,10 @@ public class EmpireSummaryBean
|
||||||
DebugInformation di = this.dTemplate.queryForObject( sql , this.mMainInfo , empireId );
|
DebugInformation di = this.dTemplate.queryForObject( sql , this.mMainInfo , empireId );
|
||||||
|
|
||||||
sql = "SELECT * FROM bugs.dump_research_view WHERE empire_id = ?";
|
sql = "SELECT * FROM bugs.dump_research_view WHERE empire_id = ?";
|
||||||
for ( ResearchInformation ri : this.dTemplate.query( sql , this.mResearch , empireId ) ) {
|
di.getResearch( ).addAll( this.dTemplate.query( sql , this.mResearch , empireId ) );
|
||||||
di.getResearch( ).add( ri );
|
|
||||||
}
|
sql = "SELECT * FROM bugs.dump_technologies_view WHERE empire_id = ?";
|
||||||
|
di.getTechnologies( ).addAll( this.dTemplate.query( sql , this.mTechnology , empireId ) );
|
||||||
|
|
||||||
sql = "SELECT * FROM bugs.dump_planets_view WHERE empire_id = ?";
|
sql = "SELECT * FROM bugs.dump_planets_view WHERE empire_id = ?";
|
||||||
Map< Integer , PlanetInformation > planets = new HashMap< Integer , PlanetInformation >( );
|
Map< Integer , PlanetInformation > planets = new HashMap< Integer , PlanetInformation >( );
|
||||||
|
|
|
@ -15,26 +15,29 @@ public class DebugInformation
|
||||||
implements Serializable
|
implements Serializable
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 2L;
|
||||||
|
|
||||||
@XStreamAsAttribute
|
@XStreamAsAttribute
|
||||||
@XStreamAlias( "dump-version" )
|
@XStreamAlias( "dump-version" )
|
||||||
private int version = 1;
|
private final int version = 2;
|
||||||
|
|
||||||
private SystemInformation system = new SystemInformation( );
|
private final SystemInformation system = new SystemInformation( );
|
||||||
|
|
||||||
private AccountInformation account = new AccountInformation( );
|
private final AccountInformation account = new AccountInformation( );
|
||||||
|
|
||||||
private EmpireInformation empire = new EmpireInformation( );
|
private final EmpireInformation empire = new EmpireInformation( );
|
||||||
|
|
||||||
@XStreamAlias( "research" )
|
@XStreamAlias( "research" )
|
||||||
private List< ResearchInformation > research = new LinkedList< ResearchInformation >( );
|
private final List< ResearchInformation > research = new LinkedList< ResearchInformation >( );
|
||||||
|
|
||||||
|
@XStreamAlias( "technologies" )
|
||||||
|
private final List< TechnologyInformation > technologies = new LinkedList< TechnologyInformation >( );
|
||||||
|
|
||||||
@XStreamAlias( "planets" )
|
@XStreamAlias( "planets" )
|
||||||
private List< PlanetInformation > planets = new LinkedList< PlanetInformation >( );
|
private final List< PlanetInformation > planets = new LinkedList< PlanetInformation >( );
|
||||||
|
|
||||||
@XStreamAlias( "fleets" )
|
@XStreamAlias( "fleets" )
|
||||||
private List< FleetInformation > fleets = new LinkedList< FleetInformation >( );
|
private final List< FleetInformation > fleets = new LinkedList< FleetInformation >( );
|
||||||
|
|
||||||
|
|
||||||
public int getVersion( )
|
public int getVersion( )
|
||||||
|
@ -67,6 +70,12 @@ public class DebugInformation
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public List< TechnologyInformation > getTechnologies( )
|
||||||
|
{
|
||||||
|
return technologies;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public List< PlanetInformation > getPlanets( )
|
public List< PlanetInformation > getPlanets( )
|
||||||
{
|
{
|
||||||
return planets;
|
return planets;
|
||||||
|
|
|
@ -8,64 +8,34 @@ import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@XStreamAlias( "research-line" )
|
@XStreamAlias( "research-topic" )
|
||||||
public class ResearchInformation
|
public class ResearchInformation
|
||||||
implements Serializable
|
implements Serializable
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 2L;
|
||||||
|
|
||||||
@XStreamAsAttribute
|
@XStreamAsAttribute
|
||||||
@XStreamAlias( "line")
|
private String name;
|
||||||
private int id;
|
|
||||||
|
|
||||||
@XStreamAsAttribute
|
@XStreamAsAttribute
|
||||||
@XStreamAlias( "level")
|
@XStreamAlias( "accumulated-points" )
|
||||||
private int currentLevel;
|
|
||||||
|
|
||||||
@XStreamAsAttribute
|
|
||||||
@XStreamAlias( "name")
|
|
||||||
private String levelName;
|
|
||||||
|
|
||||||
@XStreamAsAttribute
|
|
||||||
@XStreamAlias( "accumulated-points")
|
|
||||||
private double accumulated;
|
private double accumulated;
|
||||||
|
|
||||||
|
@XStreamAsAttribute
|
||||||
|
private int priority;
|
||||||
|
|
||||||
public int getId( )
|
|
||||||
|
public String getName( )
|
||||||
{
|
{
|
||||||
return id;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void setId( int id )
|
public void setName( String name )
|
||||||
{
|
{
|
||||||
this.id = id;
|
this.name = name;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public int getCurrentLevel( )
|
|
||||||
{
|
|
||||||
return currentLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setCurrentLevel( int currentLevel )
|
|
||||||
{
|
|
||||||
this.currentLevel = currentLevel;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getLevelName( )
|
|
||||||
{
|
|
||||||
return levelName;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setLevelName( String levelName )
|
|
||||||
{
|
|
||||||
this.levelName = levelName;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,4 +50,16 @@ public class ResearchInformation
|
||||||
this.accumulated = accumulated;
|
this.accumulated = accumulated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getPriority( )
|
||||||
|
{
|
||||||
|
return priority;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setPriority( int priority )
|
||||||
|
{
|
||||||
|
this.priority = priority;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
package com.deepclone.lw.beans.bt.esdata;
|
||||||
|
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||||
|
import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@XStreamAlias( "technology" )
|
||||||
|
public class TechnologyInformation
|
||||||
|
implements Serializable
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@XStreamAsAttribute
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@XStreamAsAttribute
|
||||||
|
private boolean implemented;
|
||||||
|
|
||||||
|
|
||||||
|
public String getName( )
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setName( String name )
|
||||||
|
{
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isImplemented( )
|
||||||
|
{
|
||||||
|
return implemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void setImplemented( boolean implemented )
|
||||||
|
{
|
||||||
|
this.implemented = implemented;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,12 +4,12 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server-beans</artifactId>
|
<artifactId>legacyworlds-server-beans</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-beans-eventlog</artifactId>
|
<artifactId>legacyworlds-server-beans-eventlog</artifactId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<name>Legacy Worlds event log</name>
|
<name>Legacy Worlds event log</name>
|
||||||
<description>This package is responsible for all logging in Legacy Worlds through three different beans (system event logger, admin event logger and user event logger).</description>
|
<description>This package is responsible for all logging in Legacy Worlds through three different beans (system event logger, admin event logger and user event logger).</description>
|
||||||
</project>
|
</project>
|
|
@ -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>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>legacyworlds-server-beans-events</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>
|
|
@ -0,0 +1,6 @@
|
||||||
|
#Sun Apr 03 09:36:59 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
|
|
@ -0,0 +1,9 @@
|
||||||
|
#Sun Apr 03 09:36:59 CEST 2011
|
||||||
|
activeProfiles=
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
fullBuildGoals=process-test-resources
|
||||||
|
includeModules=false
|
||||||
|
resolveWorkspaceProjects=true
|
||||||
|
resourceFilterGoals=process-resources resources\:testResources
|
||||||
|
skipCompilerPlugin=true
|
||||||
|
version=1
|
|
@ -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-events</artifactId>
|
||||||
|
<version>5.99.2</version>
|
||||||
|
<name>Game events</name>
|
||||||
|
<description>This module contains components which manage game events.</description>
|
||||||
|
</project>
|
|
@ -4,13 +4,13 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server-beans</artifactId>
|
<artifactId>legacyworlds-server-beans</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-beans-i18n</artifactId>
|
<artifactId>legacyworlds-server-beans-i18n</artifactId>
|
||||||
<name>Legacy Worlds internationalisation</name>
|
<name>Legacy Worlds internationalisation</name>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<description>This package defines the two beans which control server-side internationalised text management.</description>
|
<description>This package defines the two beans which control server-side internationalised text management.</description>
|
||||||
|
|
||||||
</project>
|
</project>
|
|
@ -6,6 +6,7 @@ import java.util.Set;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import com.deepclone.lw.interfaces.i18n.LanguageTranslator;
|
||||||
import com.deepclone.lw.interfaces.i18n.Translator;
|
import com.deepclone.lw.interfaces.i18n.Translator;
|
||||||
import com.deepclone.lw.interfaces.i18n.UnknownLanguageException;
|
import com.deepclone.lw.interfaces.i18n.UnknownLanguageException;
|
||||||
import com.deepclone.lw.interfaces.i18n.UnknownStringException;
|
import com.deepclone.lw.interfaces.i18n.UnknownStringException;
|
||||||
|
@ -21,6 +22,67 @@ import com.deepclone.lw.interfaces.i18n.UnknownStringException;
|
||||||
public class TranslatorBean
|
public class TranslatorBean
|
||||||
implements Translator
|
implements Translator
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of a language-specific translator.
|
||||||
|
*/
|
||||||
|
private static class LanguageTranslatorImpl
|
||||||
|
implements LanguageTranslator
|
||||||
|
{
|
||||||
|
/** Language used by the translator */
|
||||||
|
private final String language;
|
||||||
|
|
||||||
|
/** Translations store */
|
||||||
|
private final I18NData data;
|
||||||
|
|
||||||
|
|
||||||
|
LanguageTranslatorImpl( String language , TranslatorBean translator )
|
||||||
|
{
|
||||||
|
this.language = language;
|
||||||
|
this.data = translator.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in LanguageTranslator interface */
|
||||||
|
@Override
|
||||||
|
public String getLanguage( )
|
||||||
|
{
|
||||||
|
return this.language;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in LanguageTranslator interface */
|
||||||
|
@Override
|
||||||
|
public String getLanguageName( )
|
||||||
|
{
|
||||||
|
this.data.readLock( ).lock( );
|
||||||
|
try {
|
||||||
|
return this.data.getLanguageName( language );
|
||||||
|
} finally {
|
||||||
|
this.data.readLock( ).unlock( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in LanguageTranslator interface */
|
||||||
|
@Override
|
||||||
|
public String translate( String string )
|
||||||
|
throws UnknownStringException
|
||||||
|
{
|
||||||
|
this.data.readLock( ).lock( );
|
||||||
|
try {
|
||||||
|
if ( !this.data.hasString( string ) ) {
|
||||||
|
throw new UnknownStringException( string );
|
||||||
|
}
|
||||||
|
return this.data.getTranslation( language , string );
|
||||||
|
} finally {
|
||||||
|
this.data.readLock( ).unlock( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Translations store */
|
||||||
private I18NData data;
|
private I18NData data;
|
||||||
|
|
||||||
|
|
||||||
|
@ -119,4 +181,21 @@ public class TranslatorBean
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in Translator interface */
|
||||||
|
@Override
|
||||||
|
public LanguageTranslator getLanguageTranslator( String language )
|
||||||
|
throws UnknownLanguageException
|
||||||
|
{
|
||||||
|
this.data.readLock( ).lock( );
|
||||||
|
try {
|
||||||
|
if ( !this.data.isLanguageComplete( language ) ) {
|
||||||
|
throw new UnknownLanguageException( language );
|
||||||
|
}
|
||||||
|
return new LanguageTranslatorImpl( language , this );
|
||||||
|
} finally {
|
||||||
|
this.data.readLock( ).unlock( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server-beans</artifactId>
|
<artifactId>legacyworlds-server-beans</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-beans-mailer</artifactId>
|
<artifactId>legacyworlds-server-beans-mailer</artifactId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<name>Legacy Worlds mailer</name>
|
<name>Legacy Worlds mailer</name>
|
||||||
<description>
|
<description>
|
||||||
This package contains the mailer component, which uses LW's i18n system and Spring's mail sending interfaces.
|
This package contains the mailer component, which uses LW's i18n system and Spring's mail sending interfaces.
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server-beans</artifactId>
|
<artifactId>legacyworlds-server-beans</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-beans-naming</artifactId>
|
<artifactId>legacyworlds-server-beans-naming</artifactId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<name>Legacy Worlds object naming system</name>
|
<name>Legacy Worlds object naming system</name>
|
||||||
<description>This module contains the beans responsible for managing the names of the various objects (players and planets).</description>
|
<description>This module contains the beans responsible for managing the names of the various objects (players and planets).</description>
|
||||||
</project>
|
</project>
|
|
@ -3,11 +3,11 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server-beans</artifactId>
|
<artifactId>legacyworlds-server-beans</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-beans-simple</artifactId>
|
<artifactId>legacyworlds-server-beans-simple</artifactId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<name>Legacy Worlds simple game</name>
|
<name>Legacy Worlds simple game</name>
|
||||||
<description>This module contains code that corresponds to a simple "placeholder" game. This code should become obsolete over time, as it is being replaced with actual LWB6 code, until the module can finally be removed.</description>
|
<description>This module contains code that corresponds to a simple "placeholder" game. This code should become obsolete over time, as it is being replaced with actual LWB6 code, until the module can finally be removed.</description>
|
||||||
</project>
|
</project>
|
|
@ -4,9 +4,7 @@ package com.deepclone.lw.beans.empire;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.sql.Types;
|
import java.sql.Types;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
@ -20,8 +18,6 @@ import com.deepclone.lw.cmd.player.gdata.NameIdPair;
|
||||||
import com.deepclone.lw.cmd.player.gdata.PlanetListData;
|
import com.deepclone.lw.cmd.player.gdata.PlanetListData;
|
||||||
import com.deepclone.lw.cmd.player.gdata.empire.OverviewData;
|
import com.deepclone.lw.cmd.player.gdata.empire.OverviewData;
|
||||||
import com.deepclone.lw.interfaces.game.EmpireDAO;
|
import com.deepclone.lw.interfaces.game.EmpireDAO;
|
||||||
import com.deepclone.lw.sqld.game.EmpireTechLine;
|
|
||||||
import com.deepclone.lw.sqld.game.EmpireTechnology;
|
|
||||||
import com.deepclone.lw.sqld.game.GeneralInformation;
|
import com.deepclone.lw.sqld.game.GeneralInformation;
|
||||||
import com.deepclone.lw.utils.StoredProc;
|
import com.deepclone.lw.utils.StoredProc;
|
||||||
|
|
||||||
|
@ -31,7 +27,6 @@ public class EmpireDAOBean
|
||||||
implements EmpireDAO
|
implements EmpireDAO
|
||||||
{
|
{
|
||||||
private SimpleJdbcTemplate dTemplate;
|
private SimpleJdbcTemplate dTemplate;
|
||||||
private StoredProc fImplementTech;
|
|
||||||
private StoredProc fAddEmpEnemy;
|
private StoredProc fAddEmpEnemy;
|
||||||
private StoredProc fAddAllEnemy;
|
private StoredProc fAddAllEnemy;
|
||||||
private StoredProc fRemoveEmpEnemy;
|
private StoredProc fRemoveEmpEnemy;
|
||||||
|
@ -40,16 +35,36 @@ public class EmpireDAOBean
|
||||||
|
|
||||||
private final PlanetListMapper mPlanetList = new PlanetListMapper( );
|
private final PlanetListMapper mPlanetList = new PlanetListMapper( );
|
||||||
|
|
||||||
|
private final RowMapper< GeneralInformation > mEmpireInfo;
|
||||||
|
|
||||||
|
|
||||||
|
public EmpireDAOBean( )
|
||||||
|
{
|
||||||
|
this.mEmpireInfo = new RowMapper< GeneralInformation >( ) {
|
||||||
|
@Override
|
||||||
|
public GeneralInformation mapRow( ResultSet rs , int rowNum )
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
String st = rs.getString( "status" );
|
||||||
|
Character status = ( st == null ) ? null : st.charAt( 0 );
|
||||||
|
String name = rs.getString( "name" );
|
||||||
|
String tag = rs.getString( "alliance" );
|
||||||
|
String language = rs.getString( "language" );
|
||||||
|
long cash = rs.getLong( "cash" );
|
||||||
|
long nextTick = rs.getLong( "game_time" );
|
||||||
|
int accountId = rs.getInt( "account_id" );
|
||||||
|
return new GeneralInformation( status , name , tag , language , cash , nextTick , accountId );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Autowired( required = true )
|
@Autowired( required = true )
|
||||||
public void setDataSource( DataSource dataSource )
|
public void setDataSource( DataSource dataSource )
|
||||||
{
|
{
|
||||||
this.dTemplate = new SimpleJdbcTemplate( dataSource );
|
this.dTemplate = new SimpleJdbcTemplate( dataSource );
|
||||||
|
|
||||||
this.fImplementTech = new StoredProc( dataSource , "emp" , "implement_tech" );
|
|
||||||
this.fImplementTech.addParameter( "empire_id" , Types.INTEGER );
|
|
||||||
this.fImplementTech.addParameter( "line_id" , Types.INTEGER );
|
|
||||||
|
|
||||||
this.fAddEmpEnemy = new StoredProc( dataSource , "emp" , "add_enemy_empire" );
|
this.fAddEmpEnemy = new StoredProc( dataSource , "emp" , "add_enemy_empire" );
|
||||||
this.fAddEmpEnemy.addParameter( "empire_id" , Types.INTEGER );
|
this.fAddEmpEnemy.addParameter( "empire_id" , Types.INTEGER );
|
||||||
this.fAddEmpEnemy.addParameter( "enemy_name" , Types.VARCHAR );
|
this.fAddEmpEnemy.addParameter( "enemy_name" , Types.VARCHAR );
|
||||||
|
@ -79,19 +94,8 @@ public class EmpireDAOBean
|
||||||
public GeneralInformation getInformation( int empireId )
|
public GeneralInformation getInformation( int empireId )
|
||||||
{
|
{
|
||||||
String sql = "SELECT * FROM emp.general_information WHERE id = ?";
|
String sql = "SELECT * FROM emp.general_information WHERE id = ?";
|
||||||
RowMapper< GeneralInformation > mapper = new RowMapper< GeneralInformation >( ) {
|
|
||||||
@Override
|
|
||||||
public GeneralInformation mapRow( ResultSet rs , int rowNum )
|
|
||||||
throws SQLException
|
|
||||||
{
|
|
||||||
String st = rs.getString( "status" );
|
|
||||||
Character status = ( st == null ) ? null : st.charAt( 0 );
|
|
||||||
return new GeneralInformation( status , rs.getString( "name" ) , rs.getString( "alliance" ) , rs
|
|
||||||
.getLong( "cash" ) , rs.getLong( "game_time" ) , rs.getInt( "account_id" ) );
|
|
||||||
}
|
|
||||||
};
|
|
||||||
try {
|
try {
|
||||||
return this.dTemplate.queryForObject( sql , mapper , empireId );
|
return this.dTemplate.queryForObject( sql , this.mEmpireInfo , empireId );
|
||||||
} catch ( EmptyResultDataAccessException e ) {
|
} catch ( EmptyResultDataAccessException e ) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -156,65 +160,6 @@ public class EmpireDAOBean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public List< EmpireTechLine > getTechnology( int empireId )
|
|
||||||
{
|
|
||||||
String sql = "SELECT * FROM emp.tech_lines_view WHERE empire = ?";
|
|
||||||
RowMapper< EmpireTechLine > lineMapper = new RowMapper< EmpireTechLine >( ) {
|
|
||||||
@Override
|
|
||||||
public EmpireTechLine mapRow( ResultSet rs , int rowNum )
|
|
||||||
throws SQLException
|
|
||||||
{
|
|
||||||
EmpireTechLine etl = new EmpireTechLine( );
|
|
||||||
etl.setId( rs.getInt( "tech_line" ) );
|
|
||||||
etl.setName( rs.getString( "name" ) );
|
|
||||||
etl.setDescription( rs.getString( "description" ) );
|
|
||||||
return etl;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
List< EmpireTechLine > lines = this.dTemplate.query( sql , lineMapper , empireId );
|
|
||||||
if ( lines.isEmpty( ) ) {
|
|
||||||
return lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
Map< Integer , EmpireTechLine > linesById = new HashMap< Integer , EmpireTechLine >( );
|
|
||||||
for ( EmpireTechLine etl : lines ) {
|
|
||||||
linesById.put( etl.getId( ) , etl );
|
|
||||||
}
|
|
||||||
|
|
||||||
sql = "SELECT * FROM emp.technologies_view WHERE empire = ?";
|
|
||||||
RowMapper< EmpireTechnology > techMapper = new RowMapper< EmpireTechnology >( ) {
|
|
||||||
@Override
|
|
||||||
public EmpireTechnology mapRow( ResultSet rs , int rowNum )
|
|
||||||
throws SQLException
|
|
||||||
{
|
|
||||||
EmpireTechnology et = new EmpireTechnology( );
|
|
||||||
et.setLine( rs.getInt( "tech_line" ) );
|
|
||||||
et.setName( rs.getString( "name" ) );
|
|
||||||
et.setDescription( rs.getString( "description" ) );
|
|
||||||
et.setImplemented( rs.getBoolean( "implemented" ) );
|
|
||||||
et.setProgress( (int) rs.getDouble( "progress" ) );
|
|
||||||
et.setCost( rs.getInt( "cost" ) );
|
|
||||||
return et;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
for ( EmpireTechnology et : this.dTemplate.query( sql , techMapper , empireId ) ) {
|
|
||||||
linesById.get( et.getLine( ) ).addTechnology( et );
|
|
||||||
}
|
|
||||||
|
|
||||||
return lines;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void implementTechnology( int empireId , int lineId )
|
|
||||||
{
|
|
||||||
this.fImplementTech.execute( empireId , lineId );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List< PlanetListData > getPlanetList( int empireId )
|
public List< PlanetListData > getPlanetList( int empireId )
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,19 +18,18 @@ import com.deepclone.lw.cmd.player.gdata.NameIdPair;
|
||||||
import com.deepclone.lw.cmd.player.gdata.PlanetListData;
|
import com.deepclone.lw.cmd.player.gdata.PlanetListData;
|
||||||
import com.deepclone.lw.cmd.player.gdata.battles.BattleListEntry;
|
import com.deepclone.lw.cmd.player.gdata.battles.BattleListEntry;
|
||||||
import com.deepclone.lw.cmd.player.gdata.empire.OverviewData;
|
import com.deepclone.lw.cmd.player.gdata.empire.OverviewData;
|
||||||
import com.deepclone.lw.cmd.player.gdata.empire.ResearchLineData;
|
|
||||||
import com.deepclone.lw.cmd.player.gdata.empire.TechnologyData;
|
|
||||||
import com.deepclone.lw.interfaces.acm.UsersDAO;
|
import com.deepclone.lw.interfaces.acm.UsersDAO;
|
||||||
import com.deepclone.lw.interfaces.game.BattlesCache;
|
import com.deepclone.lw.interfaces.game.BattlesCache;
|
||||||
import com.deepclone.lw.interfaces.game.BattlesDAO;
|
import com.deepclone.lw.interfaces.game.BattlesDAO;
|
||||||
import com.deepclone.lw.interfaces.game.EmpireDAO;
|
import com.deepclone.lw.interfaces.game.EmpireDAO;
|
||||||
import com.deepclone.lw.interfaces.game.EmpireManagement;
|
import com.deepclone.lw.interfaces.game.EmpireManagement;
|
||||||
|
import com.deepclone.lw.interfaces.i18n.LanguageTranslator;
|
||||||
|
import com.deepclone.lw.interfaces.i18n.Translator;
|
||||||
|
import com.deepclone.lw.interfaces.i18n.UnknownLanguageException;
|
||||||
import com.deepclone.lw.interfaces.naming.NamingDAO;
|
import com.deepclone.lw.interfaces.naming.NamingDAO;
|
||||||
import com.deepclone.lw.interfaces.prefs.AccountPreferences;
|
import com.deepclone.lw.interfaces.prefs.AccountPreferences;
|
||||||
import com.deepclone.lw.interfaces.prefs.PreferencesDAO;
|
import com.deepclone.lw.interfaces.prefs.PreferencesDAO;
|
||||||
import com.deepclone.lw.sqld.accounts.Account;
|
import com.deepclone.lw.sqld.accounts.Account;
|
||||||
import com.deepclone.lw.sqld.game.EmpireTechLine;
|
|
||||||
import com.deepclone.lw.sqld.game.EmpireTechnology;
|
|
||||||
import com.deepclone.lw.sqld.game.GeneralInformation;
|
import com.deepclone.lw.sqld.game.GeneralInformation;
|
||||||
import com.deepclone.lw.sqld.game.battle.BattleListRecord;
|
import com.deepclone.lw.sqld.game.battle.BattleListRecord;
|
||||||
import com.deepclone.lw.utils.EmailAddress;
|
import com.deepclone.lw.utils.EmailAddress;
|
||||||
|
@ -46,6 +45,7 @@ public class EmpireManagementBean
|
||||||
private EmpireDAO empireDao;
|
private EmpireDAO empireDao;
|
||||||
private PreferencesDAO prefsDao;
|
private PreferencesDAO prefsDao;
|
||||||
private BattlesDAO battlesDao;
|
private BattlesDAO battlesDao;
|
||||||
|
private Translator translator;
|
||||||
|
|
||||||
|
|
||||||
@Autowired( required = true )
|
@Autowired( required = true )
|
||||||
|
@ -83,6 +83,13 @@ public class EmpireManagementBean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setI18NManager( Translator translator )
|
||||||
|
{
|
||||||
|
this.translator = translator;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Integer getEmpireId( EmailAddress address )
|
public Integer getEmpireId( EmailAddress address )
|
||||||
{
|
{
|
||||||
|
@ -108,29 +115,22 @@ public class EmpireManagementBean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LanguageTranslator getTranslator( int empireId )
|
||||||
|
{
|
||||||
|
GeneralInformation generalInformation = this.empireDao.getInformation( empireId );
|
||||||
|
try {
|
||||||
|
return this.translator.getLanguageTranslator( generalInformation.getLanguage( ) );
|
||||||
|
} catch ( UnknownLanguageException e ) {
|
||||||
|
throw new RuntimeException( "account for empire " + empireId + " is using an unsupported language" , e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public EmpireResponse getOverview( int empireId )
|
public EmpireResponse getOverview( int empireId )
|
||||||
{
|
{
|
||||||
OverviewData overview = this.empireDao.getOverview( empireId );
|
OverviewData overview = this.empireDao.getOverview( empireId );
|
||||||
List< ResearchLineData > research = new LinkedList< ResearchLineData >( );
|
|
||||||
|
|
||||||
for ( EmpireTechLine etl : this.empireDao.getTechnology( empireId ) ) {
|
|
||||||
List< TechnologyData > implemented = new LinkedList< TechnologyData >( );
|
|
||||||
TechnologyData current = null;
|
|
||||||
|
|
||||||
for ( EmpireTechnology et : etl.getTechnologies( ) ) {
|
|
||||||
if ( et.isImplemented( ) ) {
|
|
||||||
implemented.add( new TechnologyData( et.getName( ) , et.getDescription( ) ) );
|
|
||||||
} else if ( et.getProgress( ) == 100 ) {
|
|
||||||
current = new TechnologyData( et.getName( ) , et.getDescription( ) , 100 , et.getCost( ) );
|
|
||||||
} else {
|
|
||||||
current = new TechnologyData( et.getName( ) , et.getDescription( ) , et.getProgress( ) );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
research.add( new ResearchLineData( etl.getId( ) , etl.getName( ) , etl.getDescription( ) , implemented ,
|
|
||||||
current ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
List< BattleListEntry > battles = new LinkedList< BattleListEntry >( );
|
List< BattleListEntry > battles = new LinkedList< BattleListEntry >( );
|
||||||
for ( BattleListRecord record : this.battlesDao.getBattles( empireId ) ) {
|
for ( BattleListRecord record : this.battlesDao.getBattles( empireId ) ) {
|
||||||
|
@ -150,15 +150,7 @@ public class EmpireManagementBean
|
||||||
battles.add( entry );
|
battles.add( entry );
|
||||||
}
|
}
|
||||||
|
|
||||||
return new EmpireResponse( this.getGeneralInformation( empireId ) , overview , research , battles );
|
return new EmpireResponse( this.getGeneralInformation( empireId ) , overview , battles );
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public EmpireResponse implementTechnology( int empireId , int techId )
|
|
||||||
{
|
|
||||||
this.empireDao.implementTechnology( empireId , techId );
|
|
||||||
return this.getOverview( empireId );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,138 +0,0 @@
|
||||||
package com.deepclone.lw.beans.updates;
|
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
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.UpdatesDAO;
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class GameUpdateBean
|
|
||||||
implements InitializingBean , Runnable
|
|
||||||
{
|
|
||||||
private Ticker ticker;
|
|
||||||
private SystemStatus systemStatus;
|
|
||||||
private SystemLogger logger;
|
|
||||||
|
|
||||||
private TransactionTemplate tTemplate;
|
|
||||||
private UpdatesDAO updatesDao;
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired( required = true )
|
|
||||||
public void setTicker( Ticker ticker )
|
|
||||||
{
|
|
||||||
this.ticker = ticker;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired( required = true )
|
|
||||||
public void setSystemStatus( SystemStatus systemStatus )
|
|
||||||
{
|
|
||||||
this.systemStatus = systemStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired( required = true )
|
|
||||||
public void setLogger( Logger logger )
|
|
||||||
{
|
|
||||||
this.logger = logger.getSystemLogger( "GameUpdate" );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired( required = true )
|
|
||||||
public void setTransactionManager( PlatformTransactionManager transactionManager )
|
|
||||||
{
|
|
||||||
this.tTemplate = new TransactionTemplate( transactionManager );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired( required = true )
|
|
||||||
public void setUpdatesDAO( UpdatesDAO updatesDao )
|
|
||||||
{
|
|
||||||
this.updatesDao = updatesDao;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void afterPropertiesSet( )
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
this.endPreviousTick( );
|
|
||||||
} catch ( MaintenanceStatusException e ) {
|
|
||||||
// Do nothing
|
|
||||||
}
|
|
||||||
this.ticker.registerTask( Frequency.MINUTE , "Game update" , this );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run( )
|
|
||||||
{
|
|
||||||
// Attempt to end the previous tick, if e.g. maintenance mode was initiated while it was
|
|
||||||
// being processed
|
|
||||||
try {
|
|
||||||
this.endPreviousTick( );
|
|
||||||
} catch ( MaintenanceStatusException e1 ) {
|
|
||||||
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.executeTick( tickId );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void endPreviousTick( )
|
|
||||||
throws MaintenanceStatusException
|
|
||||||
{
|
|
||||||
Long currentTick = this.systemStatus.checkStuckTick( );
|
|
||||||
if ( currentTick == null ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.logger.log( LogLevel.WARNING , "Tick " + currentTick + " restarted" ).flush( );
|
|
||||||
this.executeTick( currentTick.longValue( ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void executeTick( final long tickId )
|
|
||||||
{
|
|
||||||
boolean hasMore;
|
|
||||||
do {
|
|
||||||
hasMore = this.tTemplate.execute( new TransactionCallback< Boolean >( ) {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Boolean doInTransaction( TransactionStatus status )
|
|
||||||
{
|
|
||||||
return updatesDao.processUpdates( tickId );
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
} while ( hasMore );
|
|
||||||
this.logger.log( LogLevel.TRACE , "Tick " + tickId + " completed" ).flush( );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,43 +0,0 @@
|
||||||
package com.deepclone.lw.beans.updates;
|
|
||||||
|
|
||||||
|
|
||||||
import java.sql.Types;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.jdbc.core.SqlOutParameter;
|
|
||||||
import org.springframework.jdbc.core.SqlParameter;
|
|
||||||
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
|
|
||||||
|
|
||||||
import com.deepclone.lw.interfaces.game.UpdatesDAO;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class UpdatesDAOBean
|
|
||||||
implements UpdatesDAO
|
|
||||||
{
|
|
||||||
|
|
||||||
private SimpleJdbcCall process;
|
|
||||||
|
|
||||||
|
|
||||||
@Autowired( required = true )
|
|
||||||
public void setDataSource( DataSource dataSource )
|
|
||||||
{
|
|
||||||
this.process = new SimpleJdbcCall( dataSource );
|
|
||||||
this.process.withCatalogName( "sys" ).withFunctionName( "process_updates" );
|
|
||||||
this.process.withoutProcedureColumnMetaDataAccess( );
|
|
||||||
this.process.addDeclaredParameter( new SqlParameter( "tick_id" , Types.BIGINT ) );
|
|
||||||
this.process.addDeclaredParameter( new SqlOutParameter( "has_more" , Types.BOOLEAN ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean processUpdates( long tickId )
|
|
||||||
{
|
|
||||||
Map< String , Object > m = this.process.execute( tickId );
|
|
||||||
return (Boolean) m.get( "has_more" );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -10,13 +10,11 @@
|
||||||
<import resource="simple/empire-management-bean.xml" />
|
<import resource="simple/empire-management-bean.xml" />
|
||||||
<import resource="simple/fleet-management-bean.xml" />
|
<import resource="simple/fleet-management-bean.xml" />
|
||||||
<import resource="simple/fleets-dao-bean.xml" />
|
<import resource="simple/fleets-dao-bean.xml" />
|
||||||
<import resource="simple/game-update-bean.xml" />
|
|
||||||
<import resource="simple/map-viewer-bean.xml" />
|
<import resource="simple/map-viewer-bean.xml" />
|
||||||
<import resource="simple/message-beans.xml" />
|
<import resource="simple/message-beans.xml" />
|
||||||
<import resource="simple/planet-dao-bean.xml" />
|
<import resource="simple/planet-dao-bean.xml" />
|
||||||
<import resource="simple/planets-management-bean.xml" />
|
<import resource="simple/planets-management-bean.xml" />
|
||||||
<import resource="simple/universe-dao-bean.xml" />
|
<import resource="simple/universe-dao-bean.xml" />
|
||||||
<import resource="simple/universe-generator-bean.xml" />
|
<import resource="simple/universe-generator-bean.xml" />
|
||||||
<import resource="simple/updates-dao-bean.xml" />
|
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
|
@ -4,12 +4,12 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server-beans</artifactId>
|
<artifactId>legacyworlds-server-beans</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-beans-system</artifactId>
|
<artifactId>legacyworlds-server-beans-system</artifactId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<name>Legacy Worlds system management</name>
|
<name>Legacy Worlds system management</name>
|
||||||
<description>This module regroups system management beans such as the constants manager.</description>
|
<description>This module regroups system management beans such as the constants manager.</description>
|
||||||
</project>
|
</project>
|
|
@ -93,7 +93,7 @@ class ConstantsData
|
||||||
this.uocConstantNoBounds.addDeclaredParameter( new SqlParameter( "cname" , Types.VARCHAR ) );
|
this.uocConstantNoBounds.addDeclaredParameter( new SqlParameter( "cname" , Types.VARCHAR ) );
|
||||||
this.uocConstantNoBounds.addDeclaredParameter( new SqlParameter( "cdesc" , Types.VARCHAR ) );
|
this.uocConstantNoBounds.addDeclaredParameter( new SqlParameter( "cdesc" , Types.VARCHAR ) );
|
||||||
this.uocConstantNoBounds.addDeclaredParameter( new SqlParameter( "catname" , Types.VARCHAR ) );
|
this.uocConstantNoBounds.addDeclaredParameter( new SqlParameter( "catname" , Types.VARCHAR ) );
|
||||||
this.uocConstantNoBounds.addDeclaredParameter( new SqlParameter( "value" , Types.REAL ) );
|
this.uocConstantNoBounds.addDeclaredParameter( new SqlParameter( "value" , Types.DOUBLE ) );
|
||||||
|
|
||||||
this.uocConstantSingleBound = new SimpleJdbcCall( dataSource );
|
this.uocConstantSingleBound = new SimpleJdbcCall( dataSource );
|
||||||
this.uocConstantSingleBound.withCatalogName( "sys" ).withFunctionName( "uoc_constant" );
|
this.uocConstantSingleBound.withCatalogName( "sys" ).withFunctionName( "uoc_constant" );
|
||||||
|
@ -101,8 +101,8 @@ class ConstantsData
|
||||||
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "cname" , Types.VARCHAR ) );
|
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "cname" , Types.VARCHAR ) );
|
||||||
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "cdesc" , Types.VARCHAR ) );
|
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "cdesc" , Types.VARCHAR ) );
|
||||||
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "catname" , Types.VARCHAR ) );
|
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "catname" , Types.VARCHAR ) );
|
||||||
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "value" , Types.REAL ) );
|
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "value" , Types.DOUBLE ) );
|
||||||
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "boundary" , Types.REAL ) );
|
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "boundary" , Types.DOUBLE ) );
|
||||||
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "is_min" , Types.BOOLEAN ) );
|
this.uocConstantSingleBound.addDeclaredParameter( new SqlParameter( "is_min" , Types.BOOLEAN ) );
|
||||||
|
|
||||||
this.uocConstantTwoBounds = new SimpleJdbcCall( dataSource );
|
this.uocConstantTwoBounds = new SimpleJdbcCall( dataSource );
|
||||||
|
@ -111,13 +111,13 @@ class ConstantsData
|
||||||
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "cname" , Types.VARCHAR ) );
|
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "cname" , Types.VARCHAR ) );
|
||||||
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "cdesc" , Types.VARCHAR ) );
|
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "cdesc" , Types.VARCHAR ) );
|
||||||
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "catname" , Types.VARCHAR ) );
|
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "catname" , Types.VARCHAR ) );
|
||||||
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "value" , Types.REAL ) );
|
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "value" , Types.DOUBLE ) );
|
||||||
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "min" , Types.REAL ) );
|
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "min" , Types.DOUBLE ) );
|
||||||
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "max" , Types.REAL ) );
|
this.uocConstantTwoBounds.addDeclaredParameter( new SqlParameter( "max" , Types.DOUBLE ) );
|
||||||
|
|
||||||
this.fSetConstant = new StoredProc( dataSource , "sys" , "set_constant" );
|
this.fSetConstant = new StoredProc( dataSource , "sys" , "set_constant" );
|
||||||
this.fSetConstant.addParameter( "cname" , Types.VARCHAR );
|
this.fSetConstant.addParameter( "cname" , Types.VARCHAR );
|
||||||
this.fSetConstant.addParameter( "value" , Types.REAL );
|
this.fSetConstant.addParameter( "value" , Types.DOUBLE );
|
||||||
this.fSetConstant.addParameter( "admin" , Types.INTEGER );
|
this.fSetConstant.addParameter( "admin" , Types.INTEGER );
|
||||||
|
|
||||||
this.tTemplate = tTemplate;
|
this.tTemplate = tTemplate;
|
||||||
|
@ -149,8 +149,8 @@ class ConstantsData
|
||||||
c.setName( rs.getString( "name" ) );
|
c.setName( rs.getString( "name" ) );
|
||||||
c.setDescription( rs.getString( "description" ) );
|
c.setDescription( rs.getString( "description" ) );
|
||||||
c.setValue( rs.getDouble( "value" ) );
|
c.setValue( rs.getDouble( "value" ) );
|
||||||
c.setMinValue( (Float) rs.getObject( "min" ) );
|
c.setMinValue( (Double) rs.getObject( "min" ) );
|
||||||
c.setMaxValue( (Float) rs.getObject( "max" ) );
|
c.setMaxValue( (Double) rs.getObject( "max" ) );
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -609,7 +609,7 @@ class ConstantsData
|
||||||
@Override
|
@Override
|
||||||
protected void doInTransactionWithoutResult( TransactionStatus status )
|
protected void doInTransactionWithoutResult( TransactionStatus status )
|
||||||
{
|
{
|
||||||
fSetConstant.execute( name , value.floatValue( ) , admin );
|
fSetConstant.execute( name , value , admin );
|
||||||
}
|
}
|
||||||
|
|
||||||
} );
|
} );
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package com.deepclone.lw.beans.sys;
|
package com.deepclone.lw.beans.sys;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
import java.util.HashSet;
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
@ -92,9 +93,10 @@ public class ConstantsManagerBean
|
||||||
|
|
||||||
/* Documented in ConstantsManager interface */
|
/* Documented in ConstantsManager interface */
|
||||||
@Override
|
@Override
|
||||||
public void registerUser( ConstantsUser user , Set< String > constants )
|
public void registerUser( ConstantsUser user , String... constants )
|
||||||
{
|
{
|
||||||
this.data.registerUser( user , constants );
|
HashSet< String > cSet = new HashSet< String >( Arrays.asList( constants ) );
|
||||||
|
this.data.registerUser( user , cSet );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -112,4 +114,5 @@ public class ConstantsManagerBean
|
||||||
{
|
{
|
||||||
return new ConstantsAdministrationImpl( this.data , admin );
|
return new ConstantsAdministrationImpl( this.data , admin );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,7 +89,7 @@ public class ConstantsRegistrarBean
|
||||||
// Work and income
|
// Work and income
|
||||||
String[] wcNames = {
|
String[] wcNames = {
|
||||||
"population" , "factory" , "strikeEffect" , "wuPerPopUnit" , "destructionRecovery" , "destructionWork" ,
|
"population" , "factory" , "strikeEffect" , "wuPerPopUnit" , "destructionRecovery" , "destructionWork" ,
|
||||||
"rpPerPopUnit" , "cancelRecovery"
|
"cancelRecovery"
|
||||||
};
|
};
|
||||||
for ( int i = 0 ; i < wcNames.length ; i++ ) {
|
for ( int i = 0 ; i < wcNames.length ; i++ ) {
|
||||||
wcNames[ i ] = "game.work." + wcNames[ i ];
|
wcNames[ i ] = "game.work." + wcNames[ i ];
|
||||||
|
@ -107,10 +107,8 @@ public class ConstantsRegistrarBean
|
||||||
defs.add( new ConstantDefinition( wcNames[ 4 ] , cat , cDesc , 0.1 , 0.01 , 0.99 ) );
|
defs.add( new ConstantDefinition( wcNames[ 4 ] , cat , cDesc , 0.1 , 0.01 , 0.99 ) );
|
||||||
cDesc = "Proportion of a building's construction work units required to destroy it";
|
cDesc = "Proportion of a building's construction work units required to destroy it";
|
||||||
defs.add( new ConstantDefinition( wcNames[ 5 ] , cat , cDesc , 0.25 , 0.01 , 1.0 ) );
|
defs.add( new ConstantDefinition( wcNames[ 5 ] , cat , cDesc , 0.25 , 0.01 , 1.0 ) );
|
||||||
cDesc = "Research points per population unit.";
|
|
||||||
defs.add( new ConstantDefinition( wcNames[ 6 ] , cat , cDesc , 0.50 , 0.01 , true ) );
|
|
||||||
cDesc = "Proportion of queue investments that is recovered when flushing the queue.";
|
cDesc = "Proportion of queue investments that is recovered when flushing the queue.";
|
||||||
defs.add( new ConstantDefinition( wcNames[ 7 ] , cat , cDesc , 0.1 , 0.01 , 1.0 ) );
|
defs.add( new ConstantDefinition( wcNames[ 6 ] , cat , cDesc , 0.1 , 0.01 , 1.0 ) );
|
||||||
|
|
||||||
// Vacation mode
|
// Vacation mode
|
||||||
cDesc = "Initial vacation credits.";
|
cDesc = "Initial vacation credits.";
|
||||||
|
@ -172,29 +170,40 @@ public class ConstantsRegistrarBean
|
||||||
|
|
||||||
// Accounts - warnings
|
// Accounts - warnings
|
||||||
cDesc = "Amount of warnings that triggers an automatic ban request.";
|
cDesc = "Amount of warnings that triggers an automatic ban request.";
|
||||||
defs.add( new ConstantDefinition( "accounts.warnings.autoBan" , "Accounts - Warnings" , cDesc , 3.0 , 1.0 , true ) );
|
defs.add( new ConstantDefinition( "accounts.warnings.autoBan" , "Accounts - Warnings" , cDesc , 3.0 , 1.0 ,
|
||||||
|
true ) );
|
||||||
cDesc = "Period after a warning is received during which additional warnings will be ignored (seconds).";
|
cDesc = "Period after a warning is received during which additional warnings will be ignored (seconds).";
|
||||||
defs.add( new ConstantDefinition( "accounts.warnings.grace" , "Accounts - Warnings" , cDesc , 7200.0 , 60.0 , true ) );
|
defs.add( new ConstantDefinition( "accounts.warnings.grace" , "Accounts - Warnings" , cDesc , 7200.0 , 60.0 ,
|
||||||
|
true ) );
|
||||||
cDesc = "Time after which warnings are decreased (expressed in units as defined by a.w.expiration.units).";
|
cDesc = "Time after which warnings are decreased (expressed in units as defined by a.w.expiration.units).";
|
||||||
defs.add( new ConstantDefinition( "accounts.warnings.expiration" , "Accounts - Warnings" , cDesc , 60.0 , 1.0 , true ) );
|
defs.add( new ConstantDefinition( "accounts.warnings.expiration" , "Accounts - Warnings" , cDesc , 60.0 , 1.0 ,
|
||||||
|
true ) );
|
||||||
cDesc = "Units used to express warning expiration time (seconds).";
|
cDesc = "Units used to express warning expiration time (seconds).";
|
||||||
defs.add( new ConstantDefinition( "accounts.warnings.expiration.units" , "Accounts - Warnings" , cDesc , 86400.0 , 1.0 , true ) );
|
defs.add( new ConstantDefinition( "accounts.warnings.expiration.units" , "Accounts - Warnings" , cDesc ,
|
||||||
|
86400.0 , 1.0 , true ) );
|
||||||
|
|
||||||
// Account inactivity
|
// Account inactivity
|
||||||
cDesc = "Time units (seconds)";
|
cDesc = "Time units (seconds)";
|
||||||
defs.add( new ConstantDefinition( "accounts.inactivity.units" , "Accounts - Inactivity" , cDesc , oneWeek , 3600.0 , true ) );
|
defs.add( new ConstantDefinition( "accounts.inactivity.units" , "Accounts - Inactivity" , cDesc , oneWeek ,
|
||||||
|
3600.0 , true ) );
|
||||||
cDesc = "Time after which the inactivity warning e-mail is to be sent, expressed using units defined by a.i.units.";
|
cDesc = "Time after which the inactivity warning e-mail is to be sent, expressed using units defined by a.i.units.";
|
||||||
defs.add( new ConstantDefinition( "accounts.inactivity.warningMail" , "Accounts - Inactivity" , cDesc , 3.0 , 1.0 , true ) );
|
defs.add( new ConstantDefinition( "accounts.inactivity.warningMail" , "Accounts - Inactivity" , cDesc , 3.0 ,
|
||||||
|
1.0 , true ) );
|
||||||
cDesc = "Time between the inactivity warning e-mail and actual account deletion, expressed using units defined by a.i.units.";
|
cDesc = "Time between the inactivity warning e-mail and actual account deletion, expressed using units defined by a.i.units.";
|
||||||
defs.add( new ConstantDefinition( "accounts.inactivity.deletion" , "Accounts - Inactivity" , cDesc , 1.0 , 1.0 , true ) );
|
defs.add( new ConstantDefinition( "accounts.inactivity.deletion" , "Accounts - Inactivity" , cDesc , 1.0 , 1.0 ,
|
||||||
|
true ) );
|
||||||
|
|
||||||
// Bug reports
|
// Bug reports
|
||||||
cDesc = "Amount of credits granted for low priority bug reports.";
|
cDesc = "Amount of credits granted for low priority bug reports.";
|
||||||
defs.add( new ConstantDefinition( "bugtracker.lowCredits" , "Bug tracking system" , cDesc , 1.0 , 1.0 , true ) );
|
defs.add( new ConstantDefinition( "bugtracker.lowCredits" , "Bug tracking system" , cDesc , 1.0 , 1.0 , true ) );
|
||||||
cDesc = "Amount of credits granted for normal bug reports.";
|
cDesc = "Amount of credits granted for normal bug reports.";
|
||||||
defs.add( new ConstantDefinition( "bugtracker.mediumCredits" , "Bug tracking system" , cDesc , 2.0 , 1.0 , true ) );
|
defs
|
||||||
|
.add( new ConstantDefinition( "bugtracker.mediumCredits" , "Bug tracking system" , cDesc , 2.0 , 1.0 ,
|
||||||
|
true ) );
|
||||||
cDesc = "Amount of credits granted for critical bug reports.";
|
cDesc = "Amount of credits granted for critical bug reports.";
|
||||||
defs.add( new ConstantDefinition( "bugtracker.highCredits" , "Bug tracking system" , cDesc , 3.0 , 1.0 , true ) );
|
defs
|
||||||
|
.add( new ConstantDefinition( "bugtracker.highCredits" , "Bug tracking system" , cDesc , 3.0 , 1.0 ,
|
||||||
|
true ) );
|
||||||
|
|
||||||
cm.registerConstants( defs );
|
cm.registerConstants( defs );
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,6 @@ import javax.sql.DataSource;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.jdbc.core.RowMapper;
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
import org.springframework.jdbc.core.SqlOutParameter;
|
|
||||||
import org.springframework.jdbc.core.simple.SimpleJdbcCall;
|
|
||||||
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||||
import org.springframework.transaction.PlatformTransactionManager;
|
import org.springframework.transaction.PlatformTransactionManager;
|
||||||
import org.springframework.transaction.TransactionStatus;
|
import org.springframework.transaction.TransactionStatus;
|
||||||
|
@ -44,13 +42,14 @@ public class SystemStatusBean
|
||||||
/** Current maintenance mode record */
|
/** Current maintenance mode record */
|
||||||
private MaintenanceData maintenance = null;
|
private MaintenanceData maintenance = null;
|
||||||
|
|
||||||
private SimpleJdbcCall doStartTick;
|
|
||||||
private SimpleJdbcCall doCheckTick;
|
|
||||||
|
|
||||||
private StoredProc fEnterMaintenanceMode;
|
private StoredProc fEnterMaintenanceMode;
|
||||||
private StoredProc fExtendMaintenanceMode;
|
private StoredProc fExtendMaintenanceMode;
|
||||||
private StoredProc fExitMaintenanceMode;
|
private StoredProc fExitMaintenanceMode;
|
||||||
|
|
||||||
|
private StoredProc fCheckTick;
|
||||||
|
private StoredProc fStartTick;
|
||||||
|
private StoredProc fEndTick;
|
||||||
|
|
||||||
|
|
||||||
@Autowired( required = true )
|
@Autowired( required = true )
|
||||||
public void setDataSource( DataSource dataSource )
|
public void setDataSource( DataSource dataSource )
|
||||||
|
@ -72,16 +71,14 @@ public class SystemStatusBean
|
||||||
this.fExitMaintenanceMode.addParameter( "admin_id" , Types.INTEGER );
|
this.fExitMaintenanceMode.addParameter( "admin_id" , Types.INTEGER );
|
||||||
this.fExitMaintenanceMode.addOutput( "success" , Types.BOOLEAN );
|
this.fExitMaintenanceMode.addOutput( "success" , Types.BOOLEAN );
|
||||||
|
|
||||||
this.doStartTick = new SimpleJdbcCall( dataSource );
|
this.fCheckTick = new StoredProc( dataSource , "sys" , "check_stuck_tick" );
|
||||||
this.doStartTick.withCatalogName( "sys" ).withFunctionName( "start_tick" );
|
this.fCheckTick.addOutput( "tick_id" , Types.BIGINT );
|
||||||
this.doStartTick.withoutProcedureColumnMetaDataAccess( );
|
|
||||||
this.doStartTick.addDeclaredParameter( new SqlOutParameter( "tick_id" , Types.BIGINT ) );
|
|
||||||
|
|
||||||
this.doCheckTick = new SimpleJdbcCall( dataSource );
|
this.fStartTick = new StoredProc( dataSource , "sys" , "start_tick" );
|
||||||
this.doCheckTick.withCatalogName( "sys" ).withFunctionName( "check_stuck_tick" );
|
this.fStartTick.addOutput( "tick_id" , Types.BIGINT );
|
||||||
this.doCheckTick.withoutProcedureColumnMetaDataAccess( );
|
|
||||||
this.doCheckTick.addDeclaredParameter( new SqlOutParameter( "tick_id" , Types.BIGINT ) );
|
|
||||||
|
|
||||||
|
this.fEndTick = new StoredProc( dataSource , "sys" , "end_tick" );
|
||||||
|
this.fEndTick.addParameter( "tick_id" , Types.BIGINT );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -246,6 +243,31 @@ public class SystemStatusBean
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documented in interface */
|
||||||
|
@Override
|
||||||
|
public Long checkStuckTick( )
|
||||||
|
throws MaintenanceStatusException
|
||||||
|
{
|
||||||
|
Long tid = this.tTemplate.execute( new TransactionCallback< Long >( ) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Long doInTransaction( TransactionStatus status )
|
||||||
|
{
|
||||||
|
Map< String , Object > m = fCheckTick.execute( );
|
||||||
|
loadStatus( );
|
||||||
|
return (Long) m.get( "tick_id" );
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
|
|
||||||
|
if ( tid == null && this.maintenance != null ) {
|
||||||
|
throw new MaintenanceStatusException( this.maintenance );
|
||||||
|
}
|
||||||
|
|
||||||
|
return tid;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Documented in interface */
|
/* Documented in interface */
|
||||||
@Override
|
@Override
|
||||||
synchronized public long startTick( )
|
synchronized public long startTick( )
|
||||||
|
@ -256,7 +278,7 @@ public class SystemStatusBean
|
||||||
@Override
|
@Override
|
||||||
public Long doInTransaction( TransactionStatus status )
|
public Long doInTransaction( TransactionStatus status )
|
||||||
{
|
{
|
||||||
Map< String , Object > m = doStartTick.execute( );
|
Map< String , Object > m = fStartTick.execute( );
|
||||||
loadStatus( );
|
loadStatus( );
|
||||||
return (Long) m.get( "tick_id" );
|
return (Long) m.get( "tick_id" );
|
||||||
}
|
}
|
||||||
|
@ -277,26 +299,28 @@ public class SystemStatusBean
|
||||||
|
|
||||||
/* Documented in interface */
|
/* Documented in interface */
|
||||||
@Override
|
@Override
|
||||||
public Long checkStuckTick( )
|
public void endTick( )
|
||||||
throws MaintenanceStatusException
|
throws TickStatusException , MaintenanceStatusException
|
||||||
{
|
{
|
||||||
Long tid = this.tTemplate.execute( new TransactionCallback< Long >( ) {
|
if ( this.maintenance != null ) {
|
||||||
|
|
||||||
@Override
|
|
||||||
public Long doInTransaction( TransactionStatus status )
|
|
||||||
{
|
|
||||||
Map< String , Object > m = doCheckTick.execute( );
|
|
||||||
loadStatus( );
|
|
||||||
return (Long) m.get( "tick_id" );
|
|
||||||
}
|
|
||||||
|
|
||||||
} );
|
|
||||||
|
|
||||||
if ( tid == null && this.maintenance != null ) {
|
|
||||||
throw new MaintenanceStatusException( this.maintenance );
|
throw new MaintenanceStatusException( this.maintenance );
|
||||||
}
|
}
|
||||||
|
|
||||||
return tid;
|
final Long tid = this.status.getCurrentTick( );
|
||||||
|
if ( tid == null ) {
|
||||||
|
throw new TickStatusException( );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doInTransactionWithoutResult( TransactionStatus status )
|
||||||
|
{
|
||||||
|
fEndTick.execute( tid );
|
||||||
|
loadStatus( );
|
||||||
|
}
|
||||||
|
|
||||||
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
package com.deepclone.lw.beans.sys;
|
package com.deepclone.lw.beans.sys;
|
||||||
|
|
||||||
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.DisposableBean;
|
import org.springframework.beans.factory.DisposableBean;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -101,9 +98,7 @@ public class TickerBean
|
||||||
this.mainThread = new TickerThread( this.logger , this.tickerManager );
|
this.mainThread = new TickerThread( this.logger , this.tickerManager );
|
||||||
|
|
||||||
// Register thread as a constants user
|
// Register thread as a constants user
|
||||||
Set< String > use = new HashSet< String >( );
|
this.constantsManager.registerUser( this.mainThread , "ticker.interval" );
|
||||||
use.add( "ticker.interval" );
|
|
||||||
this.constantsManager.registerUser( this.mainThread , use );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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>
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<projectDescription>
|
||||||
|
<name>legacyworlds-server-beans-techs</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>
|
|
@ -0,0 +1,6 @@
|
||||||
|
#Mon Mar 28 09:14:01 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
|
|
@ -0,0 +1,9 @@
|
||||||
|
#Mon Mar 28 09:13:56 CEST 2011
|
||||||
|
activeProfiles=
|
||||||
|
eclipse.preferences.version=1
|
||||||
|
fullBuildGoals=process-test-resources
|
||||||
|
includeModules=false
|
||||||
|
resolveWorkspaceProjects=true
|
||||||
|
resourceFilterGoals=process-resources resources\:testResources
|
||||||
|
skipCompilerPlugin=true
|
||||||
|
version=1
|
|
@ -0,0 +1,15 @@
|
||||||
|
<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-techs</artifactId>
|
||||||
|
<version>5.99.2</version>
|
||||||
|
<name>Legacy Worlds technology management</name>
|
||||||
|
<description>This package contains components which are used to manage technologies in LW games.</description>
|
||||||
|
</project>
|
|
@ -0,0 +1,160 @@
|
||||||
|
package com.deepclone.lw.beans.techs;
|
||||||
|
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||||
|
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.EmpireTechnologyDAO;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.EmpireTechnology;
|
||||||
|
import com.deepclone.lw.utils.StoredProc;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation the empire technology and research data access component.
|
||||||
|
*
|
||||||
|
* @author tseeker
|
||||||
|
*/
|
||||||
|
public class EmpireTechnologyDAOBean
|
||||||
|
implements EmpireTechnologyDAO
|
||||||
|
{
|
||||||
|
/** SQL query that reads the list of an empire's technologies */
|
||||||
|
private static final String qGetTechnologies = "SELECT * FROM emp.technologies_view WHERE empire = ?";
|
||||||
|
|
||||||
|
/** SQL query that executes the priorities update preparation function */
|
||||||
|
private static final String qStartPrioritiesUpdate = "SELECT emp.prepare_research_priorities_update( )";
|
||||||
|
|
||||||
|
/** SQL query that inserts research priority changes into the temporary table */
|
||||||
|
private static final String qUploadPriorities = "INSERT INTO research_priorities_updates ( technology , priority ) "
|
||||||
|
+ "VALUES ( ? , ? )";
|
||||||
|
|
||||||
|
/** Data source access component */
|
||||||
|
private SimpleJdbcTemplate dTemplate;
|
||||||
|
|
||||||
|
/** Row mapper for empire technologies */
|
||||||
|
private RowMapper< EmpireTechnology > mEmpireTechnology;
|
||||||
|
|
||||||
|
/** Wrapper for the stored procedure that implements technologies */
|
||||||
|
private StoredProc fImplementTech;
|
||||||
|
|
||||||
|
/** Wrapper for the stored procedure to apply research priority updates */
|
||||||
|
private StoredProc fApplyResearchPriorities;
|
||||||
|
|
||||||
|
|
||||||
|
/** Initialise the row mapper */
|
||||||
|
public EmpireTechnologyDAOBean( )
|
||||||
|
{
|
||||||
|
this.mEmpireTechnology = new RowMapper< EmpireTechnology >( ) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public EmpireTechnology mapRow( ResultSet rs , int rowNum )
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
int techId = rs.getInt( "technology_id" );
|
||||||
|
String techName = rs.getString( "technology" );
|
||||||
|
boolean detailed = rs.getBoolean( "detailed" );
|
||||||
|
Integer completion = (Integer) rs.getObject( "completion" );
|
||||||
|
Integer cost = (Integer) rs.getObject( "cost" );
|
||||||
|
Integer priority = (Integer) rs.getObject( "priority" );
|
||||||
|
|
||||||
|
EmpireTechnology result;
|
||||||
|
if ( !detailed ) {
|
||||||
|
result = new EmpireTechnology( techId * rs.getInt( "empire" ) , techName , completion , priority );
|
||||||
|
} else if ( completion != null ) {
|
||||||
|
result = new EmpireTechnology( techName , completion , priority );
|
||||||
|
} else if ( cost != null ) {
|
||||||
|
result = new EmpireTechnology( techName , cost );
|
||||||
|
} else {
|
||||||
|
result = new EmpireTechnology( techName );
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector that initialises the database access component and stored procedure
|
||||||
|
* wrappers.
|
||||||
|
*
|
||||||
|
* @param dataSource
|
||||||
|
* the data source
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setDataSource( DataSource dataSource )
|
||||||
|
{
|
||||||
|
this.dTemplate = new SimpleJdbcTemplate( dataSource );
|
||||||
|
|
||||||
|
// Stored procedure for technology implementation
|
||||||
|
this.fImplementTech = new StoredProc( dataSource , "emp" , "implement_tech" );
|
||||||
|
this.fImplementTech.addParameter( "empire_id" , Types.INTEGER );
|
||||||
|
this.fImplementTech.addParameter( "technology" , Types.VARCHAR );
|
||||||
|
this.fImplementTech.addOutput( "error_code" , Types.INTEGER );
|
||||||
|
|
||||||
|
// Stored procedure to apply research priority updates
|
||||||
|
this.fApplyResearchPriorities = new StoredProc( dataSource , "emp" , "apply_research_priorities" );
|
||||||
|
this.fApplyResearchPriorities.addParameter( "empire_id" , Types.INTEGER );
|
||||||
|
this.fApplyResearchPriorities.addOutput( "error_code" , Types.INTEGER );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in EmpireTechnologyDAO interface */
|
||||||
|
@Override
|
||||||
|
public List< EmpireTechnology > getTechnologies( int empireId )
|
||||||
|
{
|
||||||
|
return this.dTemplate.query( qGetTechnologies , this.mEmpireTechnology , empireId );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in EmpireTechnologyDAO interface */
|
||||||
|
@Override
|
||||||
|
public int implementTechnology( int empireId , String technology )
|
||||||
|
{
|
||||||
|
return (Integer) this.fImplementTech.execute( empireId , technology ).get( "error_code" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in EmpireTechnologyDAO interface */
|
||||||
|
@Override
|
||||||
|
public void startPrioritiesUpdate( )
|
||||||
|
{
|
||||||
|
this.dTemplate.queryForList( qStartPrioritiesUpdate );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in EmpireTechnologyDAO interface */
|
||||||
|
@Override
|
||||||
|
public void uploadPriorities( Map< String , Integer > priorities )
|
||||||
|
{
|
||||||
|
List< Object[] > batch = new ArrayList< Object[] >( priorities.size( ) );
|
||||||
|
int counter = 0;
|
||||||
|
for ( Entry< String , Integer > entry : priorities.entrySet( ) ) {
|
||||||
|
Object[] values = new Object[] {
|
||||||
|
entry.getKey( ) , entry.getValue( )
|
||||||
|
};
|
||||||
|
batch.add( counter++ , values );
|
||||||
|
}
|
||||||
|
this.dTemplate.batchUpdate( qUploadPriorities , batch );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in EmpireTechnologyDAO interface */
|
||||||
|
@Override
|
||||||
|
public int finishPrioritiesUpdate( int empireId )
|
||||||
|
{
|
||||||
|
return (Integer) this.fApplyResearchPriorities.execute( empireId ).get( "error_code" );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,181 @@
|
||||||
|
package com.deepclone.lw.beans.techs;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.deepclone.lw.cmd.player.research.ResearchOperationResponse;
|
||||||
|
import com.deepclone.lw.cmd.player.research.ViewResearchResponse;
|
||||||
|
import com.deepclone.lw.interfaces.game.EmpireManagement;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.EmpireTechnologyDAO;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.EmpireTechnologyManager;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.TechnologyGraphManager;
|
||||||
|
import com.deepclone.lw.interfaces.sys.ConstantDefinition;
|
||||||
|
import com.deepclone.lw.interfaces.sys.ConstantsManager;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implementation of the empire technology and research management component.
|
||||||
|
*
|
||||||
|
* @author tseeker
|
||||||
|
*/
|
||||||
|
@Transactional
|
||||||
|
public class EmpireTechnologyManagerBean
|
||||||
|
implements EmpireTechnologyManager
|
||||||
|
{
|
||||||
|
/** Empire management component */
|
||||||
|
private EmpireManagement empireManager;
|
||||||
|
|
||||||
|
/** Data access component for empire technologies and research */
|
||||||
|
private EmpireTechnologyDAO empireTechnologyDAO;
|
||||||
|
|
||||||
|
/** Technology graph management component */
|
||||||
|
private TechnologyGraphManager techGraphManager;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector for the empire management component.
|
||||||
|
*
|
||||||
|
* @param empireManager
|
||||||
|
* the empire management component
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setEmpireManager( EmpireManagement empireManager )
|
||||||
|
{
|
||||||
|
this.empireManager = empireManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector for the data access component for empire technologies and research
|
||||||
|
*
|
||||||
|
* @param empireTechnologyDAO
|
||||||
|
* data access component for empire technologies and research
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setEmpireTechnologyDAO( EmpireTechnologyDAO empireTechnologyDAO )
|
||||||
|
{
|
||||||
|
this.empireTechnologyDAO = empireTechnologyDAO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector for the technology graph management component.
|
||||||
|
*
|
||||||
|
* @param techGraphManager
|
||||||
|
* the technology graph management component
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setTechnologyGraphManager( TechnologyGraphManager techGraphManager )
|
||||||
|
{
|
||||||
|
this.techGraphManager = techGraphManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector which registers research-related constants into the constants manager.
|
||||||
|
*
|
||||||
|
* @param constantsManager
|
||||||
|
* the constants manager component
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setConstantsManager( ConstantsManager constantsManager )
|
||||||
|
{
|
||||||
|
ConstantDefinition[] definitions = new ConstantDefinition[] {
|
||||||
|
new ConstantDefinition( "game.research.minPoints" , "Research" ,
|
||||||
|
"Minimal research points before a technology being researched is identified" , 50000.0 , 1.0 ,
|
||||||
|
true ) ,
|
||||||
|
new ConstantDefinition( "game.research.minRatio" , "Research" ,
|
||||||
|
"Minimal ratio before a technology being researched is identified" , 0.75 , 0.01 , 0.99 ) ,
|
||||||
|
new ConstantDefinition( "game.research.perPopUnit" , "Research" ,
|
||||||
|
"Research points per population unit." , 0.50 , 0.01 , true )
|
||||||
|
};
|
||||||
|
constantsManager.registerConstants( Arrays.asList( definitions ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in EmpireTechnologyManager interface */
|
||||||
|
@Override
|
||||||
|
public ViewResearchResponse getResearchData( int empireId )
|
||||||
|
{
|
||||||
|
return new ResearchResponseBuilder( empireId , this.empireManager , this.empireTechnologyDAO ,
|
||||||
|
this.techGraphManager ).getResponse( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in EmpireTechnologyManager interface */
|
||||||
|
@Override
|
||||||
|
public ResearchOperationResponse implementTechnology( int empireId , String technology )
|
||||||
|
{
|
||||||
|
int result = this.empireTechnologyDAO.implementTechnology( empireId , technology );
|
||||||
|
ResearchOperationResponse response;
|
||||||
|
|
||||||
|
if ( result == 0 ) {
|
||||||
|
response = new ResearchOperationResponse( );
|
||||||
|
} else {
|
||||||
|
ResearchResponseBuilder builder = new ResearchResponseBuilder( empireId , this.empireManager ,
|
||||||
|
this.empireTechnologyDAO , this.techGraphManager );
|
||||||
|
switch ( result ) {
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
response = builder.getResponse( ResearchOperationResponse.Result.ERR_RESOURCES );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
response = builder.getResponse( ResearchOperationResponse.Result.ERR_STATE_CHANGED );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new RuntimeException( "unsupported return value " + result );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in EmpireTechnologyManager interface */
|
||||||
|
@Override
|
||||||
|
public ResearchOperationResponse setResearchPriorities( int empireId , Map< String , Integer > priorities )
|
||||||
|
{
|
||||||
|
int result;
|
||||||
|
if ( priorities.size( ) < 2 ) {
|
||||||
|
result = 2;
|
||||||
|
} else {
|
||||||
|
this.empireTechnologyDAO.startPrioritiesUpdate( );
|
||||||
|
this.empireTechnologyDAO.uploadPriorities( priorities );
|
||||||
|
result = this.empireTechnologyDAO.finishPrioritiesUpdate( empireId );
|
||||||
|
}
|
||||||
|
|
||||||
|
ResearchOperationResponse response;
|
||||||
|
if ( result == 0 ) {
|
||||||
|
response = new ResearchOperationResponse( );
|
||||||
|
} else {
|
||||||
|
ResearchResponseBuilder builder = new ResearchResponseBuilder( empireId , this.empireManager ,
|
||||||
|
this.empireTechnologyDAO , this.techGraphManager );
|
||||||
|
|
||||||
|
switch ( result ) {
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
response = builder.getResponse( ResearchOperationResponse.Result.ERR_STATE_CHANGED );
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
response = builder.getResponse( ResearchOperationResponse.Result.ERR_INVALID );
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new RuntimeException( "unsupported return value " + result );
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,293 @@
|
||||||
|
package com.deepclone.lw.beans.techs;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import com.deepclone.lw.cmd.admin.logs.LogLevel;
|
||||||
|
import com.deepclone.lw.interfaces.eventlog.SystemLogger;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.ResearchStatus;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.ResearchUpdateInput;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.ResearchUpdateOutput;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.TechGraph;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.TechGraphException;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.Technology;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Research update implementation for a single empire.
|
||||||
|
*
|
||||||
|
* @author tseeker
|
||||||
|
*/
|
||||||
|
class EmpireUpdate
|
||||||
|
{
|
||||||
|
/** Empire identifier */
|
||||||
|
private final int id;
|
||||||
|
|
||||||
|
/** Research points produced */
|
||||||
|
private double production;
|
||||||
|
|
||||||
|
/** All technologies (known or being researched) */
|
||||||
|
private final Map< String , ResearchUpdateInput > byName;
|
||||||
|
|
||||||
|
/** Technology names by status */
|
||||||
|
private final Map< ResearchStatus , Set< String >> byStatus;
|
||||||
|
|
||||||
|
/** Output records by name */
|
||||||
|
private final Map< String , ResearchUpdateOutput > output;
|
||||||
|
|
||||||
|
/** Sum of the current research priorities */
|
||||||
|
private double totalPriority;
|
||||||
|
|
||||||
|
/** Amount of active research topics */
|
||||||
|
private int activeTopics;
|
||||||
|
|
||||||
|
/** Parent component's logging interface */
|
||||||
|
private SystemLogger logger;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the empire updater using the global lists of production points and research
|
||||||
|
* statuses.
|
||||||
|
*
|
||||||
|
* @param logger
|
||||||
|
* the component's logging system
|
||||||
|
* @param empireId
|
||||||
|
* the empire for whom the research update is to be computed
|
||||||
|
* @param production
|
||||||
|
* the map of production points for all empires in the batch
|
||||||
|
* @param status
|
||||||
|
* the list of statuses for all empires in the batch
|
||||||
|
*/
|
||||||
|
EmpireUpdate( SystemLogger logger , int empireId , Map< Integer , Double > production ,
|
||||||
|
HashMap< Integer , List< ResearchUpdateInput >> status )
|
||||||
|
{
|
||||||
|
this.id = empireId;
|
||||||
|
this.production = production.get( this.id );
|
||||||
|
this.logger = logger;
|
||||||
|
|
||||||
|
this.byName = new HashMap< String , ResearchUpdateInput >( );
|
||||||
|
this.output = new HashMap< String , ResearchUpdateOutput >( );
|
||||||
|
|
||||||
|
this.byStatus = new EnumMap< ResearchStatus , Set< String > >( ResearchStatus.class );
|
||||||
|
this.byStatus.put( ResearchStatus.IN_PROGRESS , new HashSet< String >( ) );
|
||||||
|
this.byStatus.put( ResearchStatus.RESEARCHED , new HashSet< String >( ) );
|
||||||
|
this.byStatus.put( ResearchStatus.IMPLEMENTED , new HashSet< String >( ) );
|
||||||
|
|
||||||
|
// Initialise sets and maps
|
||||||
|
List< ResearchUpdateInput > empStatus = status.get( this.id );
|
||||||
|
if ( empStatus != null ) {
|
||||||
|
for ( ResearchUpdateInput entry : status.get( this.id ) ) {
|
||||||
|
this.byName.put( entry.getTechnology( ) , entry );
|
||||||
|
this.byStatus.get( entry.getStatus( ) ).add( entry.getTechnology( ) );
|
||||||
|
}
|
||||||
|
this.logger.flush( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform the research update, filling the {@link #output} map.
|
||||||
|
*
|
||||||
|
* @param techGraph
|
||||||
|
* the technology graph
|
||||||
|
* @throws TechGraphException
|
||||||
|
* indicates an internal error
|
||||||
|
*/
|
||||||
|
void compute( TechGraph techGraph )
|
||||||
|
throws TechGraphException
|
||||||
|
{
|
||||||
|
if ( this.production == 0 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.prepareOutput( );
|
||||||
|
|
||||||
|
List< Technology > newResearch = this.findNewTechnologies( techGraph );
|
||||||
|
if ( !newResearch.isEmpty( ) ) {
|
||||||
|
this.addResearch( newResearch );
|
||||||
|
}
|
||||||
|
if ( this.output.isEmpty( ) ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List< String > inProgress = new LinkedList< String >( this.output.keySet( ) );
|
||||||
|
for ( String resName : inProgress ) {
|
||||||
|
this.researchProgress( techGraph.getTechnology( resName ) , resName );
|
||||||
|
}
|
||||||
|
|
||||||
|
this.updatePriorities( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy information from the list of research to the output map.
|
||||||
|
*/
|
||||||
|
private void prepareOutput( )
|
||||||
|
{
|
||||||
|
this.totalPriority = 0;
|
||||||
|
for ( ResearchUpdateInput entry : this.byName.values( ) ) {
|
||||||
|
if ( entry.getStatus( ) != ResearchStatus.IN_PROGRESS ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
this.output.put( entry.getTechnology( ) , new ResearchUpdateOutput( this.id , entry.getTechnology( ) ,
|
||||||
|
false , entry.getPoints( ) , entry.getPriority( ) ) );
|
||||||
|
this.totalPriority += entry.getPriority( );
|
||||||
|
}
|
||||||
|
this.activeTopics = this.byStatus.get( ResearchStatus.IN_PROGRESS ).size( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find new technologies to research
|
||||||
|
*
|
||||||
|
* XXX: we shouldn't be doing that at every update; it's only required if the techs were added
|
||||||
|
* or deleted, if dependencies were changed or if the empire implemented a technology.
|
||||||
|
*
|
||||||
|
* @param techGraph
|
||||||
|
* the technology graph
|
||||||
|
* @return the list of technologies on which research can start
|
||||||
|
* @throws TechGraphException
|
||||||
|
* indicates an internal error
|
||||||
|
*/
|
||||||
|
private List< Technology > findNewTechnologies( TechGraph techGraph )
|
||||||
|
throws TechGraphException
|
||||||
|
{
|
||||||
|
LinkedList< Technology > newResearch = new LinkedList< Technology >( );
|
||||||
|
Set< String > implemented = this.byStatus.get( ResearchStatus.IMPLEMENTED );
|
||||||
|
if ( implemented == null ) {
|
||||||
|
throw new RuntimeException( "wtf?!" );
|
||||||
|
}
|
||||||
|
for ( String catName : techGraph.getCategories( ) ) {
|
||||||
|
for ( String techName : techGraph.getCategory( catName ).getTechnologies( ) ) {
|
||||||
|
// Check if the empire "knows" of the tech
|
||||||
|
if ( this.byName.containsKey( techName ) ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check dependencies
|
||||||
|
Technology tech = techGraph.getTechnology( techName );
|
||||||
|
boolean mayStart = true;
|
||||||
|
for ( String depName : tech.getDependencies( ) ) {
|
||||||
|
if ( !implemented.contains( depName ) ) {
|
||||||
|
mayStart = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( mayStart ) {
|
||||||
|
newResearch.add( tech );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return newResearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add new entries to the list of current research topics and updates the total priority
|
||||||
|
* accordingly.
|
||||||
|
*
|
||||||
|
* @param newResearch
|
||||||
|
* the list of research topics to add
|
||||||
|
*/
|
||||||
|
private void addResearch( List< Technology > newResearch )
|
||||||
|
{
|
||||||
|
int increment;
|
||||||
|
if ( this.totalPriority == 0 ) {
|
||||||
|
increment = 1;
|
||||||
|
} else {
|
||||||
|
increment = (int) Math.ceil( this.totalPriority / this.activeTopics );
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( Technology tech : newResearch ) {
|
||||||
|
this.output.put( tech.getName( ) , new ResearchUpdateOutput( this.id , tech.getName( ) , true , 0 ,
|
||||||
|
increment ) );
|
||||||
|
this.totalPriority += increment;
|
||||||
|
}
|
||||||
|
this.activeTopics += newResearch.size( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update the progress on a research topic.
|
||||||
|
*
|
||||||
|
* @param technology
|
||||||
|
* the technology's definition
|
||||||
|
* @param name
|
||||||
|
* the name of the research topic
|
||||||
|
*/
|
||||||
|
private void researchProgress( Technology technology , String name )
|
||||||
|
{
|
||||||
|
ResearchUpdateOutput entry = this.output.get( name );
|
||||||
|
if ( entry.getPriority( ) == 0 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
double points = this.production * entry.getPriority( ) / this.totalPriority;
|
||||||
|
double total = points + entry.getPoints( );
|
||||||
|
|
||||||
|
if ( total >= technology.getPoints( ) ) {
|
||||||
|
this.totalPriority -= entry.getPriority( );
|
||||||
|
this.production = this.production + total - entry.getPoints( );
|
||||||
|
this.output.put( name , new ResearchUpdateOutput( this.id , name ) );
|
||||||
|
this.activeTopics--;
|
||||||
|
} else {
|
||||||
|
entry.addPoints( points );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update priorities of active research topics in the output map.
|
||||||
|
*/
|
||||||
|
private void updatePriorities( )
|
||||||
|
{
|
||||||
|
if ( this.activeTopics == 0 || this.totalPriority == 100 ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List< ResearchUpdateOutput > progress = new LinkedList< ResearchUpdateOutput >( );
|
||||||
|
int newTotal = 0;
|
||||||
|
for ( ResearchUpdateOutput update : this.output.values( ) ) {
|
||||||
|
Integer prio = update.getPriority( );
|
||||||
|
if ( prio == null ) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
int newValue = (int) Math.floor( 100.0 * prio / this.totalPriority );
|
||||||
|
progress.add( update );
|
||||||
|
update.setPriority( newValue );
|
||||||
|
newTotal += newValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Distribute the rest of the points
|
||||||
|
while ( newTotal < 100 ) {
|
||||||
|
for ( ResearchUpdateOutput update : progress ) {
|
||||||
|
update.setPriority( update.getPriority( ) + 1 );
|
||||||
|
newTotal++;
|
||||||
|
if ( newTotal == 100 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.logger.flush( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** @return the update output records */
|
||||||
|
Collection< ResearchUpdateOutput > getOutput( )
|
||||||
|
{
|
||||||
|
if ( !this.output.isEmpty( ) ) {
|
||||||
|
this.logger.log( LogLevel.TRACE , "Empire " + this.id + " - " + this.output.size( ) + " update(s)" )
|
||||||
|
.flush( );
|
||||||
|
}
|
||||||
|
return this.output.values( );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,280 @@
|
||||||
|
package com.deepclone.lw.beans.techs;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.deepclone.lw.cmd.player.gdata.GamePageData;
|
||||||
|
import com.deepclone.lw.cmd.player.gdata.empire.ResearchData;
|
||||||
|
import com.deepclone.lw.cmd.player.gdata.empire.TechnologyCategoryData;
|
||||||
|
import com.deepclone.lw.cmd.player.gdata.empire.TechnologyData;
|
||||||
|
import com.deepclone.lw.cmd.player.research.ResearchOperationResponse;
|
||||||
|
import com.deepclone.lw.cmd.player.research.ViewResearchResponse;
|
||||||
|
import com.deepclone.lw.cmd.player.research.ResearchOperationResponse.Result;
|
||||||
|
import com.deepclone.lw.interfaces.game.EmpireManagement;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.EmpireTechnologyDAO;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.TechnologyGraphManager;
|
||||||
|
import com.deepclone.lw.interfaces.i18n.LanguageTranslator;
|
||||||
|
import com.deepclone.lw.interfaces.i18n.UnknownStringException;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.Category;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.EmpireTechnology;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.ResearchStatus;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.TechGraph;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.TechGraphException;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.Technology;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class that builds {@link ViewResearchResponse} or {@link ResearchOperationResponse} instances.
|
||||||
|
*
|
||||||
|
* @author tseeker
|
||||||
|
*/
|
||||||
|
class ResearchResponseBuilder
|
||||||
|
{
|
||||||
|
|
||||||
|
/** Empire identifier */
|
||||||
|
private final int empireId;
|
||||||
|
|
||||||
|
/** Empire management component */
|
||||||
|
private final EmpireManagement empireManager;
|
||||||
|
|
||||||
|
/** Technology and research data access component */
|
||||||
|
private final EmpireTechnologyDAO empireTechnologyDAO;
|
||||||
|
|
||||||
|
/** Technology graph management component */
|
||||||
|
private final TechnologyGraphManager techGraphManager;
|
||||||
|
|
||||||
|
/** Game page data */
|
||||||
|
private GamePageData pageData;
|
||||||
|
|
||||||
|
/** List of current research topics */
|
||||||
|
private List< ResearchData > research;
|
||||||
|
|
||||||
|
/** Lists of implemented technologies by category */
|
||||||
|
private Map< String , List< TechnologyData > > implementedMap;
|
||||||
|
|
||||||
|
/** Final list of implemented technologies */
|
||||||
|
private List< TechnologyCategoryData > implementedLists;
|
||||||
|
|
||||||
|
/** All implemented technologies by identifier */
|
||||||
|
private Map< String , TechnologyData > implementedById;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the response builder by setting the empire identifier and the various components
|
||||||
|
* that may be required to generate the response.
|
||||||
|
*
|
||||||
|
* @param empireId
|
||||||
|
* the empire identifier
|
||||||
|
* @param empireManager
|
||||||
|
* the empire management component
|
||||||
|
* @param empireTechnologyDAO
|
||||||
|
* the technology and research data access component
|
||||||
|
* @param techGraphManager
|
||||||
|
* the technology graph management component
|
||||||
|
*/
|
||||||
|
ResearchResponseBuilder( int empireId , EmpireManagement empireManager , EmpireTechnologyDAO empireTechnologyDAO ,
|
||||||
|
TechnologyGraphManager techGraphManager )
|
||||||
|
{
|
||||||
|
this.empireId = empireId;
|
||||||
|
this.empireManager = empireManager;
|
||||||
|
this.empireTechnologyDAO = empireTechnologyDAO;
|
||||||
|
this.techGraphManager = techGraphManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a basic research view response.
|
||||||
|
*
|
||||||
|
* @return the research view response.
|
||||||
|
*/
|
||||||
|
ViewResearchResponse getResponse( )
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
this.buildResponseContents( );
|
||||||
|
} catch ( Exception e ) {
|
||||||
|
throw new RuntimeException( "internal error while processing research data" , e );
|
||||||
|
}
|
||||||
|
return new ViewResearchResponse( this.pageData , this.research , this.implementedLists );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build a research operation response.
|
||||||
|
*
|
||||||
|
* @param errorCode
|
||||||
|
* the operation's error code (should not be
|
||||||
|
* {@link ResearchOperationResponse.Result#OK}).
|
||||||
|
* @return the research operation response.
|
||||||
|
*/
|
||||||
|
ResearchOperationResponse getResponse( Result errorCode )
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
this.buildResponseContents( );
|
||||||
|
} catch ( Exception e ) {
|
||||||
|
throw new RuntimeException( "internal error while processing research data" , e );
|
||||||
|
}
|
||||||
|
return new ResearchOperationResponse( this.pageData , this.research , this.implementedLists , errorCode );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the lists and records required by research view or operation responses. This includes
|
||||||
|
* the list of current research topics as well as the list of implemented technologies.
|
||||||
|
*
|
||||||
|
* @throws UnknownStringException
|
||||||
|
* if there is an incoherence between the tech graph and the translations database.
|
||||||
|
* @throws TechGraphException
|
||||||
|
* if there is an incoherence between the empire research records and the tech
|
||||||
|
* graph.
|
||||||
|
*/
|
||||||
|
private void buildResponseContents( )
|
||||||
|
throws UnknownStringException , TechGraphException
|
||||||
|
{
|
||||||
|
LanguageTranslator translator = this.empireManager.getTranslator( this.empireId );
|
||||||
|
TechGraph techGraph = this.techGraphManager.getGraph( );
|
||||||
|
|
||||||
|
this.research = new LinkedList< ResearchData >( );
|
||||||
|
this.implementedMap = new HashMap< String , List< TechnologyData > >( );
|
||||||
|
this.implementedById = new HashMap< String , TechnologyData >( );
|
||||||
|
|
||||||
|
for ( EmpireTechnology record : this.empireTechnologyDAO.getTechnologies( this.empireId ) ) {
|
||||||
|
if ( record.getStatus( ) == ResearchStatus.IMPLEMENTED ) {
|
||||||
|
this.addImplemented( record , translator , techGraph );
|
||||||
|
} else {
|
||||||
|
this.addResearchData( record , translator , techGraph );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.pageData = this.empireManager.getGeneralInformation( this.empireId );
|
||||||
|
Collections.sort( this.research );
|
||||||
|
this.postProcessImplemented( translator , techGraph );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an implemented technology record.
|
||||||
|
*
|
||||||
|
* @param record
|
||||||
|
* the original record as returned by the {@link EmpireTechnologyDAO}.
|
||||||
|
* @param translator
|
||||||
|
* the translator for the empire's language
|
||||||
|
* @param techGraph
|
||||||
|
* the technology graph
|
||||||
|
*
|
||||||
|
* @throws TechGraphException
|
||||||
|
* if there is an incoherence between the empire research records and the tech
|
||||||
|
* graph.
|
||||||
|
* @throws UnknownStringException
|
||||||
|
* if there is an incoherence between the tech graph and the translations database.
|
||||||
|
*/
|
||||||
|
private void addImplemented( EmpireTechnology record , LanguageTranslator translator , TechGraph techGraph )
|
||||||
|
throws TechGraphException , UnknownStringException
|
||||||
|
{
|
||||||
|
String techId = record.getIdentifier( );
|
||||||
|
Technology tech = techGraph.getTechnology( techId );
|
||||||
|
Category category = tech.getCategory( );
|
||||||
|
|
||||||
|
List< TechnologyData > catTechs = this.implementedMap.get( category.getName( ) );
|
||||||
|
if ( catTechs == null ) {
|
||||||
|
catTechs = new LinkedList< TechnologyData >( );
|
||||||
|
this.implementedMap.put( category.getName( ) , catTechs );
|
||||||
|
}
|
||||||
|
|
||||||
|
TechnologyData tData;
|
||||||
|
String name = translator.translate( techId );
|
||||||
|
String description = translator.translate( tech.getDescription( ) );
|
||||||
|
tData = new TechnologyData( techId , name , description , tech.getDependencies( ) , new LinkedList< String >( ) );
|
||||||
|
|
||||||
|
catTechs.add( tData );
|
||||||
|
this.implementedById.put( techId , tData );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a research topic record.
|
||||||
|
*
|
||||||
|
* @param record
|
||||||
|
* the original record as returned by the {@link EmpireTechnologyDAO}.
|
||||||
|
* @param translator
|
||||||
|
* the translator for the empire's language
|
||||||
|
* @param techGraph
|
||||||
|
* the technology graph
|
||||||
|
*
|
||||||
|
* @throws TechGraphException
|
||||||
|
* if there is an incoherence between the empire research records and the tech
|
||||||
|
* graph.
|
||||||
|
* @throws UnknownStringException
|
||||||
|
* if there is an incoherence between the tech graph and the translations database.
|
||||||
|
*/
|
||||||
|
private void addResearchData( EmpireTechnology record , LanguageTranslator translator , TechGraph techGraph )
|
||||||
|
throws TechGraphException , UnknownStringException
|
||||||
|
{
|
||||||
|
String techId = record.getIdentifier( );
|
||||||
|
Technology tech = techGraph.getTechnology( techId );
|
||||||
|
String category = translator.translate( tech.getCategory( ).getName( ) );
|
||||||
|
|
||||||
|
ResearchData rData;
|
||||||
|
|
||||||
|
if ( !record.isDetailed( ) ) {
|
||||||
|
rData = new ResearchData( record.getNumericId( ) , category , record.getPercentage( ) , record
|
||||||
|
.getPriority( ) );
|
||||||
|
} else {
|
||||||
|
String name = translator.translate( techId );
|
||||||
|
String description = translator.translate( tech.getDescription( ) );
|
||||||
|
String[] dependencies = tech.getDependencies( ).toArray( new String[] { } );
|
||||||
|
if ( record.getStatus( ) == ResearchStatus.RESEARCHED ) {
|
||||||
|
rData = new ResearchData( techId , category , name , description , dependencies , (int) tech.getCost( ) );
|
||||||
|
} else {
|
||||||
|
rData = new ResearchData( techId , category , name , description , dependencies , record
|
||||||
|
.getPercentage( ) , record.getPriority( ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.research.add( rData );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Post-process implemented technologies by adding reverse dependencies, sorting each list, and
|
||||||
|
* generating the sorted list of technology categories.
|
||||||
|
*
|
||||||
|
* @param translator
|
||||||
|
* the translator for the empire's language
|
||||||
|
* @param techGraph
|
||||||
|
* the technology graph
|
||||||
|
*
|
||||||
|
* @throws TechGraphException
|
||||||
|
* if there is an incoherence between the empire research records and the tech
|
||||||
|
* graph.
|
||||||
|
* @throws UnknownStringException
|
||||||
|
* if there is an incoherence between the tech graph and the translations database.
|
||||||
|
*/
|
||||||
|
private void postProcessImplemented( LanguageTranslator translator , TechGraph techGraph )
|
||||||
|
throws UnknownStringException , TechGraphException
|
||||||
|
{
|
||||||
|
this.implementedLists = new LinkedList< TechnologyCategoryData >( );
|
||||||
|
for ( String catId : this.implementedMap.keySet( ) ) {
|
||||||
|
|
||||||
|
List< TechnologyData > techs = this.implementedMap.get( catId );
|
||||||
|
for ( TechnologyData tData : techs ) {
|
||||||
|
for ( String dependency : tData.getDependsOn( ) ) {
|
||||||
|
TechnologyData depData = this.implementedById.get( dependency );
|
||||||
|
if ( depData != null ) {
|
||||||
|
depData.getDependencyOf( ).add( tData.getIdentifier( ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort( techs );
|
||||||
|
|
||||||
|
String catName = translator.translate( catId );
|
||||||
|
String catDesc = translator.translate( techGraph.getCategory( catId ).getDescription( ) );
|
||||||
|
this.implementedLists.add( new TechnologyCategoryData( catName , catDesc , techs ) );
|
||||||
|
}
|
||||||
|
Collections.sort( this.implementedLists );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,180 @@
|
||||||
|
package com.deepclone.lw.beans.techs;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import com.deepclone.lw.interfaces.eventlog.Logger;
|
||||||
|
import com.deepclone.lw.interfaces.eventlog.SystemLogger;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.ResearchUpdateDAO;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.TechnologyGraphManager;
|
||||||
|
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.sqld.game.techs.ResearchUpdateInput;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.ResearchUpdateOutput;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.TechGraph;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.TechGraphException;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component responsible for updating empires' research status.
|
||||||
|
*
|
||||||
|
* @author tseeker
|
||||||
|
*/
|
||||||
|
public class ResearchUpdateBean
|
||||||
|
implements GameUpdatePhaseHandler
|
||||||
|
{
|
||||||
|
/** The component's logging interface */
|
||||||
|
private SystemLogger logger;
|
||||||
|
|
||||||
|
/** The technology graph management component */
|
||||||
|
private TechnologyGraphManager techGraphManager;
|
||||||
|
|
||||||
|
/** The current technology graph */
|
||||||
|
private TechGraph techGraph;
|
||||||
|
|
||||||
|
/** The main game update data access component */
|
||||||
|
private UpdatesDAO updatesDAO;
|
||||||
|
|
||||||
|
/** The research updates data access component */
|
||||||
|
private ResearchUpdateDAO researchUpdateDAO;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector that initialises the component's logging interface.
|
||||||
|
*
|
||||||
|
* @param logger
|
||||||
|
* the system logger
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setLogger( Logger logger )
|
||||||
|
{
|
||||||
|
this.logger = logger.getSystemLogger( "ResearchUpdate" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector for the technology graph management component.
|
||||||
|
*
|
||||||
|
* @param techGraphManager
|
||||||
|
* the technology graph management component
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setTechGraphManager( TechnologyGraphManager techGraphManager )
|
||||||
|
{
|
||||||
|
this.techGraphManager = techGraphManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector that sets the main game update data access component.
|
||||||
|
*
|
||||||
|
* @param updatesDAO
|
||||||
|
* the main game update data access component
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setUpdatesDAO( UpdatesDAO updatesDAO )
|
||||||
|
{
|
||||||
|
this.updatesDAO = updatesDAO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector that sets the research updates data access component
|
||||||
|
*
|
||||||
|
* @param researchUpdateDAO
|
||||||
|
* the research updates data access component
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setResearchUpdateDAO( ResearchUpdateDAO researchUpdateDAO )
|
||||||
|
{
|
||||||
|
this.researchUpdateDAO = researchUpdateDAO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector that registers the handler with the main game update manager
|
||||||
|
*
|
||||||
|
* @param updateManager
|
||||||
|
* the game update manager
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setUpdateManager( GameUpdate updateManager )
|
||||||
|
{
|
||||||
|
updateManager.registerHandler( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documentation in GameUpdatePhaseHandler interface */
|
||||||
|
@Override
|
||||||
|
public GameUpdatePhase getPhase( )
|
||||||
|
{
|
||||||
|
return GameUpdatePhase.EMPIRE_RESEARCH;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a copy of the technology graph when the update phase starts.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onPhaseStart( long updateId )
|
||||||
|
{
|
||||||
|
this.techGraph = this.techGraphManager.getGraph( );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If there are research updates left to process, lock the records, then obtain all relevant
|
||||||
|
* data, process each empire using {@link EmpireUpdate}, and send the updates to the database.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public boolean updateGame( long updateId )
|
||||||
|
{
|
||||||
|
// Look for records to update
|
||||||
|
if ( !this.updatesDAO.prepareUpdates( updateId , this.getPhase( ) ) ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map< Integer , Double > production;
|
||||||
|
HashMap< Integer , List< ResearchUpdateInput >> status;
|
||||||
|
status = new HashMap< Integer , List< ResearchUpdateInput > >( );
|
||||||
|
|
||||||
|
// Prepare update and load input
|
||||||
|
this.researchUpdateDAO.prepareUpdate( updateId );
|
||||||
|
production = this.researchUpdateDAO.getResearchPoints( updateId );
|
||||||
|
for ( ResearchUpdateInput input : this.researchUpdateDAO.getUpdateData( updateId ) ) {
|
||||||
|
List< ResearchUpdateInput > eStatus = status.get( input.getEmpireId( ) );
|
||||||
|
if ( eStatus == null ) {
|
||||||
|
eStatus = new LinkedList< ResearchUpdateInput >( );
|
||||||
|
status.put( input.getEmpireId( ) , eStatus );
|
||||||
|
}
|
||||||
|
eStatus.add( input );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle the update for each empire
|
||||||
|
List< ResearchUpdateOutput > output = new LinkedList< ResearchUpdateOutput >( );
|
||||||
|
for ( int empireId : production.keySet( ) ) {
|
||||||
|
EmpireUpdate update = new EmpireUpdate( this.logger , empireId , production , status );
|
||||||
|
try {
|
||||||
|
update.compute( this.techGraph );
|
||||||
|
} catch ( TechGraphException e ) {
|
||||||
|
throw new RuntimeException( "incoherent technology graph" , e );
|
||||||
|
}
|
||||||
|
output.addAll( update.getOutput( ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send and validate updates
|
||||||
|
this.researchUpdateDAO.submitUpdateData( output );
|
||||||
|
this.updatesDAO.validateUpdatedRecords( updateId , GameUpdatePhase.EMPIRE_RESEARCH );
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,138 @@
|
||||||
|
package com.deepclone.lw.beans.techs;
|
||||||
|
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.sql.Types;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.jdbc.core.RowMapper;
|
||||||
|
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
|
||||||
|
import org.springframework.jdbc.core.namedparam.SqlParameterSourceUtils;
|
||||||
|
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
|
||||||
|
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.ResearchUpdateDAO;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.ResearchUpdateInput;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.ResearchUpdateOutput;
|
||||||
|
import com.deepclone.lw.utils.StoredProc;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class ResearchUpdateDAOBean
|
||||||
|
implements ResearchUpdateDAO
|
||||||
|
{
|
||||||
|
/** Query that reads research update input */
|
||||||
|
private static final String qGetInput = "SELECT * FROM emp.research_update_input_view WHERE update_id = ?";
|
||||||
|
|
||||||
|
/** Query that reads empire research points production */
|
||||||
|
private static final String qGetPoints = "SELECT * FROM emp.research_points_production WHERE update_id = ?";
|
||||||
|
|
||||||
|
/** Query that adds a record to the output */
|
||||||
|
private static final String qAddOutput = "INSERT INTO research_update_output "
|
||||||
|
+ "(empire_id , technology , creation , points , priority) "
|
||||||
|
+ "VALUES ( :empireId , :technology , :creation , :points , :priority )";
|
||||||
|
|
||||||
|
/** Query that submits the update */
|
||||||
|
private static final String qSubmitUpdate = "SELECT emp.submit_research_update( )";
|
||||||
|
|
||||||
|
/** Data source access */
|
||||||
|
private SimpleJdbcTemplate dTemplate;
|
||||||
|
|
||||||
|
/** Wrapper for the stored procedure that prepares the database for update */
|
||||||
|
private StoredProc fPrepareUpdate;
|
||||||
|
|
||||||
|
/** Row mapper for research update input */
|
||||||
|
RowMapper< ResearchUpdateInput > ruiMapper;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the component's row mapper.
|
||||||
|
*/
|
||||||
|
public ResearchUpdateDAOBean( )
|
||||||
|
{
|
||||||
|
this.ruiMapper = new RowMapper< ResearchUpdateInput >( ) {
|
||||||
|
@Override
|
||||||
|
public ResearchUpdateInput mapRow( ResultSet rs , int rowNum )
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
int empireId = rs.getInt( "empire_id" );
|
||||||
|
String technology = rs.getString( "technology" );
|
||||||
|
|
||||||
|
Boolean implemented = (Boolean) rs.getObject( "implemented" );
|
||||||
|
if ( implemented == null ) {
|
||||||
|
double points = rs.getDouble( "points" );
|
||||||
|
int priority = rs.getInt( "priority" );
|
||||||
|
return new ResearchUpdateInput( empireId , technology , points , priority );
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ResearchUpdateInput( empireId , technology , implemented );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dependency injector that initialises the component's database access and stored procedure
|
||||||
|
* wrappers.
|
||||||
|
*
|
||||||
|
* @param dataSource
|
||||||
|
* the data source
|
||||||
|
*/
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setDataSource( DataSource dataSource )
|
||||||
|
{
|
||||||
|
this.dTemplate = new SimpleJdbcTemplate( dataSource );
|
||||||
|
|
||||||
|
// Stored procedure that prepares the database for update
|
||||||
|
this.fPrepareUpdate = new StoredProc( dataSource , "emp" , "prepare_research_update" );
|
||||||
|
this.fPrepareUpdate.addParameter( "update_id" , Types.BIGINT );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documented in ResearchUpdateDAO interface */
|
||||||
|
@Override
|
||||||
|
public void prepareUpdate( long updateId )
|
||||||
|
{
|
||||||
|
this.fPrepareUpdate.execute( updateId );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documented in ResearchUpdateDAO interface */
|
||||||
|
@Override
|
||||||
|
public List< ResearchUpdateInput > getUpdateData( long updateId )
|
||||||
|
{
|
||||||
|
return this.dTemplate.query( qGetInput , this.ruiMapper , updateId );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documented in ResearchUpdateDAO interface */
|
||||||
|
@Override
|
||||||
|
public Map< Integer , Double > getResearchPoints( long updateId )
|
||||||
|
{
|
||||||
|
Map< Integer , Double > result = new HashMap< Integer , Double >( );
|
||||||
|
|
||||||
|
for ( Map< String , Object > row : this.dTemplate.queryForList( qGetPoints , updateId ) ) {
|
||||||
|
result.put( (Integer) row.get( "empire_id" ) , (Double) row.get( "points" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documented in ResearchUpdateDAO interface */
|
||||||
|
@Override
|
||||||
|
public void submitUpdateData( List< ResearchUpdateOutput > output )
|
||||||
|
{
|
||||||
|
if ( !output.isEmpty( ) ) {
|
||||||
|
SqlParameterSource[] batch = SqlParameterSourceUtils.createBatch( output.toArray( ) );
|
||||||
|
this.dTemplate.batchUpdate( qAddOutput , batch );
|
||||||
|
}
|
||||||
|
this.dTemplate.queryForList( qSubmitUpdate );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,134 @@
|
||||||
|
package com.deepclone.lw.beans.techs;
|
||||||
|
|
||||||
|
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.jdbc.core.JdbcTemplate;
|
||||||
|
import org.springframework.jdbc.core.RowCallbackHandler;
|
||||||
|
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.TechnologyGraphDAO;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.TechGraph;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.TechGraphException;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class TechnologyGraphDAOBean
|
||||||
|
implements TechnologyGraphDAO
|
||||||
|
{
|
||||||
|
private static final String qGetCategories = "SELECT name , description FROM tech.categories_view";
|
||||||
|
private static final String qGetTechnologies = "SELECT category , name , description , points , cost FROM tech.technologies_view";
|
||||||
|
private static final String qGetDependencies = "SELECT technology , dependency FROM tech.dependencies_view";
|
||||||
|
|
||||||
|
private static abstract class TechGraphDBHandler
|
||||||
|
implements RowCallbackHandler
|
||||||
|
{
|
||||||
|
TechGraph graph;
|
||||||
|
TechGraphException error;
|
||||||
|
|
||||||
|
|
||||||
|
public TechGraphDBHandler( )
|
||||||
|
{
|
||||||
|
// EMPTY
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public final void setGraph( TechGraph graph )
|
||||||
|
{
|
||||||
|
this.graph = graph;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final void processRow( ResultSet rs )
|
||||||
|
throws SQLException
|
||||||
|
{
|
||||||
|
if ( this.error != null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.extractData( rs );
|
||||||
|
} catch ( TechGraphException e ) {
|
||||||
|
this.error = e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected abstract void extractData( ResultSet rs )
|
||||||
|
throws TechGraphException , SQLException;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class CategoryExtractor
|
||||||
|
extends TechGraphDBHandler
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void extractData( ResultSet rs )
|
||||||
|
throws TechGraphException , SQLException
|
||||||
|
{
|
||||||
|
this.graph.addCategory( rs.getString( "name" ) , rs.getString( "description" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TechnologyExtractor
|
||||||
|
extends TechGraphDBHandler
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void extractData( ResultSet rs )
|
||||||
|
throws TechGraphException , SQLException
|
||||||
|
{
|
||||||
|
this.graph.addTechnology( rs.getString( "category" ) , rs.getString( "name" ) , rs
|
||||||
|
.getString( "description" ) , rs.getInt( "points" ) , rs.getInt( "cost" ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DependencyExtractor
|
||||||
|
extends TechGraphDBHandler
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
protected void extractData( ResultSet rs )
|
||||||
|
throws TechGraphException , SQLException
|
||||||
|
{
|
||||||
|
this.graph.addDependency( rs.getString( "technology" ) , rs.getString( "dependency" ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private JdbcTemplate dTemplate;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setDataSource( DataSource dataSource )
|
||||||
|
{
|
||||||
|
this.dTemplate = new JdbcTemplate( dataSource );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TechGraph loadGraph( )
|
||||||
|
throws TechGraphException
|
||||||
|
{
|
||||||
|
TechGraph result = new TechGraph( );
|
||||||
|
this.extractGraphData( result , new CategoryExtractor( ) , qGetCategories );
|
||||||
|
this.extractGraphData( result , new TechnologyExtractor( ) , qGetTechnologies );
|
||||||
|
this.extractGraphData( result , new DependencyExtractor( ) , qGetDependencies );
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void extractGraphData( TechGraph graph , TechGraphDBHandler extractor , String query )
|
||||||
|
throws TechGraphException
|
||||||
|
{
|
||||||
|
extractor.setGraph( graph );
|
||||||
|
this.dTemplate.query( query , extractor );
|
||||||
|
if ( extractor.error != null ) {
|
||||||
|
throw extractor.error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,74 @@
|
||||||
|
package com.deepclone.lw.beans.techs;
|
||||||
|
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import com.deepclone.lw.cmd.admin.techs.TechCategory;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.TechnologyGraphDAO;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.TechnologyGraphManager;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.Category;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.TechGraph;
|
||||||
|
import com.deepclone.lw.sqld.game.techs.TechGraphException;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public class TechnologyGraphManagerBean
|
||||||
|
implements TechnologyGraphManager
|
||||||
|
{
|
||||||
|
private TechGraph graph;
|
||||||
|
private TechnologyGraphDAO technologyGraphDAO;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setTechGraphDAO( TechnologyGraphDAO technologyGraphDAO )
|
||||||
|
{
|
||||||
|
this.technologyGraphDAO = technologyGraphDAO;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void loadGraph( )
|
||||||
|
throws TechGraphException
|
||||||
|
{
|
||||||
|
if ( this.graph == null ) {
|
||||||
|
this.graph = this.technologyGraphDAO.loadGraph( );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documented in TechnologyGraphManager interface */
|
||||||
|
@Override
|
||||||
|
public TechGraph getGraph( )
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
this.loadGraph( );
|
||||||
|
} catch ( TechGraphException e ) {
|
||||||
|
throw new RuntimeException( e );
|
||||||
|
}
|
||||||
|
return new TechGraph( this.graph );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Documented in TechnologyGraphManager interface */
|
||||||
|
@Override
|
||||||
|
public List< TechCategory > listCategories( )
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
this.loadGraph( );
|
||||||
|
|
||||||
|
List< TechCategory > result = new LinkedList< TechCategory >( );
|
||||||
|
for ( String catName : this.graph.getCategories( ) ) {
|
||||||
|
Category cat = this.graph.getCategory( catName );
|
||||||
|
result.add( new TechCategory( catName , cat.getDescription( ) , cat.getTechnologies( ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch ( TechGraphException e ) {
|
||||||
|
throw new RuntimeException( e );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?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="techs/empire-technology-dao-bean.xml" />
|
||||||
|
<import resource="techs/empire-technology-manager-bean.xml" />
|
||||||
|
<import resource="techs/research-update-bean.xml" />
|
||||||
|
<import resource="techs/research-update-dao-bean.xml" />
|
||||||
|
<import resource="techs/technology-graph-dao-bean.xml" />
|
||||||
|
<import resource="techs/technology-graph-manager-bean.xml" />
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?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="empireTechnologyDAO" class="com.deepclone.lw.beans.techs.EmpireTechnologyDAOBean" />
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?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="empireTechnologyManager" class="com.deepclone.lw.beans.techs.EmpireTechnologyManagerBean" />
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?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="researchUpdate" class="com.deepclone.lw.beans.techs.ResearchUpdateBean" />
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?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="researchUpdateDAO" class="com.deepclone.lw.beans.techs.ResearchUpdateDAOBean" />
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?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="technologyGraphDAO" class="com.deepclone.lw.beans.techs.TechnologyGraphDAOBean" />
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<?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="technologyGraphManager" class="com.deepclone.lw.beans.techs.TechnologyGraphManagerBean" />
|
||||||
|
|
||||||
|
</beans>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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
|
|
@ -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
|
|
@ -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>
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -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>
|
|
@ -4,12 +4,12 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server-beans</artifactId>
|
<artifactId>legacyworlds-server-beans</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-beans-user</artifactId>
|
<artifactId>legacyworlds-server-beans-user</artifactId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<name>Legacy Worlds server - user actions</name>
|
<name>Legacy Worlds server - user actions</name>
|
||||||
<description>This module defines beans and classes that handle user actions.</description>
|
<description>This module defines beans and classes that handle user actions.</description>
|
||||||
</project>
|
</project>
|
|
@ -0,0 +1,59 @@
|
||||||
|
package com.deepclone.lw.beans.user.admin.main.techs;
|
||||||
|
|
||||||
|
|
||||||
|
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.admin.common.AdminOperation;
|
||||||
|
import com.deepclone.lw.beans.user.admin.main.AdminCommandsBean;
|
||||||
|
import com.deepclone.lw.cmd.admin.adata.Administrator;
|
||||||
|
import com.deepclone.lw.cmd.admin.adata.Privileges;
|
||||||
|
import com.deepclone.lw.cmd.admin.techs.ListCategoriesCommand;
|
||||||
|
import com.deepclone.lw.cmd.admin.techs.ListCategoriesResponse;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.TechnologyGraphManager;
|
||||||
|
import com.deepclone.lw.interfaces.session.ServerSession;
|
||||||
|
import com.deepclone.lw.session.Command;
|
||||||
|
import com.deepclone.lw.session.CommandResponse;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class ListCategoriesCommandDelegateBean
|
||||||
|
extends AdminOperation
|
||||||
|
implements AutowiredCommandDelegate
|
||||||
|
{
|
||||||
|
private TechnologyGraphManager manager;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setManager( TechnologyGraphManager manager )
|
||||||
|
{
|
||||||
|
this.manager = manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class< ? extends SessionCommandHandler > getCommandHandler( )
|
||||||
|
{
|
||||||
|
return AdminCommandsBean.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class< ? extends Command > getType( )
|
||||||
|
{
|
||||||
|
return ListCategoriesCommand.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandResponse execute( ServerSession session , Command command )
|
||||||
|
{
|
||||||
|
Administrator admin = this.getAdministrator( session );
|
||||||
|
if ( !admin.hasPrivilege( Privileges.GDAT ) ) {
|
||||||
|
return new ListCategoriesResponse( admin );
|
||||||
|
}
|
||||||
|
return new ListCategoriesResponse( admin , this.manager.listCategories( ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package com.deepclone.lw.beans.user.player.game;
|
package com.deepclone.lw.beans.user.player.game.techs;
|
||||||
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
@ -6,8 +6,9 @@ import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate;
|
import com.deepclone.lw.beans.user.abst.AutowiredCommandDelegate;
|
||||||
import com.deepclone.lw.beans.user.abst.SessionCommandHandler;
|
import com.deepclone.lw.beans.user.abst.SessionCommandHandler;
|
||||||
import com.deepclone.lw.beans.user.player.GameSubTypeBean;
|
import com.deepclone.lw.beans.user.player.GameSubTypeBean;
|
||||||
import com.deepclone.lw.cmd.player.ImplementTechCommand;
|
import com.deepclone.lw.cmd.player.research.ImplementTechCommand;
|
||||||
import com.deepclone.lw.interfaces.game.EmpireManagement;
|
import com.deepclone.lw.cmd.player.research.ResearchOperationResponse;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.EmpireTechnologyManager;
|
||||||
import com.deepclone.lw.interfaces.session.ServerSession;
|
import com.deepclone.lw.interfaces.session.ServerSession;
|
||||||
import com.deepclone.lw.session.Command;
|
import com.deepclone.lw.session.Command;
|
||||||
import com.deepclone.lw.session.CommandResponse;
|
import com.deepclone.lw.session.CommandResponse;
|
||||||
|
@ -19,13 +20,13 @@ public class ImplementTechCommandDelegateBean
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
||||||
private EmpireManagement empireManagement;
|
private EmpireTechnologyManager techManagement;
|
||||||
|
|
||||||
|
|
||||||
@Autowired( required = true )
|
@Autowired( required = true )
|
||||||
public void setEmpireManager( EmpireManagement manager )
|
public void setEmpireManager( EmpireTechnologyManager manager )
|
||||||
{
|
{
|
||||||
this.empireManagement = manager;
|
this.techManagement = manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,8 +50,8 @@ public class ImplementTechCommandDelegateBean
|
||||||
ImplementTechCommand command = (ImplementTechCommand) cParam;
|
ImplementTechCommand command = (ImplementTechCommand) cParam;
|
||||||
int empireId = session.get( "empireId" , Integer.class );
|
int empireId = session.get( "empireId" , Integer.class );
|
||||||
if ( session.get( "vacation" , Boolean.class ) ) {
|
if ( session.get( "vacation" , Boolean.class ) ) {
|
||||||
return this.empireManagement.getOverview( empireId );
|
return new ResearchOperationResponse( );
|
||||||
}
|
}
|
||||||
return this.empireManagement.implementTechnology( empireId , command.getTech( ) );
|
return this.techManagement.implementTechnology( empireId , command.getTech( ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,56 @@
|
||||||
|
package com.deepclone.lw.beans.user.player.game.techs;
|
||||||
|
|
||||||
|
|
||||||
|
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.research.ResearchOperationResponse;
|
||||||
|
import com.deepclone.lw.cmd.player.research.SetResearchPrioritiesCommand;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.EmpireTechnologyManager;
|
||||||
|
import com.deepclone.lw.interfaces.session.ServerSession;
|
||||||
|
import com.deepclone.lw.session.Command;
|
||||||
|
import com.deepclone.lw.session.CommandResponse;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class SetResearchPrioritiesCommandDelegateBean
|
||||||
|
implements AutowiredCommandDelegate
|
||||||
|
{
|
||||||
|
|
||||||
|
private EmpireTechnologyManager techManagement;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setEmpireManager( EmpireTechnologyManager manager )
|
||||||
|
{
|
||||||
|
this.techManagement = manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class< ? extends Command > getType( )
|
||||||
|
{
|
||||||
|
return SetResearchPrioritiesCommand.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class< ? extends SessionCommandHandler > getCommandHandler( )
|
||||||
|
{
|
||||||
|
return GameSubTypeBean.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandResponse execute( ServerSession session , Command cParam )
|
||||||
|
{
|
||||||
|
SetResearchPrioritiesCommand command = (SetResearchPrioritiesCommand) cParam;
|
||||||
|
int empireId = session.get( "empireId" , Integer.class );
|
||||||
|
if ( session.get( "vacation" , Boolean.class ) ) {
|
||||||
|
return new ResearchOperationResponse( );
|
||||||
|
}
|
||||||
|
return this.techManagement.setResearchPriorities( empireId , command.getPriorities( ) );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
package com.deepclone.lw.beans.user.player.game.techs;
|
||||||
|
|
||||||
|
|
||||||
|
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.research.ViewResearchCommand;
|
||||||
|
import com.deepclone.lw.interfaces.game.techs.EmpireTechnologyManager;
|
||||||
|
import com.deepclone.lw.interfaces.session.ServerSession;
|
||||||
|
import com.deepclone.lw.session.Command;
|
||||||
|
import com.deepclone.lw.session.CommandResponse;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public class ViewResearchCommandDelegateBean
|
||||||
|
implements AutowiredCommandDelegate
|
||||||
|
{
|
||||||
|
|
||||||
|
private EmpireTechnologyManager techManagement;
|
||||||
|
|
||||||
|
|
||||||
|
@Autowired( required = true )
|
||||||
|
public void setEmpireManager( EmpireTechnologyManager manager )
|
||||||
|
{
|
||||||
|
this.techManagement = manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class< ? extends Command > getType( )
|
||||||
|
{
|
||||||
|
return ViewResearchCommand.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Class< ? extends SessionCommandHandler > getCommandHandler( )
|
||||||
|
{
|
||||||
|
return GameSubTypeBean.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandResponse execute( ServerSession session , Command cParam )
|
||||||
|
{
|
||||||
|
int empireId = session.get( "empireId" , Integer.class );
|
||||||
|
return this.techManagement.getResearchData( empireId );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -94,4 +94,7 @@
|
||||||
<bean class="com.deepclone.lw.beans.user.admin.main.mntm.EndMaintenanceCommandDelegateBean" />
|
<bean class="com.deepclone.lw.beans.user.admin.main.mntm.EndMaintenanceCommandDelegateBean" />
|
||||||
<bean class="com.deepclone.lw.beans.user.admin.main.mntm.ExtendMaintenanceCommandDelegateBean" />
|
<bean class="com.deepclone.lw.beans.user.admin.main.mntm.ExtendMaintenanceCommandDelegateBean" />
|
||||||
|
|
||||||
|
<!-- Technology graph -->
|
||||||
|
<bean class="com.deepclone.lw.beans.user.admin.main.techs.ListCategoriesCommandDelegateBean" />
|
||||||
|
|
||||||
</beans>
|
</beans>
|
||||||
|
|
|
@ -44,9 +44,13 @@
|
||||||
|
|
||||||
<!-- Game: empire -->
|
<!-- Game: empire -->
|
||||||
<bean class="com.deepclone.lw.beans.user.player.game.OverviewCommandDelegateBean" />
|
<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.GetNewPlanetCommandDelegateBean" />
|
<bean class="com.deepclone.lw.beans.user.player.game.GetNewPlanetCommandDelegateBean" />
|
||||||
|
|
||||||
|
<!-- Game: technologies -->
|
||||||
|
<bean class="com.deepclone.lw.beans.user.player.game.techs.ViewResearchCommandDelegateBean" />
|
||||||
|
<bean class="com.deepclone.lw.beans.user.player.game.techs.ImplementTechCommandDelegateBean" />
|
||||||
|
<bean class="com.deepclone.lw.beans.user.player.game.techs.SetResearchPrioritiesCommandDelegateBean" />
|
||||||
|
|
||||||
<!-- Game: planet list -->
|
<!-- Game: planet list -->
|
||||||
<bean class="com.deepclone.lw.beans.user.player.game.ListPlanetsCommandDelegateBean" />
|
<bean class="com.deepclone.lw.beans.user.player.game.ListPlanetsCommandDelegateBean" />
|
||||||
|
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server</artifactId>
|
<artifactId>legacyworlds-server</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-beans</artifactId>
|
<artifactId>legacyworlds-server-beans</artifactId>
|
||||||
<name>Legacy Worlds server beans</name>
|
<name>Legacy Worlds server beans</name>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
<description>This metapackage regroups all packages which define beans for the Legacy Worlds server.</description>
|
<description>This metapackage regroups all packages which define beans for the Legacy Worlds server.</description>
|
||||||
|
|
||||||
|
@ -32,5 +32,8 @@
|
||||||
<module>legacyworlds-server-beans-bt</module>
|
<module>legacyworlds-server-beans-bt</module>
|
||||||
<module>legacyworlds-server-beans-user</module>
|
<module>legacyworlds-server-beans-user</module>
|
||||||
<module>legacyworlds-server-beans-simple</module>
|
<module>legacyworlds-server-beans-simple</module>
|
||||||
|
<module>legacyworlds-server-beans-techs</module>
|
||||||
|
<module>legacyworlds-server-beans-updates</module>
|
||||||
|
<module>legacyworlds-server-beans-events</module>
|
||||||
</modules>
|
</modules>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
\i parts/functions/030-tech-functions.sql
|
\i parts/functions/030-tech-functions.sql
|
||||||
\i parts/functions/035-users-view.sql
|
\i parts/functions/035-users-view.sql
|
||||||
\i parts/functions/040-empire-functions.sql
|
\i parts/functions/040-empire-functions.sql
|
||||||
|
\i parts/functions/045-research-functions.sql
|
||||||
\i parts/functions/050-computation-functions.sql
|
\i parts/functions/050-computation-functions.sql
|
||||||
\i parts/functions/060-universe-functions.sql
|
\i parts/functions/060-universe-functions.sql
|
||||||
\i parts/functions/070-users-functions.sql
|
\i parts/functions/070-users-functions.sql
|
||||||
|
|
|
@ -25,9 +25,9 @@ CREATE TABLE sys.constant_definitions(
|
||||||
name VARCHAR(64) NOT NULL PRIMARY KEY,
|
name VARCHAR(64) NOT NULL PRIMARY KEY,
|
||||||
category_id INT NOT NULL ,
|
category_id INT NOT NULL ,
|
||||||
description TEXT NOT NULL ,
|
description TEXT NOT NULL ,
|
||||||
min_value REAL ,
|
min_value DOUBLE PRECISION ,
|
||||||
max_value REAL ,
|
max_value DOUBLE PRECISION ,
|
||||||
c_value REAL NOT NULL ,
|
c_value DOUBLE PRECISION NOT NULL ,
|
||||||
CHECK(
|
CHECK(
|
||||||
( min_value IS NULL OR (
|
( min_value IS NULL OR (
|
||||||
min_value IS NOT NULL AND c_value >= min_value ) )
|
min_value IS NOT NULL AND c_value >= min_value ) )
|
||||||
|
|
|
@ -8,49 +8,65 @@
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Technology lines
|
-- Categories
|
||||||
--
|
--
|
||||||
|
CREATE TABLE tech.categories(
|
||||||
CREATE TABLE tech.lines(
|
|
||||||
name_id INT NOT NULL PRIMARY KEY ,
|
name_id INT NOT NULL PRIMARY KEY ,
|
||||||
description_id INT NOT NULL
|
description_id INT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX idx_lines_description
|
CREATE INDEX idx_categories_description
|
||||||
ON tech.lines (description_id);
|
ON tech.categories (description_id);
|
||||||
|
|
||||||
ALTER TABLE tech.lines
|
ALTER TABLE tech.categories
|
||||||
ADD CONSTRAINT fk_lines_name
|
ADD CONSTRAINT fk_categories_name
|
||||||
FOREIGN KEY (name_id) REFERENCES defs.strings ,
|
FOREIGN KEY (name_id) REFERENCES defs.strings ,
|
||||||
ADD CONSTRAINT fk_lines_description
|
ADD CONSTRAINT fk_categories_description
|
||||||
FOREIGN KEY (description_id) REFERENCES defs.strings;
|
FOREIGN KEY (description_id) REFERENCES defs.strings;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Technology levels
|
-- Technologies
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE TABLE tech.levels(
|
CREATE TABLE tech.technologies(
|
||||||
id SERIAL NOT NULL PRIMARY KEY ,
|
name_id INT NOT NULL PRIMARY KEY ,
|
||||||
line_id INT NOT NULL ,
|
|
||||||
level INT NOT NULL CHECK( level > 0 ) ,
|
|
||||||
name_id INT NOT NULL ,
|
|
||||||
description_id INT NOT NULL ,
|
description_id INT NOT NULL ,
|
||||||
|
category_id INT NOT NULL ,
|
||||||
points INT NOT NULL CHECK( points > 0 ) ,
|
points INT NOT NULL CHECK( points > 0 ) ,
|
||||||
cost INT NOT NULL CHECK( cost > 0 )
|
cost INT NOT NULL CHECK( cost > 0 )
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE UNIQUE INDEX idx_levels_linelevel
|
CREATE INDEX idx_technologies_description
|
||||||
ON tech.levels (line_id, level);
|
ON tech.technologies (description_id);
|
||||||
CREATE INDEX idx_levels_name
|
CREATE INDEX idx_technologies_category
|
||||||
ON tech.levels (name_id);
|
ON tech.technologies (category_id);
|
||||||
CREATE INDEX idx_levels_description
|
|
||||||
ON tech.levels (description_id);
|
|
||||||
|
|
||||||
ALTER TABLE tech.levels
|
ALTER TABLE tech.technologies
|
||||||
ADD CONSTRAINT fk_levels_line
|
ADD CONSTRAINT fk_technologies_category
|
||||||
FOREIGN KEY (line_id) REFERENCES tech.lines ,
|
FOREIGN KEY (category_id) REFERENCES tech.categories ,
|
||||||
ADD CONSTRAINT fk_levels_name
|
ADD CONSTRAINT fk_technologies_name
|
||||||
FOREIGN KEY (name_id) REFERENCES defs.strings ,
|
FOREIGN KEY (name_id) REFERENCES defs.strings ,
|
||||||
ADD CONSTRAINT fk_levels_description
|
ADD CONSTRAINT fk_technologies_description
|
||||||
FOREIGN KEY (description_id) REFERENCES defs.strings;
|
FOREIGN KEY (description_id) REFERENCES defs.strings;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dependencies
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE tech.dependencies(
|
||||||
|
technology_id INT NOT NULL ,
|
||||||
|
depends_on INT NOT NULL ,
|
||||||
|
PRIMARY KEY( technology_id , depends_on )
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_dependencies_dependson
|
||||||
|
ON tech.dependencies (depends_on);
|
||||||
|
|
||||||
|
ALTER TABLE tech.dependencies
|
||||||
|
ADD CONSTRAINT fk_dependencies_technology
|
||||||
|
FOREIGN KEY (technology_id) REFERENCES tech.technologies ,
|
||||||
|
ADD CONSTRAINT fk_dependencies_dependson
|
||||||
|
FOREIGN KEY (depends_on) REFERENCES tech.technologies;
|
||||||
|
|
|
@ -32,18 +32,18 @@ ALTER TABLE tech.buildables
|
||||||
--
|
--
|
||||||
CREATE TABLE tech.buildable_requirements(
|
CREATE TABLE tech.buildable_requirements(
|
||||||
buildable_id INT NOT NULL ,
|
buildable_id INT NOT NULL ,
|
||||||
level_id INT NOT NULL ,
|
technology_id INT NOT NULL ,
|
||||||
PRIMARY KEY( buildable_id , level_id )
|
PRIMARY KEY( buildable_id , technology_id )
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX idx_buildablereqs_level
|
CREATE INDEX idx_buildablereqs_technology
|
||||||
ON tech.buildable_requirements( level_id );
|
ON tech.buildable_requirements( technology_id );
|
||||||
|
|
||||||
ALTER TABLE tech.buildable_requirements
|
ALTER TABLE tech.buildable_requirements
|
||||||
ADD CONSTRAINT fk_buildablereqs_buildable
|
ADD CONSTRAINT fk_buildablereqs_buildable
|
||||||
FOREIGN KEY (buildable_id) REFERENCES tech.buildables ,
|
FOREIGN KEY (buildable_id) REFERENCES tech.buildables ,
|
||||||
ADD CONSTRAINT fk_buildablereqs_level
|
ADD CONSTRAINT fk_buildablereqs_technology
|
||||||
FOREIGN KEY (level_id) REFERENCES tech.levels;
|
FOREIGN KEY (technology_id) REFERENCES tech.technologies;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
|
@ -28,7 +28,7 @@ CREATE TABLE verse.planets(
|
||||||
orbit INT NOT NULL
|
orbit INT NOT NULL
|
||||||
CHECK( orbit BETWEEN 1 AND 5 ) ,
|
CHECK( orbit BETWEEN 1 AND 5 ) ,
|
||||||
picture INT NOT NULL ,
|
picture INT NOT NULL ,
|
||||||
population REAL NOT NULL
|
population DOUBLE PRECISION NOT NULL
|
||||||
CHECK( population >= 0 )
|
CHECK( population >= 0 )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -47,9 +47,9 @@ ALTER TABLE verse.planets
|
||||||
--
|
--
|
||||||
CREATE TABLE verse.planet_happiness(
|
CREATE TABLE verse.planet_happiness(
|
||||||
planet_id INT NOT NULL PRIMARY KEY ,
|
planet_id INT NOT NULL PRIMARY KEY ,
|
||||||
target REAL NOT NULL
|
target DOUBLE PRECISION NOT NULL
|
||||||
CHECK( target BETWEEN 0.0 AND 1.0 ) ,
|
CHECK( target BETWEEN 0.0 AND 1.0 ) ,
|
||||||
current REAL NOT NULL
|
current DOUBLE PRECISION NOT NULL
|
||||||
CHECK( current > 0 )
|
CHECK( current > 0 )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ ALTER TABLE verse.planet_happiness
|
||||||
--
|
--
|
||||||
CREATE TABLE verse.planet_money(
|
CREATE TABLE verse.planet_money(
|
||||||
planet_id INT NOT NULL PRIMARY KEY ,
|
planet_id INT NOT NULL PRIMARY KEY ,
|
||||||
income REAL NOT NULL
|
income DOUBLE PRECISION NOT NULL
|
||||||
CHECK( income >= 0 ) ,
|
CHECK( income >= 0 ) ,
|
||||||
upkeep REAL NOT NULL
|
upkeep DOUBLE PRECISION NOT NULL
|
||||||
CHECK( upkeep >= 0 )
|
CHECK( upkeep >= 0 )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ CREATE TABLE verse.planet_buildings(
|
||||||
planet_id INT NOT NULL ,
|
planet_id INT NOT NULL ,
|
||||||
building_id INT NOT NULL ,
|
building_id INT NOT NULL ,
|
||||||
amount INT NOT NULL CHECK( amount >= 0 ) ,
|
amount INT NOT NULL CHECK( amount >= 0 ) ,
|
||||||
damage REAL NOT NULL CHECK( damage >= 0 ) ,
|
damage DOUBLE PRECISION NOT NULL CHECK( damage >= 0 ) ,
|
||||||
PRIMARY KEY( planet_id , building_id )
|
PRIMARY KEY( planet_id , building_id )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -13,9 +13,9 @@
|
||||||
|
|
||||||
CREATE TABLE emp.empires(
|
CREATE TABLE emp.empires(
|
||||||
name_id INT NOT NULL PRIMARY KEY ,
|
name_id INT NOT NULL PRIMARY KEY ,
|
||||||
cash REAL NOT NULL
|
cash DOUBLE PRECISION NOT NULL
|
||||||
CHECK( cash >= 0 ),
|
CHECK( cash >= 0 ),
|
||||||
debt REAL NOT NULL DEFAULT 0
|
debt DOUBLE PRECISION NOT NULL DEFAULT 0
|
||||||
CHECK( debt >= 0)
|
CHECK( debt >= 0)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -25,28 +25,55 @@ ALTER TABLE emp.empires
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Empire technologies
|
-- Research in progress
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE TABLE emp.technologies(
|
CREATE TABLE emp.research(
|
||||||
empire_id INT NOT NULL ,
|
empire_id INT NOT NULL ,
|
||||||
line_id INT NOT NULL ,
|
technology_id INT NOT NULL ,
|
||||||
level INT NOT NULL DEFAULT 1
|
accumulated DOUBLE PRECISION NOT NULL DEFAULT 0
|
||||||
CHECK( level > 0 ) ,
|
CHECK( accumulated >= 0 ) ,
|
||||||
accumulated REAL NOT NULL DEFAULT 0
|
priority INT NOT NULL
|
||||||
CHECK( accumulated >= 0 ),
|
CHECK( priority BETWEEN 0 AND 100 ) ,
|
||||||
PRIMARY KEY( empire_id , line_id )
|
PRIMARY KEY( empire_id , technology_id )
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE INDEX idx_technologies_line
|
CREATE INDEX idx_research_technology
|
||||||
ON emp.technologies (line_id);
|
ON emp.research (technology_id);
|
||||||
|
|
||||||
ALTER TABLE emp.technologies
|
ALTER TABLE emp.research
|
||||||
ADD CONSTRAINT fk_technologies_empire
|
ADD CONSTRAINT fk_research_empire
|
||||||
FOREIGN KEY (empire_id) REFERENCES emp.empires
|
FOREIGN KEY (empire_id) REFERENCES emp.empires
|
||||||
ON DELETE CASCADE ,
|
ON DELETE CASCADE ,
|
||||||
ADD CONSTRAINT fk_technologies_line
|
ADD CONSTRAINT fk_research_technology
|
||||||
FOREIGN KEY (line_id) REFERENCES tech.lines;
|
FOREIGN KEY (technology_id) REFERENCES tech.technologies
|
||||||
|
ON DELETE CASCADE;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Researched technologies (both implemented and pending implementation)
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE emp.researched_technologies(
|
||||||
|
empire_id INT NOT NULL ,
|
||||||
|
technology_id INT NOT NULL ,
|
||||||
|
implemented BOOLEAN NOT NULL ,
|
||||||
|
PRIMARY KEY ( empire_id , technology_id )
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_researched_technology
|
||||||
|
ON emp.researched_technologies ( technology_id );
|
||||||
|
CREATE INDEX idx_researched_implemented
|
||||||
|
ON emp.researched_technologies ( empire_id , implemented );
|
||||||
|
|
||||||
|
ALTER TABLE emp.researched_technologies
|
||||||
|
ADD CONSTRAINT fk_researched_empire
|
||||||
|
FOREIGN KEY ( empire_id ) REFERENCES emp.empires
|
||||||
|
ON DELETE CASCADE ,
|
||||||
|
ADD CONSTRAINT fk_researched_technology
|
||||||
|
FOREIGN KEY ( technology_id ) REFERENCES tech.technologies
|
||||||
|
ON DELETE CASCADE;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
|
|
||||||
CREATE TABLE verse.bld_queues(
|
CREATE TABLE verse.bld_queues(
|
||||||
planet_id INT NOT NULL PRIMARY KEY ,
|
planet_id INT NOT NULL PRIMARY KEY ,
|
||||||
money REAL NOT NULL CHECK( money >= 0 ),
|
money DOUBLE PRECISION NOT NULL CHECK( money >= 0 ),
|
||||||
work REAL NOT NULL CHECK( work >= 0 )
|
work DOUBLE PRECISION NOT NULL CHECK( work >= 0 )
|
||||||
);
|
);
|
||||||
|
|
||||||
ALTER TABLE verse.bld_queues
|
ALTER TABLE verse.bld_queues
|
||||||
|
@ -51,8 +51,8 @@ ALTER TABLE verse.bld_items
|
||||||
|
|
||||||
CREATE TABLE verse.mil_queues(
|
CREATE TABLE verse.mil_queues(
|
||||||
planet_id INT NOT NULL PRIMARY KEY ,
|
planet_id INT NOT NULL PRIMARY KEY ,
|
||||||
money REAL NOT NULL CHECK( money >= 0 ),
|
money DOUBLE PRECISION NOT NULL CHECK( money >= 0 ),
|
||||||
work REAL NOT NULL CHECK( work >= 0 )
|
work DOUBLE PRECISION NOT NULL CHECK( work >= 0 )
|
||||||
);
|
);
|
||||||
|
|
||||||
ALTER TABLE verse.mil_queues
|
ALTER TABLE verse.mil_queues
|
||||||
|
|
|
@ -46,7 +46,7 @@ CREATE TABLE fleets.ships(
|
||||||
fleet_id BIGINT NOT NULL ,
|
fleet_id BIGINT NOT NULL ,
|
||||||
ship_id INT NOT NULL ,
|
ship_id INT NOT NULL ,
|
||||||
amount INT NOT NULL CHECK( amount >= 0 ) ,
|
amount INT NOT NULL CHECK( amount >= 0 ) ,
|
||||||
damage REAL NOT NULL ,
|
damage DOUBLE PRECISION NOT NULL ,
|
||||||
PRIMARY KEY( fleet_id , ship_id )
|
PRIMARY KEY( fleet_id , ship_id )
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -89,8 +89,8 @@ ALTER TABLE fleets.movements
|
||||||
|
|
||||||
CREATE TABLE fleets.ms_space(
|
CREATE TABLE fleets.ms_space(
|
||||||
movement_id BIGINT NOT NULL PRIMARY KEY ,
|
movement_id BIGINT NOT NULL PRIMARY KEY ,
|
||||||
start_x REAL NOT NULL ,
|
start_x DOUBLE PRECISION NOT NULL ,
|
||||||
start_y REAL NOT NULL
|
start_y DOUBLE PRECISION NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
ALTER TABLE fleets.ms_space
|
ALTER TABLE fleets.ms_space
|
||||||
|
|
|
@ -3,10 +3,163 @@
|
||||||
--
|
--
|
||||||
-- Storage of events (internal messages)
|
-- Storage of events (internal messages)
|
||||||
--
|
--
|
||||||
-- Copyright(C) 2004-2010, DeepClone Development
|
-- Copyright(C) 2004-2011, DeepClone Development
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Event type definitionss
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE events.event_type_definitions(
|
||||||
|
etd_type VARCHAR( 48 ) NOT NULL
|
||||||
|
PRIMARY KEY ,
|
||||||
|
etd_priority INT NOT NULL
|
||||||
|
CHECK( etd_priority BETWEEN 1 AND 5 ) ,
|
||||||
|
etd_user_priority BOOLEAN NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Types of field contents
|
||||||
|
--
|
||||||
|
-- INMB integer
|
||||||
|
-- RNMB real number
|
||||||
|
-- TEXT text
|
||||||
|
-- BOOL boolean
|
||||||
|
-- I18N internationalised string
|
||||||
|
-- EREF game entity reference
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TYPE events.field_content_type
|
||||||
|
AS ENUM ( 'INMB' , 'RNMB' , 'TEXT' , 'BOOL' , 'I18N' , 'EREF' );
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Subtypes of reference field contents
|
||||||
|
--
|
||||||
|
-- EMP empire
|
||||||
|
-- MAP map object
|
||||||
|
-- FLT fleet
|
||||||
|
-- BAT battle
|
||||||
|
-- ADM administrator
|
||||||
|
-- MSG message
|
||||||
|
-- BUG bug report
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TYPE events.field_reference_type
|
||||||
|
AS ENUM ( 'EMP' , 'MAP' , 'FLT' , 'BAT' , 'ADM' , 'MSG' , 'BUG' );
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Event field definitions
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE events.event_field_definitions(
|
||||||
|
etd_type VARCHAR( 48 ) NOT NULL ,
|
||||||
|
efd_field VARCHAR( 48 ) NOT NULL ,
|
||||||
|
efd_required BOOLEAN NOT NULL ,
|
||||||
|
efd_type events.field_content_type NOT NULL ,
|
||||||
|
efd_reference_type events.field_reference_type ,
|
||||||
|
efd_low_boundary DOUBLE PRECISION ,
|
||||||
|
efd_high_boundary DOUBLE PRECISION ,
|
||||||
|
|
||||||
|
PRIMARY KEY ( etd_type , efd_field ) ,
|
||||||
|
|
||||||
|
CHECK( efd_type = 'EREF' AND efd_reference_type IS NOT NULL
|
||||||
|
OR efd_type <> 'EREF' AND efd_reference_type IS NULL ) ,
|
||||||
|
|
||||||
|
CHECK ( efd_type IN ( 'INMB' , 'RNMB' , 'TEXT' )
|
||||||
|
OR efd_type NOT IN ( 'INMB' , 'RNMB' , 'TEXT' )
|
||||||
|
AND efd_low_boundary IS NULL
|
||||||
|
AND efd_high_boundary IS NULL ) ,
|
||||||
|
|
||||||
|
CHECK ( efd_low_boundary IS NULL OR efd_high_boundary IS NULL
|
||||||
|
OR efd_low_boundary < efd_high_boundary )
|
||||||
|
);
|
||||||
|
|
||||||
|
ALTER TABLE events.event_field_definitions
|
||||||
|
ADD CONSTRAINT fk_efd_type
|
||||||
|
FOREIGN KEY ( etd_type ) REFERENCES events.event_type_definitions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Event format definitions
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE events.event_format_definitions(
|
||||||
|
etd_type VARCHAR( 48 ) NOT NULL ,
|
||||||
|
efmd_order INT NOT NULL ,
|
||||||
|
efmd_template INT NOT NULL ,
|
||||||
|
|
||||||
|
PRIMARY KEY ( etd_type , efmd_order )
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_efmd_template
|
||||||
|
ON events.event_format_definitions ( efmd_template );
|
||||||
|
|
||||||
|
ALTER TABLE events.event_format_definitions
|
||||||
|
ADD CONSTRAINT fk_efmd_type
|
||||||
|
FOREIGN KEY ( etd_type ) REFERENCES events.event_type_definitions ,
|
||||||
|
ADD CONSTRAINT fk_efmd_template
|
||||||
|
FOREIGN KEY ( efmd_template ) REFERENCES defs.strings;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Types of format conditions
|
||||||
|
--
|
||||||
|
-- EX has value all
|
||||||
|
-- EQ is equal to ... all except EREF
|
||||||
|
-- NE is not equal to ... all except EREF
|
||||||
|
-- GT > ... INMB , RNMB
|
||||||
|
-- length > ... TEXT
|
||||||
|
-- LT < ... INMB , RNMB
|
||||||
|
-- shorter than ... TEXT
|
||||||
|
-- GE >= ... INMB , RNMB
|
||||||
|
-- length >= ... TEXT
|
||||||
|
-- LE <= ... INMB , RNMB
|
||||||
|
-- length <= ... TEXT
|
||||||
|
-- AV available EREF
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TYPE events.format_condition_type
|
||||||
|
AS ENUM ( 'EX' , 'EQ' , 'NE' , 'GT' , 'LT' , 'GE' , 'LE' , 'AV' );
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Conditions on format definitions
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE events.efmt_conditions(
|
||||||
|
etd_type VARCHAR( 48 ) NOT NULL ,
|
||||||
|
efmd_order INT NOT NULL ,
|
||||||
|
efd_field VARCHAR( 48 ) NOT NULL ,
|
||||||
|
efc_type events.format_condition_type NOT NULL ,
|
||||||
|
efc_boolean BOOLEAN ,
|
||||||
|
efc_numeric DOUBLE PRECISION ,
|
||||||
|
efc_string TEXT ,
|
||||||
|
|
||||||
|
PRIMARY KEY( etd_type , efmd_order , efd_field , efc_type )
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE INDEX idx_efmtc_field
|
||||||
|
ON events.efmt_conditions ( etd_type , efd_field );
|
||||||
|
|
||||||
|
ALTER TABLE events.efmt_conditions
|
||||||
|
ADD CONSTRAINT fk_efmtc_format
|
||||||
|
FOREIGN KEY ( etd_type , efmd_order ) REFERENCES events.event_format_definitions ,
|
||||||
|
ADD CONSTRAINT fk_efmtc_field
|
||||||
|
FOREIGN KEY ( etd_type , efd_field ) REFERENCES events.event_field_definitions;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
-- OLD CODE BELOW
|
||||||
|
--
|
||||||
|
|
||||||
CREATE TYPE event_type
|
CREATE TYPE event_type
|
||||||
AS ENUM ( 'QUEUE' , 'EMPIRE' , 'FLEETS' , 'PLANET', 'ALLIANCE', 'ADMIN' , 'BUGS' );
|
AS ENUM ( 'QUEUE' , 'EMPIRE' , 'FLEETS' , 'PLANET', 'ALLIANCE', 'ADMIN' , 'BUGS' );
|
||||||
|
|
||||||
|
@ -101,7 +254,7 @@ ALTER TABLE events.empire_events
|
||||||
FOREIGN KEY (event_id) REFERENCES events.events
|
FOREIGN KEY (event_id) REFERENCES events.events
|
||||||
ON DELETE CASCADE,
|
ON DELETE CASCADE,
|
||||||
ADD CONSTRAINT fk_empevents_tech
|
ADD CONSTRAINT fk_empevents_tech
|
||||||
FOREIGN KEY (technology_id) REFERENCES tech.levels;
|
FOREIGN KEY (technology_id) REFERENCES tech.technologies;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -57,8 +57,8 @@ $$ LANGUAGE plpgsql;
|
||||||
-- the constant's actual value
|
-- the constant's actual value
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval REAL )
|
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT
|
STRICT
|
||||||
VOLATILE
|
VOLATILE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
|
@ -66,7 +66,7 @@ CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT ,
|
||||||
DECLARE
|
DECLARE
|
||||||
ccid INT;
|
ccid INT;
|
||||||
occid INT;
|
occid INT;
|
||||||
cval REAL;
|
cval DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
ccid := sys.cog_constant_category( ccnm );
|
ccid := sys.cog_constant_category( ccnm );
|
||||||
|
|
||||||
|
@ -97,7 +97,7 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL ) TO :dbuser;
|
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , DOUBLE PRECISION ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,8 +116,8 @@ GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL ) TO :dbus
|
||||||
-- the constant's actual value
|
-- the constant's actual value
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval REAL , bval REAL , ismin BOOLEAN )
|
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval DOUBLE PRECISION , bval DOUBLE PRECISION , ismin BOOLEAN )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT
|
STRICT
|
||||||
VOLATILE
|
VOLATILE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
|
@ -125,9 +125,9 @@ CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT ,
|
||||||
DECLARE
|
DECLARE
|
||||||
ccid INT;
|
ccid INT;
|
||||||
occid INT;
|
occid INT;
|
||||||
cval REAL;
|
cval DOUBLE PRECISION;
|
||||||
mival REAL;
|
mival DOUBLE PRECISION;
|
||||||
maval REAL;
|
maval DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
IF ismin THEN
|
IF ismin THEN
|
||||||
mival := bval;
|
mival := bval;
|
||||||
|
@ -175,7 +175,7 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL , REAL , BOOLEAN ) TO :dbuser;
|
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , DOUBLE PRECISION , DOUBLE PRECISION , BOOLEAN ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -194,8 +194,8 @@ GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL , REAL , B
|
||||||
-- the constant's actual value
|
-- the constant's actual value
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval REAL , mival REAL , maval REAL )
|
CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT , dval DOUBLE PRECISION , mival DOUBLE PRECISION , maval DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT
|
STRICT
|
||||||
VOLATILE
|
VOLATILE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
|
@ -203,7 +203,7 @@ CREATE OR REPLACE FUNCTION sys.uoc_constant( cnm TEXT , cdesc TEXT , ccnm TEXT ,
|
||||||
DECLARE
|
DECLARE
|
||||||
ccid INT;
|
ccid INT;
|
||||||
occid INT;
|
occid INT;
|
||||||
cval REAL;
|
cval DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
ccid := sys.cog_constant_category( ccnm );
|
ccid := sys.cog_constant_category( ccnm );
|
||||||
|
|
||||||
|
@ -243,7 +243,7 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL , REAL , REAL ) TO :dbuser;
|
GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , DOUBLE PRECISION , DOUBLE PRECISION , DOUBLE PRECISION ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -259,7 +259,7 @@ GRANT EXECUTE ON FUNCTION sys.uoc_constant( TEXT , TEXT , TEXT , REAL , REAL , R
|
||||||
-- TRUE on success, FALSE on failure
|
-- TRUE on success, FALSE on failure
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION sys.set_constant( cnm TEXT , nval REAL , aid INT )
|
CREATE OR REPLACE FUNCTION sys.set_constant( cnm TEXT , nval DOUBLE PRECISION , aid INT )
|
||||||
RETURNS BOOLEAN
|
RETURNS BOOLEAN
|
||||||
STRICT
|
STRICT
|
||||||
VOLATILE
|
VOLATILE
|
||||||
|
@ -282,7 +282,7 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
GRANT EXECUTE ON FUNCTION sys.set_constant( TEXT , REAL , INT ) TO :dbuser;
|
GRANT EXECUTE ON FUNCTION sys.set_constant( TEXT , DOUBLE PRECISION , INT ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ GRANT EXECUTE ON FUNCTION sys.set_constant( TEXT , REAL , INT ) TO :dbuser;
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION sys.get_constant( cnm TEXT )
|
CREATE OR REPLACE FUNCTION sys.get_constant( cnm TEXT )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT STABLE
|
STRICT STABLE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
AS $$
|
AS $$
|
||||||
|
|
|
@ -42,92 +42,224 @@ CREATE VIEW tech.ships_view
|
||||||
ON b.name_id = s.buildable_id;
|
ON b.name_id = s.buildable_id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Categories view
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE VIEW tech.categories_view
|
||||||
|
AS SELECT ns.name AS name , ds.name AS description
|
||||||
|
FROM tech.categories c
|
||||||
|
INNER JOIN defs.strings ns
|
||||||
|
ON ns.id = c.name_id
|
||||||
|
INNER JOIN defs.strings ds
|
||||||
|
ON ds.id = c.description_id;
|
||||||
|
|
||||||
|
GRANT SELECT ON tech.categories_view TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Creates or updates a technology line
|
-- Technologies view
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE VIEW tech.technologies_view
|
||||||
|
AS SELECT cs.name AS category , ns.name AS name ,
|
||||||
|
ds.name AS description , t.points , t.cost
|
||||||
|
FROM tech.technologies t
|
||||||
|
INNER JOIN defs.strings cs
|
||||||
|
ON cs.id = t.category_id
|
||||||
|
INNER JOIN defs.strings ns
|
||||||
|
ON ns.id = t.name_id
|
||||||
|
INNER JOIN defs.strings ds
|
||||||
|
ON ds.id = t.description_id;
|
||||||
|
|
||||||
|
GRANT SELECT ON tech.technologies_view TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Dependencies view
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE VIEW tech.dependencies_view
|
||||||
|
AS SELECT ts.name AS technology , ds.name AS dependency
|
||||||
|
FROM tech.dependencies d
|
||||||
|
INNER JOIN defs.strings ts
|
||||||
|
ON ts.id = d.technology_id
|
||||||
|
INNER JOIN defs.strings ds
|
||||||
|
ON ds.id = d.depends_on;
|
||||||
|
|
||||||
|
GRANT SELECT ON tech.dependencies_view TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Creates or updates a technology category
|
||||||
--
|
--
|
||||||
-- Parameters:
|
-- Parameters:
|
||||||
-- tln Tech line name
|
-- cat_name String identifier of the category's name
|
||||||
-- tld Tech line description
|
-- cat_desc String identifier of the category's description
|
||||||
|
--
|
||||||
|
-- Returns:
|
||||||
|
-- 0 No error
|
||||||
|
-- 1 Name string not found
|
||||||
|
-- 2 Description string not found
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION tech.uoc_line( tln TEXT , tld TEXT )
|
CREATE OR REPLACE FUNCTION tech.uoc_category( cat_name TEXT , cat_desc TEXT )
|
||||||
RETURNS VOID
|
RETURNS INT
|
||||||
STRICT
|
STRICT VOLATILE
|
||||||
VOLATILE
|
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
nid INT;
|
cn_id INT;
|
||||||
did INT;
|
cd_id INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get string identifiers
|
-- Get name / description identifiers
|
||||||
SELECT INTO nid id FROM defs.strings WHERE name = tln;
|
SELECT INTO cn_id id FROM defs.strings WHERE name = cat_name;
|
||||||
SELECT INTO did id FROM defs.strings WHERE name = tld;
|
IF NOT FOUND THEN
|
||||||
|
RETURN 1;
|
||||||
|
END IF;
|
||||||
|
SELECT INTO cd_id id FROM defs.strings WHERE name = cat_desc;
|
||||||
|
IF NOT FOUND THEN
|
||||||
|
RETURN 2;
|
||||||
|
END IF;
|
||||||
|
|
||||||
-- Try creating / updating
|
-- Create or update the category
|
||||||
BEGIN
|
BEGIN
|
||||||
INSERT INTO tech.lines ( name_id , description_id )
|
INSERT INTO tech.categories ( name_id , description_id )
|
||||||
VALUES ( nid , did );
|
VALUES ( cn_id , cd_id );
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN unique_violation THEN
|
WHEN unique_violation THEN
|
||||||
UPDATE tech.lines SET description_id = did
|
UPDATE tech.categories SET description_id = cd_id
|
||||||
WHERE name_id = nid;
|
WHERE name_id = cn_id;
|
||||||
END;
|
END;
|
||||||
|
RETURN 0;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
GRANT EXECUTE ON FUNCTION tech.uoc_line( TEXT , TEXT ) TO :dbuser;
|
GRANT EXECUTE ON FUNCTION tech.uoc_category( TEXT , TEXT ) to :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Creates or updates a technology level
|
-- Creates or updates a technology. If there are dependencies, clear them.
|
||||||
--
|
--
|
||||||
-- Parameters:
|
-- Parameters:
|
||||||
-- tln Tech line name
|
-- nt_name Name string identifier
|
||||||
-- lv Level
|
-- nt_category Category string identifier
|
||||||
-- lvn Level name
|
-- nt_desc Description string identifier
|
||||||
-- lvd Level description
|
-- nt_points Research points for the technology
|
||||||
-- lvp Points
|
-- nt_cost Cost of the technology
|
||||||
-- lvc Cost
|
--
|
||||||
|
-- Returns:
|
||||||
|
-- 0 No error
|
||||||
|
-- 1 Name string not found
|
||||||
|
-- 2 Category not found
|
||||||
|
-- 3 Description string not found
|
||||||
|
-- 4 Invalid parameters (points or cost)
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION tech.uoc_level( tln TEXT , lv INT , lvn TEXT , lvd TEXT , lvp INT , lvc INT )
|
CREATE OR REPLACE FUNCTION tech.uoc_technology( nt_name TEXT , nt_category TEXT , nt_desc TEXT ,
|
||||||
RETURNS VOID
|
nt_points INT , nt_cost INT )
|
||||||
STRICT
|
RETURNS INT
|
||||||
VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
lid INT;
|
n_id INT;
|
||||||
nid INT;
|
c_id INT;
|
||||||
did INT;
|
d_id INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get tech line
|
-- Get name, category and description identifiers
|
||||||
SELECT INTO lid t.name_id
|
SELECT INTO n_id id FROM defs.strings WHERE name = nt_name;
|
||||||
FROM tech.lines t
|
IF NOT FOUND THEN
|
||||||
|
RETURN 1;
|
||||||
|
END IF;
|
||||||
|
SELECT INTO c_id c.name_id FROM tech.categories c
|
||||||
INNER JOIN defs.strings s
|
INNER JOIN defs.strings s
|
||||||
ON s.id = t.name_id
|
ON s.id = c.name_id AND s.name = nt_category;
|
||||||
WHERE s.name = tln;
|
IF NOT FOUND THEN
|
||||||
|
RETURN 2;
|
||||||
|
END IF;
|
||||||
|
SELECT INTO d_id id FROM defs.strings WHERE name = nt_desc;
|
||||||
|
IF NOT FOUND THEN
|
||||||
|
RETURN 3;
|
||||||
|
END IF;
|
||||||
|
|
||||||
-- Get name / description IDs
|
-- Create or update the technology
|
||||||
SELECT INTO nid id FROM defs.strings WHERE name = lvn;
|
|
||||||
SELECT INTO did id FROM defs.strings WHERE name = lvd;
|
|
||||||
|
|
||||||
-- Create or update the level
|
|
||||||
BEGIN
|
BEGIN
|
||||||
INSERT INTO tech.levels ( line_id , level , name_id , description_id , points , cost )
|
BEGIN
|
||||||
VALUES ( lid , lv , nid , did , lvp , lvc );
|
INSERT INTO tech.technologies ( name_id , category_id , description_id , points , cost )
|
||||||
|
VALUES ( n_id , c_id , d_id , nt_points , nt_cost );
|
||||||
EXCEPTION
|
EXCEPTION
|
||||||
WHEN unique_violation THEN
|
WHEN unique_violation THEN
|
||||||
UPDATE tech.levels SET name_id = nid , description_id = did , points = lvp , cost = lvc
|
UPDATE tech.technologies
|
||||||
WHERE line_id = lid AND level = lv;
|
SET category_id = c_id , description_id = cd_id ,
|
||||||
|
points = nt_points , cost = nt_cost
|
||||||
|
WHERE name_id = n_id;
|
||||||
|
DELETE FROM tech.dependencies
|
||||||
|
WHERE technology_id = n_id;
|
||||||
END;
|
END;
|
||||||
|
EXCEPTION
|
||||||
|
WHEN check_violation THEN
|
||||||
|
RETURN 4;
|
||||||
|
END;
|
||||||
|
RETURN 0;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
GRANT EXECUTE ON FUNCTION tech.uoc_level( TEXT , INT , TEXT , TEXT , INT , INT ) to :dbuser;
|
GRANT EXECUTE ON FUNCTION tech.uoc_technology( TEXT , TEXT , TEXT , INT , INT ) to :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Adds a technology dependency
|
||||||
|
--
|
||||||
|
-- Parameters:
|
||||||
|
-- nd_name Name of the dependent technology
|
||||||
|
-- nd_dep Name of the dependency
|
||||||
|
--
|
||||||
|
-- Returns:
|
||||||
|
-- 0 No error
|
||||||
|
-- 1 Technology not found
|
||||||
|
-- 2 Dependency not found
|
||||||
|
-- 3 Duplicate dependency
|
||||||
|
--
|
||||||
|
CREATE OR REPLACE FUNCTION tech.add_dependency( nd_name TEXT , nd_dep TEXT )
|
||||||
|
RETURNS INT
|
||||||
|
STRICT VOLATILE
|
||||||
|
SECURITY DEFINER
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
t_id INT;
|
||||||
|
d_id INT;
|
||||||
|
BEGIN
|
||||||
|
-- Get technology
|
||||||
|
SELECT INTO t_id t.name_id FROM tech.technologies t
|
||||||
|
INNER JOIN defs.strings s
|
||||||
|
ON s.id = t.name_id AND s.name = nd_name;
|
||||||
|
IF NOT FOUND THEN
|
||||||
|
RETURN 1;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Get dependency
|
||||||
|
SELECT INTO d_id t.name_id FROM tech.technologies t
|
||||||
|
INNER JOIN defs.strings s
|
||||||
|
ON s.id = t.name_id AND s.name = nd_dep;
|
||||||
|
IF NOT FOUND THEN
|
||||||
|
RETURN 2;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Add dependency
|
||||||
|
BEGIN
|
||||||
|
INSERT INTO tech.dependencies ( technology_id , depends_on )
|
||||||
|
VALUES ( t_id , d_id );
|
||||||
|
EXCEPTION
|
||||||
|
WHEN unique_violation THEN
|
||||||
|
RETURN 3;
|
||||||
|
END;
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION tech.add_dependency( TEXT, TEXT ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -140,14 +272,13 @@ GRANT EXECUTE ON FUNCTION tech.uoc_level( TEXT , INT , TEXT , TEXT , INT , INT )
|
||||||
-- bdc Cost
|
-- bdc Cost
|
||||||
-- bdw Work
|
-- bdw Work
|
||||||
-- bdu Upkeep
|
-- bdu Upkeep
|
||||||
-- bdtn Dependency (name)
|
-- bdtn Dependency
|
||||||
-- bdtl Dependency (level)
|
|
||||||
--
|
--
|
||||||
-- Returns:
|
-- Returns:
|
||||||
-- the buildable's identifier
|
-- the buildable's identifier
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION tech.uoc_buildable( bdn TEXT , bdd TEXT , bdc INT , bdw INT , bdu INT , bdtn TEXT , bdtl INT )
|
CREATE OR REPLACE FUNCTION tech.uoc_buildable( bdn TEXT , bdd TEXT , bdc INT , bdw INT , bdu INT , bdtn TEXT )
|
||||||
RETURNS INT
|
RETURNS INT
|
||||||
STRICT
|
STRICT
|
||||||
VOLATILE
|
VOLATILE
|
||||||
|
@ -162,10 +293,10 @@ BEGIN
|
||||||
SELECT INTO nid id FROM defs.strings WHERE name = bdn;
|
SELECT INTO nid id FROM defs.strings WHERE name = bdn;
|
||||||
SELECT INTO did id FROM defs.strings WHERE name = bdd;
|
SELECT INTO did id FROM defs.strings WHERE name = bdd;
|
||||||
IF bdtn <> '' THEN
|
IF bdtn <> '' THEN
|
||||||
SELECT INTO tdid tl.id FROM tech.levels tl
|
SELECT INTO tdid tl.name_id FROM tech.technologies tl
|
||||||
INNER JOIN defs.strings s
|
INNER JOIN defs.strings s
|
||||||
ON s.id = tl.line_id
|
ON s.id = tl.name_id
|
||||||
WHERE s.name = bdtn AND tl.level = bdtl;
|
WHERE s.name = bdtn;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Create or update the definition
|
-- Create or update the definition
|
||||||
|
@ -181,7 +312,7 @@ BEGIN
|
||||||
-- Set dependencies
|
-- Set dependencies
|
||||||
DELETE FROM tech.buildable_requirements WHERE buildable_id = nid;
|
DELETE FROM tech.buildable_requirements WHERE buildable_id = nid;
|
||||||
IF bdtn <> '' THEN
|
IF bdtn <> '' THEN
|
||||||
INSERT INTO tech.buildable_requirements ( buildable_id , level_id )
|
INSERT INTO tech.buildable_requirements ( buildable_id , technology_id )
|
||||||
VALUES ( nid , tdid );
|
VALUES ( nid , tdid );
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
@ -215,7 +346,7 @@ CREATE OR REPLACE FUNCTION tech.uoc_building( bdn TEXT , bdd TEXT , bdc INT , bd
|
||||||
DECLARE
|
DECLARE
|
||||||
bdid INT;
|
bdid INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
bdid := tech.uoc_buildable( bdn , bdd , bdc , bdw , bdu , '' , 0 );
|
bdid := tech.uoc_buildable( bdn , bdd , bdc , bdw , bdu , '' );
|
||||||
|
|
||||||
PERFORM buildable_id FROM tech.ships WHERE buildable_id = bdid;
|
PERFORM buildable_id FROM tech.ships WHERE buildable_id = bdid;
|
||||||
IF FOUND THEN
|
IF FOUND THEN
|
||||||
|
@ -249,22 +380,20 @@ GRANT EXECUTE ON FUNCTION tech.uoc_building( TEXT , TEXT , INT , INT , INT , INT
|
||||||
-- bdwk Workers
|
-- bdwk Workers
|
||||||
-- bdot Output type
|
-- bdot Output type
|
||||||
-- bdo Output
|
-- bdo Output
|
||||||
-- bdtn Dependency (name)
|
-- bdtn Dependency
|
||||||
-- bdtl Dependency (level)
|
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION tech.uoc_building( bdn TEXT , bdd TEXT , bdc INT , bdw INT ,
|
CREATE OR REPLACE FUNCTION tech.uoc_building( bdn TEXT , bdd TEXT , bdc INT , bdw INT ,
|
||||||
bdu INT , bdwk INT , bdot building_output_type , bdo INT ,
|
bdu INT , bdwk INT , bdot building_output_type , bdo INT ,
|
||||||
bdtn TEXT , bdtl INT )
|
bdtn TEXT )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT
|
STRICT VOLATILE
|
||||||
VOLATILE
|
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
bdid INT;
|
bdid INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
bdid := tech.uoc_buildable( bdn , bdd , bdc , bdw , bdu , bdtn , bdtl );
|
bdid := tech.uoc_buildable( bdn , bdd , bdc , bdw , bdu , bdtn );
|
||||||
|
|
||||||
PERFORM buildable_id FROM tech.ships WHERE buildable_id = bdid;
|
PERFORM buildable_id FROM tech.ships WHERE buildable_id = bdid;
|
||||||
IF FOUND THEN
|
IF FOUND THEN
|
||||||
|
@ -282,7 +411,7 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
GRANT EXECUTE ON FUNCTION tech.uoc_building( TEXT , TEXT , INT , INT , INT , INT , building_output_type , INT , TEXT , INT ) TO :dbuser;
|
GRANT EXECUTE ON FUNCTION tech.uoc_building( TEXT , TEXT , INT , INT , INT , INT , building_output_type , INT , TEXT ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -309,7 +438,7 @@ CREATE OR REPLACE FUNCTION tech.uoc_ship( sn TEXT , sd TEXT , sc INT , sw INT ,
|
||||||
DECLARE
|
DECLARE
|
||||||
bdid INT;
|
bdid INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
bdid := tech.uoc_buildable( sn , sd , sc , sw , su , '' , 0 );
|
bdid := tech.uoc_buildable( sn , sd , sc , sw , su , '' );
|
||||||
|
|
||||||
PERFORM buildable_id FROM tech.buildings WHERE buildable_id = bdid;
|
PERFORM buildable_id FROM tech.buildings WHERE buildable_id = bdid;
|
||||||
IF FOUND THEN
|
IF FOUND THEN
|
||||||
|
@ -342,12 +471,11 @@ GRANT EXECUTE ON FUNCTION tech.uoc_ship( TEXT , TEXT , INT , INT , INT , INT , I
|
||||||
-- su Upkeep
|
-- su Upkeep
|
||||||
-- sp Power
|
-- sp Power
|
||||||
-- sft Orbital flight time
|
-- sft Orbital flight time
|
||||||
-- stdn Tech line name
|
-- stdn Tech name
|
||||||
-- stdl Tech level
|
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION tech.uoc_ship( sn TEXT , sd TEXT , sc INT , sw INT ,
|
CREATE OR REPLACE FUNCTION tech.uoc_ship( sn TEXT , sd TEXT , sc INT , sw INT ,
|
||||||
su INT , sp INT , sft INT , stdn TEXT , stdl INT )
|
su INT , sp INT , sft INT , stdn TEXT )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT
|
STRICT
|
||||||
VOLATILE
|
VOLATILE
|
||||||
|
@ -356,7 +484,7 @@ CREATE OR REPLACE FUNCTION tech.uoc_ship( sn TEXT , sd TEXT , sc INT , sw INT ,
|
||||||
DECLARE
|
DECLARE
|
||||||
bdid INT;
|
bdid INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
bdid := tech.uoc_buildable( sn , sd , sc , sw , su , stdn , stdl );
|
bdid := tech.uoc_buildable( sn , sd , sc , sw , su , stdn );
|
||||||
|
|
||||||
PERFORM buildable_id FROM tech.buildings WHERE buildable_id = bdid;
|
PERFORM buildable_id FROM tech.buildings WHERE buildable_id = bdid;
|
||||||
IF FOUND THEN
|
IF FOUND THEN
|
||||||
|
@ -374,6 +502,6 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
GRANT EXECUTE ON FUNCTION tech.uoc_ship( TEXT , TEXT , INT , INT , INT , INT , INT , TEXT , INT ) TO :dbuser;
|
GRANT EXECUTE ON FUNCTION tech.uoc_ship( TEXT , TEXT , INT , INT , INT , INT , INT , TEXT ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
--
|
--
|
||||||
-- Empire management functions and views
|
-- Empire management functions and views
|
||||||
--
|
--
|
||||||
-- Copyright(C) 2004-2010, DeepClone Development
|
-- Copyright(C) 2004-2011, DeepClone Development
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
||||||
-- pid Planet identifier
|
-- pid Planet identifier
|
||||||
-- icash Initial cash
|
-- icash Initial cash
|
||||||
--
|
--
|
||||||
CREATE OR REPLACE FUNCTION emp.create_empire( nid INT , pid INT , icash REAL )
|
CREATE OR REPLACE FUNCTION emp.create_empire( nid INT , pid INT , icash DOUBLE PRECISION )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT
|
STRICT
|
||||||
VOLATILE
|
VOLATILE
|
||||||
|
@ -81,49 +81,6 @@ $$ LANGUAGE SQL;
|
||||||
GRANT EXECUTE ON FUNCTION emp.get_current( INT ) TO :dbuser;
|
GRANT EXECUTE ON FUNCTION emp.get_current( INT ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Implements a technology
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION emp.implement_tech( e_id INT , l_id INT )
|
|
||||||
RETURNS VOID
|
|
||||||
STRICT VOLATILE
|
|
||||||
SECURITY DEFINER
|
|
||||||
AS $$
|
|
||||||
DECLARE
|
|
||||||
e_cash REAL;
|
|
||||||
lev INT;
|
|
||||||
cost REAL;
|
|
||||||
BEGIN
|
|
||||||
SELECT INTO e_cash , lev , cost e.cash , et.level , tl.cost
|
|
||||||
FROM emp.empires e
|
|
||||||
INNER JOIN emp.technologies et
|
|
||||||
ON et.line_id = l_id AND et.empire_id = e.name_id
|
|
||||||
INNER JOIN tech.levels tl
|
|
||||||
ON tl.line_id = l_id AND tl.level = et.level
|
|
||||||
AND tl.points = floor( et.accumulated )
|
|
||||||
AND tl.cost <= e.cash
|
|
||||||
WHERE e.name_id = e_id
|
|
||||||
FOR UPDATE OF e , et;
|
|
||||||
|
|
||||||
IF NOT FOUND THEN
|
|
||||||
RETURN;
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
UPDATE emp.empires
|
|
||||||
SET cash = e_cash - cost
|
|
||||||
WHERE name_id = e_id;
|
|
||||||
UPDATE emp.technologies
|
|
||||||
SET level = lev + 1 , accumulated = 0
|
|
||||||
WHERE empire_id = e_id AND line_id = l_id;
|
|
||||||
END;
|
|
||||||
$$ LANGUAGE plpgsql;
|
|
||||||
|
|
||||||
GRANT EXECUTE ON FUNCTION emp.implement_tech( INT , INT ) TO :dbuser;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Add an enemy empire
|
-- Add an enemy empire
|
||||||
--
|
--
|
||||||
|
@ -413,7 +370,7 @@ CREATE OR REPLACE FUNCTION emp.get_new_planet( e_id INT , p_name TEXT , OUT err_
|
||||||
DECLARE
|
DECLARE
|
||||||
plid INT;
|
plid INT;
|
||||||
accid INT;
|
accid INT;
|
||||||
ccash REAL;
|
ccash DOUBLE PRECISION;
|
||||||
f_id BIGINT;
|
f_id BIGINT;
|
||||||
fleets BIGINT[];
|
fleets BIGINT[];
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -484,7 +441,7 @@ CREATE VIEW emp.enemies
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE VIEW emp.general_information
|
CREATE VIEW emp.general_information
|
||||||
AS SELECT e.name_id AS id , en.name AS name ,
|
AS SELECT e.name_id AS id , en.name AS name , av.language ,
|
||||||
( CASE
|
( CASE
|
||||||
WHEN av.status = 'QUITTING' THEN 'q'
|
WHEN av.status = 'QUITTING' THEN 'q'
|
||||||
WHEN av.status = 'VACATION' THEN 'v'
|
WHEN av.status = 'VACATION' THEN 'v'
|
||||||
|
@ -600,50 +557,6 @@ CREATE VIEW emp.overview
|
||||||
GRANT SELECT ON emp.overview TO :dbuser;
|
GRANT SELECT ON emp.overview TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Empire tech lines
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE VIEW emp.tech_lines_view
|
|
||||||
AS SELECT e.name_id AS empire , tl.name_id AS tech_line ,
|
|
||||||
t1.translated_string AS name ,
|
|
||||||
t2.translated_string AS description
|
|
||||||
FROM emp.empires e
|
|
||||||
INNER JOIN emp.technologies et ON et.empire_id = e.name_id
|
|
||||||
INNER JOIN tech.lines tl ON tl.name_id = et.line_id
|
|
||||||
INNER JOIN naming.empire_names en ON en.id = e.name_id
|
|
||||||
INNER JOIN users.credentials c ON c.address_id = en.owner_id
|
|
||||||
INNER JOIN defs.translations t1 ON t1.string_id = tl.name_id AND t1.lang_id = c.language_id
|
|
||||||
INNER JOIN defs.translations t2 ON t2.string_id = tl.description_id AND t2.lang_id = c.language_id
|
|
||||||
ORDER BY t1.translated_string;
|
|
||||||
|
|
||||||
GRANT SELECT ON emp.tech_lines_view TO :dbuser;
|
|
||||||
|
|
||||||
|
|
||||||
--
|
|
||||||
-- Empire technologies
|
|
||||||
--
|
|
||||||
|
|
||||||
CREATE VIEW emp.technologies_view
|
|
||||||
AS SELECT e.name_id AS empire , tl.name_id AS tech_line ,
|
|
||||||
t1.translated_string AS name ,
|
|
||||||
t2.translated_string AS description ,
|
|
||||||
( et.level > tlv.level ) AS implemented ,
|
|
||||||
floor( 100 * et.accumulated / tlv.points ) AS progress ,
|
|
||||||
tlv.cost AS cost
|
|
||||||
FROM emp.empires e
|
|
||||||
INNER JOIN emp.technologies et ON et.empire_id = e.name_id
|
|
||||||
INNER JOIN tech.lines tl ON tl.name_id = et.line_id
|
|
||||||
INNER JOIN tech.levels tlv ON tlv.line_id = tl.name_id AND tlv.level <= et.level
|
|
||||||
INNER JOIN naming.empire_names en ON en.id = e.name_id
|
|
||||||
INNER JOIN users.credentials c ON c.address_id = en.owner_id
|
|
||||||
INNER JOIN defs.translations t1 ON t1.string_id = tlv.name_id AND t1.lang_id = c.language_id
|
|
||||||
INNER JOIN defs.translations t2 ON t2.string_id = tlv.description_id AND t2.lang_id = c.language_id
|
|
||||||
ORDER BY tl.name_id , tlv.level;
|
|
||||||
|
|
||||||
GRANT SELECT ON emp.technologies_view TO :dbuser;
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Enemy lists
|
-- Enemy lists
|
||||||
--
|
--
|
||||||
|
|
|
@ -0,0 +1,227 @@
|
||||||
|
-- LegacyWorlds Beta 6
|
||||||
|
-- PostgreSQL database scripts
|
||||||
|
--
|
||||||
|
-- Research mananagement functions and views
|
||||||
|
--
|
||||||
|
-- Copyright(C) 2004-2011, DeepClone Development
|
||||||
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Implement a technology
|
||||||
|
--
|
||||||
|
-- Parameters:
|
||||||
|
-- e_id Empire identifier
|
||||||
|
-- t_name Technology name
|
||||||
|
--
|
||||||
|
-- Returns:
|
||||||
|
-- 0 on success
|
||||||
|
-- 1 if the empire does not posses the necessary resources
|
||||||
|
-- 2 if the technology or empire were not found
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION emp.implement_tech( e_id INT , t_name TEXT )
|
||||||
|
RETURNS INT
|
||||||
|
STRICT VOLATILE
|
||||||
|
SECURITY DEFINER
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
e_cash DOUBLE PRECISION;
|
||||||
|
t_id INT;
|
||||||
|
t_cost DOUBLE PRECISION;
|
||||||
|
BEGIN
|
||||||
|
SELECT INTO e_cash , t_id , t_cost e.cash , ns.id , td.cost
|
||||||
|
FROM defs.strings ns
|
||||||
|
INNER JOIN tech.technologies td
|
||||||
|
ON td.name_id = ns.id
|
||||||
|
INNER JOIN emp.researched_technologies rt
|
||||||
|
ON rt.technology_id = td.name_id
|
||||||
|
INNER JOIN emp.empires e
|
||||||
|
ON rt.empire_id = e.name_id
|
||||||
|
WHERE e.name_id = e_id AND ns.name = t_name
|
||||||
|
FOR UPDATE OF e , rt;
|
||||||
|
IF NOT FOUND THEN
|
||||||
|
RETURN 2;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
IF e_cash < t_cost THEN
|
||||||
|
RETURN 1;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
UPDATE emp.empires
|
||||||
|
SET cash = e_cash - t_cost
|
||||||
|
WHERE name_id = e_id;
|
||||||
|
UPDATE emp.researched_technologies
|
||||||
|
SET implemented = TRUE
|
||||||
|
WHERE empire_id = e_id AND technology_id = t_id;
|
||||||
|
|
||||||
|
RETURN 0;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION emp.implement_tech( INT , TEXT ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Prepare for research priorities updates
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION emp.prepare_research_priorities_update( )
|
||||||
|
RETURNS VOID
|
||||||
|
STRICT VOLATILE
|
||||||
|
SECURITY DEFINER
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
CREATE TEMPORARY TABLE research_priorities_updates(
|
||||||
|
technology TEXT ,
|
||||||
|
priority INT
|
||||||
|
);
|
||||||
|
CREATE INDEX rpu_technology ON research_priorities_updates ( technology );
|
||||||
|
IF session_user <> current_user THEN
|
||||||
|
EXECUTE 'GRANT INSERT ON research_priorities_updates TO ' || session_user;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION emp.prepare_research_priorities_update( ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Applies research priorities updates
|
||||||
|
--
|
||||||
|
-- Parameters:
|
||||||
|
-- e_id identifier of the empire the updates should be applied to
|
||||||
|
--
|
||||||
|
-- Returns:
|
||||||
|
-- an error code:
|
||||||
|
-- 0 success
|
||||||
|
-- 1 list of updates does not match current research topics
|
||||||
|
-- 2 invalid priorities
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION emp.apply_research_priorities( IN e_id INT )
|
||||||
|
RETURNS INT
|
||||||
|
STRICT VOLATILE
|
||||||
|
SECURITY DEFINER
|
||||||
|
AS $$
|
||||||
|
DECLARE
|
||||||
|
rec RECORD;
|
||||||
|
t INT;
|
||||||
|
rval INT;
|
||||||
|
BEGIN
|
||||||
|
-- Lock empire and research info
|
||||||
|
PERFORM er.technology_id
|
||||||
|
FROM emp.empires e
|
||||||
|
INNER JOIN emp.research er ON er.empire_id = e.name_id
|
||||||
|
WHERE e.name_id = e_id
|
||||||
|
FOR UPDATE OF e , er;
|
||||||
|
|
||||||
|
-- Check values
|
||||||
|
t := 0;
|
||||||
|
rval := 0;
|
||||||
|
FOR rec IN SELECT rpu.priority , r.technology_id FROM research_priorities_updates rpu
|
||||||
|
LEFT OUTER JOIN emp.research_view r
|
||||||
|
ON ( r.detailed AND r.technology = rpu.technology )
|
||||||
|
OR ( NOT r.detailed AND ( 'unknown-' || ( r.technology_id * e_id )::TEXT ) = rpu.technology )
|
||||||
|
WHERE r.empire = e_id OR r.empire IS NULL
|
||||||
|
UNION SELECT rpu.priority , r.technology_id FROM research_priorities_updates rpu
|
||||||
|
RIGHT OUTER JOIN emp.research_view r
|
||||||
|
ON ( r.detailed AND r.technology = rpu.technology )
|
||||||
|
OR ( NOT r.detailed AND ( 'unknown-' || ( r.technology_id * e_id )::TEXT ) = rpu.technology )
|
||||||
|
WHERE r.empire = e_id
|
||||||
|
LOOP
|
||||||
|
IF rec.priority IS NULL OR rec.technology_id IS NULL THEN
|
||||||
|
rval := 1;
|
||||||
|
EXIT;
|
||||||
|
ELSIF rec.priority NOT BETWEEN 0 AND 100 THEN
|
||||||
|
rval := 2;
|
||||||
|
EXIT;
|
||||||
|
END IF;
|
||||||
|
t := t + rec.priority;
|
||||||
|
END LOOP;
|
||||||
|
IF rval = 0 AND t <> 100 THEN
|
||||||
|
rval := 2;
|
||||||
|
END IF;
|
||||||
|
|
||||||
|
-- Update research info
|
||||||
|
IF rval = 0 THEN
|
||||||
|
UPDATE emp.research er SET priority = rpu.priority
|
||||||
|
FROM research_priorities_updates rpu , emp.research_view rv
|
||||||
|
WHERE ( rpu.technology = CASE
|
||||||
|
WHEN rv.detailed THEN
|
||||||
|
rv.technology
|
||||||
|
ELSE
|
||||||
|
( 'unknown-' || ( rv.technology_id * e_id )::TEXT )
|
||||||
|
END )
|
||||||
|
AND rv.empire = e_id
|
||||||
|
AND er.empire_id = e_id
|
||||||
|
AND er.technology_id = rv.technology_id;
|
||||||
|
END IF;
|
||||||
|
DROP TABLE research_priorities_updates;
|
||||||
|
RETURN rval;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION emp.apply_research_priorities( INT ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Base research view
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE VIEW emp.base_research_view
|
||||||
|
AS SELECT er.empire_id AS empire , er.technology_id , ns.name AS technology ,
|
||||||
|
td.points AS required , ( CASE
|
||||||
|
WHEN er.accumulated > td.points THEN
|
||||||
|
td.points - 1
|
||||||
|
ELSE
|
||||||
|
er.accumulated
|
||||||
|
END ) AS accumulated , er.priority
|
||||||
|
FROM emp.research er
|
||||||
|
INNER JOIN tech.technologies td ON td.name_id = er.technology_id
|
||||||
|
INNER JOIN defs.strings ns ON ns.id = er.technology_id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Research view
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE VIEW emp.research_view
|
||||||
|
AS SELECT empire , technology , technology_id ,
|
||||||
|
FLOOR( 100 * accumulated / required )::INT AS completion ,
|
||||||
|
( accumulated >= sys.get_constant( 'game.research.minPoints' )
|
||||||
|
OR accumulated / required >= sys.get_constant( 'game.research.minRatio' ) ) AS detailed ,
|
||||||
|
priority
|
||||||
|
FROM emp.base_research_view;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Researched and implemented technologies view
|
||||||
|
|
||||||
|
CREATE VIEW emp.known_techs_view
|
||||||
|
AS SELECT et.empire_id AS empire , et.technology_id , ns.name AS technology ,
|
||||||
|
( CASE WHEN et.implemented THEN NULL::INT ELSE td.cost END ) AS cost
|
||||||
|
FROM emp.researched_technologies et
|
||||||
|
INNER JOIN tech.technologies td ON td.name_id = et.technology_id
|
||||||
|
INNER JOIN defs.strings ns ON ns.id = et.technology_id;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Combined research and technologies view
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE VIEW emp.technologies_view
|
||||||
|
AS SELECT empire , technology_id , technology ,
|
||||||
|
detailed , completion , priority , NULL::INT AS cost
|
||||||
|
FROM emp.research_view
|
||||||
|
UNION ALL SELECT empire , technology_id , technology ,
|
||||||
|
TRUE AS detailed , NULL::INT AS completion , NULL::INT AS priority , cost
|
||||||
|
FROM emp.known_techs_view;
|
||||||
|
|
||||||
|
GRANT SELECT ON emp.technologies_view TO :dbuser;
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
-- sigma( x ) = exp( x ) / ( 1 + exp( x ) )
|
-- sigma( x ) = exp( x ) / ( 1 + exp( x ) )
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.sigma( x REAL )
|
CREATE OR REPLACE FUNCTION verse.sigma( x DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE SECURITY INVOKER
|
STRICT IMMUTABLE SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
SELECT ( CASE
|
SELECT ( CASE
|
||||||
WHEN $1 < -100 THEN 0
|
WHEN $1 < -100 THEN 0
|
||||||
WHEN $1 > 100 THEN 1
|
WHEN $1 > 100 THEN 1
|
||||||
ELSE ( exp( $1 ) / ( 1 + exp( $1 ) ) )::REAL
|
ELSE ( exp( $1 ) / ( 1 + exp( $1 ) ) )
|
||||||
END );
|
END );
|
||||||
$$ LANGUAGE SQL;
|
$$ LANGUAGE SQL;
|
||||||
|
|
||||||
|
@ -28,8 +28,8 @@ $$ LANGUAGE SQL;
|
||||||
-- poly( x , a , b , c ) = ( a * x + b ) * x + c
|
-- poly( x , a , b , c ) = ( a * x + b ) * x + c
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.poly( x REAL , a REAL , b REAL , c REAL )
|
CREATE OR REPLACE FUNCTION verse.poly( x DOUBLE PRECISION , a DOUBLE PRECISION , b DOUBLE PRECISION , c DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE SECURITY INVOKER
|
STRICT IMMUTABLE SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
SELECT ( $2 * $1 + $3 ) * $1 + $4;
|
SELECT ( $2 * $1 + $3 ) * $1 + $4;
|
||||||
|
@ -41,11 +41,11 @@ $$ LANGUAGE SQL;
|
||||||
-- Happiness curve, K1 constant
|
-- Happiness curve, K1 constant
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.hcc_const_k1( xmax REAL , ymax REAL , xlimit REAL , ylimit REAL )
|
CREATE OR REPLACE FUNCTION verse.hcc_const_k1( xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE SECURITY INVOKER
|
STRICT IMMUTABLE SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
SELECT ( ( $4 - $2 ) / ( ( $3 - $1 ) ^ 2 ) )::REAL;
|
SELECT ( ( $4 - $2 ) / ( ( $3 - $1 ) ^ 2 ) );
|
||||||
$$ LANGUAGE SQL;
|
$$ LANGUAGE SQL;
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,11 +54,11 @@ $$ LANGUAGE SQL;
|
||||||
-- Happiness curve, K2 constant
|
-- Happiness curve, K2 constant
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.hcc_const_k2( ylimit REAL , yasymptote REAL )
|
CREATE OR REPLACE FUNCTION verse.hcc_const_k2( ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE SECURITY INVOKER
|
STRICT IMMUTABLE SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
SELECT ( 2 * ( $1 - $2 ) )::REAL;
|
SELECT ( 2 * ( $1 - $2 ) );
|
||||||
$$ LANGUAGE SQL;
|
$$ LANGUAGE SQL;
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,11 +67,11 @@ $$ LANGUAGE SQL;
|
||||||
-- Happiness curve, K3 constant
|
-- Happiness curve, K3 constant
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.hcc_const_k3( xmax REAL , ymax REAL , xlimit REAL , ylimit REAL , yasymptote REAL )
|
CREATE OR REPLACE FUNCTION verse.hcc_const_k3( xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE SECURITY INVOKER
|
STRICT IMMUTABLE SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
SELECT ( verse.hcc_const_k1( $1 , $2 , $3 , $4 ) * 4 * ( $3 - $1 ) / ( $5 - $4 ) ) ::REAL;
|
SELECT ( verse.hcc_const_k1( $1 , $2 , $3 , $4 ) * 4 * ( $3 - $1 ) / ( $5 - $4 ) );
|
||||||
$$ LANGUAGE SQL;
|
$$ LANGUAGE SQL;
|
||||||
|
|
||||||
|
|
||||||
|
@ -80,15 +80,15 @@ $$ LANGUAGE SQL;
|
||||||
-- Happiness curve, first part
|
-- Happiness curve, first part
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.hcc_part_1( x REAL , ymin REAL , ymax REAL , xmax REAL )
|
CREATE OR REPLACE FUNCTION verse.hcc_part_1( x DOUBLE PRECISION , ymin DOUBLE PRECISION , ymax DOUBLE PRECISION , xmax DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE SECURITY INVOKER
|
STRICT IMMUTABLE SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
v REAL;
|
v DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
v := ( ymin - ymax ) / xmax;
|
v := ( ymin - ymax ) / xmax;
|
||||||
RETURN verse.poly( x , ( v / xmax )::REAL , ( -2 * v )::REAL , ymin );
|
RETURN verse.poly( x , v / xmax , -2 * v , ymin );
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
@ -98,15 +98,15 @@ $$ LANGUAGE plpgsql;
|
||||||
-- Happiness curve, second part
|
-- Happiness curve, second part
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.hcc_part_2( x REAL , xmax REAL , ymax REAL , xlimit REAL , ylimit REAL )
|
CREATE OR REPLACE FUNCTION verse.hcc_part_2( x DOUBLE PRECISION , xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE SECURITY INVOKER
|
STRICT IMMUTABLE SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
k1 REAL;
|
k1 DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
k1 := verse.hcc_const_k1( xmax , ymax , xlimit , ylimit );
|
k1 := verse.hcc_const_k1( xmax , ymax , xlimit , ylimit );
|
||||||
RETURN verse.poly( x , k1 , ( -2 * xmax * k1 )::REAL , ( ymax + k1 * xmax * xmax )::REAL );
|
RETURN verse.poly( x , k1 , -2 * xmax * k1 , ymax + k1 * xmax * xmax );
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
@ -116,17 +116,17 @@ $$ LANGUAGE plpgsql;
|
||||||
-- Happiness curve, third part
|
-- Happiness curve, third part
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.hcc_part_3( x REAL , xmax REAL , ymax REAL , xlimit REAL , ylimit REAL , yasymptote REAL )
|
CREATE OR REPLACE FUNCTION verse.hcc_part_3( x DOUBLE PRECISION , xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE SECURITY INVOKER
|
STRICT IMMUTABLE SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
k2 REAL;
|
k2 DOUBLE PRECISION;
|
||||||
k3 REAL;
|
k3 DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
k2 := verse.hcc_const_k2( ylimit , yasymptote );
|
k2 := verse.hcc_const_k2( ylimit , yasymptote );
|
||||||
k3 := verse.hcc_const_k3( xmax , ymax , xlimit , ylimit , yasymptote );
|
k3 := verse.hcc_const_k3( xmax , ymax , xlimit , ylimit , yasymptote );
|
||||||
RETURN yasymptote + k2 * ( 1 - verse.sigma( ( k3 * ( x - xlimit ) ) )::REAL );
|
RETURN yasymptote + k2 * ( 1 - verse.sigma( ( k3 * ( x - xlimit ) ) ) );
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
@ -136,8 +136,8 @@ $$ LANGUAGE plpgsql;
|
||||||
-- Happiness curve
|
-- Happiness curve
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.happiness_curve( x REAL , ymin REAL , xmax REAL , ymax REAL , xlimit REAL , ylimit REAL , yasymptote REAL )
|
CREATE OR REPLACE FUNCTION verse.happiness_curve( x DOUBLE PRECISION , ymin DOUBLE PRECISION , xmax DOUBLE PRECISION , ymax DOUBLE PRECISION , xlimit DOUBLE PRECISION , ylimit DOUBLE PRECISION , yasymptote DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE SECURITY INVOKER
|
STRICT IMMUTABLE SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
SELECT (CASE
|
SELECT (CASE
|
||||||
|
@ -156,37 +156,37 @@ $$ LANGUAGE SQL;
|
||||||
-- Happiness computation
|
-- Happiness computation
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.compute_happiness( population REAL , workers REAL , defence REAL , empsize INT )
|
CREATE OR REPLACE FUNCTION verse.compute_happiness( population DOUBLE PRECISION , workers DOUBLE PRECISION , defence DOUBLE PRECISION , empsize INT )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT STABLE SECURITY INVOKER
|
STRICT STABLE SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
whappiness REAL;
|
whappiness DOUBLE PRECISION;
|
||||||
dhappiness REAL;
|
dhappiness DOUBLE PRECISION;
|
||||||
shappiness REAL;
|
shappiness DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Work-related happiness
|
-- Work-related happiness
|
||||||
whappiness := verse.happiness_curve(
|
whappiness := verse.happiness_curve(
|
||||||
( workers / population )::REAL ,
|
workers / population ,
|
||||||
sys.get_constant( 'game.happiness.noEmployment' ) , 1.0 , 1.0 ,
|
sys.get_constant( 'game.happiness.noEmployment' ) , 1.0 , 1.0 ,
|
||||||
sys.get_constant( 'game.happiness.employmentLimit' ) , 0.5 , 0
|
sys.get_constant( 'game.happiness.employmentLimit' ) , 0.5 , 0
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Defence-related happiness
|
-- Defence-related happiness
|
||||||
dhappiness := verse.happiness_curve(
|
dhappiness := verse.happiness_curve(
|
||||||
( sys.get_constant( 'game.happiness.popPerDefencePoint' ) * defence / population )::REAL ,
|
sys.get_constant( 'game.happiness.popPerDefencePoint' ) * defence / population ,
|
||||||
sys.get_constant( 'game.happiness.noDefence' ) , 1.0 , 1.0 ,
|
sys.get_constant( 'game.happiness.noDefence' ) , 1.0 , 1.0 ,
|
||||||
sys.get_constant( 'game.happiness.defenceLimit' ) , 0.5 , 0
|
sys.get_constant( 'game.happiness.defenceLimit' ) , 0.5 , 0
|
||||||
);
|
);
|
||||||
|
|
||||||
-- Influence of empire size
|
-- Influence of empire size
|
||||||
shappiness := verse.happiness_curve(
|
shappiness := verse.happiness_curve(
|
||||||
( empsize::REAL / sys.get_constant( 'game.happiness.idealEmpireSize' ) )::REAL ,
|
empsize / sys.get_constant( 'game.happiness.idealEmpireSize' ) ,
|
||||||
sys.get_constant( 'game.happiness.smallEmpire' ) , 1.0 , 1.0 ,
|
sys.get_constant( 'game.happiness.smallEmpire' ) , 1.0 , 1.0 ,
|
||||||
sys.get_constant( 'game.happiness.eSizeLimit' ) , 0.5 , 0
|
sys.get_constant( 'game.happiness.eSizeLimit' ) , 0.5 , 0
|
||||||
);
|
);
|
||||||
|
|
||||||
RETURN ( shappiness * ( whappiness + dhappiness ) / 2.0 )::REAL;
|
RETURN shappiness * ( whappiness + dhappiness ) / 2.0;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
@ -195,14 +195,14 @@ $$ LANGUAGE plpgsql;
|
||||||
--
|
--
|
||||||
-- Production adjustment
|
-- Production adjustment
|
||||||
--
|
--
|
||||||
CREATE OR REPLACE FUNCTION verse.adjust_production( prod REAL , happiness REAL )
|
CREATE OR REPLACE FUNCTION verse.adjust_production( prod DOUBLE PRECISION , happiness DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE
|
STRICT IMMUTABLE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
SELECT ( CASE
|
SELECT ( CASE
|
||||||
WHEN $2 < sys.get_constant( 'game.happiness.strike' ) THEN
|
WHEN $2 < sys.get_constant( 'game.happiness.strike' ) THEN
|
||||||
( $1 * ( 1 - ( $2 / sys.get_constant( 'game.happiness.strike' ) ) ) )::REAL
|
$1 * ( 1 - ( $2 / sys.get_constant( 'game.happiness.strike' ) ) )
|
||||||
ELSE
|
ELSE
|
||||||
$1
|
$1
|
||||||
END );
|
END );
|
||||||
|
@ -213,15 +213,15 @@ $$ LANGUAGE SQL;
|
||||||
-- Income computation
|
-- Income computation
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.compute_income( population REAL , happiness REAL , cashprod REAL )
|
CREATE OR REPLACE FUNCTION verse.compute_income( population DOUBLE PRECISION , happiness DOUBLE PRECISION , cashprod DOUBLE PRECISION )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT STABLE
|
STRICT STABLE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
base REAL;
|
base DOUBLE PRECISION;
|
||||||
badj REAL;
|
badj DOUBLE PRECISION;
|
||||||
cprod REAL;
|
cprod DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
badj := ( 1 - verse.adjust_production( 1.0 , happiness ) ) * sys.get_constant( 'game.work.strikeEffect' );
|
badj := ( 1 - verse.adjust_production( 1.0 , happiness ) ) * sys.get_constant( 'game.work.strikeEffect' );
|
||||||
base := floor( population ) * sys.get_constant( 'game.work.population' ) * ( 1 - badj );
|
base := floor( population ) * sys.get_constant( 'game.work.population' ) * ( 1 - badj );
|
||||||
|
|
|
@ -19,14 +19,14 @@
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.get_raw_production( pid INT , pt building_output_type )
|
CREATE OR REPLACE FUNCTION verse.get_raw_production( pid INT , pt building_output_type )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT STABLE
|
STRICT STABLE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
rv REAL;
|
rv DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT INTO rv SUM( b.amount * d.output )::REAL
|
SELECT INTO rv SUM( b.amount * d.output )
|
||||||
FROM verse.planet_buildings b
|
FROM verse.planet_buildings b
|
||||||
INNER JOIN tech.buildings d
|
INNER JOIN tech.buildings d
|
||||||
ON d.buildable_id = b.building_id AND d.output_type = pt
|
ON d.buildable_id = b.building_id AND d.output_type = pt
|
||||||
|
@ -114,14 +114,14 @@ $$ LANGUAGE SQL;
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.get_planet_upkeep( pid INT )
|
CREATE OR REPLACE FUNCTION verse.get_planet_upkeep( pid INT )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT STABLE
|
STRICT STABLE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
rv REAL;
|
rv DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT INTO rv SUM( b.amount * d.upkeep )::REAL
|
SELECT INTO rv SUM( b.amount * d.upkeep )
|
||||||
FROM verse.planet_buildings b
|
FROM verse.planet_buildings b
|
||||||
INNER JOIN tech.buildables d
|
INNER JOIN tech.buildables d
|
||||||
ON d.name_id = b.building_id
|
ON d.name_id = b.building_id
|
||||||
|
@ -145,7 +145,7 @@ $$ LANGUAGE plpgsql;
|
||||||
-- npics Amount of planet pictures
|
-- npics Amount of planet pictures
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.create_planet( sid INT , o INT , ipop REAL , npics INT )
|
CREATE OR REPLACE FUNCTION verse.create_planet( sid INT , o INT , ipop DOUBLE PRECISION , npics INT )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
|
@ -156,7 +156,7 @@ DECLARE
|
||||||
bpp INT;
|
bpp INT;
|
||||||
uid BIGINT;
|
uid BIGINT;
|
||||||
utp update_type;
|
utp update_type;
|
||||||
happiness REAL;
|
happiness DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Planet name and planet
|
-- Planet name and planet
|
||||||
pnid := naming.create_map_name( 'P' );
|
pnid := naming.create_map_name( 'P' );
|
||||||
|
@ -217,7 +217,7 @@ $$ LANGUAGE plpgsql;
|
||||||
-- npics Amount of planet pictures
|
-- npics Amount of planet pictures
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.create_system( sx INT , sy INT , ipop REAL , npics INT )
|
CREATE OR REPLACE FUNCTION verse.create_system( sx INT , sy INT , ipop DOUBLE PRECISION , npics INT )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
|
@ -249,7 +249,7 @@ $$ LANGUAGE plpgsql;
|
||||||
-- ipop Initial population
|
-- ipop Initial population
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.create_systems( x0 INT , y0 INT , x1 INT , y1 INT , ipop REAL )
|
CREATE OR REPLACE FUNCTION verse.create_systems( x0 INT , y0 INT , x1 INT , y1 INT , ipop DOUBLE PRECISION )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
|
@ -283,7 +283,7 @@ CREATE OR REPLACE FUNCTION verse.generate_initial_universe( )
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
sz INT;
|
sz INT;
|
||||||
pop REAL;
|
pop DOUBLE PRECISION;
|
||||||
npics INT;
|
npics INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
sz := floor( sys.get_constant( 'game.universe.initialSize' ) );
|
sz := floor( sys.get_constant( 'game.universe.initialSize' ) );
|
||||||
|
@ -316,7 +316,7 @@ DECLARE
|
||||||
y0 INT;
|
y0 INT;
|
||||||
x1 INT;
|
x1 INT;
|
||||||
y1 INT;
|
y1 INT;
|
||||||
pop REAL;
|
pop DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get current bounds
|
-- Get current bounds
|
||||||
SELECT INTO min_x , max_x , min_y , max_y
|
SELECT INTO min_x , max_x , min_y , max_y
|
||||||
|
@ -368,7 +368,7 @@ CREATE OR REPLACE FUNCTION verse.generate( )
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
p_count INT;
|
p_count INT;
|
||||||
f_ratio REAL;
|
f_ratio DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get total planet count
|
-- Get total planet count
|
||||||
SELECT INTO p_count 5 * count(*)
|
SELECT INTO p_count 5 * count(*)
|
||||||
|
@ -381,7 +381,7 @@ BEGIN
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
-- Get available planets ratio
|
-- Get available planets ratio
|
||||||
SELECT INTO f_ratio count(*)::REAL / p_count::REAL
|
SELECT INTO f_ratio count(*)::DOUBLE PRECISION / p_count::DOUBLE PRECISION
|
||||||
FROM verse.available_planets;
|
FROM verse.available_planets;
|
||||||
|
|
||||||
-- Expand universe if required
|
-- Expand universe if required
|
||||||
|
|
|
@ -175,17 +175,17 @@ CREATE OR REPLACE FUNCTION verse.get_orbital_view( e_id INT , p_id INT )
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
rv planet_orbital_data;
|
rv planet_orbital_data;
|
||||||
happ REAL;
|
happ DOUBLE PRECISION;
|
||||||
e_att BOOLEAN;
|
e_att BOOLEAN;
|
||||||
rec RECORD;
|
rec RECORD;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get the planet's population and defence
|
-- Get the planet's population and defence
|
||||||
SELECT INTO rv.population , happ
|
SELECT INTO rv.population , happ
|
||||||
floor( p.population )::BIGINT , ( ph.current / p.population )::REAL
|
floor( p.population )::BIGINT , ( ph.current / p.population )::DOUBLE PRECISION
|
||||||
FROM verse.planets p
|
FROM verse.planets p
|
||||||
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
||||||
WHERE p.name_id = p_id;
|
WHERE p.name_id = p_id;
|
||||||
rv.defence := round( verse.adjust_production( verse.get_raw_production( p_id , 'DEF' ) , happ ) );
|
rv.defence := verse.adjust_production( verse.get_raw_production( p_id , 'DEF' ) , happ );
|
||||||
|
|
||||||
-- Get the empire's fleet mode
|
-- Get the empire's fleet mode
|
||||||
SELECT INTO e_att f.attacking
|
SELECT INTO e_att f.attacking
|
||||||
|
@ -332,8 +332,7 @@ AS $$
|
||||||
( bd.workers * b.amount )::INT AS jobs ,
|
( bd.workers * b.amount )::INT AS jobs ,
|
||||||
( bd.upkeep * b.amount )::BIGINT AS upkeep ,
|
( bd.upkeep * b.amount )::BIGINT AS upkeep ,
|
||||||
bd.output_type AS p_type ,
|
bd.output_type AS p_type ,
|
||||||
floor( verse.adjust_production( ( bd.output * b.amount )::REAL ,
|
floor( verse.adjust_production( bd.output * b.amount , ph.current / p.population )
|
||||||
( ph.current / p.population )::REAL )
|
|
||||||
)::BIGINT AS p_value
|
)::BIGINT AS p_value
|
||||||
FROM verse.planet_buildings b
|
FROM verse.planet_buildings b
|
||||||
INNER JOIN verse.planets p ON p.name_id = b.planet_id
|
INNER JOIN verse.planets p ON p.name_id = b.planet_id
|
||||||
|
@ -373,9 +372,9 @@ AS $$
|
||||||
ELSE floor( qi.amount * bd.cost - ( CASE WHEN qi.queue_order = 0 THEN q.money ELSE 0 END ) )
|
ELSE floor( qi.amount * bd.cost - ( CASE WHEN qi.queue_order = 0 THEN q.money ELSE 0 END ) )
|
||||||
END )::BIGINT AS investment ,
|
END )::BIGINT AS investment ,
|
||||||
( CASE
|
( CASE
|
||||||
WHEN ceil( verse.adjust_production( ( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) )::REAL , ( ph.current / p.population )::REAL ) ) = 0 THEN NULL
|
WHEN ceil( verse.adjust_production( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) , ph.current / p.population ) ) = 0 THEN NULL
|
||||||
ELSE ceil( ( qi.amount * bd.work * ( CASE WHEN qi.destroy THEN sys.get_constant( 'game.work.destructionWork' ) ELSE 1 END ) - ( CASE WHEN qi.queue_order = 0 THEN q.work ELSE 0 END ) )
|
ELSE ceil( ( qi.amount * bd.work * ( CASE WHEN qi.destroy THEN sys.get_constant( 'game.work.destructionWork' ) ELSE 1 END ) - ( CASE WHEN qi.queue_order = 0 THEN q.work ELSE 0 END ) )
|
||||||
/ verse.adjust_production( ( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) )::REAL , ( ph.current / p.population )::REAL ) )
|
/ verse.adjust_production( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) , ph.current / p.population ) )
|
||||||
END )::BIGINT AS time_left
|
END )::BIGINT AS time_left
|
||||||
FROM verse.planets p
|
FROM verse.planets p
|
||||||
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
||||||
|
@ -414,9 +413,9 @@ AS $$
|
||||||
qi.amount AS amount , FALSE AS destroy ,
|
qi.amount AS amount , FALSE AS destroy ,
|
||||||
floor( qi.amount * bd.cost - ( CASE WHEN qi.queue_order = 0 THEN q.money ELSE 0 END ) )::BIGINT AS investment ,
|
floor( qi.amount * bd.cost - ( CASE WHEN qi.queue_order = 0 THEN q.money ELSE 0 END ) )::BIGINT AS investment ,
|
||||||
( CASE
|
( CASE
|
||||||
WHEN ceil( verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ( ph.current / p.population )::REAL ) ) = 0 THEN NULL
|
WHEN ceil( verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ph.current / p.population ) ) = 0 THEN NULL
|
||||||
ELSE ceil( ( qi.amount * bd.work - ( CASE WHEN qi.queue_order = 0 THEN q.work ELSE 0 END ) )
|
ELSE ceil( ( qi.amount * bd.work - ( CASE WHEN qi.queue_order = 0 THEN q.work ELSE 0 END ) )
|
||||||
/ verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ( ph.current / p.population )::REAL ) )
|
/ verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ph.current / p.population ) )
|
||||||
END )::BIGINT AS time_left
|
END )::BIGINT AS time_left
|
||||||
FROM verse.planets p
|
FROM verse.planets p
|
||||||
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
||||||
|
@ -465,12 +464,12 @@ AS $$
|
||||||
UNION SELECT bv.*
|
UNION SELECT bv.*
|
||||||
FROM tech.buildings_view bv
|
FROM tech.buildings_view bv
|
||||||
INNER JOIN tech.buildable_requirements r ON r.buildable_id = bv.name_id
|
INNER JOIN tech.buildable_requirements r ON r.buildable_id = bv.name_id
|
||||||
INNER JOIN tech.levels l ON l.id = r.level_id
|
INNER JOIN tech.technologies l ON l.name_id = r.technology_id
|
||||||
INNER JOIN emp.planets ep ON ep.planet_id = $1
|
INNER JOIN emp.planets ep ON ep.planet_id = $1
|
||||||
INNER JOIN emp.technologies t
|
INNER JOIN emp.researched_technologies t
|
||||||
ON t.empire_id = ep.empire_id AND t.line_id = l.line_id AND t.level > l.level
|
ON t.empire_id = ep.empire_id AND t.technology_id = l.name_id
|
||||||
) AS bv , (
|
) AS bv , (
|
||||||
SELECT verse.adjust_production( ( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) )::REAL , ( ph.current / p.population )::REAL ) AS p_work ,
|
SELECT verse.adjust_production( p.population * sys.get_constant( 'game.work.wuPerPopUnit' ) , ph.current / p.population ) AS p_work ,
|
||||||
c.language_id AS language
|
c.language_id AS language
|
||||||
FROM verse.planets p
|
FROM verse.planets p
|
||||||
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
||||||
|
@ -517,12 +516,12 @@ AS $$
|
||||||
UNION SELECT bv.*
|
UNION SELECT bv.*
|
||||||
FROM tech.ships_view bv
|
FROM tech.ships_view bv
|
||||||
INNER JOIN tech.buildable_requirements r ON r.buildable_id = bv.name_id
|
INNER JOIN tech.buildable_requirements r ON r.buildable_id = bv.name_id
|
||||||
INNER JOIN tech.levels l ON l.id = r.level_id
|
INNER JOIN tech.technologies l ON l.name_id = r.technology_id
|
||||||
INNER JOIN emp.planets ep ON ep.planet_id = $1
|
INNER JOIN emp.planets ep ON ep.planet_id = $1
|
||||||
INNER JOIN emp.technologies t
|
INNER JOIN emp.researched_technologies t
|
||||||
ON t.empire_id = ep.empire_id AND t.line_id = l.line_id AND t.level > l.level
|
ON t.empire_id = ep.empire_id AND t.technology_id = l.name_id
|
||||||
) AS bv , (
|
) AS bv , (
|
||||||
SELECT verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ( ph.current / p.population )::REAL ) AS p_work ,
|
SELECT verse.adjust_production( verse.get_raw_production( $1 , 'WORK' ) , ph.current / p.population ) AS p_work ,
|
||||||
c.language_id AS language
|
c.language_id AS language
|
||||||
FROM verse.planets p
|
FROM verse.planets p
|
||||||
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
INNER JOIN verse.planet_happiness ph ON ph.planet_id = p.name_id
|
||||||
|
@ -594,7 +593,7 @@ CREATE OR REPLACE FUNCTION verse.flush_build_queue( p_id INT )
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
e_id INT;
|
e_id INT;
|
||||||
q_cash REAL;
|
q_cash DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT INTO e_id , q_cash e.name_id , q.money
|
SELECT INTO e_id , q_cash e.name_id , q.money
|
||||||
FROM verse.planets p
|
FROM verse.planets p
|
||||||
|
@ -633,7 +632,7 @@ CREATE OR REPLACE FUNCTION verse.flush_military_queue( p_id INT )
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
e_id INT;
|
e_id INT;
|
||||||
q_cash REAL;
|
q_cash DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT INTO e_id , q_cash e.name_id , q.money
|
SELECT INTO e_id , q_cash e.name_id , q.money
|
||||||
FROM verse.planets p
|
FROM verse.planets p
|
||||||
|
@ -699,10 +698,10 @@ BEGIN
|
||||||
FROM tech.ships s
|
FROM tech.ships s
|
||||||
LEFT OUTER JOIN tech.buildable_requirements r
|
LEFT OUTER JOIN tech.buildable_requirements r
|
||||||
ON r.buildable_id = s.buildable_id
|
ON r.buildable_id = s.buildable_id
|
||||||
LEFT OUTER JOIN tech.levels l
|
LEFT OUTER JOIN tech.technologies l
|
||||||
ON l.id = r.level_id
|
ON l.name_id = r.technology_id
|
||||||
LEFT OUTER JOIN emp.technologies t
|
LEFT OUTER JOIN emp.researched_technologies t
|
||||||
ON t.empire_id = e_id AND t.line_id = l.line_id AND t.level > l.level
|
ON t.empire_id = e_id AND t.technology_id = l.name_id
|
||||||
WHERE s.buildable_id = s_id;
|
WHERE s.buildable_id = s_id;
|
||||||
IF NOT FOUND OR ( has_level IS NULL AND dep_level IS NOT NULL ) THEN
|
IF NOT FOUND OR ( has_level IS NULL AND dep_level IS NOT NULL ) THEN
|
||||||
RETURN;
|
RETURN;
|
||||||
|
@ -765,10 +764,10 @@ BEGIN
|
||||||
FROM tech.buildings b
|
FROM tech.buildings b
|
||||||
LEFT OUTER JOIN tech.buildable_requirements r
|
LEFT OUTER JOIN tech.buildable_requirements r
|
||||||
ON r.buildable_id = b.buildable_id
|
ON r.buildable_id = b.buildable_id
|
||||||
LEFT OUTER JOIN tech.levels l
|
LEFT OUTER JOIN tech.technologies l
|
||||||
ON l.id = r.level_id
|
ON l.name_id = r.technology_id
|
||||||
LEFT OUTER JOIN emp.technologies t
|
LEFT OUTER JOIN emp.researched_technologies t
|
||||||
ON t.empire_id = e_id AND t.line_id = l.line_id AND t.level > l.level
|
ON t.empire_id = e_id AND t.technology_id = l.name_id
|
||||||
WHERE b.buildable_id = b_id;
|
WHERE b.buildable_id = b_id;
|
||||||
IF NOT FOUND OR ( has_level IS NULL AND dep_level IS NOT NULL ) THEN
|
IF NOT FOUND OR ( has_level IS NULL AND dep_level IS NOT NULL ) THEN
|
||||||
RETURN;
|
RETURN;
|
||||||
|
@ -979,7 +978,7 @@ $$ LANGUAGE plpgsql;
|
||||||
-- tick Current tick
|
-- tick Current tick
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.inflict_battle_damage( p_id INT , t_power BIGINT , dmg REAL , b_id BIGINT , tick BIGINT )
|
CREATE OR REPLACE FUNCTION verse.inflict_battle_damage( p_id INT , t_power BIGINT , dmg DOUBLE PRECISION , b_id BIGINT , tick BIGINT )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
|
@ -987,7 +986,7 @@ CREATE OR REPLACE FUNCTION verse.inflict_battle_damage( p_id INT , t_power BIGIN
|
||||||
DECLARE
|
DECLARE
|
||||||
rec RECORD;
|
rec RECORD;
|
||||||
bp_id BIGINT;
|
bp_id BIGINT;
|
||||||
st_dmg REAL;
|
st_dmg DOUBLE PRECISION;
|
||||||
n_dest INT;
|
n_dest INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
PERFORM sys.write_log( 'BattleUpdate' , 'TRACE'::log_level , 'Inflicting ' || dmg
|
PERFORM sys.write_log( 'BattleUpdate' , 'TRACE'::log_level , 'Inflicting ' || dmg
|
||||||
|
@ -1038,18 +1037,18 @@ $$ LANGUAGE plpgsql;
|
||||||
-- d_ratio Debt damage ratio
|
-- d_ratio Debt damage ratio
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION verse.handle_debt( e_id INT , t_upkeep REAL , debt REAL , d_ratio REAL )
|
CREATE OR REPLACE FUNCTION verse.handle_debt( e_id INT , t_upkeep DOUBLE PRECISION , debt DOUBLE PRECISION , d_ratio DOUBLE PRECISION )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
tick BIGINT;
|
tick BIGINT;
|
||||||
tot_damage REAL;
|
tot_damage DOUBLE PRECISION;
|
||||||
p_rec RECORD;
|
p_rec RECORD;
|
||||||
b_rec RECORD;
|
b_rec RECORD;
|
||||||
bp_id BIGINT;
|
bp_id BIGINT;
|
||||||
b_damage REAL;
|
b_damage DOUBLE PRECISION;
|
||||||
n_destroy INT;
|
n_destroy INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
tick := sys.get_tick( ) - 1;
|
tick := sys.get_tick( ) - 1;
|
||||||
|
@ -1066,7 +1065,7 @@ BEGIN
|
||||||
bp_id := NULL;
|
bp_id := NULL;
|
||||||
|
|
||||||
FOR b_rec IN SELECT b.building_id AS building , b.amount AS amount ,
|
FOR b_rec IN SELECT b.building_id AS building , b.amount AS amount ,
|
||||||
( b.amount * bb.upkeep )::REAL AS upkeep ,
|
b.amount * bb.upkeep AS upkeep ,
|
||||||
b.damage AS damage , ( bd.output_type = 'DEF' ) AS is_def
|
b.damage AS damage , ( bd.output_type = 'DEF' ) AS is_def
|
||||||
FROM verse.planet_buildings b
|
FROM verse.planet_buildings b
|
||||||
INNER JOIN tech.buildables bb ON bb.name_id = b.building_id
|
INNER JOIN tech.buildables bb ON bb.name_id = b.building_id
|
||||||
|
|
|
@ -626,7 +626,7 @@ $$ LANGUAGE plpgsql;
|
||||||
-- tick Current tick identifier
|
-- tick Current tick identifier
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION battles.inflict_damage( b_id BIGINT , dmg REAL , att BOOLEAN , tick BIGINT )
|
CREATE OR REPLACE FUNCTION battles.inflict_damage( b_id BIGINT , dmg DOUBLE PRECISION , att BOOLEAN , tick BIGINT )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
|
@ -654,9 +654,9 @@ BEGIN
|
||||||
st_power := battles.get_defence_power( b_id , tick );
|
st_power := battles.get_defence_power( b_id , tick );
|
||||||
tot_power := tot_power + st_power;
|
tot_power := tot_power + st_power;
|
||||||
PERFORM sys.write_log( 'BattleUpdate' , 'TRACE'::log_level , 'About to inflict planet damage; total power: ' || tot_power
|
PERFORM sys.write_log( 'BattleUpdate' , 'TRACE'::log_level , 'About to inflict planet damage; total power: ' || tot_power
|
||||||
|| '; planet power: ' || st_power || '; computed damage: ' || ( dmg * st_power / tot_power )::REAL );
|
|| '; planet power: ' || st_power || '; computed damage: ' || ( dmg * st_power / tot_power ) );
|
||||||
IF st_power <> 0 THEN
|
IF st_power <> 0 THEN
|
||||||
PERFORM verse.inflict_battle_damage( planet , st_power , ( dmg * st_power / tot_power )::REAL , b_id , tick );
|
PERFORM verse.inflict_battle_damage( planet , st_power , dmg * st_power / tot_power , b_id , tick );
|
||||||
END IF;
|
END IF;
|
||||||
END IF;
|
END IF;
|
||||||
|
|
||||||
|
@ -668,7 +668,7 @@ BEGIN
|
||||||
LEFT OUTER JOIN fleets.movements m ON m.fleet_id = f.id
|
LEFT OUTER JOIN fleets.movements m ON m.fleet_id = f.id
|
||||||
WHERE b.id = b_id AND m.fleet_id IS NULL AND f.attacking = att
|
WHERE b.id = b_id AND m.fleet_id IS NULL AND f.attacking = att
|
||||||
LOOP
|
LOOP
|
||||||
PERFORM fleets.inflict_battle_damage( rec.id , ( dmg * rec.power / tot_power )::REAL , b_id , tick );
|
PERFORM fleets.inflict_battle_damage( rec.id , dmg * rec.power / tot_power , b_id , tick );
|
||||||
END LOOP;
|
END LOOP;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
|
@ -256,8 +256,8 @@ CREATE VIEW battles.buildings_history
|
||||||
WHEN rbp.raw_power = 0 THEN
|
WHEN rbp.raw_power = 0 THEN
|
||||||
rbh.raw_power
|
rbh.raw_power
|
||||||
ELSE
|
ELSE
|
||||||
rbh.raw_power::REAL * rbp.actual_power::REAL / rbp.raw_power::REAL
|
rbh.raw_power * rbp.actual_power / rbp.raw_power
|
||||||
END )::REAL AS power
|
END ) AS power
|
||||||
FROM battles.empire_list_view elv
|
FROM battles.empire_list_view elv
|
||||||
INNER JOIN battles.raw_buildings_history rbh USING (battle)
|
INNER JOIN battles.raw_buildings_history rbh USING (battle)
|
||||||
INNER JOIN battles.raw_buildings_power rbp USING (battle,tick)
|
INNER JOIN battles.raw_buildings_power rbp USING (battle,tick)
|
||||||
|
|
|
@ -55,7 +55,7 @@ $$ LANGUAGE plpgsql;
|
||||||
-- the in-system movement's duration
|
-- the in-system movement's duration
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION fleets.compute_insystem_duration( f_time INT , s_orbit REAL , d_orbit REAL )
|
CREATE OR REPLACE FUNCTION fleets.compute_insystem_duration( f_time INT , s_orbit DOUBLE PRECISION , d_orbit DOUBLE PRECISION )
|
||||||
RETURNS INT
|
RETURNS INT
|
||||||
STRICT IMMUTABLE
|
STRICT IMMUTABLE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
|
@ -84,7 +84,7 @@ $$ LANGUAGE plpgsql;
|
||||||
-- the outer space movement's duration
|
-- the outer space movement's duration
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION fleets.compute_outerspace_duration( f_time INT , s_x REAL , s_y REAL , d_x REAL , d_y REAL )
|
CREATE OR REPLACE FUNCTION fleets.compute_outerspace_duration( f_time INT , s_x DOUBLE PRECISION , s_y DOUBLE PRECISION , d_x DOUBLE PRECISION , d_y DOUBLE PRECISION )
|
||||||
RETURNS INT
|
RETURNS INT
|
||||||
STRICT IMMUTABLE
|
STRICT IMMUTABLE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
|
@ -115,16 +115,16 @@ $$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION fleets.compute_current_orbit(
|
CREATE OR REPLACE FUNCTION fleets.compute_current_orbit(
|
||||||
f_time INT , rp_orbit INT , outwards BOOLEAN , past_rp BOOLEAN , ft_left INT )
|
f_time INT , rp_orbit INT , outwards BOOLEAN , past_rp BOOLEAN , ft_left INT )
|
||||||
RETURNS REAL
|
RETURNS DOUBLE PRECISION
|
||||||
STRICT IMMUTABLE
|
STRICT IMMUTABLE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
dist REAL;
|
dist DOUBLE PRECISION;
|
||||||
dir REAL;
|
dir DOUBLE PRECISION;
|
||||||
rloc REAL;
|
rloc DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
dist := 1.0 - ft_left::REAL / f_time::REAL;
|
dist := 1.0 - ft_left::DOUBLE PRECISION / f_time::DOUBLE PRECISION;
|
||||||
dir := ( CASE WHEN outwards THEN 0.5 ELSE -0.5 END );
|
dir := ( CASE WHEN outwards THEN 0.5 ELSE -0.5 END );
|
||||||
IF past_rp THEN
|
IF past_rp THEN
|
||||||
rloc := rp_orbit;
|
rloc := rp_orbit;
|
||||||
|
@ -157,13 +157,14 @@ $$ LANGUAGE plpgsql;
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION fleets.compute_current_location(
|
CREATE OR REPLACE FUNCTION fleets.compute_current_location(
|
||||||
f_time INT , s_x REAL , s_y REAL , d_x REAL , d_y REAL , r_time INT ,
|
f_time INT , s_x DOUBLE PRECISION , s_y DOUBLE PRECISION ,
|
||||||
OUT c_x REAL , OUT c_y REAL )
|
d_x DOUBLE PRECISION , d_y DOUBLE PRECISION , r_time INT ,
|
||||||
|
OUT c_x DOUBLE PRECISION , OUT c_y DOUBLE PRECISION )
|
||||||
STRICT IMMUTABLE
|
STRICT IMMUTABLE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
tot_time REAL;
|
tot_time DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
tot_time := fleets.compute_outerspace_duration( f_time , s_x , s_y , d_x , d_y );
|
tot_time := fleets.compute_outerspace_duration( f_time , s_x , s_y , d_x , d_y );
|
||||||
c_x := s_x + ( d_x - s_x ) * ( 1 - r_time / tot_time );
|
c_x := s_x + ( d_x - s_x ) * ( 1 - r_time / tot_time );
|
||||||
|
@ -251,7 +252,7 @@ $$ LANGUAGE plpgsql;
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION fleets.compute_insystem_redirect(
|
CREATE OR REPLACE FUNCTION fleets.compute_insystem_redirect(
|
||||||
f_time INT , s_sys INT , s_orbit REAL , d_id INT ,
|
f_time INT , s_sys INT , s_orbit DOUBLE PRECISION , d_id INT ,
|
||||||
OUT duration INT , OUT direction BOOLEAN , OUT s_duration INT ,
|
OUT duration INT , OUT direction BOOLEAN , OUT s_duration INT ,
|
||||||
OUT ref_point INT , OUT past_rp BOOLEAN )
|
OUT ref_point INT , OUT past_rp BOOLEAN )
|
||||||
STRICT IMMUTABLE
|
STRICT IMMUTABLE
|
||||||
|
@ -260,7 +261,7 @@ CREATE OR REPLACE FUNCTION fleets.compute_insystem_redirect(
|
||||||
DECLARE
|
DECLARE
|
||||||
s_rec RECORD;
|
s_rec RECORD;
|
||||||
d_rec RECORD;
|
d_rec RECORD;
|
||||||
torb REAL;
|
torb DOUBLE PRECISION;
|
||||||
rporb INT;
|
rporb INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get destination planet coordinates, orbit and system ID
|
-- Get destination planet coordinates, orbit and system ID
|
||||||
|
@ -294,9 +295,9 @@ BEGIN
|
||||||
ELSE
|
ELSE
|
||||||
torb := floor( torb );
|
torb := floor( torb );
|
||||||
END IF;
|
END IF;
|
||||||
s_duration := fleets.compute_insystem_duration( f_time , s_orbit , ( torb / 2 )::REAL );
|
s_duration := fleets.compute_insystem_duration( f_time , s_orbit , torb / 2 );
|
||||||
rporb := round( s_orbit );
|
rporb := round( s_orbit );
|
||||||
past_rp := ( CASE WHEN direction THEN ( rporb::REAL <= s_orbit ) ELSE ( rporb::REAL >= s_orbit ) END );
|
past_rp := ( CASE WHEN direction THEN ( rporb <= s_orbit ) ELSE ( rporb >= s_orbit ) END );
|
||||||
END IF;
|
END IF;
|
||||||
SELECT INTO ref_point name_id FROM verse.planets p
|
SELECT INTO ref_point name_id FROM verse.planets p
|
||||||
WHERE p.system_id = s_sys AND orbit = rporb;
|
WHERE p.system_id = s_sys AND orbit = rporb;
|
||||||
|
@ -322,7 +323,7 @@ $$ LANGUAGE plpgsql;
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION fleets.compute_outerspace_redirect(
|
CREATE OR REPLACE FUNCTION fleets.compute_outerspace_redirect(
|
||||||
f_time INT , s_x REAL , s_y REAL , d_id INT ,
|
f_time INT , s_x DOUBLE PRECISION , s_y DOUBLE PRECISION , d_id INT ,
|
||||||
OUT duration INT , OUT s_duration INT )
|
OUT duration INT , OUT s_duration INT )
|
||||||
STRICT IMMUTABLE
|
STRICT IMMUTABLE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
|
@ -365,8 +366,8 @@ DECLARE
|
||||||
dir BOOLEAN;
|
dir BOOLEAN;
|
||||||
rpid INT;
|
rpid INT;
|
||||||
prp BOOLEAN;
|
prp BOOLEAN;
|
||||||
cx REAL;
|
cx DOUBLE PRECISION;
|
||||||
cy REAL;
|
cy DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Lock fleets and planets
|
-- Lock fleets and planets
|
||||||
PERFORM * FROM fleets.fleets f
|
PERFORM * FROM fleets.fleets f
|
||||||
|
@ -676,10 +677,10 @@ DECLARE
|
||||||
old_ft INT;
|
old_ft INT;
|
||||||
new_ft INT;
|
new_ft INT;
|
||||||
sp_ft INT;
|
sp_ft INT;
|
||||||
x REAL;
|
x DOUBLE PRECISION;
|
||||||
y REAL;
|
y DOUBLE PRECISION;
|
||||||
cx REAL;
|
cx DOUBLE PRECISION;
|
||||||
cy REAL;
|
cy DOUBLE PRECISION;
|
||||||
sid INT;
|
sid INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
SELECT INTO main * FROM fleet_split_main;
|
SELECT INTO main * FROM fleet_split_main;
|
||||||
|
@ -705,7 +706,7 @@ BEGIN
|
||||||
IF new_ft <> old_ft THEN
|
IF new_ft <> old_ft THEN
|
||||||
IF ism_rec IS NULL THEN
|
IF ism_rec IS NULL THEN
|
||||||
-- Outer space movement
|
-- Outer space movement
|
||||||
SELECT INTO x , y s.x::REAL , s.y::REAL
|
SELECT INTO x , y s.x , s.y
|
||||||
FROM verse.planets p
|
FROM verse.planets p
|
||||||
INNER JOIN verse.systems s ON s.id = p.system_id
|
INNER JOIN verse.systems s ON s.id = p.system_id
|
||||||
WHERE p.name_id = main.location;
|
WHERE p.name_id = main.location;
|
||||||
|
@ -754,7 +755,7 @@ BEGIN
|
||||||
IF sp_ft <> old_ft THEN
|
IF sp_ft <> old_ft THEN
|
||||||
IF ism_rec IS NULL THEN
|
IF ism_rec IS NULL THEN
|
||||||
-- Outer space movement
|
-- Outer space movement
|
||||||
SELECT INTO x , y s.x::REAL , s.y::REAL
|
SELECT INTO x , y s.x , s.y
|
||||||
FROM verse.planets p
|
FROM verse.planets p
|
||||||
INNER JOIN verse.systems s ON s.id = p.system_id
|
INNER JOIN verse.systems s ON s.id = p.system_id
|
||||||
WHERE p.name_id = main.location;
|
WHERE p.name_id = main.location;
|
||||||
|
@ -983,7 +984,7 @@ GRANT EXECUTE ON FUNCTION fleets.disband( INT , BIGINT[] ) TO :dbuser;
|
||||||
-- tick Current tick
|
-- tick Current tick
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION fleets.inflict_battle_damage( f_id BIGINT , dmg REAL , b_id BIGINT , tick BIGINT )
|
CREATE OR REPLACE FUNCTION fleets.inflict_battle_damage( f_id BIGINT , dmg DOUBLE PRECISION , b_id BIGINT , tick BIGINT )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
|
@ -995,7 +996,7 @@ DECLARE
|
||||||
bp_id BIGINT;
|
bp_id BIGINT;
|
||||||
bf_id BIGINT;
|
bf_id BIGINT;
|
||||||
rec RECORD;
|
rec RECORD;
|
||||||
st_dmg REAL;
|
st_dmg DOUBLE PRECISION;
|
||||||
n_dest INT;
|
n_dest INT;
|
||||||
found INT;
|
found INT;
|
||||||
deleted INT;
|
deleted INT;
|
||||||
|
@ -1066,19 +1067,19 @@ $$ LANGUAGE plpgsql;
|
||||||
-- d_ratio Debt damage ratio
|
-- d_ratio Debt damage ratio
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION fleets.handle_debt( e_id INT , t_upkeep REAL , debt REAL , d_ratio REAL )
|
CREATE OR REPLACE FUNCTION fleets.handle_debt( e_id INT , t_upkeep DOUBLE PRECISION , debt DOUBLE PRECISION , d_ratio DOUBLE PRECISION )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
tot_damage REAL;
|
tot_damage DOUBLE PRECISION;
|
||||||
f_rec RECORD;
|
f_rec RECORD;
|
||||||
s_rec RECORD;
|
s_rec RECORD;
|
||||||
n_found INT;
|
n_found INT;
|
||||||
n_killed INT;
|
n_killed INT;
|
||||||
s_killed INT;
|
s_killed INT;
|
||||||
s_damage REAL;
|
s_damage DOUBLE PRECISION;
|
||||||
n_ships INT;
|
n_ships INT;
|
||||||
tick BIGINT;
|
tick BIGINT;
|
||||||
bp_id BIGINT;
|
bp_id BIGINT;
|
||||||
|
@ -1086,10 +1087,10 @@ DECLARE
|
||||||
mv_rec fleets.movements%ROWTYPE;
|
mv_rec fleets.movements%ROWTYPE;
|
||||||
ism_rec fleets.ms_system%ROWTYPE;
|
ism_rec fleets.ms_system%ROWTYPE;
|
||||||
osm_rec fleets.ms_space%ROWTYPE;
|
osm_rec fleets.ms_space%ROWTYPE;
|
||||||
x REAL;
|
x DOUBLE PRECISION;
|
||||||
y REAL;
|
y DOUBLE PRECISION;
|
||||||
cx REAL;
|
cx DOUBLE PRECISION;
|
||||||
cy REAL;
|
cy DOUBLE PRECISION;
|
||||||
sid INT;
|
sid INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
tick := sys.get_tick( ) - 1;
|
tick := sys.get_tick( ) - 1;
|
||||||
|
@ -1120,7 +1121,7 @@ BEGIN
|
||||||
n_killed := 0;
|
n_killed := 0;
|
||||||
s_killed := 0;
|
s_killed := 0;
|
||||||
FOR s_rec IN SELECT s.ship_id AS ship , s.amount AS amount , s.damage AS damage ,
|
FOR s_rec IN SELECT s.ship_id AS ship , s.amount AS amount , s.damage AS damage ,
|
||||||
( d.upkeep * s.amount )::REAL AS upkeep
|
d.upkeep * s.amount AS upkeep
|
||||||
FROM fleets.ships s
|
FROM fleets.ships s
|
||||||
INNER JOIN tech.buildables d ON d.name_id = s.ship_id
|
INNER JOIN tech.buildables d ON d.name_id = s.ship_id
|
||||||
WHERE s.fleet_id = f_rec.fleet
|
WHERE s.fleet_id = f_rec.fleet
|
||||||
|
@ -1174,7 +1175,7 @@ BEGIN
|
||||||
|
|
||||||
IF ism_rec IS NULL THEN
|
IF ism_rec IS NULL THEN
|
||||||
-- Outer space movement
|
-- Outer space movement
|
||||||
SELECT INTO x , y s.x::REAL , s.y::REAL
|
SELECT INTO x , y s.x , s.y
|
||||||
FROM verse.planets p
|
FROM verse.planets p
|
||||||
INNER JOIN verse.systems s ON s.id = p.system_id
|
INNER JOIN verse.systems s ON s.id = p.system_id
|
||||||
WHERE p.name_id = f_rec.location;
|
WHERE p.name_id = f_rec.location;
|
||||||
|
@ -1386,7 +1387,7 @@ GRANT SELECT ON fleets.static_fleets TO :dbuser;
|
||||||
CREATE VIEW fleets.outer_space_fleets
|
CREATE VIEW fleets.outer_space_fleets
|
||||||
AS SELECT s.movement_id AS id , m.state_time_left AS time_left ,
|
AS SELECT s.movement_id AS id , m.state_time_left AS time_left ,
|
||||||
s.start_x AS x0 , s.start_y AS y0 ,
|
s.start_x AS x0 , s.start_y AS y0 ,
|
||||||
ts.x::REAL AS x1 , ts.y::REAL AS y1
|
ts.x::DOUBLE PRECISION AS x1 , ts.y::DOUBLE PRECISION AS y1
|
||||||
FROM fleets.ms_space s
|
FROM fleets.ms_space s
|
||||||
INNER JOIN fleets.movements m ON m.fleet_id = s.movement_id
|
INNER JOIN fleets.movements m ON m.fleet_id = s.movement_id
|
||||||
INNER JOIN fleets.fleets f ON m.fleet_id = f.id
|
INNER JOIN fleets.fleets f ON m.fleet_id = f.id
|
||||||
|
@ -1422,14 +1423,14 @@ CREATE VIEW fleets.moving_fleets
|
||||||
f.location_id AS to_id , dn.name AS to_name ,
|
f.location_id AS to_id , dn.name AS to_name ,
|
||||||
( CASE
|
( CASE
|
||||||
WHEN osf.id IS NULL THEN isf.x
|
WHEN osf.id IS NULL THEN isf.x
|
||||||
ELSE ( osf.x1 - osf.time_left::REAL * ( osf.x1 - osf.x0 )
|
ELSE ( osf.x1 - osf.time_left * ( osf.x1 - osf.x0 )
|
||||||
/ fleets.compute_outerspace_duration( fs.flight_time , osf.x0 , osf.y0 , osf.x1 , osf.y1 ) )
|
/ fleets.compute_outerspace_duration( fs.flight_time , osf.x0 , osf.y0 , osf.x1 , osf.y1 ) )
|
||||||
END )::REAL AS cx ,
|
END )::DOUBLE PRECISION AS cx ,
|
||||||
( CASE
|
( CASE
|
||||||
WHEN osf.id IS NULL THEN isf.y
|
WHEN osf.id IS NULL THEN isf.y
|
||||||
ELSE ( osf.y1 - osf.time_left::REAL * ( osf.y1 - osf.y0 )
|
ELSE ( osf.y1 - osf.time_left * ( osf.y1 - osf.y0 )
|
||||||
/ fleets.compute_outerspace_duration( fs.flight_time , osf.x0 , osf.y0 , osf.x1 , osf.y1 ) )
|
/ fleets.compute_outerspace_duration( fs.flight_time , osf.x0 , osf.y0 , osf.x1 , osf.y1 ) )
|
||||||
END )::REAL AS cy ,
|
END )::DOUBLE PRECISION AS cy ,
|
||||||
( CASE
|
( CASE
|
||||||
WHEN osf.id IS NULL THEN isf.planet
|
WHEN osf.id IS NULL THEN isf.planet
|
||||||
ELSE NULL
|
ELSE NULL
|
||||||
|
@ -1487,7 +1488,7 @@ GRANT SELECT ON fleets.ships_view TO :dbuser;
|
||||||
CREATE VIEW fleets.short_static_fleets
|
CREATE VIEW fleets.short_static_fleets
|
||||||
AS SELECT sf.empire , sf.location AS location_id ,
|
AS SELECT sf.empire , sf.location AS location_id ,
|
||||||
fl.name AS location_name ,
|
fl.name AS location_name ,
|
||||||
fl.x::REAL AS x , fl.y::REAL AS y ,
|
fl.x::DOUBLE PRECISION AS x , fl.y::DOUBLE PRECISION AS y ,
|
||||||
sf.id , sf.name , sf.status , sf.penalty ,
|
sf.id , sf.name , sf.status , sf.penalty ,
|
||||||
fl.attacking , sf.power , sf.flight_time
|
fl.attacking , sf.power , sf.flight_time
|
||||||
FROM fleets.static_fleets sf
|
FROM fleets.static_fleets sf
|
||||||
|
|
|
@ -15,7 +15,7 @@ CREATE VIEW emp.planets_list_basic
|
||||||
AS SELECT e.name_id AS empire ,
|
AS SELECT e.name_id AS empire ,
|
||||||
p.name_id AS id , n.name ,
|
p.name_id AS id , n.name ,
|
||||||
s.x , s.y , p.orbit ,
|
s.x , s.y , p.orbit ,
|
||||||
p.population , ph.current / p.population::REAL AS happiness ,
|
p.population , ph.current / p.population AS happiness ,
|
||||||
floor( pm.income )::BIGINT AS income ,
|
floor( pm.income )::BIGINT AS income ,
|
||||||
floor( pm.upkeep )::BIGINT AS upkeep
|
floor( pm.upkeep )::BIGINT AS upkeep
|
||||||
FROM emp.empires e
|
FROM emp.empires e
|
||||||
|
|
|
@ -860,7 +860,7 @@ CREATE VIEW events.empire_events_view
|
||||||
AS SELECT e.event_id AS id , e.evt_type , e.evt_subtype , e.tick , e.real_time , s.name AS technology
|
AS SELECT e.event_id AS id , e.evt_type , e.evt_subtype , e.tick , e.real_time , s.name AS technology
|
||||||
FROM events.events e
|
FROM events.events e
|
||||||
LEFT OUTER JOIN events.empire_events ed USING (event_id)
|
LEFT OUTER JOIN events.empire_events ed USING (event_id)
|
||||||
LEFT OUTER JOIN tech.levels tl ON tl.id = ed.technology_id
|
LEFT OUTER JOIN tech.technologies tl ON tl.name_id = ed.technology_id
|
||||||
LEFT OUTER JOIN defs.strings s ON s.id = tl.name_id
|
LEFT OUTER JOIN defs.strings s ON s.id = tl.name_id
|
||||||
WHERE e.evt_type = 'EMPIRE';
|
WHERE e.evt_type = 'EMPIRE';
|
||||||
|
|
||||||
|
|
|
@ -1196,18 +1196,24 @@ GRANT SELECT ON bugs.dump_main_view TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
CREATE VIEW bugs.dump_research_view
|
CREATE VIEW bugs.dump_research_view
|
||||||
AS SELECT et.empire_id , et.line_id AS line_id , et.level AS level ,
|
AS SELECT r.empire_id , ns.name , r.accumulated , r.priority
|
||||||
tst.name AS name , et.accumulated AS accumulated
|
FROM emp.research r
|
||||||
FROM emp.technologies et
|
INNER JOIN defs.strings ns ON ns.id = r.technology_id;
|
||||||
LEFT OUTER JOIN tech.levels tlv ON tlv.line_id = et.line_id AND tlv.level = et.level
|
|
||||||
LEFT OUTER JOIN defs.strings tst ON tst.id = tlv.name_id;
|
|
||||||
|
|
||||||
GRANT SELECT ON bugs.dump_research_view TO :dbuser;
|
GRANT SELECT ON bugs.dump_research_view TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
CREATE VIEW bugs.dump_technologies_view
|
||||||
|
AS SELECT et.empire_id , ns.name , et.implemented
|
||||||
|
FROM emp.researched_technologies et
|
||||||
|
INNER JOIN defs.strings ns ON ns.id = et.technology_id;
|
||||||
|
|
||||||
|
GRANT SELECT ON bugs.dump_technologies_view TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
CREATE VIEW bugs.dump_planets_view
|
CREATE VIEW bugs.dump_planets_view
|
||||||
AS SELECT ep.empire_id , ep.planet_id , p.population ,
|
AS SELECT ep.empire_id , ep.planet_id , p.population ,
|
||||||
( ph.current / p.population )::REAL AS current_happiness , ph.target AS target_happiness ,
|
ph.current / p.population AS current_happiness , ph.target AS target_happiness ,
|
||||||
cq.money AS civ_money , cq.work AS civ_work ,
|
cq.money AS civ_money , cq.work AS civ_work ,
|
||||||
mq.money AS mil_money , mq.work AS mil_work
|
mq.money AS mil_money , mq.work AS mil_work
|
||||||
FROM emp.planets ep
|
FROM emp.planets ep
|
||||||
|
|
|
@ -52,7 +52,7 @@ GRANT EXECUTE ON FUNCTION sys.start_tick( ) TO :dbuser;
|
||||||
CREATE OR REPLACE FUNCTION sys.end_tick( IN tick_id BIGINT )
|
CREATE OR REPLACE FUNCTION sys.end_tick( IN tick_id BIGINT )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY INVOKER
|
SECURITY DEFINER
|
||||||
AS $$
|
AS $$
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE events.events SET status = 'READY'
|
UPDATE events.events SET status = 'READY'
|
||||||
|
@ -62,6 +62,8 @@ BEGIN
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION sys.end_tick( BIGINT ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
|
@ -103,70 +105,78 @@ GRANT EXECUTE ON FUNCTION sys.check_stuck_tick( ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Process game updates
|
-- Prepare game updates
|
||||||
--
|
--
|
||||||
-- Parameters:
|
-- Parameters:
|
||||||
-- c_tick Current tick
|
-- u_id Current update identifier
|
||||||
|
-- u_type Type of game updates to prepare
|
||||||
--
|
--
|
||||||
-- Returns:
|
-- Returns:
|
||||||
-- TRUE if the function must be called again, FALSE otherwise
|
-- has_more TRUE if there are more updates, FALSE otherwise
|
||||||
--
|
--
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION sys.process_updates( IN c_tick BIGINT , OUT has_more BOOLEAN )
|
CREATE OR REPLACE FUNCTION sys.prepare_updates( IN u_id BIGINT , IN u_type update_type , OUT has_more BOOLEAN )
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY DEFINER
|
SECURITY DEFINER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
|
||||||
b_size INT;
|
|
||||||
p_utype update_type;
|
|
||||||
utype update_type;
|
|
||||||
uid BIGINT;
|
|
||||||
BEGIN
|
BEGIN
|
||||||
b_size := sys.get_constant( 'game.batchSize' );
|
UPDATE sys.updates SET status = 'PROCESSING'
|
||||||
p_utype := NULL;
|
WHERE id IN (
|
||||||
|
SELECT id FROM sys.updates
|
||||||
|
WHERE gu_type = u_type
|
||||||
|
AND last_tick = u_id
|
||||||
|
AND status = 'FUTURE'
|
||||||
|
ORDER BY id
|
||||||
|
LIMIT sys.get_constant( 'game.batchSize' )::BIGINT
|
||||||
|
);
|
||||||
|
|
||||||
-- Mark at most b_size entries as being updated
|
has_more := FOUND;
|
||||||
FOR uid , utype IN SELECT id , gu_type FROM sys.updates
|
|
||||||
WHERE last_tick = c_tick AND status = 'FUTURE'
|
|
||||||
ORDER BY gu_type LIMIT b_size
|
|
||||||
LOOP
|
|
||||||
IF p_utype IS NULL THEN
|
|
||||||
p_utype := utype;
|
|
||||||
END IF;
|
|
||||||
EXIT WHEN utype <> p_utype;
|
|
||||||
UPDATE sys.updates SET status = 'PROCESSING' WHERE id = uid;
|
|
||||||
END LOOP;
|
|
||||||
|
|
||||||
has_more := p_utype IS NOT NULL;
|
|
||||||
IF has_more THEN
|
|
||||||
-- Execute actual updates
|
|
||||||
EXECUTE 'SELECT sys.process_' || lower( p_utype::TEXT ) || '_updates( $1 )'
|
|
||||||
USING c_tick;
|
|
||||||
UPDATE sys.updates SET status = 'PROCESSED'
|
|
||||||
WHERE status = 'PROCESSING' AND last_tick = c_tick;
|
|
||||||
ELSE
|
|
||||||
-- If nothing was found, we're done
|
|
||||||
PERFORM sys.end_tick( c_tick );
|
|
||||||
END IF;
|
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
GRANT EXECUTE ON FUNCTION sys.process_updates( BIGINT ) TO :dbuser;
|
GRANT EXECUTE ON FUNCTION sys.prepare_updates( BIGINT , update_type ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Execute procedural game updates
|
||||||
|
--
|
||||||
|
-- Parameters:
|
||||||
|
-- c_tick Current tick identifier
|
||||||
|
-- u_type Type of updates to execute
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION sys.exec_update_proc( IN c_tick BIGINT , IN u_type update_type )
|
||||||
|
RETURNS VOID
|
||||||
|
STRICT VOLATILE
|
||||||
|
SECURITY DEFINER
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
EXECUTE 'SELECT sys.process_' || lower( u_type::TEXT ) || '_updates( $1 )'
|
||||||
|
USING c_tick;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION sys.exec_update_proc( BIGINT , update_type ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Mark updates as processed
|
||||||
|
--
|
||||||
|
-- Parameters:
|
||||||
|
-- c_tick Current tick identifier
|
||||||
|
-- u_type Type of updates to execute
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION sys.updates_processed( IN c_tick BIGINT , IN u_type update_type )
|
||||||
|
RETURNS VOID
|
||||||
|
STRICT VOLATILE
|
||||||
|
SECURITY DEFINER
|
||||||
|
AS $$
|
||||||
|
UPDATE sys.updates SET status = 'PROCESSED'
|
||||||
|
WHERE status = 'PROCESSING'
|
||||||
|
AND last_tick = $1
|
||||||
|
AND gu_type = $2
|
||||||
|
$$ LANGUAGE SQL;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION sys.updates_processed( BIGINT , update_type ) TO :dbuser;
|
||||||
|
|
|
@ -14,8 +14,8 @@ CREATE OR REPLACE FUNCTION sys.process_empire_money_updates( c_tick BIGINT )
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
rec RECORD;
|
rec RECORD;
|
||||||
c_cash REAL;
|
c_cash DOUBLE PRECISION;
|
||||||
c_debt REAL;
|
c_debt DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Lock empires for update
|
-- Lock empires for update
|
||||||
PERFORM e.name_id FROM sys.updates su
|
PERFORM e.name_id FROM sys.updates su
|
||||||
|
|
|
@ -7,15 +7,22 @@
|
||||||
-- --------------------------------------------------------
|
-- --------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION sys.process_empire_research_updates( c_tick BIGINT )
|
|
||||||
|
--
|
||||||
|
-- Prepare the research update
|
||||||
|
--
|
||||||
|
-- Parameters:
|
||||||
|
-- update_id The current update's identifier
|
||||||
|
--
|
||||||
|
-- Returns:
|
||||||
|
-- a set of tech._research_update_input records
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE OR REPLACE FUNCTION emp.prepare_research_update( update_id BIGINT )
|
||||||
RETURNS VOID
|
RETURNS VOID
|
||||||
STRICT VOLATILE
|
STRICT VOLATILE
|
||||||
SECURITY INVOKER
|
SECURITY DEFINER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
|
||||||
rec RECORD;
|
|
||||||
r_points REAL;
|
|
||||||
tu_rec RECORD;
|
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Lock empires for update and planets for share
|
-- Lock empires for update and planets for share
|
||||||
PERFORM e.name_id FROM sys.updates su
|
PERFORM e.name_id FROM sys.updates su
|
||||||
|
@ -23,14 +30,80 @@ BEGIN
|
||||||
INNER JOIN emp.empires e ON eu.empire_id = e.name_id
|
INNER JOIN emp.empires e ON eu.empire_id = e.name_id
|
||||||
INNER JOIN emp.planets ep ON ep.empire_id = e.name_id
|
INNER JOIN emp.planets ep ON ep.empire_id = e.name_id
|
||||||
INNER JOIN verse.planets p ON p.name_id = ep.planet_id
|
INNER JOIN verse.planets p ON p.name_id = ep.planet_id
|
||||||
WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
|
WHERE su.last_tick = update_id AND su.status = 'PROCESSING'
|
||||||
AND su.gu_type = 'EMPIRE_RESEARCH'
|
AND su.gu_type = 'EMPIRE_RESEARCH'
|
||||||
FOR UPDATE OF e
|
FOR UPDATE OF e
|
||||||
FOR SHARE OF ep , p;
|
FOR SHARE OF ep , p;
|
||||||
|
|
||||||
-- Process empires
|
-- Create temporary table for update output and grant INSERT privilege
|
||||||
FOR rec IN SELECT e.name_id AS id , ( v.status = 'PROCESSED' ) AS on_vacation ,
|
-- to session user.
|
||||||
sum( p.population ) AS population
|
CREATE TEMPORARY TABLE research_update_output(
|
||||||
|
empire_id INT ,
|
||||||
|
technology TEXT ,
|
||||||
|
creation BOOLEAN ,
|
||||||
|
points DOUBLE PRECISION ,
|
||||||
|
priority INT
|
||||||
|
);
|
||||||
|
IF session_user <> current_user THEN
|
||||||
|
EXECUTE 'GRANT INSERT ON research_update_output TO ' || session_user;
|
||||||
|
END IF;
|
||||||
|
END;
|
||||||
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION emp.prepare_research_update( update_id BIGINT ) TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Research update input views
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE VIEW emp.rui_inprogress_view
|
||||||
|
AS SELECT su.last_tick AS update_id , er.empire_id , ns.name AS technology ,
|
||||||
|
er.accumulated AS points , er.priority AS priority
|
||||||
|
FROM sys.updates su
|
||||||
|
INNER JOIN emp.updates eu ON eu.update_id = su.id
|
||||||
|
INNER JOIN emp.research er ON er.empire_id = eu.empire_id
|
||||||
|
INNER JOIN defs.strings ns ON ns.id = er.technology_id
|
||||||
|
WHERE su.status = 'PROCESSING'
|
||||||
|
AND su.gu_type = 'EMPIRE_RESEARCH';
|
||||||
|
|
||||||
|
|
||||||
|
CREATE VIEW emp.rui_researched_view
|
||||||
|
AS SELECT su.last_tick AS update_id , er.empire_id , ns.name AS technology ,
|
||||||
|
er.implemented AS implemented
|
||||||
|
FROM sys.updates su
|
||||||
|
INNER JOIN emp.updates eu ON eu.update_id = su.id
|
||||||
|
INNER JOIN emp.researched_technologies er
|
||||||
|
ON er.empire_id = eu.empire_id
|
||||||
|
INNER JOIN defs.strings ns ON ns.id = er.technology_id
|
||||||
|
WHERE su.status = 'PROCESSING'
|
||||||
|
AND su.gu_type = 'EMPIRE_RESEARCH';
|
||||||
|
|
||||||
|
CREATE VIEW emp.research_update_input_view
|
||||||
|
AS SELECT update_id , empire_id , technology ,
|
||||||
|
NULL::BOOLEAN AS implemented , points , priority
|
||||||
|
FROM emp.rui_inprogress_view
|
||||||
|
UNION ALL SELECT update_id , empire_id , technology ,
|
||||||
|
implemented , NULL::DOUBLE PRECISION AS points ,
|
||||||
|
NULL::INT AS priority
|
||||||
|
FROM emp.rui_researched_view;
|
||||||
|
|
||||||
|
GRANT SELECT ON emp.research_update_input_view TO :dbuser;
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Research points production view
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE VIEW emp.research_points_production
|
||||||
|
AS SELECT su.last_tick AS update_id , e.name_id AS empire_id ,
|
||||||
|
( sum( p.population ) * sys.get_constant( 'game.research.perPopUnit' )
|
||||||
|
/ ( sys.get_constant( 'game.updatesPerDay' ) * ( CASE
|
||||||
|
WHEN v.status = 'PROCESSED' THEN
|
||||||
|
sys.get_constant( 'game.research.perPopUnit' )
|
||||||
|
ELSE
|
||||||
|
1.0
|
||||||
|
END ) ) ) AS points
|
||||||
FROM sys.updates su
|
FROM sys.updates su
|
||||||
INNER JOIN emp.updates eu ON eu.update_id = su.id
|
INNER JOIN emp.updates eu ON eu.update_id = su.id
|
||||||
INNER JOIN emp.empires e ON eu.empire_id = e.name_id
|
INNER JOIN emp.empires e ON eu.empire_id = e.name_id
|
||||||
|
@ -38,49 +111,56 @@ BEGIN
|
||||||
INNER JOIN verse.planets p ON p.name_id = ep.planet_id
|
INNER JOIN verse.planets p ON p.name_id = ep.planet_id
|
||||||
INNER JOIN naming.empire_names en ON en.id = e.name_id
|
INNER JOIN naming.empire_names en ON en.id = e.name_id
|
||||||
LEFT OUTER JOIN users.vacations v ON v.account_id = en.owner_id
|
LEFT OUTER JOIN users.vacations v ON v.account_id = en.owner_id
|
||||||
WHERE su.last_tick = c_tick AND su.status = 'PROCESSING'
|
WHERE su.status = 'PROCESSING' AND su.gu_type = 'EMPIRE_RESEARCH'
|
||||||
AND su.gu_type = 'EMPIRE_RESEARCH'
|
GROUP BY su.last_tick , e.name_id , v.status;
|
||||||
GROUP BY e.name_id , v.status
|
|
||||||
LOOP
|
|
||||||
-- Insert any missing tech line
|
|
||||||
INSERT INTO emp.technologies ( empire_id , line_id )
|
|
||||||
SELECT rec.id , l.name_id
|
|
||||||
FROM tech.lines l
|
|
||||||
LEFT OUTER JOIN emp.technologies t
|
|
||||||
ON t.line_id = l.name_id AND t.empire_id = rec.id
|
|
||||||
WHERE t.empire_id IS NULL;
|
|
||||||
|
|
||||||
-- Compute research output
|
GRANT SELECT ON emp.research_points_production TO :dbuser;
|
||||||
r_points := rec.population * sys.get_constant( 'game.work.rpPerPopUnit' ) / 1440.0;
|
|
||||||
IF rec.on_vacation
|
|
||||||
THEN
|
|
||||||
r_points := r_points / sys.get_constant( 'vacation.researchDivider' );
|
|
||||||
END IF;
|
|
||||||
|
|
||||||
-- Update technologies where:
|
|
||||||
-- 1) the level actually exists and
|
|
||||||
-- 2) accumulated points haven't reach the level's
|
|
||||||
FOR tu_rec IN SELECT t.line_id AS line_id , t.accumulated AS accumulated ,
|
|
||||||
l.points AS points , ( l.points - t.accumulated ) AS diff ,
|
|
||||||
l.id AS level_id
|
|
||||||
FROM emp.technologies t
|
|
||||||
INNER JOIN tech.levels l ON l.line_id = t.line_id
|
|
||||||
AND l.level = t.level AND t.accumulated < l.points
|
|
||||||
WHERE t.empire_id = rec.id
|
|
||||||
FOR UPDATE OF t
|
|
||||||
LOOP
|
|
||||||
UPDATE emp.technologies t SET accumulated = ( CASE
|
|
||||||
WHEN tu_rec.diff <= r_points THEN tu_rec.points
|
|
||||||
ELSE tu_rec.accumulated + r_points
|
|
||||||
END )
|
|
||||||
WHERE t.line_id = tu_rec.line_id AND t.empire_id = rec.id;
|
|
||||||
|
|
||||||
-- Send message
|
|
||||||
IF tu_rec.diff <= r_points
|
--
|
||||||
THEN
|
-- Submit the contents of the research update table
|
||||||
PERFORM events.tech_ready_event( rec.id , tu_rec.level_id );
|
--
|
||||||
END IF;
|
|
||||||
END LOOP;
|
CREATE OR REPLACE FUNCTION emp.submit_research_update( )
|
||||||
END LOOP;
|
RETURNS VOID
|
||||||
|
STRICT VOLATILE
|
||||||
|
SECURITY DEFINER
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
-- Delete finished research topics
|
||||||
|
DELETE FROM emp.research er
|
||||||
|
USING research_update_output ruo , defs.strings ns
|
||||||
|
WHERE er.empire_id = ruo.empire_id
|
||||||
|
AND er.technology_id = ns.id AND ns.name = ruo.technology
|
||||||
|
AND ruo.points IS NULL;
|
||||||
|
|
||||||
|
-- Insert researched technologies
|
||||||
|
INSERT INTO emp.researched_technologies ( empire_id , technology_id , implemented )
|
||||||
|
SELECT ruo.empire_id , ns.id , FALSE
|
||||||
|
FROM research_update_output ruo
|
||||||
|
INNER JOIN defs.strings ns ON ns.name = ruo.technology
|
||||||
|
WHERE ruo.points IS NULL;
|
||||||
|
|
||||||
|
-- Insert new research topics
|
||||||
|
INSERT INTO emp.research ( empire_id , technology_id , accumulated , priority )
|
||||||
|
SELECT ruo.empire_id , ns.id , ruo.points , ruo.priority
|
||||||
|
FROM research_update_output ruo
|
||||||
|
INNER JOIN defs.strings ns ON ns.name = ruo.technology
|
||||||
|
WHERE ruo.points IS NOT NULL AND ruo.creation;
|
||||||
|
|
||||||
|
-- Update existing research topics
|
||||||
|
UPDATE emp.research er
|
||||||
|
SET accumulated = ruo.points , priority = ruo.priority
|
||||||
|
FROM research_update_output ruo , defs.strings ns
|
||||||
|
WHERE ruo.points IS NOT NULL AND NOT ruo.creation
|
||||||
|
AND ns.name = ruo.technology
|
||||||
|
AND er.technology_id = ns.id
|
||||||
|
AND er.empire_id = ruo.empire_id;
|
||||||
|
|
||||||
|
-- Drop temporary table
|
||||||
|
DROP TABLE research_update_output;
|
||||||
END;
|
END;
|
||||||
$$ LANGUAGE plpgsql;
|
$$ LANGUAGE plpgsql;
|
||||||
|
|
||||||
|
GRANT EXECUTE ON FUNCTION emp.submit_research_update( ) TO :dbuser;
|
||||||
|
|
|
@ -15,11 +15,11 @@ CREATE OR REPLACE FUNCTION sys.process_empire_debt_updates( c_tick BIGINT )
|
||||||
SECURITY INVOKER
|
SECURITY INVOKER
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
fleet_dr REAL;
|
fleet_dr DOUBLE PRECISION;
|
||||||
bld_dr REAL;
|
bld_dr DOUBLE PRECISION;
|
||||||
empire INT;
|
empire INT;
|
||||||
debt REAL;
|
debt DOUBLE PRECISION;
|
||||||
upkeep REAL;
|
upkeep DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
fleet_dr := sys.get_constant( 'game.debt.fleet');
|
fleet_dr := sys.get_constant( 'game.debt.fleet');
|
||||||
bld_dr := sys.get_constant( 'game.debt.buildings');
|
bld_dr := sys.get_constant( 'game.debt.buildings');
|
||||||
|
|
|
@ -42,17 +42,17 @@ CREATE OR REPLACE FUNCTION sys.process_planet_battle_main_updates( c_tick BIGINT
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
ttfi INT;
|
ttfi INT;
|
||||||
initi REAL;
|
initi DOUBLE PRECISION;
|
||||||
dbonus REAL;
|
dbonus DOUBLE PRECISION;
|
||||||
dmg REAL;
|
dmg DOUBLE PRECISION;
|
||||||
rdmg REAL;
|
rdmg DOUBLE PRECISION;
|
||||||
rec RECORD;
|
rec RECORD;
|
||||||
a_power BIGINT;
|
a_power BIGINT;
|
||||||
d_power BIGINT;
|
d_power BIGINT;
|
||||||
p_power BIGINT;
|
p_power BIGINT;
|
||||||
bmod REAL;
|
bmod DOUBLE PRECISION;
|
||||||
a_dmg REAL;
|
a_dmg DOUBLE PRECISION;
|
||||||
d_dmg REAL;
|
d_dmg DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
ttfi := floor( sys.get_constant( 'game.battle.timeToFullIntensity' ) )::INT;
|
ttfi := floor( sys.get_constant( 'game.battle.timeToFullIntensity' ) )::INT;
|
||||||
initi := sys.get_constant( 'game.battle.initialIntensity' );
|
initi := sys.get_constant( 'game.battle.initialIntensity' );
|
||||||
|
@ -61,7 +61,7 @@ BEGIN
|
||||||
rdmg := sys.get_constant( 'game.battle.randomDamage' );
|
rdmg := sys.get_constant( 'game.battle.randomDamage' );
|
||||||
|
|
||||||
FOR rec IN SELECT b.id AS battle , b.first_tick AS first_tick ,
|
FOR rec IN SELECT b.id AS battle , b.first_tick AS first_tick ,
|
||||||
b.location_id AS location , ( ph.current / p.population )::REAL AS happiness
|
b.location_id AS location , ph.current / p.population AS happiness
|
||||||
FROM sys.updates su
|
FROM sys.updates su
|
||||||
INNER JOIN verse.updates vu ON vu.update_id = su.id
|
INNER JOIN verse.updates vu ON vu.update_id = su.id
|
||||||
INNER JOIN verse.planets p ON vu.planet_id = p.name_id
|
INNER JOIN verse.planets p ON vu.planet_id = p.name_id
|
||||||
|
|
|
@ -14,20 +14,20 @@ CREATE OR REPLACE FUNCTION sys.process_planet_construction_updates( c_tick BIGIN
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
rec RECORD;
|
rec RECORD;
|
||||||
wu_per_pop REAL;
|
wu_per_pop DOUBLE PRECISION;
|
||||||
dest_work REAL;
|
dest_work DOUBLE PRECISION;
|
||||||
dest_rec REAL;
|
dest_rec DOUBLE PRECISION;
|
||||||
cur_empire INT;
|
cur_empire INT;
|
||||||
cur_cash REAL;
|
cur_cash DOUBLE PRECISION;
|
||||||
cur_planet INT;
|
cur_planet INT;
|
||||||
p_finished BOOLEAN;
|
p_finished BOOLEAN;
|
||||||
cur_wus REAL;
|
cur_wus DOUBLE PRECISION;
|
||||||
cur_acc_c REAL;
|
cur_acc_c DOUBLE PRECISION;
|
||||||
n_found INT;
|
n_found INT;
|
||||||
n_removed INT;
|
n_removed INT;
|
||||||
i_work REAL;
|
i_work DOUBLE PRECISION;
|
||||||
i_cost REAL;
|
i_cost DOUBLE PRECISION;
|
||||||
can_do REAL;
|
can_do DOUBLE PRECISION;
|
||||||
must_do INT;
|
must_do INT;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get constants
|
-- Get constants
|
||||||
|
@ -39,7 +39,7 @@ BEGIN
|
||||||
cur_empire := NULL;
|
cur_empire := NULL;
|
||||||
cur_planet := NULL;
|
cur_planet := NULL;
|
||||||
FOR rec IN SELECT p.name_id AS id , p.population AS pop ,
|
FOR rec IN SELECT p.name_id AS id , p.population AS pop ,
|
||||||
( ph.current / p.population )::REAL AS happiness ,
|
ph.current / p.population AS happiness ,
|
||||||
e.name_id AS owner , e.cash AS cash ,
|
e.name_id AS owner , e.cash AS cash ,
|
||||||
q.money AS acc_cash , q.work AS acc_work ,
|
q.money AS acc_cash , q.work AS acc_work ,
|
||||||
qi.queue_order AS qorder , qi.amount AS amount ,
|
qi.queue_order AS qorder , qi.amount AS amount ,
|
||||||
|
@ -100,10 +100,7 @@ BEGIN
|
||||||
IF cur_planet IS NULL THEN
|
IF cur_planet IS NULL THEN
|
||||||
cur_planet := rec.id;
|
cur_planet := rec.id;
|
||||||
cur_cash := cur_cash + rec.acc_cash;
|
cur_cash := cur_cash + rec.acc_cash;
|
||||||
cur_wus := rec.acc_work + verse.adjust_production(
|
cur_wus := rec.acc_work + verse.adjust_production( rec.pop * wu_per_pop , rec.happiness );
|
||||||
( rec.pop * wu_per_pop )::REAL ,
|
|
||||||
rec.happiness
|
|
||||||
);
|
|
||||||
n_found := 1;
|
n_found := 1;
|
||||||
n_removed := 0;
|
n_removed := 0;
|
||||||
cur_acc_c := 0;
|
cur_acc_c := 0;
|
||||||
|
|
|
@ -15,14 +15,14 @@ CREATE OR REPLACE FUNCTION sys.process_planet_military_updates( c_tick BIGINT )
|
||||||
DECLARE
|
DECLARE
|
||||||
rec RECORD;
|
rec RECORD;
|
||||||
cur_empire INT;
|
cur_empire INT;
|
||||||
cur_cash REAL;
|
cur_cash DOUBLE PRECISION;
|
||||||
cur_planet INT;
|
cur_planet INT;
|
||||||
p_finished BOOLEAN;
|
p_finished BOOLEAN;
|
||||||
cur_wus REAL;
|
cur_wus DOUBLE PRECISION;
|
||||||
cur_acc_c REAL;
|
cur_acc_c DOUBLE PRECISION;
|
||||||
n_found INT;
|
n_found INT;
|
||||||
n_removed INT;
|
n_removed INT;
|
||||||
can_do REAL;
|
can_do DOUBLE PRECISION;
|
||||||
must_do INT;
|
must_do INT;
|
||||||
fl_id BIGINT;
|
fl_id BIGINT;
|
||||||
BEGIN
|
BEGIN
|
||||||
|
@ -38,7 +38,7 @@ BEGIN
|
||||||
cur_empire := NULL;
|
cur_empire := NULL;
|
||||||
cur_planet := NULL;
|
cur_planet := NULL;
|
||||||
FOR rec IN SELECT p.name_id AS id ,
|
FOR rec IN SELECT p.name_id AS id ,
|
||||||
( ph.current / p.population )::REAL AS happiness ,
|
ph.current / p.population AS happiness ,
|
||||||
e.name_id AS owner , e.cash AS cash ,
|
e.name_id AS owner , e.cash AS cash ,
|
||||||
q.money AS acc_cash , q.work AS acc_work ,
|
q.money AS acc_cash , q.work AS acc_work ,
|
||||||
qi.queue_order AS qorder , qi.amount AS amount ,
|
qi.queue_order AS qorder , qi.amount AS amount ,
|
||||||
|
|
|
@ -14,16 +14,16 @@ CREATE OR REPLACE FUNCTION sys.process_planet_population_updates( c_tick BIGINT
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
rec RECORD;
|
rec RECORD;
|
||||||
rel_ch REAL;
|
rel_ch DOUBLE PRECISION;
|
||||||
abs_ch REAL;
|
abs_ch DOUBLE PRECISION;
|
||||||
g_fact REAL;
|
g_fact DOUBLE PRECISION;
|
||||||
gf_inc REAL;
|
gf_inc DOUBLE PRECISION;
|
||||||
n_happ REAL;
|
n_happ DOUBLE PRECISION;
|
||||||
t_happ REAL;
|
t_happ DOUBLE PRECISION;
|
||||||
temp REAL;
|
temp DOUBLE PRECISION;
|
||||||
growth REAL;
|
growth DOUBLE PRECISION;
|
||||||
workers REAL;
|
workers DOUBLE PRECISION;
|
||||||
str_thr REAL;
|
str_thr DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
-- Get constants
|
-- Get constants
|
||||||
rel_ch := sys.get_constant( 'game.happiness.relativeChange' );
|
rel_ch := sys.get_constant( 'game.happiness.relativeChange' );
|
||||||
|
@ -35,7 +35,7 @@ BEGIN
|
||||||
-- Process planets
|
-- Process planets
|
||||||
FOR rec IN SELECT p.name_id AS id , p.population AS pop ,
|
FOR rec IN SELECT p.name_id AS id , p.population AS pop ,
|
||||||
ph.target AS target , ph.current AS happy_pop ,
|
ph.target AS target , ph.current AS happy_pop ,
|
||||||
( ph.current / p.population )::REAL AS current
|
ph.current / p.population AS current
|
||||||
FROM sys.updates su
|
FROM sys.updates su
|
||||||
INNER JOIN verse.updates vu ON vu.update_id = su.id
|
INNER JOIN verse.updates vu ON vu.update_id = su.id
|
||||||
INNER JOIN verse.planets p ON vu.planet_id = p.name_id
|
INNER JOIN verse.planets p ON vu.planet_id = p.name_id
|
||||||
|
|
|
@ -14,10 +14,10 @@ CREATE OR REPLACE FUNCTION sys.process_planet_money_updates( c_tick BIGINT )
|
||||||
AS $$
|
AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
rec RECORD;
|
rec RECORD;
|
||||||
incme REAL;
|
incme DOUBLE PRECISION;
|
||||||
BEGIN
|
BEGIN
|
||||||
FOR rec IN SELECT p.name_id AS id , p.population AS pop ,
|
FOR rec IN SELECT p.name_id AS id , p.population AS pop ,
|
||||||
( ph.current / p.population )::REAL AS happiness ,
|
ph.current / p.population AS happiness ,
|
||||||
( ea.planet_id IS NULL ) AS produces_income
|
( ea.planet_id IS NULL ) AS produces_income
|
||||||
FROM sys.updates su
|
FROM sys.updates su
|
||||||
INNER JOIN verse.updates vu ON vu.update_id = su.id
|
INNER JOIN verse.updates vu ON vu.update_id = su.id
|
||||||
|
|
|
@ -4,13 +4,13 @@
|
||||||
<parent>
|
<parent>
|
||||||
<artifactId>legacyworlds-server</artifactId>
|
<artifactId>legacyworlds-server</artifactId>
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
</parent>
|
</parent>
|
||||||
|
|
||||||
<groupId>com.deepclone.lw</groupId>
|
<groupId>com.deepclone.lw</groupId>
|
||||||
<artifactId>legacyworlds-server-data</artifactId>
|
<artifactId>legacyworlds-server-data</artifactId>
|
||||||
<name>Legacy Worlds server data</name>
|
<name>Legacy Worlds server data</name>
|
||||||
<version>5.99.1</version>
|
<version>5.99.2</version>
|
||||||
<description>This package contains all data access classes for the Legacy Worlds server.</description>
|
<description>This package contains all data access classes for the Legacy Worlds server.</description>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
|
|
@ -1,66 +0,0 @@
|
||||||
package com.deepclone.lw.sqld.game;
|
|
||||||
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public class EmpireTechLine
|
|
||||||
{
|
|
||||||
private int id;
|
|
||||||
|
|
||||||
private String name;
|
|
||||||
|
|
||||||
private String description;
|
|
||||||
|
|
||||||
private List< EmpireTechnology > technologies = new LinkedList< EmpireTechnology >( );
|
|
||||||
|
|
||||||
|
|
||||||
public int getId( )
|
|
||||||
{
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setId( int id )
|
|
||||||
{
|
|
||||||
this.id = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getName( )
|
|
||||||
{
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setName( String name )
|
|
||||||
{
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getDescription( )
|
|
||||||
{
|
|
||||||
return description;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setDescription( String description )
|
|
||||||
{
|
|
||||||
this.description = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public List< EmpireTechnology > getTechnologies( )
|
|
||||||
{
|
|
||||||
return technologies;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void addTechnology( EmpireTechnology eTech )
|
|
||||||
{
|
|
||||||
this.technologies.add( eTech );
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue