Project: * Clean-up (Eclipse cruft, unused files, etc...) * Git-specific changes * Maven POMs clean-up and changes for the build system * Version set to 1.0.0-0 in the development branches * Maven plug-ins updated to latest versions * Very partial dev. documentation added

This commit is contained in:
Emmanuel BENOîT 2011-12-09 08:07:33 +01:00
parent c74e30d5ba
commit 0665a760de
1439 changed files with 1020 additions and 1649 deletions
legacyworlds-server-beans-simple/src
main
java/com/deepclone/lw/beans
resources/configuration
test
java
resources

View file

@ -0,0 +1,265 @@
package com.deepclone.lw.beans.empire;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.deepclone.lw.cmd.player.gdata.NameIdPair;
import com.deepclone.lw.cmd.player.gdata.alliance.AllianceLeaderData;
import com.deepclone.lw.cmd.player.gdata.alliance.AllianceMemberData;
import com.deepclone.lw.cmd.player.gdata.alliance.AlliancePlanetData;
import com.deepclone.lw.cmd.player.gdata.alliance.PublicAllianceInformation;
import com.deepclone.lw.interfaces.game.AllianceDAO;
import com.deepclone.lw.sqld.game.AllianceMembership;
import com.deepclone.lw.utils.StoredProc;
public class AllianceDAOBean
implements AllianceDAO
{
private SimpleJdbcTemplate dTemplate;
private StoredProc fCreateAlliance;
private StoredProc fJoinAlliance;
private StoredProc fCancelJoin;
private StoredProc fLeaveAlliance;
private StoredProc fTransferLeadership;
private StoredProc fAcceptMembers;
private StoredProc fRejectMembers;
private StoredProc fKickMembers;
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.fCreateAlliance = new StoredProc( dataSource , "emp" , "create_alliance" );
this.fCreateAlliance.addParameter( "empire_id" , Types.INTEGER );
this.fCreateAlliance.addParameter( "alliance_tag" , Types.VARCHAR );
this.fCreateAlliance.addParameter( "alliance_name" , Types.VARCHAR );
this.fCreateAlliance.addOutput( "alliance_id" , Types.INTEGER );
this.fJoinAlliance = new StoredProc( dataSource , "emp" , "join_alliance" );
this.fJoinAlliance.addParameter( "empire_id" , Types.INTEGER );
this.fJoinAlliance.addParameter( "alliance_id" , Types.INTEGER );
this.fJoinAlliance.addOutput( "success" , Types.BOOLEAN );
this.fCancelJoin = new StoredProc( dataSource , "emp" , "cancel_join" );
this.fCancelJoin.addParameter( "empire_id" , Types.INTEGER );
this.fLeaveAlliance = new StoredProc( dataSource , "emp" , "leave_alliance" );
this.fLeaveAlliance.addParameter( "empire_id" , Types.INTEGER );
this.fTransferLeadership = new StoredProc( dataSource , "emp" , "transfer_leadership" );
this.fTransferLeadership.addParameter( "empire_id" , Types.INTEGER );
this.fTransferLeadership.addParameter( "target_id" , Types.INTEGER );
this.fAcceptMembers = new StoredProc( dataSource , "emp" , "accept_members" );
this.fAcceptMembers.addParameter( "empire_id" , Types.INTEGER );
this.fAcceptMembers.addParameter( "member_ids" , "INT[]" );
this.fRejectMembers = new StoredProc( dataSource , "emp" , "reject_members" );
this.fRejectMembers.addParameter( "empire_id" , Types.INTEGER );
this.fRejectMembers.addParameter( "member_ids" , "INT[]" );
this.fKickMembers = new StoredProc( dataSource , "emp" , "kick_members" );
this.fKickMembers.addParameter( "empire_id" , Types.INTEGER );
this.fKickMembers.addParameter( "member_ids" , "INT[]" );
}
@Override
public Integer findAlliance( String tag )
{
String sql = "SELECT id FROM emp.alliances_public WHERE lower( tag ) = ?";
try {
return this.dTemplate.queryForInt( sql , tag.toLowerCase( ) );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public AllianceMembership getAlliance( int empireId )
{
String sql = "SELECT alliance , pending FROM emp.alliance_membership WHERE id = ?";
RowMapper< AllianceMembership > mapper = new RowMapper< AllianceMembership >( ) {
@Override
public AllianceMembership mapRow( ResultSet rs , int rowNum )
throws SQLException
{
AllianceMembership am = new AllianceMembership( );
am.setAllianceId( rs.getInt( "alliance" ) );
am.setPending( rs.getBoolean( "pending" ) );
return am;
}
};
try {
return this.dTemplate.queryForObject( sql , mapper , empireId );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public Integer createAlliance( int empireId , String tag , String name )
{
return (Integer) this.fCreateAlliance.execute( empireId , tag , name ).get( "alliance_id" );
}
@Override
public PublicAllianceInformation getPublicInformation( int allianceId )
{
String sql = "SELECT * FROM emp.alliances_public WHERE id = ?";
RowMapper< PublicAllianceInformation > mapper = new RowMapper< PublicAllianceInformation >( ) {
@Override
public PublicAllianceInformation mapRow( ResultSet rs , int rowNum )
throws SQLException
{
return new PublicAllianceInformation( rs.getInt( "id" ) , rs.getString( "tag" ) ,
rs.getString( "name" ) , rs.getInt( "leader_id" ) , rs.getString( "leader_name" ) , rs
.getLong( "planets" ) );
}
};
try {
return this.dTemplate.queryForObject( sql , mapper , allianceId );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
private List< NameIdPair > getMembers( int allianceId , boolean pending )
{
String mSql = "SELECT id , name FROM emp.alliance_membership WHERE alliance = ? AND ";
if ( !pending ) {
mSql += "NOT ";
}
mSql += "pending";
RowMapper< NameIdPair > mMapper = new RowMapper< NameIdPair >( ) {
@Override
public NameIdPair mapRow( ResultSet rs , int rowNum )
throws SQLException
{
return new NameIdPair( rs.getInt( 1 ) , rs.getString( 2 ) );
}
};
List< NameIdPair > members = this.dTemplate.query( mSql , mMapper , allianceId );
return members;
}
private List< AlliancePlanetData > getPlanets( int allianceId )
{
String pSql = "SELECT * FROM emp.alliance_planets WHERE alliance = ?";
RowMapper< AlliancePlanetData > pMapper = new RowMapper< AlliancePlanetData >( ) {
@Override
public AlliancePlanetData mapRow( ResultSet rs , int rowNum )
throws SQLException
{
AlliancePlanetData apd = new AlliancePlanetData( );
apd.setId( rs.getInt( "planet_id" ) );
apd.setName( rs.getString( "planet_name" ) );
apd.setX( rs.getInt( "x" ) );
apd.setY( rs.getInt( "y" ) );
apd.setOrbit( rs.getInt( "orbit" ) );
apd.setOwnerId( rs.getInt( "owner_id" ) );
apd.setOwner( rs.getString( "owner_name" ) );
apd.setBattle( rs.getBoolean( "battle" ) );
apd.setAttack( rs.getLong( "attack" ) );
apd.setDefence( rs.getLong( "defence" ) );
return apd;
}
};
return this.dTemplate.query( pSql , pMapper , allianceId );
}
@Override
public AllianceMemberData getMemberData( int allianceId )
{
List< NameIdPair > members = this.getMembers( allianceId , false );
List< AlliancePlanetData > planets = this.getPlanets( allianceId );
return new AllianceMemberData( members , planets );
}
@Override
public AllianceLeaderData getLeaderData( int allianceId )
{
return new AllianceLeaderData( this.getMembers( allianceId , true ) );
}
@Override
public boolean requestJoin( int empireId , int allianceId )
{
return (Boolean) this.fJoinAlliance.execute( empireId , allianceId ).get( "success" );
}
@Override
public void cancelJoin( int empireId )
{
this.fCancelJoin.execute( empireId );
}
@Override
public void leave( int empireId )
{
this.fLeaveAlliance.execute( empireId );
}
@Override
public void transferLeadership( int empireId , int toMember )
{
this.fTransferLeadership.execute( empireId , toMember );
}
private String toSQLArray( int[] members )
{
StringBuilder mArray = new StringBuilder( ).append( "{" );
for ( int i = 0 ; i < members.length ; i++ ) {
mArray.append( members[ i ] ).append( ( i == members.length - 1 ) ? '}' : ',' );
}
String mStr = mArray.toString( );
return mStr;
}
@Override
public void manageRequests( int empireId , boolean accept , int[] members )
{
StoredProc proc = accept ? this.fAcceptMembers : this.fRejectMembers;
proc.execute( empireId , this.toSQLArray( members ) );
}
@Override
public void kick( int empireId , int[] members )
{
this.fKickMembers.execute( empireId , this.toSQLArray( members ) );
}
}

View file

@ -0,0 +1,176 @@
package com.deepclone.lw.beans.empire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.deepclone.lw.cmd.ObjectNameError;
import com.deepclone.lw.cmd.player.alliances.AllianceStatusResponse;
import com.deepclone.lw.cmd.player.alliances.CreateAllianceResponse;
import com.deepclone.lw.cmd.player.alliances.JoinAllianceResponse;
import com.deepclone.lw.cmd.player.alliances.ViewAllianceResponse;
import com.deepclone.lw.cmd.player.gdata.GamePageData;
import com.deepclone.lw.cmd.player.gdata.alliance.AllianceCreationStatus;
import com.deepclone.lw.cmd.player.gdata.alliance.AllianceData;
import com.deepclone.lw.cmd.player.gdata.alliance.AllianceLeaderData;
import com.deepclone.lw.cmd.player.gdata.alliance.AllianceMemberData;
import com.deepclone.lw.cmd.player.gdata.alliance.PublicAllianceInformation;
import com.deepclone.lw.interfaces.game.AllianceDAO;
import com.deepclone.lw.interfaces.game.AllianceManagement;
import com.deepclone.lw.interfaces.game.EmpireManagement;
import com.deepclone.lw.sqld.game.AllianceMembership;
@Transactional
public class AllianceManagementBean
implements AllianceManagement
{
private EmpireManagement empireManagement;
private AllianceDAO allianceDao;
@Autowired( required = true )
public void setEmpireManager( EmpireManagement manager )
{
this.empireManagement = manager;
}
@Autowired( required = true )
public void setAllianceDao( AllianceDAO allianceDao )
{
this.allianceDao = allianceDao;
}
private AllianceData getAllianceData( int empireId )
{
PublicAllianceInformation pub = null;
AllianceMemberData member = null;
AllianceLeaderData leader = null;
AllianceMembership m = this.allianceDao.getAlliance( empireId );
if ( m != null ) {
int allianceId = m.getAllianceId( );
pub = this.allianceDao.getPublicInformation( allianceId );
if ( !m.isPending( ) ) {
member = this.allianceDao.getMemberData( allianceId );
if ( empireId == pub.getLeaderId( ) ) {
leader = this.allianceDao.getLeaderData( allianceId );
}
}
}
return new AllianceData( pub , member , leader );
}
@Override
public AllianceStatusResponse getView( int empireId )
{
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
AllianceData alliance = this.getAllianceData( empireId );
return new AllianceStatusResponse( page , alliance );
}
@Override
public AllianceStatusResponse getInformation( int empireId , String tag )
{
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
AllianceData alliance = this.getAllianceData( empireId );
if ( "".equals( tag ) ) {
return new AllianceStatusResponse( page , alliance );
}
Integer allianceId = this.allianceDao.findAlliance( tag );
PublicAllianceInformation pub;
if ( allianceId == null ) {
pub = null;
} else {
pub = this.allianceDao.getPublicInformation( allianceId );
}
return new ViewAllianceResponse( page , alliance , tag , pub );
}
@Override
public AllianceStatusResponse create( int empireId , String tag , String name )
{
Integer aId = this.allianceDao.createAlliance( empireId , tag , name );
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
AllianceData alliance = this.getAllianceData( empireId );
if ( aId == null ) {
AllianceCreationStatus acs = new AllianceCreationStatus( tag , ObjectNameError.UNAVAILABLE , name , null );
return new CreateAllianceResponse( page , alliance , acs );
}
return new AllianceStatusResponse( page , alliance );
}
@Override
public AllianceStatusResponse requestJoin( int empireId , String tag )
{
Integer aId = this.allianceDao.findAlliance( tag );
boolean joined;
if ( aId == null ) {
joined = false;
} else {
joined = this.allianceDao.requestJoin( empireId , aId );
}
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
AllianceData alliance = this.getAllianceData( empireId );
return joined
? new AllianceStatusResponse( page , alliance )
: new JoinAllianceResponse( page , alliance , tag );
}
@Override
public AllianceStatusResponse cancelJoin( int empireId )
{
this.allianceDao.cancelJoin( empireId );
return this.getView( empireId );
}
@Override
public AllianceStatusResponse leave( int empireId )
{
this.allianceDao.leave( empireId );
return this.getView( empireId );
}
@Override
public AllianceStatusResponse transferLeadership( int empireId , int toMember )
{
this.allianceDao.transferLeadership( empireId , toMember );
return this.getView( empireId );
}
@Override
public AllianceStatusResponse manageRequests( int empireId , boolean accept , int[] members )
{
this.allianceDao.manageRequests( empireId , accept , members );
return this.getView( empireId );
}
@Override
public AllianceStatusResponse kick( int empireId , int[] members )
{
this.allianceDao.kick( empireId , members );
return this.getView( empireId );
}
}

View file

@ -0,0 +1,289 @@
package com.deepclone.lw.beans.empire;
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.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.deepclone.lw.cmd.ObjectNameError;
import com.deepclone.lw.cmd.player.gdata.NameIdPair;
import com.deepclone.lw.cmd.player.gdata.PlanetListData;
import com.deepclone.lw.cmd.player.gdata.empire.OverviewData;
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.utils.StoredProc;
public class EmpireDAOBean
implements EmpireDAO
{
private SimpleJdbcTemplate dTemplate;
private StoredProc fImplementTech;
private StoredProc fAddEmpEnemy;
private StoredProc fAddAllEnemy;
private StoredProc fRemoveEmpEnemy;
private StoredProc fRemoveAllEnemy;
private StoredProc fGetNewPlanet;
private final PlanetListMapper mPlanetList = new PlanetListMapper( );
@Autowired( required = true )
public void setDataSource( DataSource 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.addParameter( "empire_id" , Types.INTEGER );
this.fAddEmpEnemy.addParameter( "enemy_name" , Types.VARCHAR );
this.fAddEmpEnemy.addOutput( "err_code" , Types.INTEGER );
this.fAddAllEnemy = new StoredProc( dataSource , "emp" , "add_enemy_alliance" );
this.fAddAllEnemy.addParameter( "empire_id" , Types.INTEGER );
this.fAddAllEnemy.addParameter( "enemy_tag" , Types.VARCHAR );
this.fAddAllEnemy.addOutput( "err_code" , Types.INTEGER );
this.fRemoveEmpEnemy = new StoredProc( dataSource , "emp" , "remove_enemy_empires" );
this.fRemoveEmpEnemy.addParameter( "empire_id" , Types.INTEGER );
this.fRemoveEmpEnemy.addParameter( "to_remove" , "INT[]" );
this.fRemoveAllEnemy = new StoredProc( dataSource , "emp" , "remove_enemy_alliances" );
this.fRemoveAllEnemy.addParameter( "empire_id" , Types.INTEGER );
this.fRemoveAllEnemy.addParameter( "to_remove" , "INT[]" );
this.fGetNewPlanet = new StoredProc( dataSource , "emp" , "get_new_planet" );
this.fGetNewPlanet.addParameter( "empire_id" , Types.INTEGER );
this.fGetNewPlanet.addParameter( "planet_name" , Types.VARCHAR );
this.fGetNewPlanet.addOutput( "err_code" , Types.INTEGER );
}
@Override
public GeneralInformation getInformation( int empireId )
{
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 {
return this.dTemplate.queryForObject( sql , mapper , empireId );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public List< NameIdPair > getPlanets( int empireId )
{
String sql = "SELECT id , name FROM emp.planets_view WHERE empire = ?";
RowMapper< NameIdPair > mapper = new RowMapper< NameIdPair >( ) {
@Override
public NameIdPair mapRow( ResultSet rs , int rowNum )
throws SQLException
{
return new NameIdPair( rs.getInt( "id" ) , rs.getString( "name" ) );
}
};
return this.dTemplate.query( sql , mapper , empireId );
}
@Override
public OverviewData getOverview( int empireId )
{
String sql = "SELECT * FROM emp.overview WHERE empire = ?";
RowMapper< OverviewData > mapper = new RowMapper< OverviewData >( ) {
@Override
public OverviewData mapRow( ResultSet rs , int rowNum )
throws SQLException
{
OverviewData info = new OverviewData( );
info.setPlanets( rs.getLong( "planets" ) );
Double dTemp;
dTemp = rs.getDouble( "population" );
info.setPopulation( dTemp == null ? 0 : dTemp.longValue( ) );
dTemp = rs.getDouble( "avg_happiness" );
info.setAvgHappiness( dTemp == null ? 0 : dTemp.intValue( ) );
dTemp = rs.getDouble( "planet_income" );
info.setPlanetIncome( dTemp == null ? 0 : dTemp.longValue( ) );
dTemp = rs.getDouble( "planet_upkeep" );
info.setPlanetUpkeep( dTemp == null ? 0 : dTemp.longValue( ) );
Long lTemp;
lTemp = rs.getLong( "fleet_power" );
info.setFleetPower( lTemp == null ? 0 : lTemp );
lTemp = rs.getLong( "fleet_upkeep" );
info.setFleetUpkeep( lTemp == null ? 0 : lTemp );
Long lTemp2;
lTemp = rs.getLong( "civ_investment" );
lTemp2 = rs.getLong( "mil_investment" );
info.setInvestment( ( lTemp == null ? 0 : lTemp ) + ( lTemp2 == null ? 0 : lTemp2 ) );
info.setNewMessages( rs.getInt( "new_messages" ) );
return info;
}
};
return this.dTemplate.queryForObject( sql , mapper , empireId );
}
@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
public List< PlanetListData > getPlanetList( int empireId )
{
String sql = "SELECT * FROM emp.planets_list WHERE empire = ?";
return this.dTemplate.query( sql , this.mPlanetList , empireId );
}
@Override
public List< NameIdPair > getEnemies( int empireId , boolean alliances )
{
String sql = "SELECT id , name FROM emp.enemy_lists WHERE empire = ? AND ";
if ( !alliances ) {
sql += "NOT ";
}
sql += "alliance";
RowMapper< NameIdPair > mapper = new RowMapper< NameIdPair >( ) {
@Override
public NameIdPair mapRow( ResultSet rs , int rowNum )
throws SQLException
{
return new NameIdPair( rs.getInt( "id" ) , rs.getString( "name" ) );
}
};
return this.dTemplate.query( sql , mapper , empireId );
}
@Override
public ObjectNameError addEnemy( int empireId , boolean alliance , String name )
{
StoredProc addProc = alliance ? this.fAddAllEnemy : this.fAddEmpEnemy;
int rv = (Integer) addProc.execute( empireId , name ).get( "err_code" );
switch ( rv ) {
case 0:
return null;
case 1:
return ObjectNameError.INVALID;
case 2:
return ObjectNameError.BANNED;
case 3:
return ObjectNameError.UNAVAILABLE;
default:
throw new RuntimeException( "unexpected error code " + rv );
}
}
@Override
public void removeEnemies( int empireId , boolean alliance , int[] ids )
{
StoredProc remProc = alliance ? this.fRemoveAllEnemy : this.fRemoveEmpEnemy;
StringBuilder idArray = new StringBuilder( ).append( "{" );
for ( int i = 0 ; i < ids.length ; i++ ) {
idArray.append( ids[ i ] ).append( ( i == ids.length - 1 ) ? "}" : "," );
}
remProc.execute( empireId , idArray.toString( ) );
}
@Override
public int getNewPlanet( int empireId , String name )
{
return (Integer) this.fGetNewPlanet.execute( empireId , name ).get( "err_code" );
}
}

View file

@ -0,0 +1,238 @@
package com.deepclone.lw.beans.empire;
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.ObjectNameError;
import com.deepclone.lw.cmd.player.EmpireResponse;
import com.deepclone.lw.cmd.player.GetNewPlanetResponse;
import com.deepclone.lw.cmd.player.ListPlanetsResponse;
import com.deepclone.lw.cmd.player.elist.AddEnemyResponse;
import com.deepclone.lw.cmd.player.elist.EnemyListResponse;
import com.deepclone.lw.cmd.player.gdata.GamePageData;
import com.deepclone.lw.cmd.player.gdata.NameIdPair;
import com.deepclone.lw.cmd.player.gdata.PlanetListData;
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.ResearchLineData;
import com.deepclone.lw.cmd.player.gdata.empire.TechnologyData;
import com.deepclone.lw.interfaces.acm.UsersDAO;
import com.deepclone.lw.interfaces.game.BattlesCache;
import com.deepclone.lw.interfaces.game.BattlesDAO;
import com.deepclone.lw.interfaces.game.EmpireDAO;
import com.deepclone.lw.interfaces.game.EmpireManagement;
import com.deepclone.lw.interfaces.naming.NamingDAO;
import com.deepclone.lw.interfaces.prefs.AccountPreferences;
import com.deepclone.lw.interfaces.prefs.PreferencesDAO;
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.battle.BattleListRecord;
import com.deepclone.lw.utils.EmailAddress;
@Transactional
public class EmpireManagementBean
implements EmpireManagement
{
private NamingDAO namingDao;
private UsersDAO usersDao;
private EmpireDAO empireDao;
private PreferencesDAO prefsDao;
private BattlesDAO battlesDao;
@Autowired( required = true )
public void setUsersDao( UsersDAO usersDao )
{
this.usersDao = usersDao;
}
@Autowired( required = true )
public void setNamingDao( NamingDAO namingDao )
{
this.namingDao = namingDao;
}
@Autowired( required = true )
public void setEmpireDao( EmpireDAO empireDao )
{
this.empireDao = empireDao;
}
@Autowired( required = true )
public void setPrefsDao( PreferencesDAO prefsDao )
{
this.prefsDao = prefsDao;
}
@Autowired( required = true )
public void setBattlesDao( BattlesCache battlesDao )
{
this.battlesDao = battlesDao;
}
@Override
public Integer getEmpireId( EmailAddress address )
{
Account acnt = usersDao.getAccount( address );
if ( acnt == null || !acnt.getStatus( ).isActive( ) ) {
return null;
}
return namingDao.getCurrentEmpire( acnt );
}
@Override
public GamePageData getGeneralInformation( int empireId )
{
GeneralInformation generalInformation = this.empireDao.getInformation( empireId );
List< NameIdPair > planets = this.empireDao.getPlanets( empireId );
AccountPreferences prefs = this.prefsDao.getPreferences( generalInformation.getAccountId( ) );
boolean rlTime = prefs.getPreference( "useRLTime" , Boolean.class );
return new GamePageData( generalInformation.getName( ) , generalInformation.getStatus( ) , generalInformation
.getTag( ) , generalInformation.getCash( ) , generalInformation.getNextTick( ) , planets , rlTime );
}
@Override
public EmpireResponse getOverview( int 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 >( );
for ( BattleListRecord record : this.battlesDao.getBattles( empireId ) ) {
if ( record.getLastTick( ) != null ) {
break;
}
BattleListEntry entry = new BattleListEntry( );
entry.setId( record.getBattle( ) );
entry.setLocation( new NameIdPair( record.getPlanetId( ) , record.getName( ) ) );
entry.setX( record.getX( ) );
entry.setY( record.getY( ) );
entry.setOrbit( record.getOrbit( ) );
entry.setFirst( record.getFirstTick( ) );
if ( record.getLastTick( ) != null ) {
entry.setLast( record.getLastTick( ) );
}
battles.add( entry );
}
return new EmpireResponse( this.getGeneralInformation( empireId ) , overview , research , battles );
}
@Override
public EmpireResponse implementTechnology( int empireId , int techId )
{
this.empireDao.implementTechnology( empireId , techId );
return this.getOverview( empireId );
}
@Override
public ListPlanetsResponse getPlanetList( int empireId )
{
GamePageData page = this.getGeneralInformation( empireId );
List< PlanetListData > planets = this.empireDao.getPlanetList( empireId );
return new ListPlanetsResponse( page , planets );
}
@Override
public EnemyListResponse getEnemyLists( int empireId )
{
GamePageData page = this.getGeneralInformation( empireId );
List< NameIdPair > empires = this.empireDao.getEnemies( empireId , false );
List< NameIdPair > alliances = this.empireDao.getEnemies( empireId , true );
return new EnemyListResponse( page , empires , alliances );
}
@Override
public EnemyListResponse addEnemy( int empireId , boolean alliance , String name )
{
ObjectNameError error = this.empireDao.addEnemy( empireId , alliance , name );
GamePageData page = this.getGeneralInformation( empireId );
List< NameIdPair > empires = this.empireDao.getEnemies( empireId , false );
List< NameIdPair > alliances = this.empireDao.getEnemies( empireId , true );
if ( error == null ) {
return new EnemyListResponse( page , empires , alliances );
}
return new AddEnemyResponse( page , empires , alliances , error , alliance , name );
}
@Override
public EnemyListResponse removeEnemies( int empireId , boolean alliance , int[] ids )
{
this.empireDao.removeEnemies( empireId , alliance , ids );
return this.getEnemyLists( empireId );
}
@Override
public GetNewPlanetResponse getNewPlanet( int empireId , String name )
{
int errCode = this.empireDao.getNewPlanet( empireId , name );
ObjectNameError error;
switch ( errCode ) {
case 0:
error = null;
break;
case 1:
error = ObjectNameError.BANNED;
break;
case 2:
error = ObjectNameError.UNAVAILABLE;
break;
default:
return new GetNewPlanetResponse( this.getGeneralInformation( empireId ) , null , null );
}
Integer planetId;
if ( error == null ) {
planetId = this.empireDao.getPlanetList( empireId ).get( 0 ).getId( );
} else {
planetId = null;
}
if ( planetId == null ) {
return new GetNewPlanetResponse( this.getGeneralInformation( empireId ) , name , error );
}
return new GetNewPlanetResponse( this.getGeneralInformation( empireId ) , planetId );
}
}

View file

@ -0,0 +1,59 @@
package com.deepclone.lw.beans.empire;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.jdbc.core.RowMapper;
import com.deepclone.lw.cmd.player.gdata.PlanetListData;
final class PlanetListMapper
implements RowMapper< PlanetListData >
{
@Override
public PlanetListData mapRow( ResultSet rs , int rowNum )
throws SQLException
{
PlanetListData pl = new PlanetListData( );
pl.setId( rs.getInt( "id" ) );
pl.setName( rs.getString( "name" ) );
pl.setX( rs.getInt( "x" ) );
pl.setY( rs.getInt( "y" ) );
pl.setOrbit( rs.getInt( "orbit" ) );
pl.setPopulation( rs.getLong( "population" ) );
pl.setHappiness( rs.getInt( "happiness" ) );
pl.setIncome( rs.getLong( "income" ) );
pl.setUpkeep( rs.getLong( "upkeep" ) );
pl.setMilitaryProduction( rs.getLong( "military_production" ) );
pl.setIndustrialProduction( rs.getLong( "industrial_production" ) );
pl.setGrowthProduction( rs.getLong( "growth_production" ) );
pl.setCivInvestment( rs.getLong( "civ_investment" ) );
pl.setCivAmount( rs.getInt( "civ_amount" ) );
pl.setCivDestroy( rs.getBoolean( "civ_destroy" ) );
pl.setCivName( rs.getString( "civ_name" ) );
pl.setMilInvestment( rs.getLong( "mil_investment" ) );
pl.setMilAmount( rs.getInt( "mil_amount" ) );
pl.setMilName( rs.getString( "mil_name" ) );
pl.setFpStatic( rs.getLong( "static_defence" ) );
pl.setFpOwn( rs.getLong( "own_fleet" ) );
pl.setFpFriendly( rs.getLong( "friendly_fleet" ) );
pl.setFpHostile( rs.getLong( "hostile_fleet" ) );
pl.setBattle( (Long) rs.getObject( "battle" ) );
return pl;
}
}

View file

@ -0,0 +1,359 @@
package com.deepclone.lw.beans.fleets;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import com.deepclone.lw.cmd.player.battles.GetBattleResponse;
import com.deepclone.lw.cmd.player.battles.ListBattlesResponse;
import com.deepclone.lw.cmd.player.gdata.GamePageData;
import com.deepclone.lw.cmd.player.gdata.NameIdPair;
import com.deepclone.lw.cmd.player.gdata.PlanetRelationType;
import com.deepclone.lw.cmd.player.gdata.TimeCombo;
import com.deepclone.lw.cmd.player.gdata.battles.*;
import com.deepclone.lw.interfaces.game.BattleViewer;
import com.deepclone.lw.interfaces.game.BattlesCache;
import com.deepclone.lw.interfaces.game.EmpireManagement;
import com.deepclone.lw.sqld.game.battle.*;
public class BattleViewerBean
implements BattleViewer
{
private static final int pageSize = 10;
private EmpireManagement empireManagement;
private BattlesCache battlesDao;
@Autowired( required = true )
public void setEmpireManagement( EmpireManagement empireManagement )
{
this.empireManagement = empireManagement;
}
@Autowired( required = true )
public void setBattlesDao( BattlesCache dao )
{
this.battlesDao = dao;
}
@Override
public GetBattleResponse getBattle( int empireId , long battleId )
{
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
BattleView battle = this.createBattleView( empireId , battleId , null );
return new GetBattleResponse( page , battle );
}
@Override
public GetBattleResponse getBattle( int empireId , long battleId , long tick )
{
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
BattleView battle = this.createBattleView( empireId , battleId , tick );
return new GetBattleResponse( page , battle );
}
private BattleView createBattleView( int empireId , long battleId , Long tick )
{
EmpireBattleRecord battle = this.battlesDao.getBattleRecord( empireId , battleId );
if ( battle == null ) {
return null;
}
BattleView view = new BattleView( );
BattleDescription bDescription = new BattleDescription( );
BattleDisplay bDisplay = new BattleDisplay( );
view.setDescription( bDescription );
view.setDisplay( bDisplay );
// Generate main battle description
bDescription.setId( battleId );
bDescription.setLocation( new NameIdPair( battle.getPlanetId( ) , battle.getPlanetName( ) ) );
bDescription.setX( battle.getX( ) );
bDescription.setY( battle.getY( ) );
bDescription.setOrbit( battle.getOrbit( ) );
// Generate list of ticks
List< PresenceRecord > presence = this.battlesDao.getPresence( battle );
Long previous = null;
Long next = null;
Long display = null;
boolean planetOwner = false;
boolean wasPresent = false;
for ( PresenceRecord pRec : presence ) {
if ( !pRec.isPresent( ) && !wasPresent ) {
continue;
}
long prTick = pRec.getTick( );
if ( tick == null || display == null || display < tick ) {
previous = display;
display = prTick;
planetOwner = pRec.isPlanetOwner( );
} else if ( next == null ) {
next = prTick;
}
bDisplay.addTime( prTick );
wasPresent = pRec.isPresent( );
}
if ( display == null && presence.size( ) == 1 ) {
display = presence.get( 0 ).getTick( );
bDisplay.addTime( display );
}
bDisplay.setCurrent( display );
if ( previous != null ) {
bDisplay.setPrevious( previous );
}
if ( next != null ) {
bDisplay.setNext( next );
}
// Get the status at the current tick
Map< Long , Map< Long , ProtagonistRecord >> protagonists = this.battlesDao.getProtagonists( battle );
view.setShips( this.getBattleStatus( battle , display , protagonists , planetOwner ) );
// Determine history intervals to display
List< BattleHistoryInterval > intervals = this.getIntervals( battle , presence , display );
// Add battle history
Collections.reverse( intervals );
this.addEvents( battle , intervals , protagonists , display );
for ( BattleHistoryInterval i : intervals ) {
view.addHistoryInterval( i );
}
return view;
}
private List< BattleHistoryInterval > getIntervals( EmpireBattleRecord battle , List< PresenceRecord > presence ,
long display )
{
List< BattleHistoryInterval > intervals = new LinkedList< BattleHistoryInterval >( );
for ( PresenceRecord pRec : presence ) {
long prTick = pRec.getTick( );
if ( prTick > display ) {
break;
}
if ( intervals.isEmpty( ) || intervals.get( intervals.size( ) - 1 ).getEnd( ) != null ) {
if ( !pRec.isPresent( ) ) {
continue;
}
BattleHistoryInterval interval = new BattleHistoryInterval( );
interval.setBegin( prTick , prTick == battle.getFirstTick( ) );
intervals.add( interval );
} else if ( !pRec.isPresent( ) ) {
BattleHistoryInterval interval = intervals.get( intervals.size( ) - 1 );
interval.setEnd( prTick , false );
} else if ( battle.getLastTick( ) != null && prTick == battle.getLastTick( ) ) {
BattleHistoryInterval interval = intervals.get( intervals.size( ) - 1 );
interval.setEnd( prTick , true );
}
}
if ( intervals.isEmpty( ) && presence.size( ) == 1 ) {
PresenceRecord pRec = presence.get( 0 );
BattleHistoryInterval interval = new BattleHistoryInterval( );
interval.setBegin( pRec.getTick( ) , true );
interval.setEnd( pRec.getTick( ) , true );
intervals.add( interval );
}
return intervals;
}
private void addEvents( EmpireBattleRecord battle , List< BattleHistoryInterval > intervals ,
Map< Long , Map< Long , ProtagonistRecord >> protagonists , long display )
{
Map< Boolean , Map< Long , List< EventItemRecord >>> eItems = this.battlesDao.getEventItems( battle );
ListIterator< BattleHistoryInterval > bhIterator = intervals.listIterator( );
BattleHistoryInterval cInterval = bhIterator.next( );
BattleHistoryTick cTick = null;
for ( EventRecord event : this.battlesDao.getEvents( battle ) ) {
long eTick = event.getTick( );
if ( eTick > display ) {
continue;
}
// Do not add events after the end of the current interval
TimeCombo intEnd = cInterval.getEnd( );
if ( intEnd != null && eTick > intEnd.getTicks( ) ) {
continue;
}
// If the event is before the current interval, try fetching the "next" (previous in
// terms of ticks) interval
if ( eTick < cInterval.getBegin( ).getTicks( ) ) {
if ( !bhIterator.hasNext( ) ) {
break;
}
cInterval = bhIterator.next( );
cTick = null;
if ( eTick > cInterval.getEnd( ).getTicks( ) ) {
continue;
}
}
// Create and add the event's tick if necessary
if ( cTick == null || cTick.getTime( ).getTicks( ) != eTick ) {
cTick = new BattleHistoryTick( eTick );
cInterval.addEntry( cTick );
}
// Create the event's record
BattleEvent bEvent = new BattleEvent( );
bEvent.setType( BattleEventType.valueOf( event.getEventType( ) ) );
bEvent.setPlanet( event.isPlanet( ) );
bEvent.setName( event.getName( ) );
if ( event.getAttack( ) != null ) {
ProtagonistRecord self = protagonists.get( eTick ).get( battle.getProtagonistId( ) );
if ( !event.isPlanet( ) && self.getName( ).equals( event.getName( ) ) ) {
bEvent.setHostile( event.getAttack( ) );
} else {
bEvent.setHostile( self.isAttacking( ) != event.getAttack( ) );
}
}
// Add event to history
cTick.addEvent( bEvent );
// Add ships/buildings
if ( event.getEventId( ) == null ) {
continue;
}
List< EventItemRecord > items = eItems.get( event.isPlanet( ) ).get( event.getEventId( ) );
if ( items == null ) {
continue;
}
for ( EventItemRecord eir : items ) {
BattleShipType item = new BattleShipType( );
item.setName( eir.getNature( ) );
item.setcAmount( eir.getAmount( ) );
bEvent.addShip( item );
}
}
}
private BattleShipsView getBattleStatus( EmpireBattleRecord battle , Long display ,
Map< Long , Map< Long , ProtagonistRecord >> pHistory , boolean planetOwner )
{
BattleShipsView view = new BattleShipsView( );
Map< Long , ProtagonistRecord > protagonists = pHistory.get( display );
Map< Long , List< ShipHistoryRecord >> ships = this.battlesDao.getShipsHistory( battle ).get( display );
boolean vMode = protagonists.get( battle.getProtagonistId( ) ).isAttacking( );
// Handle fleets
for ( ProtagonistRecord protagonist : protagonists.values( ) ) {
BattlePlayerShips pShips;
boolean isSelf = ( protagonist.getProtagonistId( ) == battle.getProtagonistId( ) );
if ( isSelf ) {
pShips = view.getOwn( );
} else {
pShips = new BattlePlayerShips( );
}
// Add ships
List< ShipHistoryRecord > pShipList = ships.get( protagonist.getProtagonistId( ) );
if ( pShipList == null ) {
continue;
}
for ( ShipHistoryRecord shr : pShipList ) {
BattleShipType shipType = new BattleShipType( );
shipType.setName( shr.getNature( ) );
shipType.setcAmount( shr.getCurrent( ) );
shipType.setcPower( shr.getCurrent( ) * shr.getPower( ) );
shipType.setlAmount( shr.getLost( ) );
shipType.setlPower( shr.getLost( ) * shr.getPower( ) );
pShips.addShip( shipType );
}
// Set empire name & identifier
int eId = protagonist.getEmpireId( ) == null ? -1 : protagonist.getEmpireId( ).intValue( );
pShips.setPlayer( new NameIdPair( eId , protagonist.getName( ) ) );
// Add to the appropriate list
if ( isSelf || pShips.getcPower( ) == 0 && pShips.getlPower( ) == 0 ) {
continue;
}
BattleSideShips side = ( protagonist.isAttacking( ) == vMode ) ? view.getFriendly( ) : view.getHostile( );
side.addPlayer( pShips );
}
// Handle planet
BattlePlanetBuildings planet = view.getPlanet( );
if ( planetOwner ) {
planet.setRelation( PlanetRelationType.OWN );
} else {
planet.setRelation( vMode ? PlanetRelationType.ENEMY : PlanetRelationType.ALLIED );
}
List< BuildingHistoryRecord > toDisplay = this.battlesDao.getBuildingsHistory( battle ).get( display );
if ( toDisplay != null ) {
for ( BuildingHistoryRecord bhr : toDisplay ) {
BattleShipType building = new BattleShipType( );
building.setName( bhr.getNature( ) );
building.setcAmount( bhr.getCurrent( ) );
building.setcPower( bhr.getCurrent( ) * bhr.getPower( ) );
building.setlAmount( bhr.getLost( ) );
building.setlPower( bhr.getLost( ) * bhr.getPower( ) );
planet.addShip( building );
}
}
return view;
}
@Override
public ListBattlesResponse getBattles( int empireId , int page )
{
List< BattleListRecord > records = this.battlesDao.getBattles( empireId );
int rSize = records.size( );
int mod = rSize % BattleViewerBean.pageSize;
int pages = ( rSize - mod ) / BattleViewerBean.pageSize + ( mod > 0 ? 1 : 0 );
if ( page < 0 ) {
page = 0;
} else if ( page >= pages ) {
page = pages - 1;
}
List< BattleListEntry > entries = new LinkedList< BattleListEntry >( );
if ( pages > 0 ) {
records = records.subList( page * BattleViewerBean.pageSize , Math.min( ( page + 1 )
* BattleViewerBean.pageSize , rSize ) );
for ( BattleListRecord record : records ) {
BattleListEntry entry = new BattleListEntry( );
entry.setId( record.getBattle( ) );
entry.setLocation( new NameIdPair( record.getPlanetId( ) , record.getName( ) ) );
entry.setX( record.getX( ) );
entry.setY( record.getY( ) );
entry.setOrbit( record.getOrbit( ) );
entry.setFirst( record.getFirstTick( ) );
if ( record.getLastTick( ) != null ) {
entry.setLast( record.getLastTick( ) );
}
entries.add( entry );
}
}
return new ListBattlesResponse( this.empireManagement.getGeneralInformation( empireId ) , entries , page ,
pages );
}
}

View file

@ -0,0 +1,336 @@
package com.deepclone.lw.beans.fleets;
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.cmd.admin.logs.LogLevel;
import com.deepclone.lw.interfaces.eventlog.Logger;
import com.deepclone.lw.interfaces.eventlog.SystemLogger;
import com.deepclone.lw.interfaces.game.BattlesCache;
import com.deepclone.lw.interfaces.sys.Ticker;
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
import com.deepclone.lw.sqld.game.battle.*;
public class BattlesCacheBean
implements BattlesCache , Runnable
{
private static final int cacheTime = 6; // Half an hour
private static class CacheKey
{
private final int empireId;
private final long battleId;
public CacheKey( int empireId , long battleId )
{
this.empireId = empireId;
this.battleId = battleId;
}
@Override
public int hashCode( )
{
final int prime = 31;
int result = 1;
result = prime * result + (int) ( battleId ^ ( battleId >>> 32 ) );
result = prime * result + empireId;
return result;
}
@Override
public boolean equals( Object obj )
{
if ( this == obj )
return true;
if ( obj == null )
return false;
if ( getClass( ) != obj.getClass( ) )
return false;
CacheKey other = (CacheKey) obj;
if ( battleId != other.battleId )
return false;
if ( empireId != other.empireId )
return false;
return true;
}
}
private static class CacheData
{
public int timeLeft = BattlesCacheBean.cacheTime;
public EmpireBattleRecord battle;
public List< PresenceRecord > presence;
public Map< Long , Map< Long , ProtagonistRecord >> protagonists;
public List< EventRecord > events;
public Map< Boolean , Map< Long , List< EventItemRecord >>> eventItems;
public Map< Long , List< BuildingHistoryRecord >> buildings;
public Map< Long , Map< Long , List< ShipHistoryRecord >>> ships;
};
private static class ListCache
{
public int timeLeft = BattlesCacheBean.cacheTime;
public Long lastUpdate;
public List< BattleListRecord > list = new LinkedList< BattleListRecord >( );
};
private BattlesDAOBean battlesDao;
private SystemLogger logger;
private final Map< CacheKey , CacheData > cache = new HashMap< CacheKey , CacheData >( );
private final Map< Integer , ListCache > listCache = new HashMap< Integer , ListCache >( );
@Autowired( required = true )
public void setBattlesDAO( BattlesDAOBean battlesDao )
{
this.battlesDao = battlesDao;
}
@Autowired( required = true )
public void setTicker( Ticker ticker )
{
ticker.registerTask( Frequency.LOW , "Battles cache cleaner" , this );
}
@Autowired( required = true )
public void setLogger( Logger logger )
{
this.logger = logger.getSystemLogger( "BattlesCache" );
}
private void initCache( CacheKey cKey , EmpireBattleRecord record )
{
this.logger.log( LogLevel.TRACE ,
"Adding battle #" + record.getBattleId( ) + " for empire #" + record.getEmpireId( ) + " to the cache" )
.flush( );
CacheData data = new CacheData( );
data.battle = record;
data.presence = this.battlesDao.getPresence( record );
data.protagonists = this.battlesDao.getProtagonists( record );
data.events = this.battlesDao.getEvents( record );
data.eventItems = this.battlesDao.getEventItems( record );
data.buildings = this.battlesDao.getBuildingsHistory( record );
data.ships = this.battlesDao.getShipsHistory( record );
this.cache.put( cKey , data );
}
private CacheData getCached( EmpireBattleRecord record )
{
CacheKey cKey = new CacheKey( record.getEmpireId( ) , record.getBattleId( ) );
CacheData data;
synchronized ( this.cache ) {
data = this.cache.get( cKey );
if ( data != null ) {
data.timeLeft = BattlesCacheBean.cacheTime;
}
}
return data;
}
@Override
public void run( )
{
// Battle data cache
synchronized ( this.cache ) {
List< CacheKey > toRemove = new LinkedList< CacheKey >( );
for ( Map.Entry< CacheKey , CacheData > entry : this.cache.entrySet( ) ) {
CacheData data = entry.getValue( );
data.timeLeft--;
if ( data.timeLeft < 0 ) {
toRemove.add( entry.getKey( ) );
}
}
for ( CacheKey k : toRemove ) {
this.cache.remove( k );
}
if ( !toRemove.isEmpty( ) ) {
this.logger.log( LogLevel.DEBUG ,
"data cache - " + toRemove.size( ) + " entries removed; cache size: " + this.cache.size( ) )
.flush( );
}
}
// Battle lists cache
synchronized ( this.listCache ) {
List< Integer > toRemove = new LinkedList< Integer >( );
for ( Map.Entry< Integer , ListCache > entry : this.listCache.entrySet( ) ) {
ListCache data = entry.getValue( );
data.timeLeft--;
if ( data.timeLeft < 0 ) {
toRemove.add( entry.getKey( ) );
}
}
for ( Integer k : toRemove ) {
this.listCache.remove( k );
}
if ( !toRemove.isEmpty( ) ) {
this.logger.log( LogLevel.DEBUG ,
"list cache - " + toRemove.size( ) + " entries removed; cache size: " + this.listCache.size( ) )
.flush( );
}
}
}
@Override
public EmpireBattleRecord getBattleRecord( int empireId , long battleId )
{
CacheKey cKey = new CacheKey( empireId , battleId );
synchronized ( this.cache ) {
CacheData data = this.cache.get( cKey );
if ( data != null ) {
data.timeLeft = BattlesCacheBean.cacheTime;
return data.battle;
}
EmpireBattleRecord record = this.battlesDao.getBattleRecord( empireId , battleId );
if ( record != null && record.getLastTick( ) != null ) {
this.initCache( cKey , record );
}
return record;
}
}
@Override
public List< PresenceRecord > getPresence( EmpireBattleRecord record )
{
CacheData cData = this.getCached( record );
if ( cData != null ) {
return cData.presence;
}
return this.battlesDao.getPresence( record );
}
@Override
public Map< Long , Map< Long , ProtagonistRecord >> getProtagonists( EmpireBattleRecord record )
{
CacheData cData = this.getCached( record );
if ( cData != null ) {
return cData.protagonists;
}
return this.battlesDao.getProtagonists( record );
}
@Override
public List< EventRecord > getEvents( EmpireBattleRecord record )
{
CacheData cData = this.getCached( record );
if ( cData != null ) {
return cData.events;
}
return this.battlesDao.getEvents( record );
}
@Override
public Map< Boolean , Map< Long , List< EventItemRecord >>> getEventItems( EmpireBattleRecord record )
{
CacheData cData = this.getCached( record );
if ( cData != null ) {
return cData.eventItems;
}
return this.battlesDao.getEventItems( record );
}
@Override
public Map< Long , List< BuildingHistoryRecord >> getBuildingsHistory( EmpireBattleRecord record )
{
CacheData cData = this.getCached( record );
if ( cData != null ) {
return cData.buildings;
}
return this.battlesDao.getBuildingsHistory( record );
}
@Override
public Map< Long , Map< Long , List< ShipHistoryRecord >>> getShipsHistory( EmpireBattleRecord record )
{
CacheData cData = this.getCached( record );
if ( cData != null ) {
return cData.ships;
}
return this.battlesDao.getShipsHistory( record );
}
@Override
public List< BattleListRecord > getBattles( int empireId )
{
List< BattleListRecord > results;
synchronized ( this.listCache ) {
ListCache lcEntry = this.listCache.get( empireId );
int nCached;
if ( lcEntry == null ) {
// No cached data, get the whole list and add finished battles to the cache
lcEntry = new ListCache( );
nCached = 0;
results = this.battlesDao.getBattles( empireId );
for ( BattleListRecord record : results ) {
if ( !record.isFinished( ) ) {
continue;
}
if ( lcEntry.lastUpdate == null ) {
lcEntry.lastUpdate = record.getLastUpdate( );
}
lcEntry.list.add( record );
}
if ( !lcEntry.list.isEmpty( ) ) {
this.listCache.put( empireId , lcEntry );
}
} else {
// Cached data present, get updates
results = new LinkedList< BattleListRecord >( );
nCached = lcEntry.list.size( );
int i = 0;
for ( BattleListRecord record : this.battlesDao.getBattles( empireId , lcEntry.lastUpdate ) ) {
if ( !record.isFinished( ) ) {
results.add( record );
continue;
}
if ( i == 0 ) {
lcEntry.lastUpdate = record.getLastUpdate( );
}
lcEntry.list.add( i++ , record );
}
results.addAll( lcEntry.list );
lcEntry.timeLeft = BattlesCacheBean.cacheTime;
}
nCached = lcEntry.list.size( ) - nCached;
this.logger.log(
LogLevel.TRACE ,
"List of battles for empire #" + empireId + ": " + nCached + " new items cached ("
+ lcEntry.list.size( ) + " total), " + results.size( ) + " items returned" ).flush( );
}
return results;
}
}

View file

@ -0,0 +1,309 @@
package com.deepclone.lw.beans.fleets;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.deepclone.lw.interfaces.game.BattlesDAO;
import com.deepclone.lw.sqld.game.battle.*;
public class BattlesDAOBean
implements BattlesDAO
{
private static final String sGetBattleRecord = "SELECT * FROM battles.empire_list_view WHERE empire = ? AND battle = ?";
private static final String sGetPresenceList = "SELECT * FROM battles.protagonist_presence WHERE protagonist = ?";
private static final String sGetEvents = "SELECT e.* FROM battles.events_history e WHERE e.battle = ? AND e.tick IN ( SELECT tick FROM battles.protagonist_presence WHERE protagonist = ? AND present )";
private static final String sGetEventItems = "SELECT is_planet , event_id , nature , amount FROM battles.event_items i WHERE empire = ? AND battle = ?";
private static final String sGetProtagonists = "SELECT * FROM battles.mode_history_view WHERE battle = ?";
private static final String sGetBuildings = "SELECT * FROM battles.buildings_history WHERE empire = ? AND battle = ?";
private static final String sGetShips = "SELECT * FROM battles.fleets_history WHERE empire = ? AND battle = ?";
private static final String sGetAllBattles = "SELECT * FROM battles.battles_list WHERE empire = ? ORDER BY last_tick DESC NULLS FIRST , first_tick DESC , x , y , orbit";
private static final String sGetNewBattles = "SELECT * FROM battles.battles_list WHERE empire = ? AND ( last_update > ? OR NOT finished ) ORDER BY last_tick DESC NULLS FIRST , first_tick DESC , x , y , orbit";
private SimpleJdbcTemplate dTemplate;
private final RowMapper< EmpireBattleRecord > mGetBattleRecord;
private final RowMapper< PresenceRecord > mGetPresenceList;
private final RowMapper< EventRecord > mGetEvents;
private final RowMapper< EventItemRecord > mGetEventItems;
private final RowMapper< ProtagonistRecord > mGetProtagonists;
private final RowMapper< BuildingHistoryRecord > mGetBuildings;
private final RowMapper< ShipHistoryRecord > mGetShips;
private final RowMapper< BattleListRecord > mBattleListEntry;
public BattlesDAOBean( )
{
this.mGetBattleRecord = new RowMapper< EmpireBattleRecord >( ) {
@Override
public EmpireBattleRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
EmpireBattleRecord r = new EmpireBattleRecord( );
r.setFirstTick( rs.getLong( "first_tick" ) );
r.setLastTick( (Long) rs.getObject( "last_tick" ) );
r.setPlanetId( rs.getInt( "planet" ) );
r.setPlanetName( rs.getString( "name" ) );
r.setX( rs.getInt( "x" ) );
r.setY( rs.getInt( "y" ) );
r.setOrbit( rs.getInt( "orbit" ) );
r.setProtagonistId( rs.getLong( "protagonist" ) );
return r;
}
};
this.mGetPresenceList = new RowMapper< PresenceRecord >( ) {
@Override
public PresenceRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
PresenceRecord pView = new PresenceRecord( );
pView.setTick( rs.getLong( "tick" ) );
pView.setPresent( rs.getBoolean( "present" ) );
pView.setPlanetOwner( rs.getBoolean( "planet_owner" ) );
return pView;
}
};
this.mGetEvents = new RowMapper< EventRecord >( ) {
@Override
public EventRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
EventRecord r = new EventRecord( );
r.setEventType( rs.getString( "event_type" ) );
r.setTick( rs.getLong( "tick" ) );
r.setPlanet( rs.getBoolean( "is_planet" ) );
r.setAttack( (Boolean) rs.getObject( "attack" ) );
r.setEventId( (Long) rs.getObject( "event_id" ) );
r.setName( rs.getString( "name" ) );
return r;
}
};
this.mGetEventItems = new RowMapper< EventItemRecord >( ) {
@Override
public EventItemRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
EventItemRecord r = new EventItemRecord( );
r.setPlanetEvent( rs.getBoolean( "is_planet" ) );
r.setEventId( rs.getLong( "event_id" ) );
r.setNature( rs.getString( "nature" ) );
r.setAmount( rs.getInt( "amount" ) );
return r;
}
};
this.mGetProtagonists = new RowMapper< ProtagonistRecord >( ) {
@Override
public ProtagonistRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
ProtagonistRecord p = new ProtagonistRecord( );
p.setTick( rs.getLong( "tick" ) );
p.setProtagonistId( rs.getLong( "protagonist" ) );
p.setEmpireId( (Long) rs.getObject( "empire_id" ) );
p.setName( rs.getString( "empire_name" ) );
p.setAttacking( rs.getBoolean( "attacking" ) );
return p;
}
};
this.mGetBuildings = new RowMapper< BuildingHistoryRecord >( ) {
@Override
public BuildingHistoryRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
BuildingHistoryRecord bhr = new BuildingHistoryRecord( );
bhr.setTick( rs.getLong( "tick" ) );
bhr.setNature( rs.getString( "building" ) );
bhr.setCurrent( rs.getLong( "current" ) );
bhr.setLost( rs.getLong( "lost" ) );
bhr.setPower( (long) Math.floor( rs.getDouble( "power" ) ) );
return bhr;
}
};
this.mGetShips = new RowMapper< ShipHistoryRecord >( ) {
@Override
public ShipHistoryRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
ShipHistoryRecord shr = new ShipHistoryRecord( );
shr.setProtagonist( rs.getLong( "protagonist" ) );
shr.setTick( rs.getLong( "tick" ) );
shr.setNature( rs.getString( "ship_type" ) );
shr.setCurrent( rs.getLong( "current" ) );
shr.setLost( rs.getLong( "lost" ) );
shr.setPower( rs.getInt( "ship_power" ) );
return shr;
}
};
this.mBattleListEntry = new RowMapper< BattleListRecord >( ) {
@Override
public BattleListRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
BattleListRecord entry = new BattleListRecord( );
entry.setBattle( rs.getLong( "battle" ) );
entry.setPlanetId( rs.getInt( "planet" ) );
entry.setX( rs.getInt( "x" ) );
entry.setY( rs.getInt( "y" ) );
entry.setOrbit( rs.getInt( "orbit" ) );
entry.setName( rs.getString( "name" ) );
entry.setFirstTick( rs.getLong( "first_tick" ) );
entry.setLastTick( (Long) rs.getObject( "last_tick" ) );
entry.setLastUpdate( rs.getLong( "last_update" ) );
entry.setFinished( rs.getBoolean( "finished" ) );
return entry;
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
}
@Override
public EmpireBattleRecord getBattleRecord( int empireId , long battleId )
{
EmpireBattleRecord ebv;
try {
ebv = this.dTemplate.queryForObject( sGetBattleRecord , this.mGetBattleRecord , empireId , battleId );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
ebv.setBattleId( battleId );
ebv.setEmpireId( empireId );
return ebv;
}
@Override
public List< PresenceRecord > getPresence( EmpireBattleRecord record )
{
return this.dTemplate.query( sGetPresenceList , this.mGetPresenceList , record.getProtagonistId( ) );
}
@Override
public Map< Long , Map< Long , ProtagonistRecord > > getProtagonists( EmpireBattleRecord record )
{
List< ProtagonistRecord > all;
all = this.dTemplate.query( sGetProtagonists , this.mGetProtagonists , record.getBattleId( ) );
Map< Long , Map< Long , ProtagonistRecord >> result = new HashMap< Long , Map< Long , ProtagonistRecord > >( );
for ( ProtagonistRecord r : all ) {
Map< Long , ProtagonistRecord > atTick = result.get( r.getTick( ) );
if ( atTick == null ) {
atTick = new HashMap< Long , ProtagonistRecord >( );
result.put( r.getTick( ) , atTick );
}
atTick.put( r.getProtagonistId( ) , r );
}
return result;
}
@Override
public List< EventRecord > getEvents( EmpireBattleRecord record )
{
return this.dTemplate.query( sGetEvents , this.mGetEvents , record.getBattleId( ) , record.getProtagonistId( ) );
}
@Override
public Map< Boolean , Map< Long , List< EventItemRecord >>> getEventItems( EmpireBattleRecord record )
{
List< EventItemRecord > raw;
raw = this.dTemplate
.query( sGetEventItems , this.mGetEventItems , record.getEmpireId( ) , record.getBattleId( ) );
Map< Boolean , Map< Long , List< EventItemRecord >>> result = new HashMap< Boolean , Map< Long , List< EventItemRecord >> >( );
result.put( true , new HashMap< Long , List< EventItemRecord >>( ) );
result.put( false , new HashMap< Long , List< EventItemRecord >>( ) );
for ( EventItemRecord eir : raw ) {
List< EventItemRecord > event = result.get( eir.isPlanetEvent( ) ).get( eir.getEventId( ) );
if ( event == null ) {
event = new LinkedList< EventItemRecord >( );
result.get( eir.isPlanetEvent( ) ).put( eir.getEventId( ) , event );
}
event.add( eir );
}
return result;
}
@Override
public Map< Long , List< BuildingHistoryRecord >> getBuildingsHistory( EmpireBattleRecord record )
{
List< BuildingHistoryRecord > records;
records = this.dTemplate.query( sGetBuildings , this.mGetBuildings , record.getEmpireId( ) , record
.getBattleId( ) );
Map< Long , List< BuildingHistoryRecord > > result = new HashMap< Long , List< BuildingHistoryRecord > >( );
for ( BuildingHistoryRecord bhr : records ) {
List< BuildingHistoryRecord > atTick = result.get( bhr.getTick( ) );
if ( atTick == null ) {
atTick = new LinkedList< BuildingHistoryRecord >( );
result.put( bhr.getTick( ) , atTick );
}
atTick.add( bhr );
}
return result;
}
@Override
public Map< Long , Map< Long , List< ShipHistoryRecord >>> getShipsHistory( EmpireBattleRecord record )
{
List< ShipHistoryRecord > records;
records = this.dTemplate.query( sGetShips , this.mGetShips , record.getEmpireId( ) , record.getBattleId( ) );
Map< Long , Map< Long , List< ShipHistoryRecord > >> result = new HashMap< Long , Map< Long , List< ShipHistoryRecord > > >( );
for ( ShipHistoryRecord shr : records ) {
Map< Long , List< ShipHistoryRecord > > atTick = result.get( shr.getTick( ) );
if ( atTick == null ) {
atTick = new HashMap< Long , List< ShipHistoryRecord > >( );
result.put( shr.getTick( ) , atTick );
}
List< ShipHistoryRecord > pShips = atTick.get( shr.getProtagonist( ) );
if ( pShips == null ) {
pShips = new LinkedList< ShipHistoryRecord >( );
atTick.put( shr.getProtagonist( ) , pShips );
}
pShips.add( shr );
}
return result;
}
@Override
public List< BattleListRecord > getBattles( int empireId )
{
return this.dTemplate.query( sGetAllBattles , this.mBattleListEntry , empireId );
}
public List< BattleListRecord > getBattles( int empireId , long after )
{
return this.dTemplate.query( sGetNewBattles , this.mBattleListEntry , empireId , after );
}
}

View file

@ -0,0 +1,236 @@
package com.deepclone.lw.beans.fleets;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.deepclone.lw.cmd.player.fleets.DisbandFleetsResponse;
import com.deepclone.lw.cmd.player.fleets.MergeFleetsResponse;
import com.deepclone.lw.cmd.player.fleets.MoveFleetsResponse;
import com.deepclone.lw.cmd.player.fleets.MultiFleetsResponse;
import com.deepclone.lw.cmd.player.fleets.RenameFleetsResponse;
import com.deepclone.lw.cmd.player.fleets.SetFleetsModeResponse;
import com.deepclone.lw.cmd.player.fleets.SplitFleetResponse;
import com.deepclone.lw.cmd.player.fleets.ViewFleetsResponse;
import com.deepclone.lw.cmd.player.gdata.GamePageData;
import com.deepclone.lw.cmd.player.gdata.fleets.FleetStatus;
import com.deepclone.lw.cmd.player.gdata.fleets.FleetsView;
import com.deepclone.lw.cmd.player.gdata.fleets.ShortFleetView;
import com.deepclone.lw.cmd.player.gdata.fleets.SplitShips;
import com.deepclone.lw.interfaces.game.EmpireManagement;
import com.deepclone.lw.interfaces.game.FleetManagement;
import com.deepclone.lw.interfaces.game.FleetsDAO;
@Transactional
public class FleetManagementBean
implements FleetManagement
{
private EmpireManagement empireManagement;
private FleetsDAO fleetsDao;
@Autowired( required = true )
public void setEmpireManagement( EmpireManagement empireManagement )
{
this.empireManagement = empireManagement;
}
@Autowired( required = true )
public void setFleetsDao( FleetsDAO fleetsDao )
{
this.fleetsDao = fleetsDao;
}
@Override
public ViewFleetsResponse getFleets( int empireId )
{
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
FleetsView fleets = this.fleetsDao.getFleets( empireId );
return new ViewFleetsResponse( page , fleets );
}
@Override
public MultiFleetsResponse setMode( int empireId , long[] fleets , boolean attack , boolean doIt )
{
SetFleetsModeResponse response;
response = new SetFleetsModeResponse( this.empireManagement.getGeneralInformation( empireId ) );
List< ShortFleetView > sFleets = new LinkedList< ShortFleetView >( );
for ( ShortFleetView sfv : this.fleetsDao.getShortFleets( empireId , fleets , false ) ) {
if ( sfv.isAttack( ) != attack ) {
sFleets.add( sfv );
}
}
if ( sFleets.isEmpty( ) ) {
return response;
}
if ( doIt ) {
this.fleetsDao.setMode( empireId , fleets , attack );
return response;
}
for ( ShortFleetView sfv : sFleets ) {
response.addFleet( sfv );
}
response.setAttack( attack );
return response;
}
@Override
public MultiFleetsResponse move( int empireId , long[] fleets , String destination , boolean attack )
{
MoveFleetsResponse response = new MoveFleetsResponse( this.empireManagement.getGeneralInformation( empireId ) );
List< ShortFleetView > sFleets = this.fleetsDao.getShortFleets( empireId , fleets , true );
if ( sFleets.isEmpty( ) ) {
return response;
}
boolean moved;
if ( destination != null && !sFleets.isEmpty( ) ) {
moved = this.fleetsDao.move( empireId , fleets , destination );
if ( !moved ) {
response.setError( true );
response.setDestination( destination );
response.setMode( attack );
} else {
this.fleetsDao.setMode( empireId , fleets , attack );
}
} else {
moved = false;
}
if ( !moved ) {
for ( ShortFleetView sfv : sFleets ) {
response.addFleet( sfv );
}
}
return response;
}
@Override
public MultiFleetsResponse rename( int empireId , long[] fleets , String name )
{
RenameFleetsResponse response;
response = new RenameFleetsResponse( this.empireManagement.getGeneralInformation( empireId ) );
List< ShortFleetView > sFleets = this.fleetsDao.getShortFleets( empireId , fleets , false );
if ( sFleets.isEmpty( ) ) {
return response;
}
if ( name != null ) {
this.fleetsDao.rename( empireId , fleets , name );
} else {
for ( ShortFleetView sfv : sFleets ) {
response.addFleet( sfv );
}
}
return response;
}
@Override
public MultiFleetsResponse merge( int empireId , long[] fleets )
{
MergeFleetsResponse response = new MergeFleetsResponse( this.empireManagement.getGeneralInformation( empireId ) );
List< ShortFleetView > sFleets = this.fleetsDao.getShortFleets( empireId , fleets , true );
if ( !sFleets.isEmpty( ) ) {
this.fleetsDao.merge( empireId , fleets );
}
return response;
}
@Override
public SplitFleetResponse split( int empireId , long fleetId , Map< Integer , Integer > ships , int nFleets ,
String name , boolean simulate )
{
SplitFleetResponse response = new SplitFleetResponse( this.empireManagement.getGeneralInformation( empireId ) );
if ( fleetId == -1 ) {
return response;
}
// Try finding the fleet
ShortFleetView fleet = this.fleetsDao.getShortFleet( empireId , fleetId );
if ( fleet == null || fleet.getStatus( ) != FleetStatus.AVAILABLE ) {
return response;
}
// If the name is not set, this is the initial request
if ( name == null ) {
for ( SplitShips sShips : this.fleetsDao.getShips( empireId , fleetId ) ) {
sShips.setSelectedAmount( 0 );
response.addShips( sShips );
}
response.setInitialFleet( fleet );
return response;
}
// Try splitting / simulating the split
boolean splitOk;
splitOk = this.fleetsDao.initSplit( fleetId , nFleets , name );
if ( splitOk ) {
for ( Map.Entry< Integer , Integer > entry : ships.entrySet( ) ) {
this.fleetsDao.setSplitShips( entry.getKey( ) , entry.getValue( ) );
}
splitOk = this.fleetsDao.executeSplit( simulate );
}
// If there was an error, or if we were simulating
if ( !splitOk || simulate ) {
for ( SplitShips sShips : this.fleetsDao.getShips( empireId , fleetId ) ) {
Integer amount = ships.get( sShips.getType( ) );
if ( amount == null ) {
amount = 0;
}
sShips.setSelectedAmount( amount );
response.addShips( sShips );
}
response.setInitialFleet( fleet );
response.setShipsError( !splitOk );
response.setnFleets( nFleets );
response.setName( name );
}
return response;
}
@Override
public MultiFleetsResponse disband( int empireId , long[] fleets , boolean doIt )
{
DisbandFleetsResponse response;
response = new DisbandFleetsResponse( this.empireManagement.getGeneralInformation( empireId ) );
List< ShortFleetView > sFleets = this.fleetsDao.getShortFleets( empireId , fleets , false );
if ( sFleets.isEmpty( ) ) {
return response;
}
if ( doIt ) {
this.fleetsDao.disband( empireId , fleets );
} else {
for ( ShortFleetView sfv : sFleets ) {
response.addFleet( sfv );
}
}
return response;
}
}

View file

@ -0,0 +1,446 @@
package com.deepclone.lw.beans.fleets;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import com.deepclone.lw.cmd.player.gdata.NameIdPair;
import com.deepclone.lw.cmd.player.gdata.PlanetRelationType;
import com.deepclone.lw.cmd.player.gdata.ShortBattleView;
import com.deepclone.lw.cmd.player.gdata.fleets.*;
import com.deepclone.lw.interfaces.game.FleetsDAO;
import com.deepclone.lw.sqld.game.RawFleetOwner;
import com.deepclone.lw.sqld.game.RawFleetShip;
import com.deepclone.lw.sqld.game.RawStaticFleet;
import com.deepclone.lw.utils.StoredProc;
public class FleetsDAOBean
implements FleetsDAO
{
private static String sqlLocations = "SELECT * FROM fleets.locations_view WHERE empire = ?";
private static String sqlOwners = "SELECT * FROM fleets.owners_view WHERE empire = ? ORDER BY relation";
private static String sqlStaticFleets = "SELECT * FROM fleets.static_fleets WHERE empire = ? ORDER BY power DESC, name NULLS LAST, id DESC";
private static String sqlMovingFleets = "SELECT * FROM fleets.moving_fleets WHERE empire = ? ORDER BY time_left + penalty, name NULLS LAST, id DESC";
private static String sqlShips = "SELECT * FROM fleets.ships_view WHERE empire = ?";
private static String sqlShortStatic = "SELECT * FROM fleets.short_static_fleets WHERE empire = ? AND id IN ( SELECT unnest AS id FROM unnest( ?::BIGINT[] ) )";
private static String sqlShortMoving = "SELECT * FROM fleets.moving_fleets WHERE empire = ? AND id IN ( SELECT unnest AS id FROM unnest( ?::BIGINT[] ) )";
private static String sqlSingleShort = "SELECT * FROM fleets.short_static_fleets WHERE empire = ? AND id = ?";
private static String sqlSingleMoving = "SELECT * FROM fleets.moving_fleets WHERE empire = ? AND id = ?";
private static String sqlFleetShips = "SELECT * FROM fleets.ships_view WHERE empire = ? AND id = ?";
private SimpleJdbcTemplate dTemplate;
private RowMapper< FleetLocation > mLocations;
private RowMapper< RawFleetOwner > mOwners;
private RowMapper< RawStaticFleet > mStaticFleets;
private RowMapper< MovingFleet > mMovingFleets;
private RowMapper< RawFleetShip > mShips;
private RowMapper< ShortFleetView > mShortStatic;
private RowMapper< ShortFleetView > mShortMoving;
private StoredProc fMoveFleets;
private StoredProc fSetMode;
private StoredProc fRenameFleets;
private StoredProc fMergeFleets;
private StoredProc fDisbandFleets;
private StoredProc fInitSplit;
private StoredProc fSetSplitShips;
private StoredProc fExecuteSplit;
public FleetsDAOBean( )
{
this.mLocations = new RowMapper< FleetLocation >( ) {
@Override
public FleetLocation mapRow( ResultSet rs , int rowNum )
throws SQLException
{
FleetLocation location = new FleetLocation( rs.getInt( "location" ) , rs.getString( "name" ) );
location.setOwn( rs.getBoolean( "is_own" ) );
location.setAttacking( rs.getBoolean( "attacking" ) );
location.setX( rs.getInt( "x" ) );
location.setY( rs.getInt( "y" ) );
location.setOrbit( rs.getInt( "orbit" ) );
location.setTag( rs.getString( "tag" ) );
location.setPicture( rs.getInt( "picture" ) );
location.setPopulation( rs.getLong( "population" ) );
location.setDefence( rs.getLong( "defence" ) );
if ( rs.getObject( "battle" ) == null ) {
location.setBattle( null );
location.setOnVacation( rs.getBoolean( "on_vacation" ) );
} else {
ShortBattleView battle = new ShortBattleView( );
battle.setId( rs.getLong( "battle" ) );
battle.setFriendly( rs.getLong( "friendly_power" ) );
battle.setHostile( rs.getLong( "hostile_power" ) );
location.setBattle( battle );
location.setOnVacation( false );
}
return location;
}
};
this.mOwners = new RowMapper< RawFleetOwner >( ) {
@Override
public RawFleetOwner mapRow( ResultSet rs , int rowNum )
throws SQLException
{
RawFleetOwner info = new RawFleetOwner( );
info.setLocation( rs.getInt( "location" ) );
info.setId( rs.getInt( "id" ) );
info.setName( rs.getString( "name" ) );
info.setRelation( rs.getString( "relation" ) );
return info;
}
};
this.mStaticFleets = new RowMapper< RawStaticFleet >( ) {
@Override
public RawStaticFleet mapRow( ResultSet rs , int rowNum )
throws SQLException
{
RawStaticFleet info = new RawStaticFleet( );
info.setLocation( rs.getInt( "location" ) );
info.setOwner( rs.getInt( "owner" ) );
info.setId( rs.getLong( "id" ) );
info.setName( rs.getString( "name" ) );
info.setStatus( rs.getString( "status" ) );
info.setPenalty( rs.getInt( "penalty" ) );
info.setPower( rs.getLong( "power" ) );
info.setFlightTime( rs.getInt( "flight_time" ) );
return info;
}
};
this.mMovingFleets = new RowMapper< MovingFleet >( ) {
@Override
public MovingFleet mapRow( ResultSet rs , int rowNum )
throws SQLException
{
MovingFleet fleet = new MovingFleet( rs.getLong( "id" ) , rs.getString( "name" ) );
fleet.setAttacking( rs.getBoolean( "attacking" ) );
fleet.setStatus( FleetStatus.valueOf( rs.getString( "status" ) ) );
fleet.setPenalty( rs.getInt( "penalty" ) );
fleet.setFlightTime( rs.getInt( "flight_time" ) );
fleet.setPower( rs.getLong( "power" ) );
fleet.setTimeLeft( rs.getInt( "time_left" ) );
fleet.setSource( new NameIdPair( rs.getInt( "from_id" ) , rs.getString( "from_name" ) ) );
fleet.setDestination( new NameIdPair( rs.getInt( "to_id" ) , rs.getString( "to_name" ) ) );
fleet.setCurrentX( rs.getDouble( "cx" ) );
fleet.setCurrentY( rs.getDouble( "cy" ) );
if ( rs.getString( "nearest_name" ) != null ) {
fleet.setNearest( new NameIdPair( rs.getInt( "nearest_id" ) , rs.getString( "nearest_name" ) ) );
}
return fleet;
}
};
this.mShips = new RowMapper< RawFleetShip >( ) {
@Override
public RawFleetShip mapRow( ResultSet rs , int rowNum )
throws SQLException
{
RawFleetShip ship = new RawFleetShip( );
ship.setFleet( rs.getLong( "id" ) );
ship.setShipType( rs.getInt( "ship_id" ) );
ship.setAmount( rs.getInt( "amount" ) );
ship.setPower( rs.getInt( "power" ) );
ship.setName( rs.getString( "name" ) );
return ship;
}
};
this.mShortStatic = new RowMapper< ShortFleetView >( ) {
@Override
public ShortFleetView mapRow( ResultSet rs , int rowNum )
throws SQLException
{
ShortFleetView sfv = new ShortFleetView( rs.getLong( "id" ) , rs.getString( "name" ) );
sfv.setFlightTime( rs.getInt( "flight_time" ) );
sfv.setStatus( FleetStatus.valueOf( rs.getString( "status" ) ) );
sfv.setPenalty( rs.getInt( "penalty" ) );
sfv.setPower( rs.getLong( "power" ) );
sfv.setAttack( rs.getBoolean( "attacking" ) );
sfv.setAtPlanet( true );
sfv.setX( rs.getDouble( "x" ) );
sfv.setY( rs.getDouble( "y" ) );
sfv.setNearest( new NameIdPair( rs.getInt( "location_id" ) , rs.getString( "location_name" ) ) );
return sfv;
}
};
this.mShortMoving = new RowMapper< ShortFleetView >( ) {
@Override
public ShortFleetView mapRow( ResultSet rs , int rowNum )
throws SQLException
{
ShortFleetView sfv = new ShortFleetView( rs.getLong( "id" ) , rs.getString( "name" ) );
sfv.setFlightTime( rs.getInt( "flight_time" ) );
sfv.setStatus( FleetStatus.valueOf( rs.getString( "status" ) ) );
sfv.setPenalty( rs.getInt( "penalty" ) );
sfv.setPower( rs.getLong( "power" ) );
sfv.setAttack( rs.getBoolean( "attacking" ) );
sfv.setAtPlanet( false );
sfv.setX( rs.getDouble( "cx" ) );
sfv.setY( rs.getDouble( "cy" ) );
if ( rs.getString( "nearest_name" ) != null ) {
sfv.setNearest( new NameIdPair( rs.getInt( "nearest_id" ) , rs.getString( "nearest_name" ) ) );
}
return sfv;
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.fMoveFleets = new StoredProc( dataSource , "fleets" , "move_fleets" );
this.fMoveFleets.addParameter( "empire_id" , Types.INTEGER );
this.fMoveFleets.addParameter( "fleet_ids" , "BIGINT[]" );
this.fMoveFleets.addParameter( "destination" , Types.VARCHAR );
this.fMoveFleets.addOutput( "success" , Types.BOOLEAN );
this.fSetMode = new StoredProc( dataSource , "fleets" , "set_mode" );
this.fSetMode.addParameter( "empire_id" , Types.INTEGER );
this.fSetMode.addParameter( "fleet_ids" , "BIGINT[]" );
this.fSetMode.addParameter( "attack" , Types.BOOLEAN );
this.fRenameFleets = new StoredProc( dataSource , "fleets" , "rename_fleets" );
this.fRenameFleets.addParameter( "empire_id" , Types.INTEGER );
this.fRenameFleets.addParameter( "fleet_ids" , "BIGINT[]" );
this.fRenameFleets.addParameter( "new_name" , Types.VARCHAR );
this.fMergeFleets = new StoredProc( dataSource , "fleets" , "merge" );
this.fMergeFleets.addParameter( "empire_id" , Types.INTEGER );
this.fMergeFleets.addParameter( "fleet_ids" , "BIGINT[]" );
this.fDisbandFleets = new StoredProc( dataSource , "fleets" , "disband" );
this.fDisbandFleets.addParameter( "empire_id" , Types.INTEGER );
this.fDisbandFleets.addParameter( "fleet_ids" , "BIGINT[]" );
this.fInitSplit = new StoredProc( dataSource , "fleets" , "init_split" );
this.fInitSplit.addParameter( "fleet_id" , Types.BIGINT );
this.fInitSplit.addParameter( "n_fleets" , Types.INTEGER );
this.fInitSplit.addParameter( "name" , Types.VARCHAR );
this.fInitSplit.addOutput( "success" , Types.BOOLEAN );
this.fSetSplitShips = new StoredProc( dataSource , "fleets" , "set_split_ships" );
this.fSetSplitShips.addParameter( "ships_type" , Types.INTEGER );
this.fSetSplitShips.addParameter( "split_amount" , Types.INTEGER );
this.fExecuteSplit = new StoredProc( dataSource , "fleets" , "execute_split" );
this.fExecuteSplit.addParameter( "simulate" , Types.BOOLEAN );
this.fExecuteSplit.addOutput( "success" , Types.BOOLEAN );
}
private String getSQLArray( long[] fleets )
{
StringBuilder fArray = new StringBuilder( ).append( "{" );
for ( int i = 0 ; i < fleets.length ; i++ ) {
fArray.append( fleets[ i ] );
if ( i != fleets.length - 1 ) {
fArray.append( "," );
}
}
fArray.append( "}" );
return fArray.toString( );
}
@Override
public FleetsView getFleets( int empireId )
{
FleetsView result = new FleetsView( );
// Get visible locations
Map< Integer , FleetLocation > locations = new HashMap< Integer , FleetLocation >( );
Map< Integer , Map< Integer , FleetOwner >> owners = new HashMap< Integer , Map< Integer , FleetOwner > >( );
for ( FleetLocation l : this.dTemplate.query( FleetsDAOBean.sqlLocations , this.mLocations , empireId ) ) {
locations.put( (int) l.getId( ) , l );
owners.put( (int) l.getId( ) , new HashMap< Integer , FleetOwner >( ) );
result.addLocation( l );
}
// Get visible fleet owners
for ( RawFleetOwner rfo : this.dTemplate.query( FleetsDAOBean.sqlOwners , this.mOwners , empireId ) ) {
FleetOwner owner;
int ownerId = rfo.getId( );
owner = new FleetOwner( ownerId , rfo.getName( ) , PlanetRelationType.valueOf( rfo.getRelation( ) ) );
int locationId = rfo.getLocation( );
FleetLocation location = locations.get( locationId );
Map< Integer , FleetOwner > lOwners = owners.get( locationId );
location.addFleetOwner( owner );
lOwners.put( ownerId , owner );
}
// Get static fleets
Map< Long , StaticFleet > fleets = new HashMap< Long , StaticFleet >( );
for ( RawStaticFleet rsf : this.dTemplate.query( FleetsDAOBean.sqlStaticFleets , this.mStaticFleets , empireId ) ) {
int ownerId = rsf.getOwner( );
int locationId = rsf.getLocation( );
long fleetId = rsf.getId( );
StaticFleet fleet = new StaticFleet( fleetId , rsf.getName( ) );
fleet.setFlightTime( rsf.getFlightTime( ) );
fleet.setStatus( FleetStatus.valueOf( rsf.getStatus( ) ) );
fleet.setPenalty( rsf.getPenalty( ) );
fleet.setPower( rsf.getPower( ) );
fleets.put( fleetId , fleet );
owners.get( locationId ).get( ownerId ).addFleet( fleet );
}
// Get moving fleets
for ( MovingFleet f : this.dTemplate.query( FleetsDAOBean.sqlMovingFleets , this.mMovingFleets , empireId ) ) {
result.addMovingFleet( f );
fleets.put( f.getId( ) , f );
}
// Fetch fleet ships
for ( RawFleetShip rfs : this.dTemplate.query( FleetsDAOBean.sqlShips , this.mShips , empireId ) ) {
FleetShips ships = new FleetShips( );
ships.setAmount( rfs.getAmount( ) );
ships.setPower( rfs.getPower( ) );
ships.setName( rfs.getName( ) );
fleets.get( rfs.getFleet( ) ).addShips( ships );
}
return result;
}
@Override
public List< ShortFleetView > getShortFleets( int empireId , long[] fleets , boolean needsAvailable )
{
String fArray = this.getSQLArray( fleets );
List< ShortFleetView > result = new LinkedList< ShortFleetView >( );
for ( ShortFleetView sfv : this.dTemplate.query( FleetsDAOBean.sqlShortStatic , this.mShortStatic , empireId ,
fArray ) ) {
if ( needsAvailable && sfv.getStatus( ) != FleetStatus.AVAILABLE ) {
continue;
}
result.add( sfv );
}
for ( ShortFleetView sfv : this.dTemplate.query( FleetsDAOBean.sqlShortMoving , this.mShortMoving , empireId ,
fArray ) ) {
if ( needsAvailable && sfv.getStatus( ) != FleetStatus.AVAILABLE ) {
continue;
}
result.add( sfv );
}
return result;
}
@Override
public boolean move( int empireId , long[] fleets , String destination )
{
return (Boolean) this.fMoveFleets.execute( empireId , this.getSQLArray( fleets ) , destination )
.get( "success" );
}
@Override
public void setMode( int empireId , long[] fleets , boolean attack )
{
this.fSetMode.execute( empireId , this.getSQLArray( fleets ) , attack );
}
@Override
public void rename( int empireId , long[] fleets , String name )
{
this.fRenameFleets.execute( empireId , this.getSQLArray( fleets ) , name );
}
@Override
public void merge( int empireId , long[] fleets )
{
this.fMergeFleets.execute( empireId , this.getSQLArray( fleets ) );
}
@Override
public void disband( int empireId , long[] fleets )
{
this.fDisbandFleets.execute( empireId , this.getSQLArray( fleets ) );
}
@Override
public ShortFleetView getShortFleet( int empireId , long fleetId )
{
try {
return this.dTemplate.queryForObject( sqlSingleShort , mShortStatic , empireId , fleetId );
} catch ( EmptyResultDataAccessException e ) {
// EMPTY
}
try {
return this.dTemplate.queryForObject( sqlSingleMoving , mShortMoving , empireId , fleetId );
} catch ( EmptyResultDataAccessException e ) {
return null;
}
}
@Override
public List< SplitShips > getShips( int empireId , long fleetId )
{
List< SplitShips > result = new LinkedList< SplitShips >( );
for ( RawFleetShip rfs : this.dTemplate.query( sqlFleetShips , mShips , empireId , fleetId ) ) {
SplitShips ships = new SplitShips( );
ships.setId( rfs.getShipType( ) );
ships.setType( rfs.getShipType( ) );
ships.setAmount( rfs.getAmount( ) );
ships.setPower( rfs.getPower( ) );
ships.setName( rfs.getName( ) );
result.add( ships );
}
return result;
}
@Override
public boolean initSplit( long fleetId , int nFleets , String name )
{
return (Boolean) this.fInitSplit.execute( fleetId , nFleets , name ).get( "success" );
}
@Override
public void setSplitShips( int shipType , int amount )
{
this.fSetSplitShips.execute( shipType , amount );
}
@Override
public boolean executeSplit( boolean simulate )
{
return (Boolean) this.fExecuteSplit.execute( simulate ).get( "success" );
}
}

View file

@ -0,0 +1,96 @@
package com.deepclone.lw.beans.map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.deepclone.lw.cmd.player.gdata.MapSize;
import com.deepclone.lw.cmd.player.gdata.PlanetRelationType;
import com.deepclone.lw.cmd.player.gdata.map.MapPlanetData;
import com.deepclone.lw.cmd.player.gdata.map.MapSystemData;
import com.deepclone.lw.interfaces.acm.UsersDAO;
import com.deepclone.lw.interfaces.game.MapViewParameters;
import com.deepclone.lw.interfaces.game.MapViewer;
import com.deepclone.lw.interfaces.game.UniverseDAO;
import com.deepclone.lw.interfaces.prefs.AccountPreferences;
import com.deepclone.lw.interfaces.prefs.PreferencesDAO;
import com.deepclone.lw.sqld.accounts.Account;
import com.deepclone.lw.sqld.game.MapData;
import com.deepclone.lw.utils.EmailAddress;
@Transactional
public class MapViewerBean
implements MapViewer
{
private UsersDAO usersDao;
private PreferencesDAO preferencesDao;
private UniverseDAO universeDao;
@Autowired( required = true )
public void setUsersDao( UsersDAO usersDao )
{
this.usersDao = usersDao;
}
@Autowired( required = true )
public void setPreferencesDao( PreferencesDAO preferencesDao )
{
this.preferencesDao = preferencesDao;
}
@Autowired( required = true )
public void setUniverseDao( UniverseDAO universeDao )
{
this.universeDao = universeDao;
}
@Override
public MapViewParameters getDefaults( EmailAddress address )
{
Account accnt = this.usersDao.getAccount( address );
AccountPreferences prefs = this.preferencesDao.getPreferences( accnt );
int x = (Integer) prefs.getPreference( "mapX" , Integer.class );
int y = (Integer) prefs.getPreference( "mapY" , Integer.class );
MapSize size = (MapSize) prefs.getPreference( "mapSize" , MapSize.class );
return new MapViewParameters( x , y , size );
}
@Override
public MapSystemData[][] getMapView( int empireId , MapViewParameters parameters )
{
int size = 3 + ( 2 * parameters.size.ordinal( ) );
int minX = parameters.x - ( size >> 1 );
int maxX = parameters.x + ( size >> 1 );
int minY = parameters.y - ( size >> 1 );
int maxY = parameters.y + ( size >> 1 );
MapSystemData[][] results = new MapSystemData[ size ][ size ];
for ( MapData entry : this.universeDao.getMap( empireId , minX , minY , maxX , maxY ) ) {
int x = entry.getX( ) - minX;
int y = maxY - entry.getY( );
if ( entry.getOrbit( ) == 1 ) {
results[ y ][ x ] = new MapSystemData( );
}
PlanetRelationType relation;
String rValue = entry.getDisplay( );
relation = ( rValue == null ) ? null : PlanetRelationType.valueOf( rValue );
MapPlanetData planet;
planet = new MapPlanetData( entry.getId( ) , entry.getPicture( ) , entry.getName( ) , entry.getTag( ) ,
relation );
results[ y ][ x ].setPlanet( entry.getOrbit( ) , planet );
}
return results;
}
}

View file

@ -0,0 +1,341 @@
package com.deepclone.lw.beans.map;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.List;
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.cmd.player.gdata.planets.BuildableBuildingData;
import com.deepclone.lw.cmd.player.gdata.planets.BuildableShipData;
import com.deepclone.lw.cmd.player.gdata.planets.BuildingData;
import com.deepclone.lw.cmd.player.gdata.planets.QueueData;
import com.deepclone.lw.cmd.player.gdata.planets.QueueItemData;
import com.deepclone.lw.interfaces.game.PlanetDAO;
import com.deepclone.lw.sqld.game.PlanetData.AccessType;
import com.deepclone.lw.sqld.game.PlanetData.Basic;
import com.deepclone.lw.sqld.game.PlanetData.Orbital;
import com.deepclone.lw.sqld.game.PlanetData.Owner;
import com.deepclone.lw.utils.StoredProc;
public class PlanetDAOBean
implements PlanetDAO
{
private SimpleJdbcTemplate dTemplate;
private RowMapper< Basic > mPlanetBasics;
private RowMapper< Orbital > mPlanetOrbital;
private RowMapper< Owner > mPlanetOwner;
private RowMapper< BuildingData > mOwnerBuildings;
private RowMapper< BuildingData > mOrbitalBuildings;
private RowMapper< QueueItemData > mQueueItem;
private RowMapper< BuildableBuildingData > mAvailableBuilding;
private RowMapper< BuildableShipData > mAvailableShip;
private StoredProc fFlushBuildQueue;
private StoredProc fFlushMilitaryQueue;
private StoredProc fAddToMilitaryQueue;
private StoredProc fConstructBuildings;
private StoredProc fDestroyBuildings;
private StoredProc fAbandon;
private StoredProc fCancelAbandon;
public PlanetDAOBean( )
{
this.mPlanetBasics = new RowMapper< Basic >( ) {
@Override
public Basic mapRow( ResultSet rs , int rowNum )
throws SQLException
{
if ( rs.getString( "access" ) == null ) {
return null;
}
Basic info = new Basic( );
info.setAccess( AccessType.valueOf( rs.getString( "access" ) ) );
info.setX( rs.getInt( "x" ) );
info.setY( rs.getInt( "y" ) );
info.setOrbit( rs.getInt( "orbit" ) );
info.setPicture( rs.getInt( "picture" ) );
info.setName( rs.getString( "name" ) );
info.setTag( rs.getString( "tag" ) );
return info;
}
};
this.mPlanetOrbital = new RowMapper< Orbital >( ) {
@Override
public Orbital mapRow( ResultSet rs , int rowNum )
throws SQLException
{
Orbital info = new Orbital( );
info.setPopulation( rs.getLong( "population" ) );
info.setDefence( rs.getLong( "defence" ) );
info.setOwnPower( rs.getLong( "own_power" ) );
info.setFriendlyPower( rs.getLong( "friendly_power" ) );
info.setHostilePower( rs.getLong( "hostile_power" ) );
info.setBattle( (Long) rs.getObject( "battle_id" ) );
return info;
}
};
this.mPlanetOwner = new RowMapper< Owner >( ) {
@Override
public Owner mapRow( ResultSet rs , int rowNum )
throws SQLException
{
Owner info = new Owner( );
info.setHappiness( rs.getInt( "happiness" ) );
info.sethChange( rs.getInt( "h_change" ) );
info.setIncome( rs.getLong( "income" ) );
info.setUpkeep( rs.getLong( "upkeep" ) );
info.setRenamePossible( rs.getBoolean( "can_rename" ) );
info.setAbandonPossible( rs.getBoolean( "can_abandon" ) );
info.setAbandonTime( rs.getInt( "abandon_time" ) );
return info;
}
};
this.mOrbitalBuildings = new RowMapper< BuildingData >( ) {
@Override
public BuildingData mapRow( ResultSet rs , int rowNum )
throws SQLException
{
BuildingData info = new BuildingData( );
info.setAmount( rs.getInt( "amount" ) );
info.setName( rs.getString( "name" ) );
info.setDescription( rs.getString( "description" ) );
return info;
}
};
this.mOwnerBuildings = new RowMapper< BuildingData >( ) {
@Override
public BuildingData mapRow( ResultSet rs , int rowNum )
throws SQLException
{
BuildingData info = new BuildingData( );
info.setId( rs.getInt( "id" ) );
info.setAmount( rs.getInt( "amount" ) );
info.setName( rs.getString( "name" ) );
info.setDescription( rs.getString( "description" ) );
info.setJobs( rs.getInt( "jobs" ) );
info.setUpkeep( rs.getLong( "upkeep" ) );
info.setProduces( rs.getString( "p_type" ) );
info.setOutput( rs.getLong( "p_value" ) );
return info;
}
};
this.mQueueItem = new RowMapper< QueueItemData >( ) {
@Override
public QueueItemData mapRow( ResultSet rs , int rowNum )
throws SQLException
{
QueueItemData item = new QueueItemData( );
item.setName( rs.getString( "name" ) );
item.setDescription( rs.getString( "description" ) );
item.setAmount( rs.getInt( "amount" ) );
item.setDestroy( rs.getBoolean( "destroy" ) );
item.setInvested( rs.getLong( "investment" ) );
item.setTimeLeft( (Long) rs.getObject( "time_left" ) );
return item;
}
};
this.mAvailableBuilding = new RowMapper< BuildableBuildingData >( ) {
@Override
public BuildableBuildingData mapRow( ResultSet rs , int rowNum )
throws SQLException
{
BuildableBuildingData info = new BuildableBuildingData( );
info.setId( rs.getInt( "id" ) );
info.setName( rs.getString( "name" ) );
info.setDescription( rs.getString( "description" ) );
info.setCost( rs.getInt( "cost" ) );
info.setTime( (Long) rs.getObject( "time_to_build" ) );
info.setUpkeep( rs.getInt( "upkeep" ) );
info.setWorkers( rs.getInt( "workers" ) );
info.setProdType( rs.getString( "p_type" ) );
info.setOutput( rs.getInt( "p_value" ) );
return info;
}
};
this.mAvailableShip = new RowMapper< BuildableShipData >( ) {
@Override
public BuildableShipData mapRow( ResultSet rs , int rowNum )
throws SQLException
{
BuildableShipData info = new BuildableShipData( );
info.setId( rs.getInt( "id" ) );
info.setName( rs.getString( "name" ) );
info.setDescription( rs.getString( "description" ) );
info.setCost( rs.getInt( "cost" ) );
info.setTime( (Long) rs.getObject( "time_to_build" ) );
info.setUpkeep( rs.getInt( "upkeep" ) );
info.setFlightTime( rs.getInt( "flight_time" ) );
info.setPower( rs.getInt( "power" ) );
return info;
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.fFlushBuildQueue = new StoredProc( dataSource , "verse" , "flush_build_queue" );
this.fFlushBuildQueue.addParameter( "planet_id" , Types.INTEGER );
this.fFlushMilitaryQueue = new StoredProc( dataSource , "verse" , "flush_military_queue" );
this.fFlushMilitaryQueue.addParameter( "planet_id" , Types.INTEGER );
this.fAddToMilitaryQueue = new StoredProc( dataSource , "verse" , "add_military_item" );
this.fAddToMilitaryQueue.addParameter( "planet_id" , Types.INTEGER );
this.fAddToMilitaryQueue.addParameter( "ship_id" , Types.INTEGER );
this.fAddToMilitaryQueue.addParameter( "amount" , Types.INTEGER );
this.fConstructBuildings = new StoredProc( dataSource , "verse" , "construct_buildings" );
this.fConstructBuildings.addParameter( "planet_id" , Types.INTEGER );
this.fConstructBuildings.addParameter( "building_id" , Types.INTEGER );
this.fConstructBuildings.addParameter( "amount" , Types.INTEGER );
this.fDestroyBuildings = new StoredProc( dataSource , "verse" , "destroy_buildings" );
this.fDestroyBuildings.addParameter( "planet_id" , Types.INTEGER );
this.fDestroyBuildings.addParameter( "building_id" , Types.INTEGER );
this.fDestroyBuildings.addParameter( "amount" , Types.INTEGER );
this.fDestroyBuildings.addOutput( "success" , Types.BOOLEAN );
this.fAbandon = new StoredProc( dataSource , "verse" , "abandon" );
this.fAbandon.addParameter( "planet_id" , Types.INTEGER );
this.fAbandon.addOutput( "tta" , Types.INTEGER );
this.fCancelAbandon = new StoredProc( dataSource , "verse" , "cancel_abandon" );
this.fCancelAbandon.addParameter( "planet_id" , Types.INTEGER );
}
@Override
public Basic getBasicInformation( int empireId , int planetId )
{
String sql = "SELECT * FROM verse.get_planet_basics( ? , ? )";
return this.dTemplate.queryForObject( sql , this.mPlanetBasics , empireId , planetId );
}
@Override
public Orbital getOrbitalInformation( int empireId , int planetId )
{
String sql = "SELECT * FROM verse.get_orbital_view( ? , ? )";
return this.dTemplate.queryForObject( sql , this.mPlanetOrbital , empireId , planetId );
}
@Override
public Owner getOwnerInformation( int empireId , int planetId )
{
String sql = "SELECT * FROM verse.get_owner_view( ? , ? )";
return this.dTemplate.queryForObject( sql , this.mPlanetOwner , empireId , planetId );
}
@Override
public List< BuildingData > getBuildings( int empireId , int planetId , boolean isOwner )
{
RowMapper< BuildingData > mapper = isOwner ? this.mOwnerBuildings : this.mOrbitalBuildings;
String sql = "SELECT * FROM verse.get_buildings_view( ? , ? )";
return this.dTemplate.query( sql , mapper , empireId , planetId );
}
@Override
public QueueData getConstructionQueue( int planetId )
{
String sql = "SELECT * FROM verse.get_build_queue( ? )";
List< QueueItemData > items = this.dTemplate.query( sql , this.mQueueItem , planetId );
return new QueueData( ( items.size( ) < 5 ) , items );
}
@Override
public QueueData getMilitaryQueue( int planetId )
{
String sql = "SELECT * FROM verse.get_military_queue( ? )";
List< QueueItemData > items = this.dTemplate.query( sql , this.mQueueItem , planetId );
return new QueueData( ( items.size( ) < 5 ) , items );
}
@Override
public List< BuildableBuildingData > getAvailableBuildings( int planetId )
{
String sql = "SELECT * FROM verse.get_available_buildings( ? )";
return this.dTemplate.query( sql , this.mAvailableBuilding , planetId );
}
@Override
public List< BuildableShipData > getAvailableShips( int planetId )
{
String sql = "SELECT * FROM verse.get_available_ships( ? )";
return this.dTemplate.query( sql , this.mAvailableShip , planetId );
}
@Override
public void flushQueue( int planetId , boolean military )
{
StoredProc proc = military ? this.fFlushMilitaryQueue : this.fFlushBuildQueue;
proc.execute( planetId );
}
@Override
public void addToMilitaryQueue( int planetId , int sType , int amount )
{
this.fAddToMilitaryQueue.execute( planetId , sType , amount );
}
@Override
public void constructBuildings( int planetId , int bType , int amount )
{
this.fConstructBuildings.execute( planetId , bType , amount );
}
@Override
public boolean destroyBuildings( int planetId , int bType , int amount )
{
return (Boolean) this.fDestroyBuildings.execute( planetId , bType , amount ).get( "success" );
}
@Override
public Integer abandon( int planetId )
{
int v;
v = (Integer) this.fAbandon.execute( planetId ).get( "tta" );
return v == 0 ? null : v;
}
@Override
public void cancelAbandon( int planetId )
{
this.fCancelAbandon.execute( planetId );
}
}

View file

@ -0,0 +1,302 @@
package com.deepclone.lw.beans.map;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.deepclone.lw.cmd.ObjectNameError;
import com.deepclone.lw.cmd.player.gdata.GamePageData;
import com.deepclone.lw.cmd.player.gdata.planets.BuildingData;
import com.deepclone.lw.cmd.player.gdata.planets.OwnPlanetStatusData;
import com.deepclone.lw.cmd.player.gdata.planets.PlanetBasicView;
import com.deepclone.lw.cmd.player.gdata.planets.PlanetOrbitalView;
import com.deepclone.lw.cmd.player.gdata.planets.PlanetOwnView;
import com.deepclone.lw.cmd.player.planets.BuildingActionResponse;
import com.deepclone.lw.cmd.player.planets.RenamePlanetResponse;
import com.deepclone.lw.cmd.player.planets.ViewPlanetResponse;
import com.deepclone.lw.interfaces.game.EmpireManagement;
import com.deepclone.lw.interfaces.game.PlanetDAO;
import com.deepclone.lw.interfaces.game.PlanetsManagement;
import com.deepclone.lw.interfaces.naming.NamingDAO;
import com.deepclone.lw.sqld.game.PlanetData;
import com.deepclone.lw.sqld.game.PlanetData.AccessType;
import com.deepclone.lw.sqld.game.PlanetData.Basic;
import com.deepclone.lw.sqld.game.PlanetData.Orbital;
import com.deepclone.lw.sqld.game.PlanetData.Owner;
@Transactional
public class PlanetsManagementBean
implements PlanetsManagement
{
private EmpireManagement empireManagement;
private PlanetDAO planetDao;
private NamingDAO namingDao;
@Autowired( required = true )
public void setEmpireManagement( EmpireManagement empireManagement )
{
this.empireManagement = empireManagement;
}
@Autowired( required = true )
public void setPlanetDAO( PlanetDAO planetDao )
{
this.planetDao = planetDao;
}
@Autowired( required = true )
public void setNamingDao( NamingDAO namingDao )
{
this.namingDao = namingDao;
}
private PlanetOrbitalView getOrbitalView( int empireId , int planetId , AccessType access )
{
if ( access == AccessType.BASIC ) {
return null;
}
Orbital orbital = this.planetDao.getOrbitalInformation( empireId , planetId );
List< BuildingData > buildings = this.planetDao.getBuildings( empireId , planetId ,
( access == AccessType.OWNER ) );
PlanetOrbitalView view = new PlanetOrbitalView( );
view.setPopulation( orbital.getPopulation( ) );
view.setDefencePoints( orbital.getDefence( ) );
view.setOwnFleet( orbital.getOwnPower( ) );
view.setFriendlyFleet( orbital.getFriendlyPower( ) );
view.setHostileFleet( orbital.getHostilePower( ) );
view.setBattle( orbital.getBattle( ) );
view.setBuildings( buildings );
return view;
}
private PlanetOwnView getOwnerView( int empireId , int planetId , AccessType access )
{
if ( access != AccessType.OWNER ) {
return null;
}
Owner data = this.planetDao.getOwnerInformation( empireId , planetId );
OwnPlanetStatusData status = new OwnPlanetStatusData( );
status.setRenamePossible( data.isRenamePossible( ) );
status.setAbandonPossible( data.isAbandonPossible( ) );
status.setAbandonTime( data.getAbandonTime( ) );
PlanetOwnView view = new PlanetOwnView( );
view.setStatus( status );
view.setHappiness( data.getHappiness( ) );
view.sethChange( data.gethChange( ) );
view.setIncome( data.getIncome( ) );
view.setUpkeep( data.getUpkeep( ) );
view.setCivQueue( this.planetDao.getConstructionQueue( planetId ) );
view.setMilQueue( this.planetDao.getMilitaryQueue( planetId ) );
view.setbBuildings( this.planetDao.getAvailableBuildings( planetId ) );
view.setbShips( this.planetDao.getAvailableShips( planetId ) );
return view;
}
private PlanetBasicView getBasicView( Basic data )
{
return new PlanetBasicView( data.getName( ) , data.getPicture( ) , data.getTag( ) , data.getX( ) ,
data.getY( ) , data.getOrbit( ) );
}
private ViewPlanetResponse planetNotFound( int empireId )
{
return new ViewPlanetResponse( this.empireManagement.getGeneralInformation( empireId ) );
}
private ViewPlanetResponse ownershipError( int empireId , int planetId , Basic basic )
{
AccessType access = basic.getAccess( );
PlanetOrbitalView orbital = this.getOrbitalView( empireId , planetId , access );
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
return new ViewPlanetResponse( planetId , page , this.getBasicView( basic ) , orbital );
}
private ViewPlanetResponse fullView( int empireId , int planetId , Basic basic )
{
AccessType access = basic.getAccess( );
PlanetOrbitalView orbital = this.getOrbitalView( empireId , planetId , access );
PlanetOwnView owner = this.getOwnerView( empireId , planetId , access );
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
return new ViewPlanetResponse( planetId , page , this.getBasicView( basic ) , orbital , owner );
}
@Override
public ViewPlanetResponse viewPlanet( int empireId , int planetId )
{
PlanetData.Basic basic = this.planetDao.getBasicInformation( empireId , planetId );
if ( basic == null ) {
return this.planetNotFound( empireId );
}
AccessType access = basic.getAccess( );
PlanetOrbitalView orbital = this.getOrbitalView( empireId , planetId , access );
PlanetOwnView owner = this.getOwnerView( empireId , planetId , access );
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
return new ViewPlanetResponse( planetId , page , this.getBasicView( basic ) , orbital , owner );
}
@Override
public ViewPlanetResponse renamePlanet( int empireId , int planetId , String name )
{
PlanetData.Basic basic = this.planetDao.getBasicInformation( empireId , planetId );
if ( basic == null ) {
return this.planetNotFound( empireId );
}
AccessType access = basic.getAccess( );
if ( access != AccessType.OWNER ) {
return this.ownershipError( empireId , planetId , basic );
}
int rv = this.namingDao.renamePlanet( planetId , name );
ObjectNameError one = null;
switch ( rv ) {
case 0:
basic.setName( name );
break;
case 1:
one = ObjectNameError.BANNED;
break;
case 2:
one = ObjectNameError.UNAVAILABLE;
break;
case 3:
// "Too early" - someone probably pressed F5
break;
default:
throw new RuntimeException( "unknown error code " + rv );
}
PlanetOrbitalView orbital = this.getOrbitalView( empireId , planetId , access );
PlanetOwnView owner = this.getOwnerView( empireId , planetId , access );
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
if ( one == null ) {
return new ViewPlanetResponse( planetId , page , this.getBasicView( basic ) , orbital , owner );
}
return new RenamePlanetResponse( planetId , page , this.getBasicView( basic ) , orbital , owner , name , one
.toString( ) );
}
@Override
public ViewPlanetResponse flushQueue( int empireId , int planetId , boolean military )
{
PlanetData.Basic basic = this.planetDao.getBasicInformation( empireId , planetId );
if ( basic == null ) {
return this.planetNotFound( empireId );
} else if ( basic.getAccess( ) != AccessType.OWNER ) {
return this.ownershipError( empireId , planetId , basic );
}
this.planetDao.flushQueue( planetId , military );
return this.fullView( empireId , planetId , basic );
}
@Override
public ViewPlanetResponse addToMilitaryQueue( int empireId , int planetId , int sType , int amount )
{
PlanetData.Basic basic = this.planetDao.getBasicInformation( empireId , planetId );
if ( basic == null ) {
return this.planetNotFound( empireId );
} else if ( basic.getAccess( ) != AccessType.OWNER ) {
return this.ownershipError( empireId , planetId , basic );
}
this.planetDao.addToMilitaryQueue( planetId , sType , amount );
return this.fullView( empireId , planetId , basic );
}
@Override
public ViewPlanetResponse addToCivilianQueue( int empireId , int planetId , int bType , boolean destroy , int amount )
{
PlanetData.Basic basic = this.planetDao.getBasicInformation( empireId , planetId );
if ( basic == null ) {
return this.planetNotFound( empireId );
} else if ( basic.getAccess( ) != AccessType.OWNER ) {
return this.ownershipError( empireId , planetId , basic );
}
if ( !destroy ) {
this.planetDao.constructBuildings( planetId , bType , amount );
} else if ( !this.planetDao.destroyBuildings( planetId , bType , amount ) ) {
AccessType access = basic.getAccess( );
PlanetOrbitalView orbital = this.getOrbitalView( empireId , planetId , access );
PlanetOwnView owner = this.getOwnerView( empireId , planetId , access );
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
return new BuildingActionResponse( planetId , page , this.getBasicView( basic ) , orbital , owner );
}
return this.fullView( empireId , planetId , basic );
}
@Override
public ViewPlanetResponse abandon( int empireId , int planetId )
{
PlanetData.Basic basic = this.planetDao.getBasicInformation( empireId , planetId );
if ( basic == null ) {
return this.planetNotFound( empireId );
} else if ( basic.getAccess( ) != AccessType.OWNER ) {
return this.ownershipError( empireId , planetId , basic );
}
AccessType access = basic.getAccess( );
PlanetOrbitalView orbital = this.getOrbitalView( empireId , planetId , access );
PlanetOwnView owner = this.getOwnerView( empireId , planetId , access );
GamePageData page = this.empireManagement.getGeneralInformation( empireId );
Integer x;
if ( owner.getStatus( ).isAbandonPossible( ) ) {
x = this.planetDao.abandon( planetId );
} else {
x = null;
}
if ( x != null ) {
owner.getStatus( ).setAbandonPossible( false );
owner.getStatus( ).setAbandonTime( x );
}
return new ViewPlanetResponse( planetId , page , this.getBasicView( basic ) , orbital , owner );
}
@Override
public ViewPlanetResponse cancelAbandon( int empireId , int planetId )
{
PlanetData.Basic basic = this.planetDao.getBasicInformation( empireId , planetId );
if ( basic == null ) {
return this.planetNotFound( empireId );
} else if ( basic.getAccess( ) != AccessType.OWNER ) {
return this.ownershipError( empireId , planetId , basic );
}
this.planetDao.cancelAbandon( planetId );
return this.fullView( empireId , planetId , basic );
}
}

View file

@ -0,0 +1,67 @@
package com.deepclone.lw.beans.map;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
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.UniverseDAO;
import com.deepclone.lw.sqld.game.MapData;
public class UniverseDAOBean
implements UniverseDAO
{
private SimpleJdbcTemplate dTemplate;
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
}
@Override
public void generate( )
{
this.dTemplate.getJdbcOperations( ).execute( "SELECT verse.generate( )" );
}
@Override
public List< MapData > getMap( int empireId , int minX , int minY , int maxX , int maxY )
{
String sql = "SELECT * FROM verse.get_map( ? , ? , ? , ? , ? )";
RowMapper< MapData > mapper = new RowMapper< MapData >( ) {
@Override
public MapData mapRow( ResultSet rs , int rowNum )
throws SQLException
{
MapData entry = new MapData( );
entry.setX( rs.getInt( "x" ) );
entry.setY( rs.getInt( "y" ) );
entry.setOrbit( rs.getInt( "orbit" ) );
entry.setId( rs.getInt( "id" ) );
entry.setPicture( rs.getInt( "picture" ) );
entry.setName( rs.getString( "name" ) );
entry.setTag( rs.getString( "tag" ) );
entry.setDisplay( rs.getString( "display" ) );
return entry;
}
};
return this.dTemplate.query( sql , mapper , empireId , minX , minY , maxX , maxY );
}
}

View file

@ -0,0 +1,65 @@
package com.deepclone.lw.beans.map;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.game.UniverseDAO;
import com.deepclone.lw.interfaces.sys.Ticker;
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
public class UniverseGeneratorBean
implements InitializingBean , DisposableBean
{
private TransactionTemplate tTemplate;
private Ticker ticker;
private UniverseDAO universeDao;
private UniverseGeneratorTask generator;
@Autowired( required = true )
public void setTransactionManager( PlatformTransactionManager tManager )
{
this.tTemplate = new TransactionTemplate( tManager );
}
@Autowired( required = true )
public void setTicker( Ticker ticker )
{
this.ticker = ticker;
}
@Autowired( required = true )
public void setUniverseDAO( UniverseDAO universeDao )
{
this.universeDao = universeDao;
}
@Override
public void afterPropertiesSet( )
{
// Create ticker task
this.generator = new UniverseGeneratorTask( this.tTemplate , this.universeDao );
this.ticker.registerTask( Frequency.HIGH , "Universe generator" , this.generator );
}
@Override
public void destroy( )
{
this.generator = null;
}
}

View file

@ -0,0 +1,38 @@
package com.deepclone.lw.beans.map;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;
import com.deepclone.lw.interfaces.game.UniverseDAO;
class UniverseGeneratorTask
implements Runnable
{
private final TransactionTemplate tTemplate;
private final UniverseDAO universeDao;
UniverseGeneratorTask( TransactionTemplate tTemplate , UniverseDAO universeDao )
{
this.tTemplate = tTemplate;
this.universeDao = universeDao;
}
@Override
public void run( )
{
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
@Override
protected void doInTransactionWithoutResult( TransactionStatus status )
{
universeDao.generate( );
}
} );
}
}

View file

@ -0,0 +1,344 @@
package com.deepclone.lw.beans.msgs;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.deepclone.lw.cmd.admin.adata.Administrator;
import com.deepclone.lw.cmd.msgdata.*;
import com.deepclone.lw.cmd.admin.msg.*;
import com.deepclone.lw.interfaces.admin.AdminDAO;
import com.deepclone.lw.interfaces.game.EmpireDAO;
import com.deepclone.lw.interfaces.msg.AdminMessages;
import com.deepclone.lw.interfaces.msg.MessageBoxDAO;
import com.deepclone.lw.interfaces.msg.MessageContentCache;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatRegistry;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Transactional
public class AdminMessagesBean
implements AdminMessages
{
private MessageBoxDAO mboxDao;
private MessageContentCache contentCache;
private MessageFormatRegistry formats;
private EmpireDAO empireDao;
private AdminDAO adminDao;
@Autowired( required = true )
public void setMboxDao( MessageBoxDAO mboxDao )
{
this.mboxDao = mboxDao;
}
@Autowired( required = true )
public void setContentCache( MessageContentCache contentCache )
{
this.contentCache = contentCache;
}
@Autowired( required = true )
public void setFormats( MessageFormatRegistry formats )
{
this.formats = formats;
}
@Autowired( required = true )
public void setEmpireDao( EmpireDAO empireDao )
{
this.empireDao = empireDao;
}
@Autowired( required = true )
public void setAdminDao( AdminDAO adminDao )
{
this.adminDao = adminDao;
}
private Message readMessage( Administrator admin , boolean inbox , long id )
{
// Get list of messages
List< InboxRecord > mbox = this.mboxDao.getList( true , admin.getId( ) , inbox );
Map< Long , MessageDataRecord > contents = this.contentCache.getContent( mbox );
if ( !contents.containsKey( id ) ) {
return null;
}
// Find next and previous messages
Long previous = null;
Long next = null;
InboxRecord record = null;
boolean found = false;
for ( InboxRecord message : mbox ) {
if ( !found ) {
if ( message.getId( ) == id ) {
found = true;
record = message;
} else {
previous = message.getId( );
}
} else if ( next == null ) {
next = message.getId( );
break;
}
}
MessageDataRecord content = contents.get( record.getId( ) );
MessageExtractor formatter = this.formats.getFormatter( content ).getExtractor( record , content , "en" );
// Extract basic information
Message message = new Message( );
message.setId( id );
message.setNext( next );
message.setPrevious( previous );
message.setTime( record.getReceived( ) );
message.setSender( inbox ? formatter.getSender( ) : record.getSenderName( ) );
message.setReceiver( record.getReceiverName( ) );
message.setTitle( formatter.getSubject( ) );
message.setContents( formatter.getContents( ) );
message.setUnread( !record.isRead( ) );
message.setGameTime( content.getTick( ) );
// Handle message type
String type = inbox ? record.getSenderType( ) : record.getReceiverType( );
if ( "EMP".equals( type ) ) {
message.setType( MessageType.EMPIRE );
} else if ( "ADM".equals( type ) ) {
message.setType( MessageType.ADMINISTRATOR );
} else {
throw new RuntimeException( "unknown message type " + type );
}
return message;
}
@Override
public GetMessagesResponse getMessages( Administrator admin , boolean inbox )
{
// Get list of messages
List< InboxRecord > mbox = this.mboxDao.getList( true , admin.getId( ) , inbox );
Map< Long , MessageDataRecord > contents = this.contentCache.getContent( mbox );
// Format messages and create list of entries
List< MessageListEntry > results = new LinkedList< MessageListEntry >( );
for ( InboxRecord mRecord : mbox ) {
MessageDataRecord content = contents.get( mRecord.getId( ) );
MessageExtractor formatter = this.formats.getFormatter( content ).getExtractor( mRecord , content , "en" );
MessageListEntry result = new MessageListEntry( );
result.setId( mRecord.getId( ) );
result.setTime( mRecord.getReceived( ) );
result.setRead( mRecord.isRead( ) );
result.setTitle( formatter.getSubject( ) );
result.setSender( inbox ? formatter.getSender( ) : mRecord.getReceiverName( ) );
String type = inbox ? mRecord.getSenderType( ) : mRecord.getReceiverType( );
if ( "ADM".equals( type ) ) {
result.setType( MessageType.ADMINISTRATOR );
} else if ( "EMP".equals( type ) ) {
result.setType( MessageType.EMPIRE );
} else {
throw new RuntimeException( "unknown message type " + type );
}
results.add( result );
}
return new GetMessagesResponse( admin , results );
}
@Override
public ReadMessageResponse getMessage( Administrator admin , boolean inbox , long id )
{
// Get list of messages
Message message = this.readMessage( admin , inbox , id );
if ( message == null ) {
return new ReadMessageResponse( admin , inbox );
}
// Mark message as read
if ( inbox && message.isUnread( ) ) {
this.mboxDao.markRead( true , admin.getId( ) , new long[] {
id
} );
}
return new ReadMessageResponse( admin , inbox , message );
}
@Override
public void deleteMessages( Administrator admin , boolean inbox , long[] selection )
{
if ( selection == null ) {
this.mboxDao.delete( true , admin.getId( ) , inbox );
} else {
this.mboxDao.delete( true , admin.getId( ) , inbox , selection );
}
}
@Override
public void markRead( Administrator admin , long[] selection )
{
if ( selection == null ) {
this.mboxDao.markRead( true , admin.getId( ) );
} else {
this.mboxDao.markRead( true , admin.getId( ) , selection );
}
}
@Override
public void markUnread( Administrator admin , long[] selection )
{
if ( selection == null ) {
this.mboxDao.markUnread( true , admin.getId( ) );
} else {
this.mboxDao.markUnread( true , admin.getId( ) , selection );
}
}
@Override
public ComposeMessageResponse prepareBlankMessage( Administrator admin )
{
ComposeMessageResponse response = new ComposeMessageResponse( admin );
response.setMessageType( MessageType.ADMINISTRATOR );
response.setTarget( "" );
response.setTitle( "" );
response.setContents( "" );
return response;
}
@Override
public ComposeMessageResponse prepareMessageTo( Administrator admin , MessageType type , int id )
{
ComposeMessageResponse response = this.prepareBlankMessage( admin );
response.setMessageType( type );
try {
switch ( type ) {
case EMPIRE:
response.setTarget( this.empireDao.getInformation( id ).getName( ) );
break;
case ADMINISTRATOR:
response.setTarget( this.adminDao.getAdmin( id ).getName( ) );
break;
default:
throw new RuntimeException( "unsupported target type " + type );
}
} catch ( NullPointerException e ) {
response.setTargetError( true );
}
return response;
}
@Override
public ComposeMessageResponse sendMessage( Administrator admin , MessageType type , String target , String title ,
String contents , boolean simulate )
{
int errCode = this.mboxDao.sendMessage( true , admin.getId( ) , type , target , title , contents , simulate );
if ( errCode == 0 && !simulate ) {
return this.prepareBlankMessage( admin );
}
ComposeMessageResponse response = new ComposeMessageResponse( admin );
return this.sendError( type , target , title , contents , errCode , response );
}
@Override
public ComposeMessageResponse sendReply( Administrator admin , boolean inbox , long replyTo , MessageType type ,
String target , String title , String contents , boolean simulate )
{
int errCode = this.mboxDao.sendMessage( true , admin.getId( ) , type , target , title , contents , simulate );
if ( errCode == 0 && !simulate ) {
return this.prepareBlankMessage( admin );
}
Message message = this.readMessage( admin , inbox , replyTo );
ComposeMessageResponse response;
if ( message == null || message.getType( ) == MessageType.INTERNAL ) {
response = new ComposeMessageResponse( admin );
} else {
response = new ComposeMessageResponse( admin , inbox , message );
}
return this.sendError( type , target , title , contents , errCode , response );
}
private ComposeMessageResponse sendError( MessageType type , String target , String title , String contents ,
int errCode , ComposeMessageResponse response )
{
switch ( errCode ) {
case 1:
response.setTargetError( true );
break;
case 2:
response.setTimingError( true );
break;
}
response.setMessageType( type );
response.setTarget( target );
response.setTitle( title );
response.setContents( contents );
return response;
}
@Override
public ComposeMessageResponse prepareReply( Administrator admin , boolean inbox , long id )
{
Message message = this.readMessage( admin , inbox , id );
if ( message == null || message.getType( ) == MessageType.INTERNAL ) {
return this.prepareBlankMessage( admin );
}
ComposeMessageResponse response;
response = new ComposeMessageResponse( admin , inbox , message );
response.setMessageType( message.getType( ) );
response.setTarget( message.getSender( ) );
String title = message.getTitle( );
if ( !title.startsWith( "Re: " ) ) {
title = "Re: " + title;
if ( title.length( ) > 64 ) {
title = title.substring( 0 , 64 );
}
}
response.setTitle( title );
response.setContents( "" );
return response;
}
@Override
public void sendSpam( Administrator admin , String title , String body )
{
this.mboxDao.sendSpam( admin.getId( ) , title , body );
}
}

View file

@ -0,0 +1,449 @@
package com.deepclone.lw.beans.msgs;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import com.deepclone.lw.cmd.admin.adata.AdministratorBasics;
import com.deepclone.lw.cmd.admin.naming.Name;
import com.deepclone.lw.cmd.admin.naming.NameType;
import com.deepclone.lw.cmd.msgdata.Message;
import com.deepclone.lw.cmd.msgdata.MessageListEntry;
import com.deepclone.lw.cmd.msgdata.MessageType;
import com.deepclone.lw.cmd.player.gdata.NameIdPair;
import com.deepclone.lw.cmd.player.gdata.alliance.PublicAllianceInformation;
import com.deepclone.lw.cmd.player.msgs.ComposeMessageResponse;
import com.deepclone.lw.cmd.player.msgs.GetMessagesResponse;
import com.deepclone.lw.cmd.player.msgs.ListTargetsResponse;
import com.deepclone.lw.cmd.player.msgs.ReadMessageResponse;
import com.deepclone.lw.interfaces.acm.UsersDAO;
import com.deepclone.lw.interfaces.admin.AdminDAO;
import com.deepclone.lw.interfaces.game.AllianceDAO;
import com.deepclone.lw.interfaces.game.EmpireDAO;
import com.deepclone.lw.interfaces.game.EmpireManagement;
import com.deepclone.lw.interfaces.msg.MessageBoxDAO;
import com.deepclone.lw.interfaces.msg.MessageContentCache;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatRegistry;
import com.deepclone.lw.interfaces.msg.EmpireMessages;
import com.deepclone.lw.interfaces.naming.NamingDAO;
import com.deepclone.lw.sqld.admin.AdminRecord;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Transactional
public class EmpireMessagesBean
implements EmpireMessages
{
private EmpireManagement empireManager;
private MessageBoxDAO mboxDao;
private MessageContentCache contentCache;
private MessageFormatRegistry formats;
private EmpireDAO empireDao;
private AllianceDAO allianceDao;
private UsersDAO usersDao;
private AdminDAO adminDao;
private NamingDAO namingDao;
@Autowired( required = true )
public void setEmpireManager( EmpireManagement empireManager )
{
this.empireManager = empireManager;
}
@Autowired( required = true )
public void setMboxDao( MessageBoxDAO mboxDao )
{
this.mboxDao = mboxDao;
}
@Autowired( required = true )
public void setContentCache( MessageContentCache contentCache )
{
this.contentCache = contentCache;
}
@Autowired( required = true )
public void setFormats( MessageFormatRegistry formats )
{
this.formats = formats;
}
@Autowired( required = true )
public void setEmpireDao( EmpireDAO empireDao )
{
this.empireDao = empireDao;
}
@Autowired( required = true )
public void setAllianceDao( AllianceDAO allianceDao )
{
this.allianceDao = allianceDao;
}
@Autowired( required = true )
public void setUsersDao( UsersDAO usersDao )
{
this.usersDao = usersDao;
}
@Autowired( required = true )
public void setAdminDao( AdminDAO adminDao )
{
this.adminDao = adminDao;
}
@Autowired( required = true )
public void setNamingDao( NamingDAO namingDao )
{
this.namingDao = namingDao;
}
private Message readEmpireMessage( int empireId , boolean inbox , long id )
{
int accountId = this.empireDao.getInformation( empireId ).getAccountId( );
String lang = this.usersDao.getAccount( accountId ).getLanguage( );
// Get list of messages
List< InboxRecord > mbox = this.mboxDao.getList( false , empireId , inbox );
Map< Long , MessageDataRecord > contents = this.contentCache.getContent( mbox );
if ( !contents.containsKey( id ) ) {
return null;
}
// Find next and previous messages
Long previous = null;
Long next = null;
InboxRecord record = null;
boolean found = false;
for ( InboxRecord message : mbox ) {
if ( !found ) {
if ( message.getId( ) == id ) {
found = true;
record = message;
} else {
previous = message.getId( );
}
} else if ( next == null ) {
next = message.getId( );
break;
}
}
MessageDataRecord content = contents.get( record.getId( ) );
MessageExtractor formatter = this.formats.getFormatter( content ).getExtractor( record , content , lang );
// Extract basic information
Message message = new Message( );
message.setId( id );
message.setNext( next );
message.setPrevious( previous );
message.setTime( record.getReceived( ) );
message.setSender( inbox ? formatter.getSender( ) : record.getSenderName( ) );
message.setReceiver( record.getReceiverName( ) );
message.setTitle( formatter.getSubject( ) );
message.setContents( formatter.getContents( ) );
message.setUnread( !record.isRead( ) );
message.setGameTime( content.getTick( ) );
// Handle message type
if ( record.isInternal( ) ) {
message.setType( MessageType.INTERNAL );
} else {
String type = inbox ? record.getSenderType( ) : record.getReceiverType( );
if ( "ALL".equals( record.getReceiverType( ) ) ) {
message.setType( MessageType.ALLIANCE );
message.setReceiver( "[" + message.getReceiver( ) + "]" );
} else if ( "EMP".equals( type ) ) {
message.setType( MessageType.EMPIRE );
} else if ( "ADM".equals( type ) ) {
message.setType( MessageType.ADMINISTRATOR );
} else {
throw new RuntimeException( "unknown message type " + type );
}
}
return message;
}
@Override
public GetMessagesResponse getMessages( int empireId , boolean inbox )
{
int accountId = this.empireDao.getInformation( empireId ).getAccountId( );
String lang = this.usersDao.getAccount( accountId ).getLanguage( );
// Get list of messages
List< InboxRecord > mbox = this.mboxDao.getList( false , empireId , inbox );
Map< Long , MessageDataRecord > contents = this.contentCache.getContent( mbox );
// Format messages and create list of entries
List< MessageListEntry > results = new LinkedList< MessageListEntry >( );
for ( InboxRecord mRecord : mbox ) {
MessageDataRecord content = contents.get( mRecord.getId( ) );
MessageExtractor formatter = this.formats.getFormatter( content ).getExtractor( mRecord , content , lang );
MessageListEntry result = new MessageListEntry( );
result.setId( mRecord.getId( ) );
result.setTime( mRecord.getReceived( ) );
result.setRead( mRecord.isRead( ) );
result.setTitle( formatter.getSubject( ) );
result.setSender( inbox ? formatter.getSender( ) : mRecord.getReceiverName( ) );
if ( mRecord.isInternal( ) ) {
result.setType( MessageType.INTERNAL );
} else {
String type = inbox ? mRecord.getSenderType( ) : mRecord.getReceiverType( );
if ( "ADM".equals( type ) ) {
result.setType( MessageType.ADMINISTRATOR );
} else if ( "ALL".equals( mRecord.getReceiverType( ) ) ) {
result.setType( MessageType.ALLIANCE );
result.setSender( "[" + mRecord.getReceiverName( ) + "]" );
} else if ( "EMP".equals( type ) ) {
result.setType( MessageType.EMPIRE );
} else {
throw new RuntimeException( "unknown message type " + type );
}
}
results.add( result );
}
return new GetMessagesResponse( this.empireManager.getGeneralInformation( empireId ) , results );
}
@Override
public ReadMessageResponse getMessage( int empireId , boolean inbox , long id )
{
// Get list of messages
Message message = this.readEmpireMessage( empireId , inbox , id );
if ( message == null ) {
return new ReadMessageResponse( this.empireManager.getGeneralInformation( empireId ) , inbox );
}
// Mark message as read
if ( inbox && message.isUnread( ) ) {
this.mboxDao.markRead( false , empireId , new long[] {
id
} );
}
return new ReadMessageResponse( this.empireManager.getGeneralInformation( empireId ) , inbox , message );
}
@Override
public void deleteMessages( int empireId , boolean inbox , long[] selection )
{
if ( selection == null ) {
this.mboxDao.delete( false , empireId , inbox );
} else {
this.mboxDao.delete( false , empireId , inbox , selection );
}
}
@Override
public void markRead( int empireId , long[] selection )
{
if ( selection == null ) {
this.mboxDao.markRead( false , empireId );
} else {
this.mboxDao.markRead( false , empireId , selection );
}
}
@Override
public void markUnread( int empireId , long[] selection )
{
if ( selection == null ) {
this.mboxDao.markUnread( false , empireId );
} else {
this.mboxDao.markUnread( false , empireId , selection );
}
}
@Override
public ComposeMessageResponse prepareBlankMessage( int empireId )
{
ComposeMessageResponse response = new ComposeMessageResponse( this.empireManager
.getGeneralInformation( empireId ) );
response.setMessageType( MessageType.EMPIRE );
response.setTarget( "" );
response.setTitle( "" );
response.setContents( "" );
return response;
}
@Override
public ComposeMessageResponse prepareMessageTo( int empireId , MessageType type , int id )
{
ComposeMessageResponse response = this.prepareBlankMessage( empireId );
response.setMessageType( type );
try {
switch ( type ) {
case EMPIRE:
response.setTarget( this.empireDao.getInformation( id ).getName( ) );
break;
case ALLIANCE:
response.setTarget( this.allianceDao.getPublicInformation( id ).getTag( ) );
break;
case ADMINISTRATOR:
response.setTarget( this.adminDao.getAdmin( id ).getName( ) );
break;
default:
throw new RuntimeException( "unsupported target type " + type );
}
} catch ( NullPointerException e ) {
response.setTargetError( true );
}
return response;
}
@Override
public ComposeMessageResponse sendMessage( int empireId , MessageType type , String target , String title ,
String contents , boolean simulate )
{
int errCode = this.mboxDao.sendMessage( false , empireId , type , target , title , contents , simulate );
if ( errCode == 0 && !simulate ) {
return this.prepareBlankMessage( empireId );
}
ComposeMessageResponse response = new ComposeMessageResponse( this.empireManager
.getGeneralInformation( empireId ) );
return empireSendError( type , target , title , contents , errCode , response );
}
@Override
public ComposeMessageResponse sendReply( int empireId , boolean inbox , long replyTo , MessageType type ,
String target , String title , String contents , boolean simulate )
{
int errCode = this.mboxDao.sendMessage( false , empireId , type , target , title , contents , simulate );
if ( errCode == 0 && !simulate ) {
return this.prepareBlankMessage( empireId );
}
Message message = this.readEmpireMessage( empireId , inbox , replyTo );
ComposeMessageResponse response;
if ( message == null || message.getType( ) == MessageType.INTERNAL ) {
response = new ComposeMessageResponse( this.empireManager.getGeneralInformation( empireId ) );
} else {
response = new ComposeMessageResponse( this.empireManager.getGeneralInformation( empireId ) , inbox ,
message );
}
return empireSendError( type , target , title , contents , errCode , response );
}
private ComposeMessageResponse empireSendError( MessageType type , String target , String title , String contents ,
int errCode , ComposeMessageResponse response )
{
switch ( errCode ) {
case 1:
response.setTargetError( true );
break;
case 2:
response.setTimingError( true );
break;
}
response.setMessageType( type );
response.setTarget( target );
response.setTitle( title );
response.setContents( contents );
return response;
}
@Override
public ComposeMessageResponse prepareReply( int empireId , boolean inbox , long id )
{
Message message = this.readEmpireMessage( empireId , inbox , id );
if ( message == null || message.getType( ) == MessageType.INTERNAL ) {
return this.prepareBlankMessage( empireId );
}
ComposeMessageResponse response;
response = new ComposeMessageResponse( this.empireManager.getGeneralInformation( empireId ) , inbox , message );
response.setMessageType( message.getType( ) );
if ( message.getType( ) == MessageType.ALLIANCE ) {
String allTag = message.getReceiver( );
response.setTarget( allTag.substring( 1 , allTag.length( ) - 1 ) );
} else {
response.setTarget( message.getSender( ) );
}
String title = message.getTitle( );
if ( !title.startsWith( "Re: " ) ) {
title = "Re: " + title;
if ( title.length( ) > 64 ) {
title = title.substring( 0 , 64 );
}
}
response.setTitle( title );
response.setContents( "" );
return response;
}
@Override
public ListTargetsResponse getTargets( int empireId )
{
// List all administrators
List< AdministratorBasics > admins = new LinkedList< AdministratorBasics >( );
for ( AdminRecord record : this.adminDao.listAdministrators( ) ) {
if ( !record.isActive( ) ) {
continue;
}
AdministratorBasics admin = new AdministratorBasics( );
admin.setId( record.getId( ) );
admin.setName( record.getName( ) );
admin.setPrivileges( record.getPrivileges( ) );
admins.add( admin );
}
// List active empires
List< NameIdPair > empires = new LinkedList< NameIdPair >( );
for ( Name n : this.namingDao.getNames( NameType.EMPIRE ) ) {
if ( n.getExtra( ) == null || n.getId( ) == empireId ) {
continue;
}
empires.add( new NameIdPair( n.getId( ) , n.getName( ) ) );
}
// List alliances
List< PublicAllianceInformation > alliances = new LinkedList< PublicAllianceInformation >( );
for ( Name n : this.namingDao.getNames( NameType.ALLIANCE ) ) {
alliances.add( new PublicAllianceInformation( n.getId( ) , n.getName( ) , n.getExtra( ) , 0 , null , 0 ) );
}
return new ListTargetsResponse( this.empireManager.getGeneralInformation( empireId ) , empires , alliances ,
admins );
}
}

View file

@ -0,0 +1,157 @@
package com.deepclone.lw.beans.msgs;
import java.util.List;
import java.util.Map;
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.msgdata.Message;
import com.deepclone.lw.cmd.msgdata.MessageType;
import com.deepclone.lw.interfaces.eventlog.Logger;
import com.deepclone.lw.interfaces.eventlog.SystemLogger;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.interfaces.msg.MessageContentCache;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatRegistry;
import com.deepclone.lw.interfaces.msg.NotificationsDAO;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
import com.deepclone.lw.sqld.msgs.NotificationsRecord;
abstract class MailTaskBase
implements Runnable
{
protected static class MessageData
{
public List< InboxRecord > messages;
public Map< Long , MessageDataRecord > data;
}
protected final SystemLogger logger;
protected final TransactionTemplate tTemplate;
protected final NotificationsDAO notificationsDao;
protected final MessageContentCache contents;
protected final MessageFormatRegistry formats;
protected final Translator translator;
protected final Mailer mailer;
protected final MessageCleanerBean cleaner;
protected final boolean mode;
public MailTaskBase( Logger logger , PlatformTransactionManager tManager , NotificationsDAO notificationsDao ,
MessageContentCache contents , MessageFormatRegistry formats , Translator translator , Mailer mailer ,
MessageCleanerBean cleaner , boolean mode )
{
this.logger = logger.getSystemLogger( this.getClass( ).getSimpleName( ) );
this.tTemplate = new TransactionTemplate( tManager );
this.notificationsDao = notificationsDao;
this.contents = contents;
this.formats = formats;
this.translator = translator;
this.mailer = mailer;
this.cleaner = cleaner;
this.mode = mode;
}
@Override
public void run( )
{
List< NotificationsRecord > notifications = this.getNotifications( );
for ( NotificationsRecord notification : notifications ) {
this.notify( notification );
}
}
private List< NotificationsRecord > getNotifications( )
{
return this.tTemplate.execute( new TransactionCallback< List< NotificationsRecord > >( ) {
@Override
public List< NotificationsRecord > doInTransaction( TransactionStatus status )
{
return notificationsDao.getNotificationRecords( mode );
}
} );
}
protected abstract void notify( NotificationsRecord notification );
protected final MessageData getMessagesToSend( final int id , final long maxId , final boolean nPrivate ,
final boolean nInternal , final boolean nAlliance , final boolean nAdmin )
{
return this.tTemplate.execute( new TransactionCallback< MessageData >( ) {
@Override
public MessageData doInTransaction( TransactionStatus status )
{
MessageData md = new MessageData( );
md.messages = notificationsDao.listMessages( id , maxId , mode , nPrivate , nInternal , nAlliance ,
nAdmin );
if ( !md.messages.isEmpty( ) ) {
md.data = contents.getContent( md.messages );
}
return md;
}
} );
}
protected final String translate( String string , String lang )
{
try {
return this.translator.translate( lang , string );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
}
protected final Message readMessage( int empireId , String lang , InboxRecord record , MessageDataRecord content ,
boolean needBody )
{
MessageExtractor formatter = this.formats.getFormatter( content ).getExtractor( record , content , lang );
// Extract basic information
Message message = new Message( );
message.setTime( record.getReceived( ) );
message.setSender( formatter.getSender( ) );
message.setReceiver( record.getReceiverName( ) );
message.setTitle( formatter.getSubject( ) );
if ( needBody ) {
message.setContents( formatter.getContents( ) );
}
message.setUnread( !record.isRead( ) );
message.setGameTime( content.getTick( ) );
// Handle message type
if ( record.isInternal( ) ) {
message.setType( MessageType.INTERNAL );
} else {
String type = record.getSenderType( );
if ( "ALL".equals( record.getReceiverType( ) ) ) {
message.setType( MessageType.ALLIANCE );
message.setReceiver( "[" + message.getReceiver( ) + "]" );
} else if ( "EMP".equals( type ) ) {
message.setType( MessageType.EMPIRE );
} else if ( "ADM".equals( type ) ) {
message.setType( MessageType.ADMINISTRATOR );
} else {
throw new RuntimeException( "unknown message type " + type );
}
}
return message;
}
}

View file

@ -0,0 +1,420 @@
package com.deepclone.lw.beans.msgs;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
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.simple.SimpleJdbcTemplate;
import com.deepclone.lw.cmd.msgdata.MessageType;
import com.deepclone.lw.cmd.player.msgs.MessageBoxAction;
import com.deepclone.lw.interfaces.msg.MessageBoxDAO;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.utils.StoredProc;
public class MessageBoxDAOBean
implements MessageBoxDAO
{
private static final int cacheTime = 6;
private static class CacheKey
{
private final boolean admin;
private final int id;
private final boolean inbox;
public CacheKey( boolean admin , int id , boolean inbox )
{
this.admin = admin;
this.id = id;
this.inbox = inbox;
}
@Override
public int hashCode( )
{
final int prime = 31;
int result = 1;
result = prime * result + ( admin ? 1231 : 1237 );
result = prime * result + id;
result = prime * result + ( inbox ? 1231 : 1237 );
return result;
}
@Override
public boolean equals( Object obj )
{
if ( this == obj )
return true;
if ( obj == null )
return false;
if ( getClass( ) != obj.getClass( ) )
return false;
CacheKey other = (CacheKey) obj;
if ( admin != other.admin )
return false;
if ( id != other.id )
return false;
if ( inbox != other.inbox )
return false;
return true;
}
}
private static class CacheData
{
public int timeLeft = MessageBoxDAOBean.cacheTime;
public long maxId = Long.MIN_VALUE;
public List< InboxRecord > records = new LinkedList< InboxRecord >( );
public Map< Long , MessageBoxAction > updates = new HashMap< Long , MessageBoxAction >( );
}
private final Map< CacheKey , CacheData > cache = new HashMap< CacheKey , CacheData >( );
private SimpleJdbcTemplate dTemplate;
private final RowMapper< InboxRecord > listMapper;
private StoredProc fSendSpam;
private StoredProc fEmpireSend;
private StoredProc fEmpireMarkRead;
private StoredProc fEmpireMarkReadAll;
private StoredProc fEmpireDelete;
private StoredProc fEmpireDeleteAll;
private StoredProc fEmpireMarkUnread;
private StoredProc fEmpireMarkUnreadAll;
private StoredProc fAdminSend;
private StoredProc fAdminMarkRead;
private StoredProc fAdminMarkReadAll;
private StoredProc fAdminDelete;
private StoredProc fAdminDeleteAll;
private StoredProc fAdminMarkUnread;
private StoredProc fAdminMarkUnreadAll;
public MessageBoxDAOBean( )
{
this.listMapper = new RowMapper< InboxRecord >( ) {
@Override
public InboxRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
InboxRecord iRec = new InboxRecord( );
iRec.setId( rs.getLong( "id" ) );
iRec.setRead( rs.getBoolean( "read" ) );
iRec.setSenderType( rs.getString( "sender_type" ) );
iRec.setSenderId( (Integer) rs.getObject( "sender_id" ) );
iRec.setSenderName( rs.getString( "sender_name" ) );
iRec.setReceiverType( rs.getString( "receiver_type" ) );
iRec.setReceiverId( rs.getInt( "receiver_id" ) );
iRec.setReceiverName( rs.getString( "receiver_name" ) );
iRec.setInternal( rs.getBoolean( "internal_message" ) );
iRec.setReceived( rs.getTimestamp( "r_time" ) );
iRec.setContentId( rs.getLong( "content_id" ) );
return iRec;
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.fSendSpam = new StoredProc( dataSource , "msgs" , "deliver_admin_spam" );
this.fSendSpam.addParameter( "admin_id" , Types.INTEGER );
this.fSendSpam.addParameter( "subject" , Types.VARCHAR );
this.fSendSpam.addParameter( "contents" , "TEXT" );
this.fEmpireSend = new StoredProc( dataSource , "msgs" , "send_message" );
this.fEmpireSend.addParameter( "empire_id" , Types.INTEGER );
this.fEmpireSend.addParameter( "to_type" , "receiver_type" );
this.fEmpireSend.addParameter( "target" , Types.VARCHAR );
this.fEmpireSend.addParameter( "subject" , Types.VARCHAR );
this.fEmpireSend.addParameter( "contents" , "TEXT" );
this.fEmpireSend.addParameter( "really_send" , Types.BOOLEAN );
this.fEmpireSend.addOutput( "err_code" , Types.INTEGER );
this.fEmpireMarkRead = new StoredProc( dataSource , "msgs" , "empire_mark_read" );
this.fEmpireMarkRead.addParameter( "empire_id" , Types.INTEGER );
this.fEmpireMarkRead.addParameter( "messages" , "BIGINT[]" );
this.fEmpireMarkReadAll = new StoredProc( dataSource , "msgs" , "empire_mark_read" );
this.fEmpireMarkReadAll.addParameter( "empire_id" , Types.INTEGER );
this.fEmpireMarkUnread = new StoredProc( dataSource , "msgs" , "empire_mark_unread" );
this.fEmpireMarkUnread.addParameter( "empire_id" , Types.INTEGER );
this.fEmpireMarkUnread.addParameter( "messages" , "BIGINT[]" );
this.fEmpireMarkUnreadAll = new StoredProc( dataSource , "msgs" , "empire_mark_unread" );
this.fEmpireMarkUnreadAll.addParameter( "empire_id" , Types.INTEGER );
this.fEmpireDelete = new StoredProc( dataSource , "msgs" , "empire_delete" );
this.fEmpireDelete.addParameter( "empire_id" , Types.INTEGER );
this.fEmpireDelete.addParameter( "in_inbox" , Types.BOOLEAN );
this.fEmpireDelete.addParameter( "messages" , "BIGINT[]" );
this.fEmpireDeleteAll = new StoredProc( dataSource , "msgs" , "empire_delete" );
this.fEmpireDeleteAll.addParameter( "empire_id" , Types.INTEGER );
this.fEmpireDeleteAll.addParameter( "in_inbox" , Types.BOOLEAN );
this.fAdminSend = new StoredProc( dataSource , "msgs" , "send_admin_message" );
this.fAdminSend.addParameter( "admin_id" , Types.INTEGER );
this.fAdminSend.addParameter( "to_type" , "receiver_type" );
this.fAdminSend.addParameter( "target" , Types.VARCHAR );
this.fAdminSend.addParameter( "subject" , Types.VARCHAR );
this.fAdminSend.addParameter( "contents" , "TEXT" );
this.fAdminSend.addParameter( "really_send" , Types.BOOLEAN );
this.fAdminSend.addOutput( "err_code" , Types.INTEGER );
this.fAdminMarkRead = new StoredProc( dataSource , "msgs" , "admin_mark_read" );
this.fAdminMarkRead.addParameter( "admin_id" , Types.INTEGER );
this.fAdminMarkRead.addParameter( "messages" , "BIGINT[]" );
this.fAdminMarkReadAll = new StoredProc( dataSource , "msgs" , "admin_mark_read" );
this.fAdminMarkReadAll.addParameter( "admin_id" , Types.INTEGER );
this.fAdminMarkUnread = new StoredProc( dataSource , "msgs" , "admin_mark_unread" );
this.fAdminMarkUnread.addParameter( "admin_id" , Types.INTEGER );
this.fAdminMarkUnread.addParameter( "messages" , "BIGINT[]" );
this.fAdminMarkUnreadAll = new StoredProc( dataSource , "msgs" , "admin_mark_unread" );
this.fAdminMarkUnreadAll.addParameter( "admin_id" , Types.INTEGER );
this.fAdminDelete = new StoredProc( dataSource , "msgs" , "admin_delete" );
this.fAdminDelete.addParameter( "admin_id" , Types.INTEGER );
this.fAdminDelete.addParameter( "in_inbox" , Types.BOOLEAN );
this.fAdminDelete.addParameter( "messages" , "BIGINT[]" );
this.fAdminDeleteAll = new StoredProc( dataSource , "msgs" , "admin_delete" );
this.fAdminDeleteAll.addParameter( "admin_id" , Types.INTEGER );
this.fAdminDeleteAll.addParameter( "in_inbox" , Types.BOOLEAN );
}
private String getIdArray( long[] ids )
{
StringBuilder iArray = new StringBuilder( ).append( "{" );
int i = 0;
int s = ids.length;
for ( Long id : ids ) {
iArray.append( id );
if ( i != s - 1 ) {
iArray.append( "," );
}
i++;
}
iArray.append( "}" );
return iArray.toString( );
}
@Override
public int sendMessage( boolean admin , int empireId , MessageType type , String target , String title ,
String contents , boolean simulate )
{
StoredProc send = admin ? this.fAdminSend : this.fEmpireSend;
Map< String , Object > result;
result = send.execute( empireId , type.toString( ).substring( 0 , 3 ) , target , title , contents , !simulate );
return (Integer) result.get( "err_code" );
}
@Override
public List< InboxRecord > getList( boolean admin , int id , boolean inbox )
{
CacheKey key = new CacheKey( admin , id , inbox );
CacheData data;
synchronized ( this.cache ) {
data = this.cache.get( key );
if ( data == null ) {
data = new CacheData( );
this.cache.put( key , data );
} else if ( !data.updates.isEmpty( ) ) {
this.applyUpdates( data );
}
this.getNewRecords( admin , id , inbox , data );
data.timeLeft = MessageBoxDAOBean.cacheTime;
}
return data.records;
}
private void applyUpdates( CacheData data )
{
Iterator< InboxRecord > iterator = data.records.iterator( );
while ( iterator.hasNext( ) ) {
InboxRecord record = iterator.next( );
MessageBoxAction update = data.updates.get( record.getId( ) );
if ( update == null ) {
continue;
}
switch ( update ) {
case DELETE:
iterator.remove( );
break;
case MARK_READ:
record.setRead( true );
break;
case MARK_UNREAD:
record.setRead( false );
break;
}
}
data.updates.clear( );
}
private void getNewRecords( boolean admin , int id , boolean inbox , CacheData data )
{
String tString = ( admin ? "admin" : "empire" );
String bString = ( inbox ? "in" : "out" );
String sql = "SELECT * FROM msgs." + tString + "_" + bString + "box WHERE " + tString + "_id = ? AND id > ?";
List< InboxRecord > newRecords = this.dTemplate.query( sql , this.listMapper , id , data.maxId );
if ( newRecords.isEmpty( ) ) {
return;
}
data.records.addAll( 0 , newRecords );
data.maxId = newRecords.get( 0 ).getId( );
}
@Override
public void markRead( boolean admin , int userId , long[] ids )
{
synchronized ( this.cache ) {
CacheData data = this.cache.get( new CacheKey( admin , userId , true ) );
if ( data != null ) {
for ( long id : ids ) {
if ( data.updates.containsKey( id ) ) {
continue;
}
data.updates.put( id , MessageBoxAction.MARK_READ );
}
}
StoredProc dbMark = admin ? this.fAdminMarkRead : this.fEmpireMarkRead;
dbMark.execute( userId , this.getIdArray( ids ) );
}
}
@Override
public void markRead( boolean admin , int userId )
{
synchronized ( this.cache ) {
this.cache.remove( new CacheKey( admin , userId , true ) );
StoredProc dbMark = admin ? this.fAdminMarkReadAll : this.fEmpireMarkReadAll;
dbMark.execute( userId );
}
}
@Override
public void markUnread( boolean admin , int userId , long[] ids )
{
synchronized ( this.cache ) {
CacheData data = this.cache.get( new CacheKey( admin , userId , true ) );
if ( data != null ) {
for ( long id : ids ) {
if ( data.updates.containsKey( id ) ) {
continue;
}
data.updates.put( id , MessageBoxAction.MARK_UNREAD );
}
}
StoredProc dbMark = admin ? this.fAdminMarkUnread : this.fEmpireMarkUnread;
dbMark.execute( userId , this.getIdArray( ids ) );
}
}
@Override
public void markUnread( boolean admin , int userId )
{
synchronized ( this.cache ) {
this.cache.remove( new CacheKey( admin , userId , true ) );
StoredProc dbMark = admin ? this.fAdminMarkUnreadAll : this.fEmpireMarkUnreadAll;
dbMark.execute( userId );
}
}
@Override
public void delete( boolean admin , int userId , boolean inbox , long[] ids )
{
synchronized ( this.cache ) {
CacheData data = this.cache.get( new CacheKey( admin , userId , inbox ) );
if ( data != null ) {
for ( long id : ids ) {
data.updates.put( id , MessageBoxAction.DELETE );
}
}
StoredProc dbDelete = admin ? this.fAdminDelete : this.fEmpireDelete;
dbDelete.execute( userId , inbox , this.getIdArray( ids ) );
}
}
@Override
public void delete( boolean admin , int userId , boolean inbox )
{
synchronized ( this.cache ) {
this.cache.remove( new CacheKey( admin , userId , inbox ) );
StoredProc dbDelete = admin ? this.fAdminDeleteAll : this.fEmpireDeleteAll;
dbDelete.execute( userId , inbox );
}
}
@Override
public void clearCache( )
{
List< CacheKey > toRemove = new LinkedList< CacheKey >( );
synchronized ( this.cache ) {
for ( Map.Entry< CacheKey , CacheData > entry : this.cache.entrySet( ) ) {
CacheData data = entry.getValue( );
data.timeLeft--;
if ( data.timeLeft == 0 ) {
toRemove.add( entry.getKey( ) );
}
}
for ( CacheKey key : toRemove ) {
this.cache.remove( key );
}
}
}
@Override
public void sendSpam( int adminId , String title , String body )
{
this.fSendSpam.execute( adminId , title , body );
}
}

View file

@ -0,0 +1,44 @@
package com.deepclone.lw.beans.msgs;
import java.util.regex.Pattern;
public class MessageCleanerBean
{
private final Pattern planet = Pattern.compile( "\\{\\{planet:\\d+ ([^\\}]+)\\}\\}" );
private final Pattern empire = Pattern.compile( "\\{\\{empire:\\d+ ([^\\}]+)\\}\\}" );
private final Pattern battle = Pattern.compile( "\\{\\{battle:\\d+ ([^\\}]+)\\}\\}" );
private final Pattern bug = Pattern.compile( "\\{\\{bug:(\\d+)\\}\\}" );
public String cleanMessage( String message )
{
message = message.trim( );
StringBuilder repLine = new StringBuilder( );
for ( Character c : message.toCharArray( ) ) {
int nVal = Character.codePointAt( new char[] {
c
} , 0 );
if ( c != '\n' && Character.isISOControl( nVal ) ) {
continue;
}
repLine.append( c );
}
message = repLine.toString( );
return message;
}
public String removeInternals( String message )
{
message = planet.matcher( message ).replaceAll( "$1" );
message = empire.matcher( message ).replaceAll( "$1" );
message = battle.matcher( message ).replaceAll( "$1" );
message = bug.matcher( message ).replaceAll( "#$1" );
return message;
}
}

View file

@ -0,0 +1,194 @@
package com.deepclone.lw.beans.msgs;
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.msg.MessageContentCache;
import com.deepclone.lw.interfaces.msg.MessageRecordsDAO;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.EventTypeRecord;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
public class MessageContentCacheBean
implements MessageContentCache
{
private static final int cacheTime = 24;
private static class CacheKey
{
private final boolean internal;
private final long id;
public CacheKey( boolean internal , long id )
{
this.internal = internal;
this.id = id;
}
@Override
public int hashCode( )
{
final int prime = 31;
int result = 1;
result = prime * result + (int) ( id ^ ( id >>> 32 ) );
result = prime * result + ( internal ? 1231 : 1237 );
return result;
}
@Override
public boolean equals( Object obj )
{
if ( this == obj )
return true;
if ( obj == null )
return false;
if ( getClass( ) != obj.getClass( ) )
return false;
CacheKey other = (CacheKey) obj;
if ( id != other.id )
return false;
if ( internal != other.internal )
return false;
return true;
}
}
private static class CacheData
{
public int timeLeft = MessageContentCacheBean.cacheTime;
public MessageDataRecord dataRecord;
}
private final Map< CacheKey , CacheData > cache = new HashMap< CacheKey , CacheData >( );
private MessageRecordsDAO recordsDao;
@Autowired( required = true )
public void setRecordsDao( MessageRecordsDAO recordsDao )
{
this.recordsDao = recordsDao;
}
@Override
public Map< Long , MessageDataRecord > getContent( List< InboxRecord > messages )
{
// Creates cache keys for all records
Map< Long , CacheKey > mKeys = this.extractKeys( messages );
// Generate lists of uncached messages
List< Long > uncachedText = new LinkedList< Long >( );
List< Long > uncachedEvents = new LinkedList< Long >( );
synchronized ( this.cache ) {
this.getCachedRecords( mKeys , uncachedText , uncachedEvents );
}
// Fetch missing data
List< MessageDataRecord > nRecords = new LinkedList< MessageDataRecord >( );
if ( !uncachedText.isEmpty( ) ) {
nRecords.addAll( this.recordsDao.getTextMessages( uncachedText ) );
}
if ( !uncachedEvents.isEmpty( ) ) {
this.getMissingEvents( uncachedEvents , nRecords );
}
Map< Long , MessageDataRecord > result = new HashMap< Long , MessageDataRecord >( );
synchronized ( this.cache ) {
// Add new records to the cache
for ( MessageDataRecord record : nRecords ) {
CacheKey key = new CacheKey( record.isInternal( ) , record.getId( ) );
CacheData data = new CacheData( );
data.dataRecord = record;
this.cache.put( key , data );
}
// Extract all required data
for ( Map.Entry< Long , CacheKey > entry : mKeys.entrySet( ) ) {
CacheKey key = entry.getValue( );
result.put( entry.getKey( ) , this.cache.get( key ).dataRecord );
}
}
return result;
}
private Map< Long , CacheKey > extractKeys( List< InboxRecord > messages )
{
Map< Long , CacheKey > mKeys = new HashMap< Long , CacheKey >( );
for ( InboxRecord record : messages ) {
CacheKey key = new CacheKey( record.isInternal( ) , record.getContentId( ) );
mKeys.put( record.getId( ) , key );
}
return mKeys;
}
private void getCachedRecords( Map< Long , CacheKey > mKeys , List< Long > uncachedText ,
List< Long > uncachedEvents )
{
for ( Map.Entry< Long , CacheKey > entry : mKeys.entrySet( ) ) {
CacheKey key = entry.getValue( );
CacheData data = this.cache.get( key );
if ( data == null ) {
( key.internal ? uncachedEvents : uncachedText ).add( key.id );
} else {
data.timeLeft = MessageContentCacheBean.cacheTime;
}
}
}
private void getMissingEvents( List< Long > uncachedEvents , List< MessageDataRecord > nRecords )
{
// Determine event types
Map< EventType , List< Long >> eventsByType = new HashMap< EventType , List< Long > >( );
for ( EventTypeRecord eType : this.recordsDao.getEventTypes( uncachedEvents ) ) {
List< Long > typeIds = eventsByType.get( eType.getType( ) );
if ( typeIds == null ) {
typeIds = new LinkedList< Long >( );
eventsByType.put( eType.getType( ) , typeIds );
}
typeIds.add( eType.getId( ) );
}
// Fetch data
for ( Map.Entry< EventType , List< Long > > entry : eventsByType.entrySet( ) ) {
nRecords.addAll( this.recordsDao.getEvents( entry.getKey( ) , entry.getValue( ) ) );
}
}
@Override
public void clearCache( )
{
synchronized ( this.cache ) {
List< CacheKey > toRemove = new LinkedList< CacheKey >( );
for ( Map.Entry< CacheKey , CacheData > entry : this.cache.entrySet( ) ) {
CacheData data = entry.getValue( );
data.timeLeft--;
if ( data.timeLeft < 0 ) {
toRemove.add( entry.getKey( ) );
}
}
for ( CacheKey key : toRemove ) {
this.cache.remove( key );
}
}
}
}

View file

@ -0,0 +1,47 @@
package com.deepclone.lw.beans.msgs;
import java.util.HashMap;
import java.util.Map;
import com.deepclone.lw.interfaces.msg.MessageFormatRegistry;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.EventRecord;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
public class MessageFormatRegistryBean
implements MessageFormatRegistry
{
private final Map< FormatType , MessageFormatter > formatters = new HashMap< FormatType , MessageFormatter >( );
@Override
public void addFormatter( MessageFormatter formatter )
{
for ( FormatType fmt : formatter.getFormats( ) ) {
if ( this.formatters.containsKey( fmt ) ) {
throw new IllegalArgumentException( "message formatter " + formatter.getClass( ) + " redefines format "
+ fmt.toString( ) );
}
this.formatters.put( fmt , formatter );
}
}
@Override
public MessageFormatter getFormatter( MessageDataRecord contents )
{
FormatType fmt;
if ( contents.isInternal( ) ) {
EventRecord evt = (EventRecord) contents;
fmt = new FormatType( evt.getType( ) , evt.getSubType( ) );
} else {
fmt = new FormatType( );
}
return this.formatters.get( fmt );
}
}

View file

@ -0,0 +1,62 @@
package com.deepclone.lw.beans.msgs;
import java.util.Collection;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import com.deepclone.lw.interfaces.msg.MessageFormatRegistry;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
public class MessageFormatWiringBean
implements BeanPostProcessor , ApplicationContextAware
{
private final Logger logger = Logger.getLogger( MessageFormatWiringBean.class );
private ApplicationContext context;
@Override
public void setApplicationContext( ApplicationContext applicationContext )
throws BeansException
{
this.context = applicationContext;
}
@Override
public Object postProcessAfterInitialization( Object bean , String beanName )
throws BeansException
{
if ( bean instanceof MessageFormatRegistry ) {
this.logger.debug( "Wiring message format registry" );
this.autowire( (MessageFormatRegistry) bean );
}
return bean;
}
@Override
public Object postProcessBeforeInitialization( Object bean , String beanName )
throws BeansException
{
return bean;
}
private void autowire( MessageFormatRegistry bean )
{
Collection< MessageFormatter > formatters;
formatters = this.context.getBeansOfType( MessageFormatter.class ).values( );
for ( MessageFormatter formatter : formatters ) {
this.logger.debug( "Adding formats " + formatter.getFormats( ) );
bean.addFormatter( formatter );
}
}
}

View file

@ -0,0 +1,328 @@
package com.deepclone.lw.beans.msgs;
import java.sql.ResultSet;
import java.sql.SQLException;
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.simple.SimpleJdbcTemplate;
import com.deepclone.lw.interfaces.msg.MessageRecordsDAO;
import com.deepclone.lw.sqld.msgs.*;
public class MessageRecordsDAOBean
implements MessageRecordsDAO
{
private static abstract class EventMapperBase< T extends EventRecord >
implements RowMapper< T >
{
protected void mapEvent( ResultSet rs , T event )
throws SQLException
{
event.setId( rs.getLong( "id" ) );
event.setType( EventType.valueOf( rs.getString( "evt_type" ) ) );
event.setSubType( rs.getInt( "evt_subtype" ) );
event.setTick( rs.getLong( "tick" ) );
event.setTimestamp( rs.getTimestamp( "real_time" ) );
}
}
private static final String sGetTextMessages = "SELECT * FROM msgs.text_messages WHERE id = ANY( ? ::BIGINT[] )";
private static final String sGetEventTypes = "SELECT event_id , evt_type FROM events.events WHERE event_id = ANY( ? ::BIGINT[] )";
private static final String sGetEventParts[] = {
"SELECT * FROM events." , "_events_view WHERE id = ANY( ? ::BIGINT[] )"
};
private static final String sGetQueueLocations = "SELECT * FROM events.queue_locations_view WHERE event_id = ANY( ? ::BIGINT[] )";
private static final String sGetEventFleets = "SELECT * FROM events.fleet_lists WHERE event_id = ANY( ? ::BIGINT[] )";
private SimpleJdbcTemplate dTemplate;
private final RowMapper< TextMessageRecord > mTextMessage;
private final RowMapper< EventTypeRecord > mEventTypes;
private final EventMapperBase< AdminEventRecord > mAdminEvent;
private final EventMapperBase< AllianceEventRecord > mAllianceEvent;
private final EventMapperBase< EmpireEventRecord > mEmpireEvent;
private final EventMapperBase< FleetEventRecord > mFleetEvent;
private final EventMapperBase< PlanetEventRecord > mPlanetEvent;
private final EventMapperBase< QueueEventRecord > mQueueEvent;
private final EventMapperBase< BugEventRecord > mBugEvent;
private final RowMapper< QueueEventLocation > mQueueLocation;
private final RowMapper< FleetEventFleet > mFleetList;
public MessageRecordsDAOBean( )
{
this.mTextMessage = new RowMapper< TextMessageRecord >( ) {
@Override
public TextMessageRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
TextMessageRecord tmr = new TextMessageRecord( );
tmr.setId( rs.getLong( "id" ) );
tmr.setTimestamp( rs.getTimestamp( "t" ) );
tmr.setTick( rs.getLong( "tick" ) );
tmr.setSubject( rs.getString( "title" ) );
tmr.setText( rs.getString( "contents" ) );
return tmr;
}
};
this.mEventTypes = new RowMapper< EventTypeRecord >( ) {
@Override
public EventTypeRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
EventTypeRecord etr = new EventTypeRecord( );
etr.setId( rs.getLong( "event_id" ) );
etr.setType( EventType.valueOf( rs.getString( "evt_type" ) ) );
return etr;
}
};
this.mAdminEvent = new EventMapperBase< AdminEventRecord >( ) {
@Override
public AdminEventRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
AdminEventRecord event = new AdminEventRecord( );
this.mapEvent( rs , event );
event.setWarnings( (Integer) rs.getObject( "n_warnings" ) );
event.setLocationId( (Integer) rs.getObject( "location_id" ) );
event.setOldName( rs.getString( "old_name" ) );
event.setNewName( rs.getString( "new_name" ) );
return event;
}
};
this.mAllianceEvent = new EventMapperBase< AllianceEventRecord >( ) {
@Override
public AllianceEventRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
AllianceEventRecord event = new AllianceEventRecord( );
this.mapEvent( rs , event );
event.setAllianceId( (Integer) rs.getObject( "alliance_id" ) );
event.setAllianceTag( rs.getString( "alliance_tag" ) );
event.setEmpireId( (Integer) rs.getObject( "empire_id" ) );
event.setEmpireName( rs.getString( "empire_name" ) );
event.setReqResult( (Boolean) rs.getObject( "req_result" ) );
return event;
}
};
this.mEmpireEvent = new EventMapperBase< EmpireEventRecord >( ) {
@Override
public EmpireEventRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
EmpireEventRecord event = new EmpireEventRecord( );
this.mapEvent( rs , event );
event.setTech( rs.getString( "technology" ) );
return event;
}
};
this.mFleetEvent = new EventMapperBase< FleetEventRecord >( ) {
@Override
public FleetEventRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
FleetEventRecord event = new FleetEventRecord( );
this.mapEvent( rs , event );
event.setLocationId( rs.getInt( "location_id" ) );
event.setLocationName( rs.getString( "location_name" ) );
event.setX( rs.getInt( "x" ) );
event.setY( rs.getInt( "y" ) );
event.setOrbit( rs.getInt( "orbit" ) );
return event;
}
};
this.mPlanetEvent = new EventMapperBase< PlanetEventRecord >( ) {
@Override
public PlanetEventRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
PlanetEventRecord event = new PlanetEventRecord( );
this.mapEvent( rs , event );
event.setLocationId( rs.getInt( "location_id" ) );
event.setLocationName( rs.getString( "location_name" ) );
event.setX( rs.getInt( "x" ) );
event.setY( rs.getInt( "y" ) );
event.setOrbit( rs.getInt( "orbit" ) );
event.setEmpireId( (Integer) rs.getObject( "empire_id" ) );
event.setEmpireName( rs.getString( "empire_name" ) );
event.setBattleId( (Long) rs.getObject( "battle_id" ) );
return event;
}
};
this.mQueueEvent = new EventMapperBase< QueueEventRecord >( ) {
@Override
public QueueEventRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
QueueEventRecord event = new QueueEventRecord( );
this.mapEvent( rs , event );
return event;
}
};
this.mBugEvent = new EventMapperBase< BugEventRecord >( ) {
@Override
public BugEventRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
BugEventRecord event = new BugEventRecord( );
this.mapEvent( rs , event );
event.setReportId( rs.getLong( "bug_id" ) );
event.setAdmin( rs.getBoolean( "submitter_admin" ) );
event.setSubmitter( rs.getString( "submitter_name" ) );
return event;
}
};
this.mQueueLocation = new RowMapper< QueueEventLocation >( ) {
@Override
public QueueEventLocation mapRow( ResultSet rs , int rowNum )
throws SQLException
{
QueueEventLocation loc = new QueueEventLocation( );
loc.setEventId( rs.getLong( "event_id" ) );
loc.setLocationId( rs.getInt( "location_id" ) );
loc.setLocationName( rs.getString( "location_name" ) );
loc.setX( rs.getInt( "x" ) );
loc.setY( rs.getInt( "y" ) );
loc.setOrbit( rs.getInt( "orbit" ) );
return loc;
}
};
this.mFleetList = new RowMapper< FleetEventFleet >( ) {
@Override
public FleetEventFleet mapRow( ResultSet rs , int rowNum )
throws SQLException
{
FleetEventFleet fleet = new FleetEventFleet( );
fleet.setEventId( rs.getLong( "event_id" ) );
fleet.setOwnerId( (Integer) rs.getObject( "owner_id" ) );
fleet.setOwnerName( rs.getString( "owner_name" ) );
fleet.setFleetName( rs.getString( "fleet_name" ) );
fleet.setFleetPower( rs.getLong( "fleet_power" ) );
fleet.setStatus( (Boolean) rs.getObject( "status" ) );
fleet.setSourceId( (Integer) rs.getObject( "source_id" ) );
fleet.setSourceName( rs.getString( "source_name" ) );
return fleet;
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
}
private String getIdArray( List< Long > ids )
{
StringBuilder iArray = new StringBuilder( ).append( "{" );
int i = 0;
int s = ids.size( );
for ( Long id : ids ) {
iArray.append( id );
if ( i != s - 1 ) {
iArray.append( "," );
}
i++;
}
iArray.append( "}" );
return iArray.toString( );
}
@Override
public List< TextMessageRecord > getTextMessages( List< Long > ids )
{
return this.dTemplate.query( sGetTextMessages , mTextMessage , this.getIdArray( ids ) );
}
@Override
public List< EventTypeRecord > getEventTypes( List< Long > ids )
{
return this.dTemplate.query( sGetEventTypes , mEventTypes , this.getIdArray( ids ) );
}
@Override
@SuppressWarnings( "unchecked" )
public List< EventRecord > getEvents( EventType type , List< Long > ids )
{
String query = sGetEventParts[ 0 ] + type.toString( ).toLowerCase( ) + sGetEventParts[ 1 ];
EventMapperBase< ? > mapper;
switch ( type ) {
case ADMIN:
mapper = this.mAdminEvent;
break;
case ALLIANCE:
mapper = this.mAllianceEvent;
break;
case EMPIRE:
mapper = this.mEmpireEvent;
break;
case FLEETS:
mapper = this.mFleetEvent;
break;
case PLANET:
mapper = this.mPlanetEvent;
break;
case QUEUE:
mapper = this.mQueueEvent;
break;
case BUGS:
mapper = this.mBugEvent;
break;
default:
throw new RuntimeException( "unsupported event type " + type );
}
String idArray = this.getIdArray( ids );
List< EventRecord > result = (List< EventRecord >) this.dTemplate.query( query , mapper , idArray );
if ( type == EventType.FLEETS ) {
this.getFleetDetails( idArray , result );
} else if ( type == EventType.QUEUE ) {
this.getQueueDetails( idArray , result );
}
return result;
}
private void getFleetDetails( String idArray , List< EventRecord > result )
{
Map< Long , FleetEventRecord > records = new HashMap< Long , FleetEventRecord >( );
for ( EventRecord e : result ) {
records.put( e.getId( ) , (FleetEventRecord) e );
}
List< FleetEventFleet > fleets = this.dTemplate.query( sGetEventFleets , mFleetList , idArray );
for ( FleetEventFleet fleet : fleets ) {
records.get( fleet.getEventId( ) ).addFleet( fleet );
}
}
private void getQueueDetails( String idArray , List< EventRecord > result )
{
Map< Long , QueueEventRecord > records = new HashMap< Long , QueueEventRecord >( );
for ( EventRecord e : result ) {
records.put( e.getId( ) , (QueueEventRecord) e );
}
List< QueueEventLocation > locations = this.dTemplate.query( sGetQueueLocations , mQueueLocation , idArray );
for ( QueueEventLocation l : locations ) {
records.get( l.getEventId( ) ).addLocation( l );
}
}
}

