Improved how we analyze a VASL scenario.

master v0.11a
Pacman Ghost 5 years ago
parent cbdeca5546
commit c353fbb325
  1. BIN
      vasl_templates/webapp/tests/fixtures/analyze-vsav/hip-concealed.vsav
  2. 27
      vasl_templates/webapp/tests/test_vassal.py
  3. BIN
      vassal-shim/release/vassal-shim.jar
  4. 64
      vassal-shim/src/vassal_shim/VassalShim.java

@ -577,6 +577,33 @@ def test_analyze_vsav( webapp, webdriver ):
# run the test against all versions of VASSAL+VASL
_run_tests( control_tests, do_test, not pytest.config.option.short_tests ) #pylint: disable=no-member
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@pytest.mark.skipif( not pytest.config.option.vasl_mods, reason="--vasl-mods not specified" ) #pylint: disable=no-member
@pytest.mark.skipif( not pytest.config.option.vassal, reason="--vassal not specified" ) #pylint: disable=no-member
def test_analyze_vsav_hip_concealed( webapp, webdriver ):
"""Test analyzing a scenario that contains HIP and concealed units."""
# initialize
control_tests = init_webapp( webapp, webdriver, vsav_persistence=1, scenario_persistence=1,
reset = lambda ct: ct.set_data_dir( dtype="real" )
)
def do_test(): #pylint: disable=missing-docstring
# NOTE: The test scenario contains hidden/concealed units belonging to the Russians and Germans,
# but because the owning user is test/password, they should be ignored (unless you configure VASSAL
# with these credentials, so don't do that :-/).
new_scenario()
_analyze_vsav( "hip-concealed.vsav",
[ [], [] ],
[ [], [] ],
[ "No vehicles/ordnance were imported." ]
)
# run the test against all versions of VASSAL+VASL
_run_tests( control_tests, do_test, not pytest.config.option.short_tests ) #pylint: disable=no-member
# ---------------------------------------------------------------------
def _run_tests( control_tests, func, test_all ):

@ -57,9 +57,8 @@ import VASSAL.command.AlertCommand ;
import VASSAL.build.module.map.boardPicker.Board ;
import VASSAL.counters.GamePiece ;
import VASSAL.counters.BasicPiece ;
import VASSAL.counters.Decorator ;
import VASSAL.counters.DynamicProperty ;
import VASSAL.counters.Hideable ;
import VASSAL.counters.FreeRotator ;
import VASSAL.counters.PieceCloner ;
import VASSAL.preferences.Prefs ;
import VASSAL.tools.DataArchive ;
@ -155,7 +154,31 @@ public class VassalShim
// analyze the scenario
logger.info( "Analyzing scenario: " + scenarioFilename ) ;
HashMap<String,AnalyzeNode> results = new HashMap<String,AnalyzeNode>() ;
analyzeCommand( cmd, results ) ;
for ( GamePiece gamePiece: GameModule.getGameModule().getGameState().getAllPieces() ) {
if ( gamePiece.getProperty(VASSAL.counters.Properties.OBSCURED_BY) != null || gamePiece.getProperty(VASSAL.counters.Properties.HIDDEN_BY) != null ) {
// IMPORTANT: VASSAL blanks out the name of concealed/HIP pieces if they don't belong to the calling user,
// but we still get the GPID, which is enough for the main program to figure out which entry to create.
// This means that people could use this feature to analyze a scenario in progess, to figure out
// what their opponent's concealed/hidden OB is. To avoid this, we exclude these pieces from the report.
continue ;
}
// see if this piece has a GPID
GamePiece gp = Decorator.getInnermost( gamePiece ) ;
if ( !( gp instanceof BasicPiece ) )
continue ;
// yup - check if it's one we're interested in
String gpid = ((BasicPiece)gp).getGpId() ;
if ( gpid.equals( "" ) || gpid.equals( labelGpid ) )
continue ;
// yup - add it to the results
if ( ! results.containsKey( gpid ) ) {
logger.debug( "Found new GPID " + gpid + ": " + gamePiece.getName() ) ;
results.put( gpid, new AnalyzeNode( gamePiece.getName() ) ) ;
} else {
int newCount = results.get( gpid ).incrementCount() ;
logger.debug( "Updating count for GPID " + gpid + ": #=" + newCount ) ;
}
}
// generate the report
Document doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument() ;
@ -240,6 +263,8 @@ public class VassalShim
private void extractLabels( Command cmd, Map<String,GamePieceLabelFields> ourLabels, ArrayList<GamePieceLabelFields> otherLabels )
{
// check if this command is a label we're interested in
// NOTE: We shouldn't really be looking at the object type, see analyzeScenario().
// http://www.gamesquad.com/forums/index.php?threads/new-program-to-help-set-up-vasl-scenarios.148281/post-1983751
if ( cmd instanceof AddPiece ) {
AddPiece addPieceCmd = (AddPiece) cmd ;
if ( addPieceCmd.getTarget() instanceof DynamicProperty ) {
@ -811,39 +836,6 @@ public class VassalShim
buf.append( ": " + cmd.getAllowedIds() ) ;
}
private void analyzeCommand( Command cmd, Map<String,AnalyzeNode> results )
{
// analyze the command
if ( cmd instanceof AddPiece ) {
GamePiece target = ((AddPiece)cmd).getTarget() ;
logger.debug( "Found piece: " + cmd.getClass().getName() + " ; target=" + target.getClass().getName() ) ;
// NOTE: Hideable's don't seem to be just a thing with old versions of VASSAL. We still get them
// when adding a "46mm granatnik wz. 36" (GPID 2172) using VASL 6.4.4 :-/ This also seems to happen
// with other 1/2" SW counters.
// NOTE: Other pieces also occasionally appear with weird class types e.g. the Japanese Type 88 75 AA Gun
// appears as a FreeRotator?!
if ( target instanceof DynamicProperty || target instanceof Hideable || target instanceof FreeRotator
|| target.getClass().getName().equals("VASL.counters.TextInfo")
) {
int pos = target.getState().lastIndexOf( ";" ) ;
String gpid = target.getState().substring( pos+1 ) ;
if ( ! gpid.equals( labelGpid ) ) {
if ( ! results.containsKey( gpid ) ) {
logger.debug( "Found new GPID " + gpid + ": " + target.getName() ) ;
results.put( gpid, new AnalyzeNode( target.getName() ) ) ;
} else {
int newCount = results.get( gpid ).incrementCount() ;
logger.debug( "Updating count for GPID " + gpid + ": #=" + newCount ) ;
}
}
}
}
// analyze any sub-commands
for ( Command c: cmd.getSubCommands() )
analyzeCommand( c, results ) ;
}
private static void parseGamePieceState( String state, ArrayList<String> separators, ArrayList<String> fields )
{
// parse the GamePiece state

Loading…
Cancel
Save