use of soc.game.SOCGameOption in project JSettlers2 by jdmonin.
the class NewGameOptionsFrame method showScenarioInfoDialog.
/**
* Show a popup window with this scenario's description, special rules, and number of victory points to win.
* Calls {@link EventQueue#invokeLater(Runnable)}.
* @param sc A {@link SOCScenario}, or {@code null} to do nothing
* @param gameOpts All game options if current game, or null to extract from {@code sc}'s {@link SOCScenario#scOpts}
* @param vpWinner Number of victory points to win, or {@link SOCGame#VP_WINNER_STANDARD}.
* @param cli Player client interface, required for {@link AskDialog} constructor
* @param parent Current game's player interface, or another Frame for our parent window,
* or null to look for {@code cli}'s Frame as parent
* @since 2.0.00
*/
public static void showScenarioInfoDialog(final SOCScenario sc, Map<String, SOCGameOption> gameOpts, final int vpWinner, final GameAwtDisplay cli, final Frame parent) {
if (sc == null)
return;
StringBuilder sb = new StringBuilder();
// "Game Scenario:"
sb.append(strings.get("game.options.scenario.label"));
sb.append(' ');
sb.append(sc.getDesc());
sb.append('\n');
final String scLongDesc = sc.getLongDesc();
if (scLongDesc != null) {
sb.append('\n');
sb.append(scLongDesc);
sb.append('\n');
}
// Check game for any other _SC_ game opts in effect:
// "_SC_CLVI"
final String scenOptName = "_" + sc.key;
// "Scenarios:"
final String optDescScenPrefix = strings.get("game.options.scenario.optprefix");
if ((gameOpts == null) && (sc.scOpts != null))
gameOpts = SOCGameOption.parseOptionsToMap(sc.scOpts);
if (gameOpts != null) {
for (SOCGameOption sgo : gameOpts.values()) {
if (sgo.key.equals(scenOptName))
// scenario's dedicated game option; we already showed its name from scDesc
continue;
if (!sgo.key.startsWith("_SC_"))
continue;
String optDesc = sgo.getDesc();
if (optDesc.startsWith(optDescScenPrefix))
optDesc = optDesc.substring(optDescScenPrefix.length()).trim();
// bullet point before option text
sb.append("\n\u2022 ");
sb.append(optDesc);
}
}
if (vpWinner != SOCGame.VP_WINNER_STANDARD) {
sb.append("\n\u2022 ");
// "Victory Points to win:"
sb.append(strings.get("game.options.scenario.vp"));
sb.append(' ');
sb.append(vpWinner);
}
final String scenStr = sb.toString();
NotifyDialog.createAndShow(cli, parent, scenStr, null, true);
}
use of soc.game.SOCGameOption in project JSettlers2 by jdmonin.
the class ServerGametypeInfo method receiveDefaults.
/**
* Set of default options has been received from the server, examine them.
* Sets allOptionsReceived, defaultsReceived, optionSet. If we already have non-null optionSet,
* merge (update the values) instead of replacing the entire set with servOpts.
*
* @param servOpts The allowable {@link SOCGameOption} received from the server.
* Assumes has been parsed already against the locally known opts,
* so ones that we don't know are {@link SOCGameOption#OTYPE_UNKNOWN}.
* @return null if all are known, or a list of key names for unknown options.
*/
public List<String> receiveDefaults(final Map<String, SOCGameOption> servOpts) {
if ((optionSet == null) || optionSet.isEmpty()) {
optionSet = servOpts;
} else {
for (String oKey : servOpts.keySet()) {
SOCGameOption op = servOpts.get(oKey);
SOCGameOption oldcopy = optionSet.get(oKey);
if (oldcopy != null)
optionSet.remove(oKey);
// Even OTYPE_UNKNOWN are added
optionSet.put(oKey, op);
}
}
List<String> unknowns = SOCVersionedItem.findUnknowns(servOpts);
allOptionsReceived = (unknowns == null);
defaultsReceived = true;
return unknowns;
}
use of soc.game.SOCGameOption in project JSettlers2 by jdmonin.
the class SOCDBHelper method saveGameScores.
/**
* Record this completed game's time, players, and scores in the database.
*
* @param ga Game that's just completed
* @param gameLengthSeconds Duration of game
*
* @return true if the save succeeded
* @throws IllegalArgumentException if {@link SOCGame#getPlayerWithWin() ga.getPlayerWithWin()} is null
* @throws SQLException if an error occurs
*/
public static boolean saveGameScores(final SOCGame ga, final int gameLengthSeconds) throws IllegalArgumentException, SQLException {
final SOCPlayer winner = ga.getPlayerWithWin();
if (winner == null)
throw new IllegalArgumentException("no winner");
if (checkConnection()) {
// DB max 6; ga.maxPlayers max 4 or 6
String[] names = new String[SOCGame.MAXPLAYERS];
short[] scores = new short[SOCGame.MAXPLAYERS];
for (int pn = 0; pn < ga.maxPlayers; ++pn) {
SOCPlayer pl = ga.getPlayer(pn);
names[pn] = pl.getName();
scores[pn] = (short) pl.getTotalVP();
}
final int db_max_players = (schemaVersion < SCHEMA_VERSION_1200) ? 4 : 6;
if ((ga.maxPlayers > db_max_players) && !(ga.isSeatVacant(4) && ga.isSeatVacant(5))) {
// Need to try and fit player 5 and/or player 6
// into the 4 db slots (backwards-compatibility)
saveGameScores_fit6pInto4(ga, names, scores);
}
try {
saveGameCommand.setString(1, ga.getName());
int i = 2;
for (int pn = 0; pn < db_max_players; ++i, ++pn) saveGameCommand.setString(i, names[pn]);
for (int pn = 0; pn < db_max_players; ++i, ++pn) if ((scores[pn] != 0) || (names[pn] != null))
saveGameCommand.setShort(i, scores[pn]);
else
saveGameCommand.setNull(i, Types.SMALLINT);
saveGameCommand.setTimestamp(i, new Timestamp(ga.getStartTime().getTime()));
++i;
if (schemaVersion >= SCHEMA_VERSION_1200) {
saveGameCommand.setInt(i, gameLengthSeconds);
++i;
saveGameCommand.setString(i, winner.getName());
++i;
final Map<String, SOCGameOption> opts = ga.getGameOptions();
final String optsStr = (opts == null) ? null : SOCGameOption.packOptionsToString(opts, false);
saveGameCommand.setString(i, optsStr);
}
saveGameCommand.executeUpdate();
return true;
} catch (SQLException sqlE) {
errorCondition = true;
sqlE.printStackTrace();
throw sqlE;
}
}
return false;
}
use of soc.game.SOCGameOption in project JSettlers2 by jdmonin.
the class SOCServerMessageHandler method handleGAMEOPTIONGETINFOS.
/**
* process the "game option get infos" message; reply with the info, with
* one {@link SOCGameOptionInfo GAMEOPTIONINFO} message per option keyname.
* If client version >= 2.0.00, send any unchanged but localized options using
* {@link SOCLocalizedStrings}({@link SOCLocalizedStrings#TYPE_GAMEOPT TYPE_GAMEOPT}).
* Mark the end of the option list with {@link SOCGameOptionInfo GAMEOPTIONINFO}("-").
* If this list is empty, "-" will be the only GAMEOPTIONGETINFO message sent.
*<P>
* We check the default values, not current values, so the list is unaffected by
* cases where some option values are restricted to newer client versions.
* Any option where opt.{@link SOCGameOption#minVersion minVersion} is too new for
* this client's version, is sent as {@link SOCGameOption#OTYPE_UNKNOWN}.
* If the client is older than {@link SOCGameOption#VERSION_FOR_LONGER_OPTNAMES},
* options with long names won't be sent.
*
* @param c the connection
* @param mes the message
* @since 1.1.07
*/
private void handleGAMEOPTIONGETINFOS(Connection c, SOCGameOptionGetInfos mes) {
if (c == null)
return;
final int cliVers = c.getVersion();
final SOCClientData scd = (SOCClientData) c.getAppData();
boolean alreadyTrimmedEnums = false;
Vector<String> okeys = mes.getOptionKeys();
// opts to send as SOCGameOptionInfo
List<SOCGameOption> opts = null;
// opts to send in a SOCLocalizedStrings instead
final Map<String, SOCGameOption> optsToLocal;
// if we don't have game opt localization for client's locale, ignore that request flag.
if (mes.hasTokenGetI18nDescs() && (c.getI18NLocale() != null))
scd.wantsI18N = true;
final boolean wantsLocalDescs = scd.wantsI18N && !SOCServer.i18n_gameopt_PL_desc.equals(c.getLocalized("gameopt.PL"));
if (wantsLocalDescs) {
// Gather all game opts we have that we could possibly localize;
// this list will be narrowed down soon
optsToLocal = new HashMap<String, SOCGameOption>();
for (final SOCGameOption opt : SOCGameOption.optionsForVersion(cliVers, null)) optsToLocal.put(opt.key, opt);
} else {
optsToLocal = null;
}
// Gather requested game option info:
if (okeys == null) {
// received "-", look for newer options (cli is older than us).
// opts will be null if there are no newer ones.
opts = SOCGameOption.optionsNewerThanVersion(cliVers, false, true, null);
alreadyTrimmedEnums = true;
if ((opts != null) && (cliVers < SOCGameOption.VERSION_FOR_LONGER_OPTNAMES)) {
// Client is older than 2.0.00; we can't send it any long option names.
Iterator<SOCGameOption> opi = opts.iterator();
while (opi.hasNext()) {
final SOCGameOption op = opi.next();
if ((op.key.length() > 3) || op.key.contains("_"))
opi.remove();
}
if (opts.isEmpty())
opts = null;
}
}
if ((opts != null) || (okeys != null)) {
final int L = (opts != null) ? opts.size() : okeys.size();
for (int i = 0; i < L; ++i) {
SOCGameOption opt;
// i18n-localized opt.desc, if wantsLocalDescs
String localDesc = null;
if (opts != null) {
opt = opts.get(i);
if (opt.minVersion > cliVers) {
// OTYPE_UNKNOWN
opt = new SOCGameOption(opt.key);
} else if (wantsLocalDescs) {
try {
localDesc = c.getLocalized("gameopt." + opt.key);
} catch (MissingResourceException e) {
}
}
} else {
final String okey = okeys.elementAt(i);
opt = SOCGameOption.getOption(okey, false);
if (// Don't use dynamic opt.getMinVersion(Map) here
(opt == null) || (opt.minVersion > cliVers)) {
// OTYPE_UNKNOWN
opt = new SOCGameOption(okey);
} else if (wantsLocalDescs) {
try {
localDesc = c.getLocalized("gameopt." + okey);
} catch (MissingResourceException e) {
}
}
}
if (wantsLocalDescs) {
// don't send opt's localization info again after GAMEOPTIONINFOs
optsToLocal.remove(opt.key);
if (opt.getDesc().equals(localDesc))
// don't send desc if not localized, client already has unlocalized desc string
localDesc = null;
}
// Enum-type options may have their values restricted by version.
if ((!alreadyTrimmedEnums) && (opt.enumVals != null) && (opt.optType != SOCGameOption.OTYPE_UNKNOWN) && (opt.lastModVersion > cliVers)) {
opt = SOCGameOption.trimEnumForVersion(opt, cliVers);
}
c.put(new SOCGameOptionInfo(opt, cliVers, localDesc).toCmd());
}
}
// send any opts which are localized but otherwise unchanged between server's/client's version
if (// empty is OK
optsToLocal != null) {
List<String> strs = new ArrayList<String>(2 * optsToLocal.size());
for (final SOCGameOption opt : optsToLocal.values()) {
try {
String localDesc = c.getLocalized("gameopt." + opt.key);
if (!opt.getDesc().equals(localDesc)) {
strs.add(opt.key);
strs.add(localDesc);
}
} catch (MissingResourceException e) {
}
}
c.put(new SOCLocalizedStrings(SOCLocalizedStrings.TYPE_GAMEOPT, SOCLocalizedStrings.FLAG_SENT_ALL, strs).toCmd());
}
// mark end of list, even if list was empty
// GAMEOPTIONINFO("-")
c.put(SOCGameOptionInfo.OPTINFO_NO_MORE_OPTS.toCmd());
}
use of soc.game.SOCGameOption in project JSettlers2 by jdmonin.
the class TestI18NGameoptScenStrings method testGameoptsText.
/**
* Test {@link SOCGameOption} text strings.
* @see soc.server.SOCServer#localizeKnownOptions(java.util.Locale, boolean)
* @see soc.server.SOCServerMessageHandler#handleGAMEOPTIONGETINFOS(soc.server.genericServer.Connection, soc.message.SOCGameOptionGetInfos)
*/
@Test
public void testGameoptsText() {
boolean allOK = true;
final TreeSet<String> // use TreeSet for sorted results
mismatchKeys = new TreeSet<String>(), missingKeys = new TreeSet<String>();
for (final SOCGameOption opt : allOpts.values()) {
// but if present there the description strings do need to match.
try {
final String smDesc = sm.get("gameopt." + opt.key);
if (!opt.getDesc().equals(smDesc))
mismatchKeys.add(opt.key);
} catch (MissingResourceException e) {
if (opt.key.charAt(0) != '_')
missingKeys.add(opt.key);
}
}
if (!mismatchKeys.isEmpty()) {
allOK = false;
System.out.println("Game opts which mismatch against toClient.properties gameopt.* strings: " + mismatchKeys);
}
if (!missingKeys.isEmpty()) {
allOK = false;
System.out.println("Game opts missing from toClient.properties gameopt.* strings: " + missingKeys);
}
assertTrue("SOCGameOption i18n strings", allOK);
}
Aggregations