View file

@ -0,0 +1,130 @@
package com.deepclone.lw.beans.msgs;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.PlatformTransactionManager;
import com.deepclone.lw.interfaces.eventlog.Logger;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.interfaces.msg.MessageBoxDAO;
import com.deepclone.lw.interfaces.msg.MessageContentCache;
import com.deepclone.lw.interfaces.msg.MessageFormatRegistry;
import com.deepclone.lw.interfaces.msg.NotificationsDAO;
import com.deepclone.lw.interfaces.sys.Ticker;
import com.deepclone.lw.interfaces.sys.Ticker.Frequency;
public class MessageTasksBean
implements InitializingBean , DisposableBean
{
private Ticker ticker;
private Logger logger;
private PlatformTransactionManager tManager;
private NotificationsDAO notificationsDao;
private MessageContentCache contents;
private MessageFormatRegistry formats;
private Translator translator;
private Mailer mailer;
private MessageCleanerBean cleaner;
private MessageBoxDAO mboxDao;
private Runnable notificationsTask;
private Runnable recapsTask;
@Autowired( required = true )
public void setTicker( Ticker ticker )
{
this.ticker = ticker;
}
@Autowired( required = true )
public void setLogger( Logger logger )
{
this.logger = logger;
}
@Autowired( required = true )
public void setTransactionManager( PlatformTransactionManager tManager )
{
this.tManager = tManager;
}
@Autowired( required = true )
public void setNotificationsDao( NotificationsDAO notificationsDao )
{
this.notificationsDao = notificationsDao;
}
@Autowired( required = true )
public void setContents( MessageContentCache contents )
{
this.contents = contents;
}
@Autowired( required = true )
public void setFormats( MessageFormatRegistry formats )
{
this.formats = formats;
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Autowired( required = true )
public void setMailer( Mailer mailer )
{
this.mailer = mailer;
}
@Autowired( required = true )
public void setCleaner( MessageCleanerBean cleaner )
{
this.cleaner = cleaner;
}
@Autowired( required = true )
public void setMboxDao( MessageBoxDAO mboxDao )
{
this.mboxDao = mboxDao;
}
@Override
public void afterPropertiesSet( )
{
this.notificationsTask = new NotificationsTask( this.logger , this.tManager , this.notificationsDao ,
this.contents , this.formats , this.translator , this.mailer , this.cleaner );
this.ticker.registerTask( Frequency.MEDIUM , "Instant notifications" , this.notificationsTask );
this.recapsTask = new RecapitulationTask( this.logger , this.tManager , this.notificationsDao , this.contents ,
this.formats , this.translator , this.mailer , this.cleaner , this.mboxDao );
this.ticker.registerTask( Frequency.LOW , "Message recaps/clean-up" , this.recapsTask );
}
@Override
public void destroy( )
{
this.notificationsTask = null;
this.recapsTask = null;
}
}

View file

@ -0,0 +1,168 @@
package com.deepclone.lw.beans.msgs;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.LinkedList;
import java.util.List;
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.msg.NotificationsDAO;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.NotificationsRecord;
import com.deepclone.lw.utils.StoredProc;
public class NotificationsDAOBean
implements NotificationsDAO
{
private static final String sGetInstantNotifications = "SELECT * FROM msgs.get_mail_data() WHERE last_unmailed IS NOT NULL";
private static final String sGetRecapNotifications = "SELECT * FROM msgs.get_mail_data() WHERE last_unrecaped IS NOT NULL";
private SimpleJdbcTemplate dTemplate;
private final RowMapper< NotificationsRecord > mNotifications;
private RowMapper< InboxRecord > mList;
private StoredProc fMarkInstantMessages;
private StoredProc fMarkRecap;
public NotificationsDAOBean( )
{
this.mNotifications = new RowMapper< NotificationsRecord >( ) {
@Override
public NotificationsRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
NotificationsRecord nr = new NotificationsRecord( );
nr.setId( rs.getInt( "empire" ) );
nr.setName( rs.getString( "empire_name" ) );
nr.setLanguage( rs.getString( "language" ) );
nr.setAddress( rs.getString( "address" ) );
nr.setOnPrivate( rs.getString( "on_private" ) );
nr.setOnInternal( rs.getString( "on_internal" ) );
nr.setOnAlliance( rs.getString( "on_alliance" ) );
nr.setOnAdmin( rs.getString( "on_admin" ) );
nr.setLastUnmailed( (Long) rs.getObject( "last_unmailed" ) );
nr.setLastUnrecaped( (Long) rs.getObject( "last_unrecaped" ) );
nr.setCanNotify( rs.getBoolean( "can_notify" ) );
return nr;
}
};
this.mList = new RowMapper< InboxRecord >( ) {
@Override
public InboxRecord mapRow( ResultSet rs , int rowNum )
throws SQLException
{
InboxRecord iRec = new InboxRecord( );
iRec.setId( rs.getLong( "id" ) );
iRec.setSenderType( rs.getString( "sender_type" ) );
iRec.setSenderId( (Integer) rs.getObject( "sender_id" ) );
iRec.setSenderName( rs.getString( "sender_name" ) );
iRec.setReceiverType( rs.getString( "receiver_type" ) );
iRec.setReceiverId( rs.getInt( "receiver_id" ) );
iRec.setReceiverName( rs.getString( "receiver_name" ) );
iRec.setInternal( rs.getBoolean( "internal_message" ) );
iRec.setReceived( rs.getTimestamp( "r_time" ) );
iRec.setContentId( rs.getLong( "content_id" ) );
return iRec;
}
};
}
@Autowired( required = true )
public void setDataSource( DataSource dataSource )
{
this.dTemplate = new SimpleJdbcTemplate( dataSource );
this.fMarkInstantMessages = new StoredProc( dataSource , "msgs" , "mark_instant_notifications" );
this.fMarkInstantMessages.addParameter( "empire_id" , Types.INTEGER );
this.fMarkInstantMessages.addParameter( "message_id" , Types.BIGINT );
this.fMarkInstantMessages.addParameter( "sending" , Types.BOOLEAN );
this.fMarkRecap = new StoredProc( dataSource , "msgs" , "mark_recaps" );
this.fMarkRecap.addParameter( "empire_id" , Types.INTEGER );
this.fMarkRecap.addParameter( "message_id" , Types.BIGINT );
}
@Override
public boolean isRecapTime( )
{
String sql = "SELECT msgs.is_recap_time() AS recap";
return (Boolean) this.dTemplate.queryForMap( sql ).get( "recap" );
}
@Override
public List< NotificationsRecord > getNotificationRecords( boolean instant )
{
String sql = instant ? sGetInstantNotifications : sGetRecapNotifications;
return this.dTemplate.query( sql , this.mNotifications );
}
@Override
public List< InboxRecord > listMessages( int empireId , long maxId , boolean instant , boolean nPrivate ,
boolean nInternal , boolean nAlliance , boolean nAdmin )
{
List< InboxRecord > result;
if ( nPrivate || nInternal || nAlliance || nAdmin ) {
String sql = "SELECT * FROM msgs.empire_" + ( instant ? "instant" : "recap" );
sql += " WHERE empire_id = ? AND id <= ?";
if ( ! ( nPrivate && nInternal && nAlliance && nAdmin ) ) {
sql += " AND (";
if ( nPrivate ) {
sql += "( sender_type = 'EMP' AND receiver_type='EMP' )";
}
if ( nInternal ) {
if ( nPrivate ) {
sql += " OR ";
}
sql += "sender_type = 'INT'";
}
if ( nAlliance ) {
if ( nPrivate || nInternal ) {
sql += " OR ";
}
sql += "receiver_type = 'ALL'";
}
if ( nAdmin ) {
if ( nPrivate || nInternal || nAlliance ) {
sql += " OR ";
}
sql += "sender_type = 'ADM'";
}
sql += ")";
}
result = this.dTemplate.query( sql , this.mList , empireId , maxId );
} else {
result = new LinkedList< InboxRecord >( );
}
if ( instant ) {
this.fMarkInstantMessages.execute( empireId , maxId , !result.isEmpty( ) );
} else {
this.fMarkRecap.execute( empireId , maxId );
}
return result;
}
@Override
public void cleanupMessages( )
{
this.dTemplate.getJdbcOperations( ).execute( "SELECT msgs.cleanup( )" );
}
}

