use of soc.game.SOCScenario in project JSettlers2 by jdmonin.
the class SOCServerMessageHandler method handleSCENARIOINFO.
/**
* Process client request for updated {@link SOCScenario} info.
* Added 2015-09-21 for v2.0.00.
*/
private void handleSCENARIOINFO(final Connection c, final SOCScenarioInfo mes) {
if (c == null)
return;
List<String> params = mes.getParams();
int L = params.size();
if (L == 0)
// malformed
return;
final boolean hasAnyChangedMarker = params.get(L - 1).equals(SOCScenarioInfo.MARKER_ANY_CHANGED);
if (hasAnyChangedMarker) {
params.remove(L - 1);
--L;
} else if (L == 1) {
// requesting one scenario
srv.sendGameScenarioInfo(params.get(0), null, c, false);
return;
}
// Calculate and respond; be sure to include any requested scKeys from params
final int cliVers = c.getVersion();
// caches SOCScenario.getAllKnownScenarios() if called
Map<String, SOCScenario> knownScens = null;
List<SOCScenario> changes = null;
if (hasAnyChangedMarker && (cliVers < Version.versionNumber())) {
knownScens = SOCScenario.getAllKnownScenarios();
changes = SOCVersionedItem.itemsNewerThanVersion(cliVers, false, knownScens);
}
if (L > 0) {
if (changes == null)
changes = new ArrayList<SOCScenario>();
for (String scKey : params) {
SOCScenario sc = SOCScenario.getScenario(scKey);
if ((sc == null) || (sc.minVersion > cliVers))
// unknown scenario, or too new; send too-new ones in case client encounters one as a listed game's
// scenario (server also sends too-new SOCGameOptions as unknowns, with the same intention)
c.put(new SOCScenarioInfo(scKey, true).toCmd());
else if (!changes.contains(sc))
changes.add(sc);
}
}
if (changes != null)
for (final SOCScenario sc : changes) if (sc.minVersion <= cliVers)
srv.sendGameScenarioInfo(null, sc, c, false);
else
c.put(new SOCScenarioInfo(sc.key, true).toCmd());
final SOCClientData scd = (SOCClientData) c.getAppData();
if (hasAnyChangedMarker && scd.wantsI18N && !scd.sentAllScenarioStrings) {
if (!scd.checkedLocaleScenStrings) {
scd.localeHasScenStrings = SOCServer.clientHasLocalizedStrs_gameScenarios(c);
scd.checkedLocaleScenStrings = true;
}
if (scd.localeHasScenStrings) {
if (knownScens == null)
knownScens = SOCScenario.getAllKnownScenarios();
ArrayList<String> scKeys = new ArrayList<String>();
for (final SOCScenario sc : SOCVersionedItem.itemsForVersion(cliVers, knownScens)) if ((changes == null) || !changes.contains(sc))
scKeys.add(sc.key);
List<String> scenStrs;
if (!scKeys.isEmpty())
scenStrs = SOCServer.localizeGameScenarios(scd.locale, scKeys, false, scd);
else
// re-use the empty list object
scenStrs = scKeys;
c.put(SOCLocalizedStrings.toCmd(SOCLocalizedStrings.TYPE_SCENARIO, SOCLocalizedStrings.FLAG_SENT_ALL, scenStrs));
}
scd.sentAllScenarioStrings = true;
}
// send end of list
c.put(new SOCScenarioInfo(null, null, null).toCmd());
if (hasAnyChangedMarker) {
scd.sentAllScenarioInfo = true;
scd.sentAllScenarioStrings = true;
}
}
use of soc.game.SOCScenario in project JSettlers2 by jdmonin.
the class TestI18NGameoptScenStrings method testScenariosText.
/**
* Test {@link SOCScenario} text strings: gamescen.*.n, some have gamescen.*.d.
* @see soc.server.SOCServer#clientHasLocalizedStrs_gameScenarios(soc.server.genericServer.Connection)
*/
@Test
public void testScenariosText() {
boolean allOK = true;
final TreeSet<String> // use TreeSet for sorted results
mismatchKeys = new TreeSet<String>(), missingKeys = new TreeSet<String>();
for (final SOCScenario sc : allScens.values()) {
String strKey = sc.key + ".n";
try {
final String smDesc = sm.get("gamescen." + strKey);
if (!sc.getDesc().equals(smDesc))
mismatchKeys.add(strKey);
} catch (MissingResourceException e) {
missingKeys.add(strKey);
}
final String longDesc = sc.getLongDesc();
if (longDesc != null) {
strKey = sc.key + ".d";
try {
final String smDesc = sm.get("gamescen." + strKey);
if (!longDesc.equals(smDesc))
mismatchKeys.add(strKey);
} catch (MissingResourceException e) {
missingKeys.add(strKey);
}
}
}
if (!mismatchKeys.isEmpty()) {
allOK = false;
System.out.println("SOCScenario keys which mismatch against toClient.properties gamescen.* strings: " + mismatchKeys);
}
if (!missingKeys.isEmpty()) {
allOK = false;
System.out.println("SOCScenario keys missing from toClient.properties gamescen.* strings: " + missingKeys);
}
assertTrue("SOCScenario i18n strings", allOK);
}
use of soc.game.SOCScenario in project JSettlers2 by jdmonin.
the class TestBoardLayouts method testLayouts.
/**
* Test board layouts for classic games and all {@link SOCScenario}s for 2, 3, 4 and 6 players.
* @see soc.server.SOCGameListAtServer#createGame(String, String, String, Map, soc.server.GameHandler)
* @see soc.server.SOCBoardAtServer#makeNewBoard(Map)
*/
@Test(timeout = 20000)
public void testLayouts() {
final int[] PL = { 2, 3, 4, 6 };
// use TreeSet for sorted results
final TreeSet<String> badLayouts = new TreeSet<String>();
for (int pl : PL) if (!testSingleLayout(null, pl))
badLayouts.add("classic:" + pl);
for (final SOCScenario sc : allScens.values()) for (int pl : PL) if (!testSingleLayout(sc, pl))
badLayouts.add(sc.key + ":" + pl);
if (!badLayouts.isEmpty())
System.out.println("Board layouts: Scenario:player combinations which fail layout: " + badLayouts);
assertTrue("Classic and scenario board layouts", badLayouts.isEmpty());
}
use of soc.game.SOCScenario in project JSettlers2 by jdmonin.
the class TestScenarioOpts method testScenarioConstructorGameopts.
/**
* Ensure {@link SOCScenario} constructor rejects bad game option strings as expected.
*/
@Test
public void testScenarioConstructorGameopts() {
@SuppressWarnings("unused") SOCScenario sc;
try {
sc = new SOCScenario("SC_TEST", 2000, -1, "desc", null, "-");
} catch (IllegalArgumentException e) {
fail("SOCScenario constructor accepts '-' gameopt");
}
try {
sc = new SOCScenario("SC_TEST", 2000, -1, "desc", null, null);
fail("SOCScenario constructor rejects null opt");
}// is expected
catch (IllegalArgumentException e) {
}
try {
sc = new SOCScenario("SC_TEST", 2000, -1, "desc", null, "");
fail("SOCScenario constructor rejects empty opt");
}// is expected
catch (IllegalArgumentException e) {
}
}
use of soc.game.SOCScenario in project JSettlers2 by jdmonin.
the class TestScenarioOpts method testAllScenarios.
/**
* Test all {@link SOCScenario}s' game option consistency,
* as described in {@link TestScenarioOpts class javadoc}.
*/
@Test
public void testAllScenarios() {
// use TreeSet for sorted results
final TreeSet<String> badScens = new TreeSet<String>();
for (final SOCScenario sc : SOCScenario.getAllKnownScenarios().values()) {
if (sc.scOpts.equals("-"))
continue;
try {
final Map<String, SOCGameOption> parsedOpts = SOCGameOption.parseOptionsToMap(sc.scOpts);
// will be null if any opts failed parsing
StringBuilder sb = null;
// This same pre-check is done by TestBoardLayouts.testSingleLayout(..)
if (parsedOpts != null) {
sb = SOCGameOption.adjustOptionsToKnown(parsedOpts, null, true);
if (null != sb) {
badScens.add(sc.key + ": Bad game options found by SGO.adjustOptionsToKnown: " + sb);
continue;
}
}
sb = new StringBuilder();
// Check for bad or changed values from sc.scOpts name-value pairs (nvpairs)
for (String nvpair : sc.scOpts.split(SOCMessage.sep2)) {
if (nvpair.length() == 0) {
if (sb.length() > 0)
sb.append(", ");
sb.append("Adjacent commas in sc.scOpts");
continue;
}
int i = nvpair.indexOf("=");
if ((i <= 0) || (i == nvpair.length() - 1)) {
if (sb.length() > 0)
sb.append(", ");
sb.append("Malformed name=value in sc.scOpts: \"" + nvpair + '"');
continue;
}
if (parsedOpts == null) {
if (null == SOCGameOption.parseOptionNameValue(nvpair, false)) {
if (sb.length() > 0)
sb.append(", ");
sb.append("Cannot parse option: check type and syntax: \"" + nvpair + '"');
}
} else {
final String origKey = nvpair.substring(0, i);
if (!parsedOpts.containsKey(origKey)) {
if (sb.length() > 0)
sb.append(", ");
sb.append("sc.scOpts key not found in parsed opts: \"" + nvpair + '"');
continue;
}
final String repacked = parsedOpts.get(origKey).toString();
if (!repacked.equals(nvpair)) {
if (sb.length() > 0)
sb.append(", ");
sb.append("sc.scOpts value changed by SGO.adjustOptionsToKnown: \"" + nvpair + "\" -> \"" + repacked + '"');
}
}
}
if (sb.length() > 0) {
badScens.add(sc.key + ": " + sb);
sb.delete(0, sb.length());
}
// Check opt versions
if (parsedOpts != null) {
int optsVers = -1;
for (SOCGameOption opt : parsedOpts.values()) {
final int vers = opt.minVersion;
if (vers > optsVers)
optsVers = vers;
if (vers > sc.minVersion) {
if (sb.length() > 0)
sb.append(", ");
sb.append(opt.key);
}
}
if (sb.length() > 0)
badScens.add(sc.key + ": Game options minVersion (" + optsVers + ") too new for scenario minVersion (" + sc.minVersion + "): " + sb);
}
} catch (IllegalArgumentException e) {
badScens.add(sc.key + ": bad option name: " + e.getMessage());
}
}
if (!badScens.isEmpty())
System.out.println("SOCScenarios with inconsistent game options: " + badScens);
assertTrue("SOCScenario game option consistency", badScens.isEmpty());
}
Aggregations