diff --git a/legacyworlds-server-beans-i18n/src/main/java/com/deepclone/lw/beans/i18n/I18NData.java b/legacyworlds-server-beans-i18n/src/main/java/com/deepclone/lw/beans/i18n/I18NData.java
index 77bca8a..3ebac74 100644
--- a/legacyworlds-server-beans-i18n/src/main/java/com/deepclone/lw/beans/i18n/I18NData.java
+++ b/legacyworlds-server-beans-i18n/src/main/java/com/deepclone/lw/beans/i18n/I18NData.java
@@ -239,6 +239,20 @@ class I18NData
}
+ /**
+ * Access the store for some language
+ *
+ * @param language
+ * the language to access
+ *
+ * @return the language store, or null
if the language is not defined.
+ */
+ LanguageStore getStore( String language )
+ {
+ return this.languages.get( language );
+ }
+
+
/**
* Sets or creates the translation for a given language/string identifier pair.
*
@@ -257,7 +271,8 @@ class I18NData
* @throws IllegalArgumentException
* if the string does not exist
*/
- String setTranslation( final int administrator , final String language , final String string , final String translation )
+ String setTranslation( final int administrator , final String language , final String string ,
+ final String translation )
{
// Get existing translation
LanguageStore store = this.languages.get( language );
diff --git a/legacyworlds-server-beans-i18n/src/main/java/com/deepclone/lw/beans/i18n/TranslatorBean.java b/legacyworlds-server-beans-i18n/src/main/java/com/deepclone/lw/beans/i18n/TranslatorBean.java
index 7ce8046..4e97fbf 100644
--- a/legacyworlds-server-beans-i18n/src/main/java/com/deepclone/lw/beans/i18n/TranslatorBean.java
+++ b/legacyworlds-server-beans-i18n/src/main/java/com/deepclone/lw/beans/i18n/TranslatorBean.java
@@ -1,7 +1,10 @@
package com.deepclone.lw.beans.i18n;
+import java.util.Collection;
+import java.util.HashMap;
import java.util.HashSet;
+import java.util.Map;
import java.util.Set;
import org.springframework.beans.factory.annotation.Autowired;
@@ -13,10 +16,13 @@ import com.deepclone.lw.interfaces.i18n.UnknownStringException;
/**
+ * Translation component
+ *
+ *
* The translator bean's implementation uses the contents of the {@link I18NData} instance, which it * only accesses in read-only mode. * - * @author tseeker + * @author E. Benoît */ public class TranslatorBean implements Translator @@ -83,6 +89,23 @@ public class TranslatorBean } + /* Documentation in Translator interface */ + @Override + public String getLanguageName( String language ) + throws UnknownLanguageException + { + this.data.readLock( ).lock( ); + try { + if ( !this.data.isLanguageComplete( language ) ) { + throw new UnknownLanguageException( language ); + } + return this.data.getLanguageName( language ); + } finally { + this.data.readLock( ).unlock( ); + } + } + + /* Documentation in Translator interface */ @Override public String translate( String language , String string ) @@ -103,17 +126,30 @@ public class TranslatorBean } - /* Documentation in Translator interface */ + /** + * Access the store for the specified language then extract translations + */ @Override - public String getLanguageName( String language ) - throws UnknownLanguageException + public Map< String , String > translate( String language , Collection< String > strings ) + throws UnknownStringException , UnknownLanguageException { this.data.readLock( ).lock( ); try { if ( !this.data.isLanguageComplete( language ) ) { throw new UnknownLanguageException( language ); } - return this.data.getLanguageName( language ); + + LanguageStore store = this.data.getStore( language ); + HashMap< String , String > result = new HashMap< String , String >( ); + for ( String identifier : strings ) { + String value = store.getTranslation( identifier ); + if ( value == null ) { + throw new UnknownStringException( identifier ); + } + result.put( identifier , value ); + } + + return result; } finally { this.data.readLock( ).unlock( ); } diff --git a/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/EmpireDAOBean.java b/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/EmpireDAOBean.java index 43524db..e515d04 100644 --- a/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/EmpireDAOBean.java +++ b/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/EmpireDAOBean.java @@ -79,19 +79,8 @@ public class EmpireDAOBean 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 ); + return this.dTemplate.queryForObject( sql , new GeneralInformationRowMapper( ) , empireId ); } catch ( EmptyResultDataAccessException e ) { return null; } diff --git a/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/EmpireManagementBean.java b/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/EmpireManagementBean.java index 7a4c6fe..a940ef7 100644 --- a/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/EmpireManagementBean.java +++ b/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/EmpireManagementBean.java @@ -117,7 +117,7 @@ public class EmpireManagementBean return new GamePageData( generalInformation.getName( ) , generalInformation.getStatus( ) , generalInformation.getTag( ) , generalInformation.getCash( ) , generalInformation.getNextTick( ) , - planets , rlTime ); + planets , rlTime, generalInformation.getLanguage( ) ); } diff --git a/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/GeneralInformationRowMapper.java b/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/GeneralInformationRowMapper.java new file mode 100644 index 0000000..fd8be8a --- /dev/null +++ b/legacyworlds-server-beans-simple/src/main/java/com/deepclone/lw/beans/empire/GeneralInformationRowMapper.java @@ -0,0 +1,36 @@ +package com.deepclone.lw.beans.empire; + + +import java.sql.ResultSet; +import java.sql.SQLException; + +import org.springframework.jdbc.core.RowMapper; + +import com.deepclone.lw.sqld.game.GeneralInformation; + + + +class GeneralInformationRowMapper + implements RowMapper< GeneralInformation > +{ + + @Override + public GeneralInformation mapRow( ResultSet rs , int rowNum ) + throws SQLException + { + GeneralInformation info = new GeneralInformation( ); + + info.setName( rs.getString( "name" ) ); + info.setTag( rs.getString( "alliance" ) ); + info.setCash( rs.getLong( "cash" ) ); + info.setLanguage( rs.getString( "language" ) ); + info.setNextTick( rs.getLong( "game_time" ) ); + info.setAccountId( rs.getInt( "account_id" ) ); + + String statusString = rs.getString( "status" ); + info.setStatus( rs.wasNull( ) ? null : statusString.charAt( 0 ) ); + + return info; + } + +} diff --git a/legacyworlds-server-data/db-structure/parts/040-functions/040-empire.sql b/legacyworlds-server-data/db-structure/parts/040-functions/040-empire.sql index 563c356..16443aa 100644 --- a/legacyworlds-server-data/db-structure/parts/040-functions/040-empire.sql +++ b/legacyworlds-server-data/db-structure/parts/040-functions/040-empire.sql @@ -506,6 +506,7 @@ CREATE VIEW emp.enemies -- General information view -- +DROP VIEW IF EXISTS emp.general_information CASCADE; CREATE VIEW emp.general_information AS SELECT e.name_id AS id , en.name AS name , ( CASE @@ -516,13 +517,17 @@ CREATE VIEW emp.general_information END ) AS status , e.cash AS cash , a.tag AS alliance , st.next_tick AS game_time , - av.id AS account_id + av.id AS account_id , + av.language AS language FROM emp.empires e - INNER JOIN naming.empire_names en ON en.id = e.name_id - INNER JOIN users.accounts_view av ON av.id = en.owner_id + INNER JOIN naming.empire_names en + ON en.id = e.name_id + INNER JOIN users.accounts_view av + ON av.id = en.owner_id LEFT OUTER JOIN emp.alliance_members am ON am.empire_id = e.name_id AND NOT am.is_pending - LEFT OUTER JOIN emp.alliances a ON a.id = am.alliance_id + LEFT OUTER JOIN emp.alliances a + ON a.id = am.alliance_id CROSS JOIN sys.status st; GRANT SELECT ON emp.general_information TO :dbuser; diff --git a/legacyworlds-server-data/src/main/java/com/deepclone/lw/sqld/game/GeneralInformation.java b/legacyworlds-server-data/src/main/java/com/deepclone/lw/sqld/game/GeneralInformation.java index 82b7270..afd37d3 100644 --- a/legacyworlds-server-data/src/main/java/com/deepclone/lw/sqld/game/GeneralInformation.java +++ b/legacyworlds-server-data/src/main/java/com/deepclone/lw/sqld/game/GeneralInformation.java @@ -3,11 +3,12 @@ package com.deepclone.lw.sqld.game; public class GeneralInformation { + private String name; + + private String language; private Character status; - private String name; - private String tag; private long cash; @@ -17,50 +18,87 @@ public class GeneralInformation private int accountId; - public GeneralInformation( Character status , String name , String tag , long cash , long nextTick , int accountId ) + public String getName( ) + { + return this.name; + } + + + public void setName( String name ) { - this.status = status; this.name = name; - this.tag = tag; - this.cash = cash; - this.nextTick = nextTick; - this.accountId = accountId; + } + + + public String getLanguage( ) + { + return this.language; + } + + + public void setLanguage( String language ) + { + this.language = language; } public Character getStatus( ) { - return status; + return this.status; } - public String getName( ) + public void setStatus( Character status ) { - return name; + this.status = status; } public String getTag( ) { - return tag; + return this.tag; + } + + + public void setTag( String tag ) + { + this.tag = tag; } public long getCash( ) { - return cash; + return this.cash; + } + + + public void setCash( long cash ) + { + this.cash = cash; } public long getNextTick( ) { - return nextTick; + return this.nextTick; + } + + + public void setNextTick( long nextTick ) + { + this.nextTick = nextTick; } public int getAccountId( ) { - return accountId; + return this.accountId; + } + + + public void setAccountId( int accountId ) + { + this.accountId = accountId; } } diff --git a/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/i18n/Translator.java b/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/i18n/Translator.java index 9c5eb39..92ada50 100644 --- a/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/i18n/Translator.java +++ b/legacyworlds-server-interfaces/src/main/java/com/deepclone/lw/interfaces/i18n/Translator.java @@ -1,6 +1,8 @@ package com.deepclone.lw.interfaces.i18n; +import java.util.Collection; +import java.util.Map; import java.util.Set; @@ -8,12 +10,12 @@ import java.util.Set; /** * Translator service interface * + *
* This interface defines the methods available on the Translator service. One such service should * be present on all nodes. All Translator service instances are managed by the I18NManager service, * which is shared between nodes and notifies Translator instances of database updates. * - * @author tseeker - * + * @author E. Benoît */ public interface Translator { @@ -62,4 +64,28 @@ public interface Translator */ public String translate( String language , String string ) throws UnknownStringException , UnknownLanguageException; + + + /** + * Translate multiple strings based on their identifiers + * + *
+ * This method must be implemented to allow "en masse" string translations. It will fetch the + * translations in a given language for an arbitrary quantity of string identifiers, returning + * the results as a map of identifiers to translations. + * + * @param language + * the identifier of the language to translate to + * @param strings + * a collection of string identifiers + * + * @return a map associating string identifiers to translations + * + * @throws UnknownStringException + * if one of the string identifiers does not match a string + * @throws UnknownLanguageException + * if the language does not exist or is not supported + */ + public Map< String , String > translate( String language , Collection< String > strings ) + throws UnknownStringException , UnknownLanguageException; } diff --git a/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/player/gdata/GamePageData.java b/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/player/gdata/GamePageData.java index 82e1767..59cef53 100644 --- a/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/player/gdata/GamePageData.java +++ b/legacyworlds-session/src/main/java/com/deepclone/lw/cmd/player/gdata/GamePageData.java @@ -8,23 +8,91 @@ import java.util.List; +/** + * General information included in a game response + * + *
+ * This class stores common information which is included in most in-game responses. This + * information includes some essential preferences, the general state of the empire, and some + * information about the server's state. + * + * @author E. Benoît + */ public class GamePageData implements Serializable { - + /** + * The serialisation version identifier + * + *
+ * This field indicates the "special" state of the account: q
is for accounts that
+ * are quitting, v
for accounts in vacation mode and s
for accounts
+ * that are about to enter vacation mode. null
indicates "none of the above".
+ */
private final Character special;
+
+ /** Alliance tag, or null
if not a full member of any alliance */
private final String alliance;
+
+ /**
+ * Current cash of the empire
+ *
+ *
+ * FIXME: will be replaced with actual resources
+ */
private final long cash;
+
+ /** Timestamp from the server's system */
private final Date serverTime;
+
+ /** Current game time (from last update identifier) */
private final GameTime gameTime;
+
+ /** Planets owned by the empire */
private final List< NameIdPair > planets;
+
+ /** Whether the player wants to see "real" times or in-game times */
private final boolean useRLTime;
+ /** Code of selected language */
+ private final String language;
+
+ /**
+ * Initialise the general game information record
+ *
+ * @param empire
+ * the empire's name
+ * @param special
+ * the special account state character (see {@link #special})
+ * @param alliance
+ * current alliance tag
+ * @param cash
+ * current cash
+ * @param gameTime
+ * last update identifier
+ * @param planets
+ * list of planets owned by the empire
+ * @param useRLTime
+ * whether the player wants to see "real" times or in-game times
+ * @param language
+ * selected language code
+ */
public GamePageData( String empire , Character special , String alliance , long cash , long gameTime ,
- List< NameIdPair > planets , boolean useRLTime )
+ List< NameIdPair > planets , boolean useRLTime , String language )
{
this.empire = empire;
this.special = special;
@@ -34,54 +102,107 @@ public class GamePageData
this.gameTime = new GameTime( gameTime );
this.planets = Collections.unmodifiableList( planets );
this.useRLTime = useRLTime;
+ this.language = language;
}
+ /**
+ * Gets the name of the current empire.
+ *
+ * @return the name of the current empire
+ */
public String getEmpire( )
{
- return empire;
+ return this.empire;
}
+ /**
+ * Gets the state of the account
+ *
+ * @return the state of the account
+ */
public Character getSpecial( )
{
- return special;
+ return this.special;
}
+ /**
+ * Gets the alliance tag
+ *
+ * @return the alliance tag, or null
if not a full member of any alliance
+ */
public String getAlliance( )
{
- return alliance;
+ return this.alliance;
}
+ /**
+ * Gets the current cash of the empire
+ *
+ * @return the current cash of the empire
+ */
public long getCash( )
{
- return cash;
+ return this.cash;
}
+ /**
+ * Gets the timestamp from the server's system.
+ *
+ * @return the timestamp from the server's system
+ */
public Date getServerTime( )
{
- return serverTime;
+ return this.serverTime;
}
+ /**
+ * Gets the current game time
+ *
+ * @return the current game time
+ */
public GameTime getGameTime( )
{
- return gameTime;
+ return this.gameTime;
}
+ /**
+ * Gets the planets owned by the empire.
+ *
+ * @return the list of planets owned by the empire
+ */
public List< NameIdPair > getPlanets( )
{
- return planets;
+ return this.planets;
}
+ /**
+ * Checks if the player wants to see "real" times or in-game times.
+ *
+ * @return true
if the player wants to see "real" times, false
for
+ * in-game times
+ */
public boolean isUseRLTime( )
{
- return useRLTime;
+ return this.useRLTime;
+ }
+
+
+ /**
+ * Gets the code of selected language.
+ *
+ * @return the code of selected language
+ */
+ public String getLanguage( )
+ {
+ return this.language;
}
}