View file

@ -0,0 +1,97 @@
package com.deepclone.lw.beans.msgs;
import org.springframework.transaction.PlatformTransactionManager;
import com.deepclone.lw.cmd.admin.logs.LogLevel;
import com.deepclone.lw.cmd.msgdata.Message;
import com.deepclone.lw.cmd.msgdata.MessageType;
import com.deepclone.lw.interfaces.eventlog.Logger;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.mailer.MailData;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.interfaces.mailer.MailerException;
import com.deepclone.lw.interfaces.msg.MessageContentCache;
import com.deepclone.lw.interfaces.msg.MessageFormatRegistry;
import com.deepclone.lw.interfaces.msg.NotificationsDAO;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.NotificationsRecord;
class NotificationsTask
extends MailTaskBase
{
public NotificationsTask( Logger logger , PlatformTransactionManager tManager , NotificationsDAO notificationsDao ,
MessageContentCache contents , MessageFormatRegistry formats , Translator translator , Mailer mailer ,
MessageCleanerBean cleaner )
{
super( logger , tManager , notificationsDao , contents , formats , translator , mailer , cleaner , true );
}
protected void notify( NotificationsRecord notification )
{
boolean nPrivate = "INSTANT".equals( notification.getOnPrivate( ) ) && notification.isCanNotify( );
boolean nInternal = "INSTANT".equals( notification.getOnInternal( ) ) && notification.isCanNotify( );
boolean nAlliance = "INSTANT".equals( notification.getOnAlliance( ) ) && notification.isCanNotify( );
boolean nAdmin = "INSTANT".equals( notification.getOnAdmin( ) ) && notification.isCanNotify( );
MessageData toSend = this.getMessagesToSend( notification.getId( ) , notification.getLastUnmailed( ) ,
nPrivate , nInternal , nAlliance , nAdmin );
if ( toSend.messages.isEmpty( ) ) {
return;
}
this.logger.log( LogLevel.DEBUG , "Processing messages for empire " + notification.getName( ) );
this.processMessages( notification , toSend );
}
private void processMessages( NotificationsRecord notification , MessageData toSend )
{
StringBuilder buffer = new StringBuilder( );
String lang = notification.getLanguage( );
String template = this.translate( "instantNotification" , lang );
int empireId = notification.getId( );
for ( InboxRecord record : toSend.messages ) {
Message message = this.readMessage( empireId , lang , record , toSend.data.get( record.getId( ) ) , true );
this.outputMessage( buffer , template , message );
}
MailData mailData;
try {
mailData = this.mailer.createMail( lang , "messageMail" , notification.getAddress( ) );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
mailData.setData( "empire" , notification.getName( ) );
mailData.setData( "messages" , buffer.toString( ) );
try {
mailData.queue( );
} catch ( MailerException e ) {
throw new RuntimeException( e );
}
}
private void outputMessage( StringBuilder buffer , String template , Message message )
{
String data = template.replace( "${from}" , message.getSender( ) );
data = data.replace( "${to}" , message.getReceiver( ) );
if ( message.getType( ) == MessageType.INTERNAL ) {
data = data.replace( "${subject}" , message.getTitle( ) );
data = data.replace( "${text}" , this.cleaner.removeInternals( message.getContents( ) ) );
} else {
data = data.replace( "${subject}" , this.cleaner.cleanMessage( message.getTitle( ) ) );
data = data.replace( "${text}" , this.cleaner.cleanMessage( message.getContents( ) ) );
}
buffer.append( data );
}
}

View file

@ -0,0 +1,173 @@
package com.deepclone.lw.beans.msgs;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallback;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import com.deepclone.lw.cmd.admin.logs.LogLevel;
import com.deepclone.lw.cmd.msgdata.Message;
import com.deepclone.lw.cmd.msgdata.MessageType;
import com.deepclone.lw.interfaces.eventlog.Logger;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.mailer.MailData;
import com.deepclone.lw.interfaces.mailer.Mailer;
import com.deepclone.lw.interfaces.mailer.MailerException;
import com.deepclone.lw.interfaces.msg.MessageBoxDAO;
import com.deepclone.lw.interfaces.msg.MessageContentCache;
import com.deepclone.lw.interfaces.msg.MessageFormatRegistry;
import com.deepclone.lw.interfaces.msg.NotificationsDAO;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.NotificationsRecord;
class RecapitulationTask
extends MailTaskBase
{
private MessageBoxDAO mboxDao;
public RecapitulationTask( Logger logger , PlatformTransactionManager tManager , NotificationsDAO notificationsDao ,
MessageContentCache contents , MessageFormatRegistry formats , Translator translator , Mailer mailer ,
MessageCleanerBean cleaner , MessageBoxDAO mbox )
{
super( logger , tManager , notificationsDao , contents , formats , translator , mailer , cleaner , false );
this.mboxDao = mbox;
}
@Override
public void run( )
{
if ( this.isTime( ) ) {
super.run( );
}
this.cleanup( );
this.contents.clearCache( );
this.mboxDao.clearCache( );
}
private void cleanup( )
{
this.tTemplate.execute( new TransactionCallbackWithoutResult( ) {
@Override
protected void doInTransactionWithoutResult( TransactionStatus status )
{
notificationsDao.cleanupMessages( );
}
} );
}
private boolean isTime( )
{
return this.tTemplate.execute( new TransactionCallback< Boolean >( ) {
@Override
public Boolean doInTransaction( TransactionStatus status )
{
return notificationsDao.isRecapTime( );
}
} );
}
protected void notify( NotificationsRecord notification )
{
boolean nPrivate = "DAILY_RECAP".equals( notification.getOnPrivate( ) );
boolean nInternal = "DAILY_RECAP".equals( notification.getOnInternal( ) );
boolean nAlliance = "DAILY_RECAP".equals( notification.getOnAlliance( ) );
boolean nAdmin = "DAILY_RECAP".equals( notification.getOnAdmin( ) );
MessageData toSend = this.getMessagesToSend( notification.getId( ) , notification.getLastUnrecaped( ) ,
nPrivate , nInternal , nAlliance , nAdmin );
if ( toSend.messages.isEmpty( ) ) {
return;
}
this.logger.log( LogLevel.DEBUG , "Processing messages for empire " + notification.getName( ) );
this.processMessages( notification , toSend );
}
private void processMessages( NotificationsRecord notification , MessageData toSend )
{
String lang = notification.getLanguage( );
Map< MessageType , List< Message > > messages = new HashMap< MessageType , List< Message > >( );
for ( MessageType type : MessageType.values( ) ) {
messages.put( type , new LinkedList< Message >( ) );
}
int empireId = notification.getId( );
for ( InboxRecord record : toSend.messages ) {
Message message = this.readMessage( empireId , lang , record , toSend.data.get( record.getId( ) ) , false );
messages.get( message.getType( ) ).add( message );
}
StringBuilder body = new StringBuilder( );
String template = this.translate( "recapsMessage" , lang );
for ( MessageType type : MessageType.values( ) ) {
List< Message > tMessages = messages.get( type );
if ( tMessages.isEmpty( ) ) {
continue;
}
StringBuilder typeList = new StringBuilder( );
typeList.append( this.getTypeTitle( type , lang ) ).append( "\n\n" );
for ( Message message : tMessages ) {
typeList.append( this.outputMessage( template , message ) ).append( "\n" );
}
body.append( typeList ).append( "\n" );
}
MailData mailData;
try {
mailData = this.mailer.createMail( lang , "recapMail" , notification.getAddress( ) );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
mailData.setData( "empire" , notification.getName( ) );
mailData.setData( "messages" , body.toString( ) );
try {
mailData.queue( );
} catch ( MailerException e ) {
throw new RuntimeException( e );
}
}
private String getTypeTitle( MessageType type , String lang )
{
String tString = type.toString( );
return this.translate( "recaps" + tString.substring( 0 , 1 ) + tString.substring( 1 ).toLowerCase( ) , lang );
}
private String outputMessage( String template , Message message )
{
String data = template.replace( "${from}" , message.getSender( ) );
if ( message.getType( ) == MessageType.INTERNAL ) {
data = data.replace( "${subject}" , message.getTitle( ) );
} else {
data = data.replace( "${subject}" , this.cleaner.cleanMessage( message.getTitle( ) ) );
}
SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss Z" );
data = data.replace( "${time}" , dateFormat.format( message.getTime( ) ) );
return data;
}
}

View file

@ -0,0 +1,100 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
import com.deepclone.lw.sqld.msgs.PlanetEventRecord;
@Component
public class AbandonMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class AbandonMessageExtractor
extends PlanetMessageExtractor
{
private String mTitle;
private String mBody;
private String mSource;
public AbandonMessageExtractor( PlanetEventRecord event , String mTitle , String mBody , String mSource )
{
super(event);
this.mTitle = mTitle;
this.mBody = mBody;
this.mSource = mSource;
}
@Override
public String getContents( )
{
return this.mBody.replace( "${location}" , this.getLocation( ) );
}
@Override
public String getSender( )
{
return this.mSource;
}
@Override
public String getSubject( )
{
return this.mTitle.replace( "${location}" , this.event.getLocationName( ) );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.PLANET , 5 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
PlanetEventRecord event = (PlanetEventRecord) contents;
String mTitle , mBody , mSource;
try {
mTitle = this.translator.translate( language , "imtAbandonPlanet" );
mBody = this.translator.translate( language , "imAbandonPlanet" );
mSource = this.translator.translate( language , "imSenderEco" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new AbandonMessageExtractor( event , mTitle , mBody , mSource );
}
}

View file

@ -0,0 +1,87 @@
package com.deepclone.lw.beans.msgs.fmt;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.sqld.msgs.AdminEventRecord;
public class AdminMessageExtractor
implements MessageExtractor
{
private Translator translator;
private String language;
private AdminEventRecord event;
private String eType;
private String translate( String what )
{
try {
return this.translator.translate( this.language , what );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
}
public AdminMessageExtractor( AdminEventRecord event , Translator translator , String language )
{
this.event = event;
this.translator = translator;
this.language = language;
switch ( this.event.getSubType( ) ) {
case 0:
this.eType = "Planet";
break;
case 1:
this.eType = "Empire";
break;
case 2:
this.eType = "Alliance";
break;
default:
throw new RuntimeException( "unsupported event sub-type " + this.event.getSubType( ) );
}
}
@Override
public String getSender( )
{
return this.translate( "imSenderAdmin" );
}
@Override
public String getSubject( )
{
String s = this.translate( "imtAdmin" + this.eType ).replace( "${oldName}" , this.event.getOldName( ) );
if ( this.event.getNewName( ) != null ) {
s = s.replace( "${newName}" , this.event.getNewName( ) );
}
return s;
}
@Override
public String getContents( )
{
String s = this.translate( "imAdmin" + this.eType ).replace( "${oldName}" , this.event.getOldName( ) );
if ( this.event.getNewName( ) != null ) {
s = s.replace( "${newName}" , this.event.getNewName( ) );
}
if ( this.event.getLocationId( ) != null ) {
s = s.replace( "${locationId}" , this.event.getLocationId( ).toString( ) );
}
if ( this.event.getWarnings( ) != null ) {
s += "\n\n";
s += this.translate( "imAdminWarning" ).replace( "${warnings}" , this.event.getWarnings( ).toString( ) );
}
return s;
}
}

View file

@ -0,0 +1,52 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.AdminEventRecord;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class AdminMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.ADMIN , 0 ) );
fmts.add( new FormatType( EventType.ADMIN , 1 ) );
fmts.add( new FormatType( EventType.ADMIN , 2 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
return new AdminMessageExtractor( (AdminEventRecord) contents , this.translator , language );
}
}

View file

@ -0,0 +1,85 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.AllianceEventRecord;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class AllianceDisbandedMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class AllianceDisbandedMessageExtractor
extends AllianceMessageExtractor
{
public AllianceDisbandedMessageExtractor( AllianceEventRecord event , String mTitle , String mBody )
{
super( event , mTitle , mBody );
}
@Override
public String getSubject( )
{
return this.mTitle;
}
@Override
public String getContents( )
{
return this.mBody;
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.ALLIANCE , 5 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
AllianceEventRecord event = (AllianceEventRecord) contents;
String mTitle , mBody;
try {
mTitle = this.translator.translate( language , "imtAllianceDisbanded" );
mBody = this.translator.translate( language , "imAllianceDisbanded" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new AllianceDisbandedMessageExtractor( event , mTitle , mBody );
}
}

View file

@ -0,0 +1,32 @@
package com.deepclone.lw.beans.msgs.fmt;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.sqld.msgs.AllianceEventRecord;
abstract class AllianceMessageExtractor
implements MessageExtractor
{
protected AllianceEventRecord event;
protected String mTitle;
protected String mBody;
protected AllianceMessageExtractor( AllianceEventRecord event , String mTitle , String mBody )
{
this.event = event;
this.mTitle = mTitle;
this.mBody = mBody;
}
@Override
public String getSender( )
{
return "[" + event.getAllianceTag( ) + "]";
}
}

View file

@ -0,0 +1,104 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
import com.deepclone.lw.sqld.msgs.PlanetEventRecord;
@Component
public class BattleMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class BattleMessageExtractor
extends PlanetMessageExtractor
{
private String mTitle;
private String mBody;
private String mSource;
public BattleMessageExtractor( PlanetEventRecord event , String mTitle , String mBody , String mSource )
{
super( event );
this.mTitle = mTitle;
this.mBody = mBody;
this.mSource = mSource;
}
@Override
public String getContents( )
{
String locLink = this.getLocation( );
return this.mBody.replace( "${battleId}" , this.event.getBattleId( ).toString( ) ).replace( "${location}" ,
locLink );
}
@Override
public String getSender( )
{
return this.mSource;
}
@Override
public String getSubject( )
{
return this.mTitle.replace( "${location}" , this.event.getLocationName( ) );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.PLANET , 0 ) );
fmts.add( new FormatType( EventType.PLANET , 1 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
PlanetEventRecord event = (PlanetEventRecord) contents;
boolean isEnd = ( event.getSubType( ) == 1 );
String mTitle , mBody , mSource;
try {
mTitle = this.translator.translate( language , "imtBattle" + ( isEnd ? "End" : "Start" ) );
mBody = this.translator.translate( language , "imBattle" + ( isEnd ? "End" : "Start" ) );
mSource = this.translator.translate( language , "imSenderWar" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new BattleMessageExtractor( event , mTitle , mBody , mSource );
}
}

View file

@ -0,0 +1,103 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.BugEventRecord;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class BugMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class BugMessageExtractor
implements MessageExtractor
{
private BugEventRecord event;
private String mTitle;
private String mBody;
private String mSource;
public BugMessageExtractor( BugEventRecord event , String mTitle , String mBody , String mSource )
{
this.event = event;
this.mTitle = mTitle;
this.mBody = mBody;
this.mSource = mSource;
}
@Override
public String getContents( )
{
String bug = "{{bug:" + this.event.getReportId( ) + "}}";
return this.mBody.replace( "${bug}" , bug ).replace( "${submitter}" , this.event.getSubmitter( ) );
}
@Override
public String getSender( )
{
return this.mSource;
}
@Override
public String getSubject( )
{
return this.mTitle.replace( "${id}" , ( (Long) this.event.getReportId( ) ).toString( ) );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.BUGS , 0 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
BugEventRecord event = (BugEventRecord) contents;
String suffix = event.isAdmin( ) ? "Admin" : "Empire";
String mTitle , mBody , mSource;
try {
mTitle = this.translator.translate( language , "imtBugReportUpdate" );
mBody = this.translator.translate( language , "imBugReportUpdate" + suffix );
mSource = this.translator.translate( language , "imSenderBugtracker" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new BugMessageExtractor( event , mTitle , mBody , mSource );
}
}

View file

@ -0,0 +1,101 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.EmpireEventRecord;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class DebtMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class DebtMessageExtractor
implements MessageExtractor
{
private String mTitle;
private String mBody;
private String mSource;
public DebtMessageExtractor( String mTitle , String mBody , String mSource )
{
this.mTitle = mTitle;
this.mBody = mBody;
this.mSource = mSource;
}
@Override
public String getContents( )
{
return this.mBody;
}
@Override
public String getSender( )
{
return this.mSource;
}
@Override
public String getSubject( )
{
return this.mTitle;
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.EMPIRE , 1 ) );
fmts.add( new FormatType( EventType.EMPIRE , 2 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
EmpireEventRecord event = (EmpireEventRecord) contents;
String type = ( event.getSubType( ) == 1) ? "Start" : "End";
String mTitle , mBody , mSource;
try {
mTitle = this.translator.translate( language , "imtDebt" + type );
mBody = this.translator.translate( language , "imDebt" + type );
mSource = this.translator.translate( language , "imSenderEco" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new DebtMessageExtractor( mTitle , mBody , mSource );
}
}

View file

@ -0,0 +1,75 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
import com.deepclone.lw.sqld.msgs.TextMessageRecord;
@Component
public class ExternalMessageFormatBean
implements MessageFormatter
{
static private class ExternalMessageExtractor
implements MessageExtractor
{
private InboxRecord inbox;
private TextMessageRecord message;
public ExternalMessageExtractor( InboxRecord inbox , TextMessageRecord message )
{
this.inbox = inbox;
this.message = message;
}
@Override
public String getContents( )
{
return message.getText( );
}
@Override
public String getSender( )
{
return inbox.getSenderName( );
}
@Override
public String getSubject( )
{
return message.getSubject( );
}
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
return new ExternalMessageExtractor( envelope , (TextMessageRecord) contents );
}
}

View file

@ -0,0 +1,190 @@
package com.deepclone.lw.beans.msgs.fmt;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.sqld.msgs.FleetEventFleet;
import com.deepclone.lw.sqld.msgs.FleetEventRecord;
public class FleetMessageExtractor
implements MessageExtractor
{
private FleetEventRecord event;
private Translator translator;
private String language;
private String eType;
private int empireId;
private String translate( String what )
{
try {
return this.translator.translate( this.language , what );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
}
public FleetMessageExtractor( int empireId , FleetEventRecord event , Translator translator , String language )
{
this.empireId = empireId;
this.event = event;
this.translator = translator;
this.language = language;
switch ( this.event.getSubType( ) ) {
case 0:
this.eType = "Arrival";
break;
case 1:
this.eType = "Departure";
break;
case 2:
this.eType = "Switch";
break;
case 3:
this.eType = "ELSwitch";
break;
default:
throw new RuntimeException( "unsupported event sub-type " + this.event.getSubType( ) );
}
}
@Override
public String getSender( )
{
return this.translate( "imSenderWar" );
}
@Override
public String getSubject( )
{
return this.translate( "imtFleet" + this.eType ).replace( "${location}" , this.event.getLocationName( ) );
}
@Override
public String getContents( )
{
String body = this.translate( "imFleet" + this.eType );
String fList;
if ( this.event.getSubType( ) == 2 ) {
fList = this.makeSwitchList( );
} else if ( this.event.getSubType( ) == 0 ) {
fList = this.makeArrivalList( );
} else {
fList = this.makeStandardList( );
}
String locLink = "{{planet:" + this.event.getLocationId( ) + " " + this.event.getLocationName( ) + "}} (";
locLink += this.event.getX( ) + "," + this.event.getY( ) + ";" + this.event.getOrbit( ) + ")";
return body.replace( "${location}" , locLink ) + fList;
}
private String makeStandardList( )
{
String namedOwn = this.translate( "imfOwnNamed" );
String unnamedOwn = this.translate( "imfOwnUnnamed" );
String namedFriendly = this.translate( "imfFriendlyNamed" );
String unnamedFriendly = this.translate( "imfFriendlyUnnamed" );
String namedHostile = this.translate( "imfHostileNamed" );
String unnamedHostile = this.translate( "imfHostileUnnamed" );
StringBuilder sBuilder = new StringBuilder( );
for ( FleetEventFleet fleet : this.event.getFleets( ) ) {
sBuilder.append( "\n* " );
String named , unnamed;
if ( fleet.getOwnerId( ) != null && fleet.getOwnerId( ) == this.empireId ) {
named = namedOwn;
unnamed = unnamedOwn;
} else if ( fleet.getStatus( ) == true ) {
named = namedHostile;
unnamed = unnamedHostile;
} else {
named = namedFriendly;
unnamed = unnamedFriendly;
}
sBuilder.append( this.fleetLine( fleet , named , unnamed ) );
}
return sBuilder.toString( );
}
private String makeArrivalList( )
{
String namedOwn = this.translate( "imfOwnNamed" );
String unnamedOwn = this.translate( "imfOwnUnnamed" );
String namedFriendly = this.translate( "imfFriendlyNamed" );
String unnamedFriendly = this.translate( "imfFriendlyUnnamed" );
String namedHostile = this.translate( "imfHostileNamed" );
String unnamedHostile = this.translate( "imfHostileUnnamed" );
String arrival = this.translate( "imfSource" );
StringBuilder sBuilder = new StringBuilder( );
for ( FleetEventFleet fleet : this.event.getFleets( ) ) {
sBuilder.append( "\n* " );
String named , unnamed;
if ( fleet.getOwnerId( ) != null && fleet.getOwnerId( ) == this.empireId ) {
named = namedOwn;
unnamed = unnamedOwn;
} else if ( fleet.getStatus( ) == true ) {
named = namedHostile;
unnamed = unnamedHostile;
} else {
named = namedFriendly;
unnamed = unnamedFriendly;
}
sBuilder.append( this.fleetLine( fleet , named , unnamed ) );
String source = "{{planet:" + fleet.getSourceId( ) + " " + fleet.getSourceName( ) + "}}";
sBuilder.append( arrival.replace( "${source}" , source ) );
}
return sBuilder.toString( );
}
private String makeSwitchList( )
{
String named = this.translate( "imfNamed" );
String unnamed = this.translate( "imfUnnamed" );
String toAttack = this.translate( "imfSwitchAttack" );
String toDefence = this.translate( "imfSwitchDefence" );
StringBuilder sBuilder = new StringBuilder( );
for ( FleetEventFleet fleet : this.event.getFleets( ) ) {
sBuilder.append( "\n* " );
sBuilder.append( this.fleetLine( fleet , named , unnamed ) );
sBuilder.append( fleet.getStatus( ) ? toAttack : toDefence );
}
return sBuilder.toString( );
}
private String fleetLine( FleetEventFleet fleet , String named , String unnamed )
{
String tmpl;
if ( fleet.getFleetName( ) == null ) {
tmpl = unnamed;
} else {
tmpl = named.replace( "${fleet}" , fleet.getFleetName( ) );
}
tmpl = tmpl.replace( "${power}" , ( (Long) fleet.getFleetPower( ) ).toString( ) );
String empLink;
if ( fleet.getOwnerId( ) == null ) {
empLink = fleet.getOwnerName( );
} else {
empLink = "{{empire:" + fleet.getOwnerId( ) + " " + fleet.getOwnerName( ) + "}}";
}
return tmpl.replace( "${owner}" , empLink );
}
}

View file

@ -0,0 +1,55 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FleetEventRecord;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class FleetMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.FLEETS , 0 ) );
fmts.add( new FormatType( EventType.FLEETS , 1 ) );
fmts.add( new FormatType( EventType.FLEETS , 2 ) );
fmts.add( new FormatType( EventType.FLEETS , 3 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
FleetEventRecord event = (FleetEventRecord) contents;
return new FleetMessageExtractor( envelope.getReceiverId( ) , event , this.translator , language );
}
}

View file

@ -0,0 +1,93 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.AllianceEventRecord;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class KickedMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class KickedMessageExtractor
extends AllianceMessageExtractor
{
public KickedMessageExtractor( AllianceEventRecord event , String mTitle , String mBody )
{
super( event , mTitle , mBody );
}
@Override
public String getSubject( )
{
return this.mTitle.replace( "${empire}" , this.event.getEmpireName( ) );
}
@Override
public String getContents( )
{
String empLink;
if ( this.event.getEmpireId( ) == null ) {
empLink = this.event.getEmpireName( );
} else {
empLink = "{{empire:" + this.event.getEmpireId( ) + " " + this.event.getEmpireName( ) + "}}";
}
return this.mBody.replace( "${empire}" , empLink ).replace( "${alliance}" ,
"[" + this.event.getAllianceTag( ) + "]" );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.ALLIANCE , 3 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
AllianceEventRecord event = (AllianceEventRecord) contents;
boolean self = ( event.getEmpireId( ) != null && event.getEmpireId( ) == envelope.getReceiverId( ) );
String mTitle , mBody;
try {
mTitle = this.translator.translate( language , "imtKicked" + ( self ? "Self" : "" ) );
mBody = this.translator.translate( language , "imKicked" + ( self ? "Self" : "" ) );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new KickedMessageExtractor( event , mTitle , mBody );
}
}

View file

@ -0,0 +1,91 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.AllianceEventRecord;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class LeadershipMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class LeadershipMessageExtractor
extends AllianceMessageExtractor
{
public LeadershipMessageExtractor( AllianceEventRecord event , String mTitle , String mBody )
{
super( event , mTitle , mBody );
}
@Override
public String getSubject( )
{
return this.mTitle;
}
@Override
public String getContents( )
{
String empLink;
if ( this.event.getEmpireId( ) == null ) {
empLink = this.event.getEmpireName( );
} else {
empLink = "{{empire:" + this.event.getEmpireId( ) + " " + this.event.getEmpireName( ) + "}}";
}
return this.mBody.replace( "${prevLeader}" , empLink );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.ALLIANCE , 2 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
AllianceEventRecord event = (AllianceEventRecord) contents;
String mTitle , mBody;
try {
mTitle = this.translator.translate( language , "imtLeaderChange" );
mBody = this.translator.translate( language , "imLeaderChange" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new LeadershipMessageExtractor( event , mTitle , mBody );
}
}

View file

@ -0,0 +1,91 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.AllianceEventRecord;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class LeftAllianceMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class LeftAllianceMessageExtractor
extends AllianceMessageExtractor
{
public LeftAllianceMessageExtractor( AllianceEventRecord event , String mTitle , String mBody )
{
super( event , mTitle , mBody );
}
@Override
public String getSubject( )
{
return this.mTitle.replace( "${empire}" , this.event.getEmpireName( ) );
}
@Override
public String getContents( )
{
String empLink;
if ( this.event.getEmpireId( ) == null ) {
empLink = this.event.getEmpireName( );
} else {
empLink = "{{empire:" + this.event.getEmpireId( ) + " " + this.event.getEmpireName( ) + "}}";
}
return this.mBody.replace( "${empire}" , empLink );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.ALLIANCE , 4 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
AllianceEventRecord event = (AllianceEventRecord) contents;
String mTitle , mBody;
try {
mTitle = this.translator.translate( language , "imtLeftAlliance" );
mBody = this.translator.translate( language , "imLeftAlliance" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new LeftAllianceMessageExtractor( event , mTitle , mBody );
}
}

View file

@ -0,0 +1,107 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
import com.deepclone.lw.sqld.msgs.PlanetEventRecord;
@Component
public class LostPlanetMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class LostPlanetMessageExtractor
extends PlanetMessageExtractor
{
private String mTitle;
private String mBody;
private String mSource;
public LostPlanetMessageExtractor( PlanetEventRecord event , String mTitle , String mBody , String mSource )
{
super( event );
this.mTitle = mTitle;
this.mBody = mBody;
this.mSource = mSource;
}
@Override
public String getContents( )
{
String locLink = this.getLocation( );
String empLink;
if ( this.event.getEmpireId( ) == null ) {
empLink = this.event.getEmpireName( );
} else {
empLink = "{{empire:" + this.event.getEmpireId( ) + " " + this.event.getEmpireName( ) + "}}";
}
return this.mBody.replace( "${location}" , locLink ).replace( "${taker}" , empLink );
}
@Override
public String getSender( )
{
return this.mSource;
}
@Override
public String getSubject( )
{
return this.mTitle.replace( "${location}" , this.event.getLocationName( ) );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.PLANET , 4 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
PlanetEventRecord event = (PlanetEventRecord) contents;
String mTitle , mBody , mSource;
try {
mTitle = this.translator.translate( language , "imtLostPlanet" );
mBody = this.translator.translate( language , "imLostPlanet" );
mSource = this.translator.translate( language , "imSenderWar" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new LostPlanetMessageExtractor( event , mTitle , mBody , mSource );
}
}

View file

@ -0,0 +1,91 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.AllianceEventRecord;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class PendingRequestMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class PendingRequestMessageExtractor
extends AllianceMessageExtractor
{
public PendingRequestMessageExtractor( AllianceEventRecord event , String mTitle , String mBody )
{
super( event , mTitle , mBody );
}
@Override
public String getSubject( )
{
return this.mTitle;
}
@Override
public String getContents( )
{
String empLink;
if ( this.event.getEmpireId( ) == null ) {
empLink = this.event.getEmpireName( );
} else {
empLink = "{{empire:" + this.event.getEmpireId( ) + " " + this.event.getEmpireName( ) + "}}";
}
return this.mBody.replace( "${empire}" , empLink );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.ALLIANCE , 0 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
AllianceEventRecord event = (AllianceEventRecord) contents;
String mTitle , mBody;
try {
mTitle = this.translator.translate( language , "imtPendingRequest" );
mBody = this.translator.translate( language , "imPendingRequest" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new PendingRequestMessageExtractor( event , mTitle , mBody );
}
}

View file

@ -0,0 +1,28 @@
package com.deepclone.lw.beans.msgs.fmt;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.sqld.msgs.PlanetEventRecord;
abstract class PlanetMessageExtractor
implements MessageExtractor
{
protected PlanetEventRecord event;
public PlanetMessageExtractor( PlanetEventRecord event )
{
this.event = event;
}
protected String getLocation( )
{
return "{{planet:" + this.event.getLocationId( ) + " " + this.event.getLocationName( ) + "}} ("
+ this.event.getX( ) + "," + this.event.getY( ) + ";" + this.event.getOrbit( ) + ")";
}
}

View file

@ -0,0 +1,168 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
import com.deepclone.lw.sqld.msgs.QueueEventLocation;
import com.deepclone.lw.sqld.msgs.QueueEventRecord;
@Component
public class QueueMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static abstract class QMEBase
implements MessageExtractor
{
public String formatLocation( QueueEventLocation location )
{
return "{{planet:" + location.getLocationId( ) + " " + location.getLocationName( ) + "}} ("
+ location.getX( ) + "," + location.getY( ) + ";" + location.getOrbit( ) + ")";
}
}
private static class QueuesMessageExtractor
extends QMEBase
{
private QueueEventRecord event;
private String mTitle;
private String mBody;
private String mSource;
public QueuesMessageExtractor( QueueEventRecord event , String mTitle , String mBody , String mSource )
{
this.event = event;
this.mTitle = mTitle;
this.mBody = mBody;
this.mSource = mSource;
}
@Override
public String getContents( )
{
StringBuilder sb = new StringBuilder( ).append( this.mBody );
for ( QueueEventLocation location : this.event.getLocations( ) ) {
sb.append( "\n* " ).append( this.formatLocation( location ) );
}
return sb.toString( );
}
@Override
public String getSender( )
{
return this.mSource;
}
@Override
public String getSubject( )
{
return this.mTitle;
}
}
private static class QueueMessageExtractor
extends QMEBase
{
private QueueEventRecord event;
private String mTitle;
private String mBody;
private String mSource;
public QueueMessageExtractor( QueueEventRecord event , String mTitle , String mBody , String mSource )
{
this.event = event;
this.mTitle = mTitle;
this.mBody = mBody;
this.mSource = mSource;
}
@Override
public String getContents( )
{
QueueEventLocation location = this.event.getLocations( ).get( 0 );
return this.mBody.replace( "${location}" , this.formatLocation( location ) );
}
@Override
public String getSender( )
{
return this.mSource;
}
@Override
public String getSubject( )
{
QueueEventLocation location = this.event.getLocations( ).get( 0 );
return this.mTitle.replace( "${location}" , location.getLocationName( ) );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.QUEUE , 0 ) );
fmts.add( new FormatType( EventType.QUEUE , 1 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
QueueEventRecord event = (QueueEventRecord) contents;
boolean isCiv = ( event.getSubType( ) == 0 );
boolean multi = ( event.getLocations( ).size( ) > 1 );
String mTitle , mBody , mSource;
try {
mTitle = this.translator.translate( language , "imtEmpty" + ( isCiv ? "Civ" : "Mil" ) + "Queue"
+ ( multi ? "s" : "" ) );
mBody = this.translator.translate( language , "imEmpty" + ( isCiv ? "Civ" : "Mil" ) + "Queue"
+ ( multi ? "s" : "" ) );
mSource = this.translator.translate( language , "imSender" + ( isCiv ? "Eco" : "War" ) );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
if ( multi ) {
return new QueuesMessageExtractor( event , mTitle , mBody , mSource );
}
return new QueueMessageExtractor( event , mTitle , mBody , mSource );
}
}

View file

@ -0,0 +1,86 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.AllianceEventRecord;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class RequestResultMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class PendingRequestMessageExtractor
extends AllianceMessageExtractor
{
public PendingRequestMessageExtractor( AllianceEventRecord event , String mTitle , String mBody )
{
super( event , mTitle , mBody );
}
@Override
public String getSubject( )
{
return this.mTitle;
}
@Override
public String getContents( )
{
return this.mBody.replace( "${alliance}" , "[" + this.event.getAllianceTag( ) + "]" );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.ALLIANCE , 1 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
AllianceEventRecord event = (AllianceEventRecord) contents;
String type = event.getReqResult( ) ? "Accepted" : "Rejected";
String mTitle , mBody;
try {
mTitle = this.translator.translate( language , "imtRequest" + type );
mBody = this.translator.translate( language , "imRequest" + type );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new PendingRequestMessageExtractor( event , mTitle , mBody );
}
}

View file

@ -0,0 +1,102 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
import com.deepclone.lw.sqld.msgs.PlanetEventRecord;
@Component
public class StrikeMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class StrikeMessageExtractor
extends PlanetMessageExtractor
{
private String mTitle;
private String mBody;
private String mSource;
public StrikeMessageExtractor( PlanetEventRecord event , String mTitle , String mBody , String mSource )
{
super( event );
this.mTitle = mTitle;
this.mBody = mBody;
this.mSource = mSource;
}
@Override
public String getContents( )
{
return this.mBody.replace( "${location}" , this.getLocation( ) );
}
@Override
public String getSender( )
{
return this.mSource;
}
@Override
public String getSubject( )
{
return this.mTitle.replace( "${location}" , this.event.getLocationName( ) );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.PLANET , 2 ) );
fmts.add( new FormatType( EventType.PLANET , 3 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
PlanetEventRecord event = (PlanetEventRecord) contents;
boolean isEnd = ( event.getSubType( ) == 3 );
String mTitle , mBody , mSource;
try {
mTitle = this.translator.translate( language , "imtStrike" + ( isEnd ? "End" : "Start" ) );
mBody = this.translator.translate( language , "imStrike" + ( isEnd ? "End" : "Start" ) );
mSource = this.translator.translate( language , "imSenderSec" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new StrikeMessageExtractor( event , mTitle , mBody , mSource );
}
}

View file

@ -0,0 +1,110 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
import com.deepclone.lw.sqld.msgs.PlanetEventRecord;
@Component
public class TakenPlanetMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class TakenPlanetMessageExtractor
extends PlanetMessageExtractor
{
private String mTitle;
private String mBody;
private String mSource;
public TakenPlanetMessageExtractor( PlanetEventRecord event , String mTitle , String mBody , String mSource )
{
super( event );
this.mTitle = mTitle;
this.mBody = mBody;
this.mSource = mSource;
}
@Override
public String getContents( )
{
String locLink = this.getLocation( );
String empLink;
if ( this.event.getEmpireName( ) == null ) {
empLink = "";
} else if ( this.event.getEmpireId( ) == null ) {
empLink = this.event.getEmpireName( );
} else {
empLink = "{{empire:" + this.event.getEmpireId( ) + " " + this.event.getEmpireName( ) + "}}";
}
return this.mBody.replace( "${location}" , locLink ).replace( "${owner}" , empLink );
}
@Override
public String getSender( )
{
return this.mSource;
}
@Override
public String getSubject( )
{
return this.mTitle.replace( "${location}" , this.event.getLocationName( ) );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.PLANET , 6 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
PlanetEventRecord event = (PlanetEventRecord) contents;
boolean neutral = ( event.getEmpireName( ) == null );
String mTitle , mBody , mSource;
try {
mTitle = this.translator.translate( language , "imtTakePlanet" );
mBody = this.translator.translate( language , "imTakePlanet" + ( neutral ? "Neutral" : "" ) );
mSource = this.translator.translate( language , "imSenderWar" );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new TakenPlanetMessageExtractor( event , mTitle , mBody , mSource );
}
}

View file

@ -0,0 +1,103 @@
package com.deepclone.lw.beans.msgs.fmt;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.deepclone.lw.interfaces.i18n.TranslationException;
import com.deepclone.lw.interfaces.i18n.Translator;
import com.deepclone.lw.interfaces.msg.MessageExtractor;
import com.deepclone.lw.interfaces.msg.MessageFormatter;
import com.deepclone.lw.sqld.msgs.EmpireEventRecord;
import com.deepclone.lw.sqld.msgs.EventType;
import com.deepclone.lw.sqld.msgs.FormatType;
import com.deepclone.lw.sqld.msgs.InboxRecord;
import com.deepclone.lw.sqld.msgs.MessageDataRecord;
@Component
public class TechMessageFormatterBean
implements MessageFormatter
{
private Translator translator;
private static class TechMessageExtractor
implements MessageExtractor
{
private String mTitle;
private String mBody;
private String mSource;
private String techName;
public TechMessageExtractor( String mTitle , String mBody , String mSource ,
String techName )
{
this.mTitle = mTitle;
this.mBody = mBody;
this.mSource = mSource;
this.techName = techName;
}
@Override
public String getContents( )
{
return this.mBody.replace( "${tech}" , this.techName );
}
@Override
public String getSender( )
{
return this.mSource;
}
@Override
public String getSubject( )
{
return this.mTitle.replace( "${tech}" , this.techName );
}
}
@Autowired( required = true )
public void setTranslator( Translator translator )
{
this.translator = translator;
}
@Override
public Set< FormatType > getFormats( )
{
Set< FormatType > fmts = new HashSet< FormatType >( );
fmts.add( new FormatType( EventType.EMPIRE , 0 ) );
return fmts;
}
@Override
public MessageExtractor getExtractor( InboxRecord envelope , MessageDataRecord contents , String language )
{
EmpireEventRecord event = (EmpireEventRecord) contents;
String mTitle , mBody , mSource , techName;
try {
mTitle = this.translator.translate( language , "imtTechAvailable" );
mBody = this.translator.translate( language , "imTechAvailable" );
mSource = this.translator.translate( language , "imSenderSci" );
techName = this.translator.translate( language , event.getTech( ) );
} catch ( TranslationException e ) {
throw new RuntimeException( e );
}
return new TechMessageExtractor( mTitle , mBody , mSource , techName );
}
}

View file

@ -0,0 +1,138 @@
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( );
}
}

View file

@ -0,0 +1,43 @@
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" );
}
}

View file

@ -0,0 +1,22 @@
<?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="simple/alliance-dao-bean.xml" />
<import resource="simple/alliance-management-bean.xml" />
<import resource="simple/battle-data-beans.xml" />
<import resource="simple/empire-dao-bean.xml" />
<import resource="simple/empire-management-bean.xml" />
<import resource="simple/fleet-management-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/message-beans.xml" />
<import resource="simple/planet-dao-bean.xml" />
<import resource="simple/planets-management-bean.xml" />
<import resource="simple/universe-dao-bean.xml" />
<import resource="simple/universe-generator-bean.xml" />
<import resource="simple/updates-dao-bean.xml" />
</beans>

View file

@ -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="allianceDAO" class="com.deepclone.lw.beans.empire.AllianceDAOBean" />
</beans>

View file

@ -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="allianceManagement" class="com.deepclone.lw.beans.empire.AllianceManagementBean" />
</beans>

View file

@ -0,0 +1,10 @@
<?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="battlesDao" class="com.deepclone.lw.beans.fleets.BattlesDAOBean" />
<bean id="battlesCache" class="com.deepclone.lw.beans.fleets.BattlesCacheBean" />
<bean id="battleViewer" class="com.deepclone.lw.beans.fleets.BattleViewerBean" />
</beans>

View file

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

View file

@ -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="empireManagement" class="com.deepclone.lw.beans.empire.EmpireManagementBean" />
</beans>

View file

@ -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="fleetManagement" class="com.deepclone.lw.beans.fleets.FleetManagementBean" />
</beans>

View file

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

View file

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

View file

@ -0,0 +1,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="mapViewer" class="com.deepclone.lw.beans.map.MapViewerBean" />
</beans>

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- DAOs -->
<bean id="messageBoxDao" class="com.deepclone.lw.beans.msgs.MessageBoxDAOBean" />
<bean id="messageRecordsDao" class="com.deepclone.lw.beans.msgs.MessageRecordsDAOBean" />
<!-- Caching and formatting -->
<bean id="messageContentCache" class="com.deepclone.lw.beans.msgs.MessageContentCacheBean" />
<bean id="messageFormatRegistry" class="com.deepclone.lw.beans.msgs.MessageFormatRegistryBean" />
<bean id="messageFormatWiring" class="com.deepclone.lw.beans.msgs.MessageFormatWiringBean" />
<!-- Message formatters -->
<context:annotation-config />
<context:component-scan base-package="com.deepclone.lw.beans.msgs.fmt" />
<!-- Main message handlers -->
<bean id="messages" class="com.deepclone.lw.beans.msgs.EmpireMessagesBean" />
<bean id="adminMessages" class="com.deepclone.lw.beans.msgs.AdminMessagesBean" />
<!-- Message tasks -->
<bean id="notificationsDao" class="com.deepclone.lw.beans.msgs.NotificationsDAOBean" />
<bean id="messageCleaner" class="com.deepclone.lw.beans.msgs.MessageCleanerBean" />
<bean id="messageTasks" class="com.deepclone.lw.beans.msgs.MessageTasksBean" />
</beans>

View file

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

View file

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

View file

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

View file

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

View file

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