Added support for the "Fight For Seoul" extension.

master
Pacman Ghost 3 years ago
parent 39415d9560
commit 92e17a3aaf
  1. 5
      vasl_templates/tools/make_chapter_h_placeholders.py
  2. 44
      vasl_templates/webapp/data/extensions/ffs.json
  3. 11
      vasl_templates/webapp/data/vasl-overrides.json
  4. 10
      vasl_templates/webapp/static/snippets.js
  5. 3
      vasl_templates/webapp/static/vassal.js
  6. 6
      vasl_templates/webapp/tests/control_tests_servicer.py
  7. BIN
      vasl_templates/webapp/tests/fixtures/analyze-vsav/ffs.vsav
  8. BIN
      vasl_templates/webapp/tests/fixtures/vasl-extensions/real/ffs.vmdx
  9. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/ordnance/american/1940.txt
  10. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/ordnance/american/1941.txt
  11. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/ordnance/american/1942.txt
  12. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/ordnance/american/1943.txt
  13. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/ordnance/american/1944.txt
  14. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/ordnance/american/1945.txt
  15. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/vehicles/american/1940.txt
  16. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/vehicles/american/1941.txt
  17. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/vehicles/american/1942.txt
  18. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/vehicles/american/1943.txt
  19. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/vehicles/american/1944.txt
  20. 1
      vasl_templates/webapp/tests/fixtures/vo-reports/vehicles/american/1945.txt
  21. 95
      vasl_templates/webapp/tests/test_vasl_extensions.py
  22. 31
      vasl_templates/webapp/tests/test_vassal.py
  23. 5
      vasl_templates/webapp/vasl_mod.py

@ -218,6 +218,11 @@ def load_vo_data_from_extension( fname ):
# get the extension ID
data = json.load( open( fname, "r" ) )
extn_id = data["extensionId"]
if extn_id == "08d":
# NOTE: All the vehicle/ordnance notes and multi-applicable notes in the Fight For Seoul extension
# actually reference those in K:FW (and there is code in the main application to handle this), so
# the user doesn't need to set anything up for FfS (other than what they already need to do for K:FW).
return results
# load the file
for nat in data:

@ -0,0 +1,44 @@
{
"extensionId": "08d",
"version": "0.0",
"displayName": "Fight For Seoul",
"displayNameAbbrev": "FfS",
"american": {
"vehicles": [
{ "name": "POA-CWS-H5",
"_comment_": "This was copied from kfw-uro/v:005. We can't use copy_from since K:FW is also an extension, and we don't control load order.",
"type": "MTv",
"CS#": 6,
"capabilities2": { "C": 5, "sM": 8 },
"note_number": "5\u2020",
"notes": [ "C", "M" ],
"comments": [ "TCA restrictions", "CE: MA, SA Fire NA", "Fire MA & SA NA" ],
"id": "ffs/v:000",
"gpid": "08d:15"
}
],
"ordnance": [
{ "name": "M20(L) 75mm Recoilless Rifle",
"_comment_": "This was copied from kfw-un-common/o:004. We can't use copy_from since K:FW is also an extension, and we don't control load order.",
"type": "RCL",
"capabilities": [ "H\u2020" ],
"capabilities2": { "WP": 7 },
"comments": [ "∞ H", "Crewed" ],
"note_number": "25\u2020",
"notes": [ "K", "M", "O", "P", "R" ],
"id": "ffs/o:000",
"gpid": "08d:75"
}
]
}
}

@ -142,6 +142,17 @@
"front_images": "us/veh/usSearchlight(KFW).png",
"back_images": null
}
},
"08d:75": {
"expected": {
"name": "RCL 75*",
"front_images": "amrcl75-malf.png",
"back_images": "dm-75rcl.gif"
},
"updated": {
"front_images": "amrcl75.png"
}
}
}

@ -538,7 +538,11 @@ function get_vo_note_key( vo_entry )
return null ;
var key = match[0] ;
// NOTE: The K:FW counters appear in the main VASL module, but we handle them as if they were an extension.
if ( vo_entry.extn_id )
if ( vo_entry.extn_id === "08d" ) {
// NOTE: All the FfS V/O and M/A notes actually reference K:FW (nb: there are only 2 American counters
// in this extension, so we can always map them to K:FW UN).
key = "kfw-un:" + key ;
} else if ( vo_entry.extn_id )
key = vo_entry.extn_id + ":" + key ;
else if ( vo_entry.id.match( /^kfw-(uro|bcfk|rok|ounc|un-common)\// ) )
key = "kfw-un:" + key ;
@ -617,7 +621,9 @@ function get_ma_notes_keys( nat, vo_entries, vo_type )
for ( j=0 ; j < vo_entry.notes.length ; ++j ) {
// NOTE: The K:FW counters appear in the main VASL module, but we handle them as if they were an extension.
var key = translate_kfw_key( vo_entry, j, /^kfw-(uro|bcfk|rok|ounc|un-common)\//, "kfw-un" ) ;
// NOTE: All the FfS V/O and M/A notes actually reference K:FW (nb: there are only 2 American counters
// in this extension, so we can always map them to K:FW UN).
var key = translate_kfw_key( vo_entry, j, /^(kfw-(uro|bcfk|rok|ounc|un-common)|ffs)\//, "kfw-un" ) ;
if ( key ) {
keys[0][ key ] = true ;
continue ;

@ -389,7 +389,8 @@ function _create_vo_entries_from_analysis( report )
return entries[0] ;
var entries2 = [] ;
for ( var i=0 ; i < entries.length ; ++i ) {
var isKFW = entries[i].id.substr( 0, 4 ) === "kfw-" ;
var entry_id = entries[i].id ;
var isKFW = entry_id.substr(0,4) === "kfw-" || entry_id.substr(0,3) === "ffs" ;
if ( (theater == "Korea" && isKFW) || (theater != "Korea" && !isKFW) )
entries2.push( entries[i] ) ;
}

@ -194,7 +194,11 @@ class ControlTestsServicer( BaseControlTestsServicer ): #pylint: disable=too-man
self._log_request( request, context )
vassal_version = request.vassalVersion
# set the VASSAL engine
if vassal_version:
if vassal_version == "random":
# NOTE: Some tests require VASSAL to be configured, and since they should all
# should behave in the same way, it doesn't matter which one we use.
dname = random.choice( list( self._vassal_engines.values() ) )
elif vassal_version:
dname = self._vassal_engines.get( vassal_version )
if not dname:
raise RuntimeError( "Unknown VASSAL version: {}".format( vassal_version ) )

@ -30,6 +30,7 @@ M3 3-in. AA Gun
M1A1 90mm AA Gun 26† N No Move
M2 90mm AA Gun LF [90†, 1 ROF, B11] LF [90†, 1 ROF, B11] 27†[1] B†
20mm Oerlikon Mk4 1† US P 2 TK DR
M20(L) 75mm Recoilless Rifle H† WP7 H† WP7 25† K M O P R &#8734; H | Crewed
Type 89 Heavy Grenade Launcher 1† A P Range &#8804; 2: [{ *:Air Bursts NA *:ROF 1 }] | Animal-Packed
M2 4.2-in. Mortar WP10 WP10 2† K M O P Y QSU | Area FP = 12
M3A1 37mm AT Gun C7 C7 3† C K P QSU

@ -30,6 +30,7 @@ M3 3-in. AA Gun
M1A1 90mm AA Gun 26† N No Move
M2 90mm AA Gun LF [90†, 1 ROF, B11] LF [90†, 1 ROF, B11] 27†[1] B†
20mm Oerlikon Mk4 1† US P 2 TK DR
M20(L) 75mm Recoilless Rifle H† WP7 H† WP7 25† K M O P R &#8734; H | Crewed
Type 89 Heavy Grenade Launcher 1† A P Range &#8804; 2: [{ *:Air Bursts NA *:ROF 1 }] | Animal-Packed
M2 4.2-in. Mortar WP10 WP10 2† K M O P Y QSU | Area FP = 12
M3A1 37mm AT Gun C7 C7 3† C K P QSU

@ -30,6 +30,7 @@ M3 3-in. AA Gun
M1A1 90mm AA Gun 26† N No Move
M2 90mm AA Gun LF [90†, 1 ROF, B11] LF [90†, 1 ROF, B11] 27†[1] B†
20mm Oerlikon Mk4 1† US P 2 TK DR
M20(L) 75mm Recoilless Rifle H† WP7 H† WP7 25† K M O P R &#8734; H | Crewed
Type 89 Heavy Grenade Launcher 1† A P Range &#8804; 2: [{ *:Air Bursts NA *:ROF 1 }] | Animal-Packed
M2 4.2-in. Mortar WP10 WP10 2† K M O P Y QSU | Area FP = 12
M3A1 37mm AT Gun C7 C7 3† C K P QSU

@ -30,6 +30,7 @@ M3 3-in. AA Gun
M1A1 90mm AA Gun 26† N No Move
M2 90mm AA Gun LF [90†, 1 ROF, B11] LF [90†, 1 ROF, B11] 27†[1] B†
20mm Oerlikon Mk4 1† US P 2 TK DR
M20(L) 75mm Recoilless Rifle H† WP7 H† WP7 25† K M O P R &#8734; H | Crewed
Type 89 Heavy Grenade Launcher 1† A P Range &#8804; 2: [{ *:Air Bursts NA *:ROF 1 }] | Animal-Packed
M2 4.2-in. Mortar WP10 WP10 2† K M O P Y QSU | Area FP = 12
M3A1 37mm AT Gun C7 C7 3† C K P QSU

@ -30,6 +30,7 @@ M3 3-in. AA Gun
M1A1 90mm AA Gun 26† N No Move
M2 90mm AA Gun LF [90†, 1 ROF, B11] LF [90†, 1 ROF, B11] 27†[1] B†
20mm Oerlikon Mk4 1† US P 2 TK DR
M20(L) 75mm Recoilless Rifle H† WP7 H† WP7 25† K M O P R &#8734; H | Crewed
Type 89 Heavy Grenade Launcher 1† A P Range &#8804; 2: [{ *:Air Bursts NA *:ROF 1 }] | Animal-Packed
M2 4.2-in. Mortar WP10 WP10 2† K M O P Y QSU | Area FP = 12
M3A1 37mm AT Gun C7 C7 3† C K P QSU

@ -30,6 +30,7 @@ M3 3-in. AA Gun
M1A1 90mm AA Gun 26† N No Move
M2 90mm AA Gun LF [90†, 1 ROF, B11] LF [90†, 1 ROF, B11] 27†[1] B†
20mm Oerlikon Mk4 1† US P 2 TK DR
M20(L) 75mm Recoilless Rifle H† WP7 H† WP7 25† K M O P R &#8734; H | Crewed
Type 89 Heavy Grenade Launcher 1† A P Range &#8804; 2: [{ *:Air Bursts NA *:ROF 1 }] | Animal-Packed
M2 4.2-in. Mortar WP10 WP10 2† K M O P Y QSU | Area FP = 12
M3A1 37mm AT Gun C7 C7 3† C K P QSU

@ -94,6 +94,7 @@ M4A3F WP7[J4+]†[3] s5[J4+] sM4[4+] CS 5[brewup] CS 5[brewup]
M4A3F(75)W WP7 s5 sM8 CS 6 WP7 s5 sM8 CS 6 13† US F†<sup>2</sup> US G US R†<sup>1</sup> US Y C Multiple Hits
M4A1F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 sM8 CS 6 15† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
M4A3F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 sM8 CS 6 16† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
POA-CWS-H5 C5 sM8 CS 6 C5 sM8 CS 6 5† C M TCA restrictions | CE: MA, SA Fire NA | Fire MA &amp; SA NA
M24 WP7 s5 sM8 CS 5 WP7 s5 sM8 CS 5 1† O Y Multiple Hits
M4A3E8 A†[1] s5 sM8 CS 6 A†[1] s5 sM8 CS 6 2† A†<sup>1</sup> P &#8734; A
M4A3E8(105) C7 H9 WP9 s7 sM8 CS 6 C7 H9 WP9 s7 sM8 CS 6 3† C M

@ -94,6 +94,7 @@ M4A3F WP7[J4+]†[3] s5[J4+] sM4[4+] CS 5[brewup] CS 5[brewup]
M4A3F(75)W WP7 s5 sM8 CS 6 WP7 s5 sM8 CS 6 13† US F†<sup>2</sup> US G US R†<sup>1</sup> US Y C Multiple Hits
M4A1F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 sM8 CS 6 15† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
M4A3F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 sM8 CS 6 16† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
POA-CWS-H5 C5 sM8 CS 6 C5 sM8 CS 6 5† C M TCA restrictions | CE: MA, SA Fire NA | Fire MA &amp; SA NA
M24 WP7 s5 sM8 CS 5 WP7 s5 sM8 CS 5 1† O Y Multiple Hits
M4A3E8 A†[1] s5 sM8 CS 6 A†[1] s5 sM8 CS 6 2† A†<sup>1</sup> P &#8734; A
M4A3E8(105) C7 H9 WP9 s7 sM8 CS 6 C7 H9 WP9 s7 sM8 CS 6 3† C M

@ -94,6 +94,7 @@ M4A3F WP7[J4+]†[3] s5[J4+] sM4[4+] CS 5[brewup] CS 5[brewup]
M4A3F(75)W WP7 s5 sM8 CS 6 WP7 s5 sM8 CS 6 13† US F†<sup>2</sup> US G US R†<sup>1</sup> US Y C Multiple Hits
M4A1F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 sM8 CS 6 15† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
M4A3F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 sM8 CS 6 16† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
POA-CWS-H5 C5 sM8 CS 6 C5 sM8 CS 6 5† C M TCA restrictions | CE: MA, SA Fire NA | Fire MA &amp; SA NA
M24 WP7 s5 sM8 CS 5 WP7 s5 sM8 CS 5 1† O Y Multiple Hits
M4A3E8 A†[1] s5 sM8 CS 6 A†[1] s5 sM8 CS 6 2† A†<sup>1</sup> P &#8734; A
M4A3E8(105) C7 H9 WP9 s7 sM8 CS 6 C7 H9 WP9 s7 sM8 CS 6 3† C M

@ -94,6 +94,7 @@ M4A3F WP7[J4+]†[3] s5[J4+] sM4[4+] CS 5[brewup] CS 5[brewup]
M4A3F(75)W WP7 s5 sM8 CS 6 WP7 s5 sM8 CS 6 13† US F†<sup>2</sup> US G US R†<sup>1</sup> US Y C Multiple Hits
M4A1F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 sM8 CS 6 15† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
M4A3F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 sM8 CS 6 16† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
POA-CWS-H5 C5 sM8 CS 6 C5 sM8 CS 6 5† C M TCA restrictions | CE: MA, SA Fire NA | Fire MA &amp; SA NA
M24 WP7 s5 sM8 CS 5 WP7 s5 sM8 CS 5 1† O Y Multiple Hits
M4A3E8 A†[1] s5 sM8 CS 6 A†[1] s5 sM8 CS 6 2† A†<sup>1</sup> P &#8734; A
M4A3E8(105) C7 H9 WP9 s7 sM8 CS 6 C7 H9 WP9 s7 sM8 CS 6 3† C M

@ -94,6 +94,7 @@ M4A3F WP7[J4+]†[3] s5[J4+] sM4[4+] CS 5[brewup] sM4 CS 5[brewu
M4A3F(75)W WP7 s5 sM8 CS 6 WP7 s5 sM8 CS 6 13† US F†<sup>2</sup> US G US R†<sup>1</sup> US Y C Multiple Hits
M4A1F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 sM8 CS 6 15† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
M4A3F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 sM8 CS 6 16† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
POA-CWS-H5 C5 sM8 CS 6 C5 sM8 CS 6 5† C M TCA restrictions | CE: MA, SA Fire NA | Fire MA &amp; SA NA
M24 WP7 s5 sM8 CS 5 WP7 s5 sM8 CS 5 1† O Y Multiple Hits
M4A3E8 A†[1] s5 sM8 CS 6 A†[1] s5 sM8 CS 6 2† A†<sup>1</sup> P &#8734; A
M4A3E8(105) C7 H9 WP9 s7 sM8 CS 6 C7 H9 WP9 s7 sM8 CS 6 3† C M

@ -94,6 +94,7 @@ M4A3F WP7[J4+]†[3] s5[J4+] sM4[4+] CS 5[brewup] WP7†[3] s5 s
M4A3F(75)W WP7 s5 sM8 CS 6 WP7 s5 sM8 CS 6 13† US F†<sup>2</sup> US G US R†<sup>1</sup> US Y C Multiple Hits
M4A1F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 A5†[2] s5 sM8 CS 6 15† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
M4A3F(76)W A4[A4]5[5]†[2] s5[5] sM8 CS 6 A5†[2] s5 sM8 CS 6 16† US A†<sup>2</sup> US F†<sup>1</sup> US G US <s>P</s> US Y C
POA-CWS-H5 C5 sM8 CS 6 C5 sM8 CS 6 5† C M TCA restrictions | CE: MA, SA Fire NA | Fire MA &amp; SA NA
M24 WP7 s5 sM8 CS 5 WP7 s5 sM8 CS 5 1† O Y Multiple Hits
M4A3E8 A†[1] s5 sM8 CS 6 A†[1] s5 sM8 CS 6 2† A†<sup>1</sup> P &#8734; A
M4A3E8(105) C7 H9 WP9 s7 sM8 CS 6 C7 H9 WP9 s7 sM8 CS 6 3† C M

@ -10,9 +10,10 @@ from selenium.webdriver.common.keys import Keys
from vasl_templates.webapp.utils import TempFile
from vasl_templates.webapp.tests.utils import init_webapp, set_player, select_tab, new_scenario, \
find_child, find_children, wait_for_clipboard
find_child, find_children, wait_for_clipboard, generate_sortable_entry_snippet
from vasl_templates.webapp.tests.test_scenario_persistence import load_scenario
from vasl_templates.webapp.tests.test_vehicles_ordnance import add_vo
from vasl_templates.webapp.tests.test_vassal import analyze_vsav
_TEST_VASL_EXTN_FNAME = "test-vasl-extension.zip"
@ -339,6 +340,98 @@ def test_bfp_extensions2( webapp, webdriver ):
# ---------------------------------------------------------------------
def test_ffs_extensions( webapp, webdriver ):
"""Test the Fight For Seoul extension."""
# check if the remote webapp server supports this test
if not webapp.control_tests.has_capability( "chapter-h" ):
return
# analyze a VASL scenario that has the FfS counters
webapp.control_tests \
.set_vassal_version( "random" ) \
.set_vasl_version( "random", None ) # nb: we don't load the extension
init_webapp( webapp, webdriver, vsav_persistence=1, scenario_persistence=1 )
set_player( 1, "american" )
analyze_vsav( "ffs.vsav",
[ [], [] ],
[ [], [] ],
[ "No vehicles/ordnance were imported." ]
)
# analyze the same VASL scenario with the FfS extension loaded
webapp.control_tests \
.set_data_dir( "{REAL}" ) \
.set_vassal_version( "random" ) \
.set_vasl_version( "random", "{REAL}" ) \
.set_vo_notes_dir( "{REAL}" )
init_webapp( webapp, webdriver, vsav_persistence=1, scenario_persistence=1 )
set_player( 1, "american" )
analyze_vsav( "ffs.vsav",
[ [ "ffs/v:000" ], [ "ffs/o:000" ] ],
[ [], [] ],
[ "Imported 1 American vehicle and 1 ordnance." ]
)
# NOTE: All the vehicle/ordnance and multi-applicable notes in the FfS extension
# actually refer to K:FW, so we want to make sure we get the correct ones.
select_tab( "ob1" )
# check the vehicle's OB snippet
btn = find_child( "button.generate[data-id='ob_vehicles_1']" )
btn.click()
wait_for_clipboard( 2, re.compile(
'POA-CWS-H5'
'.+<div class="note"'
'.+&#x2756;'
'.+5\u2020, C, M',
re.DOTALL
) )
# check the vehicle's multi-applicable notes
btn = find_child( "button.generate[data-id='ob_vehicles_ma_notes_1']" )
btn.click()
clipboard = wait_for_clipboard( 2, [
( True, "C", "37mm canister has 12" ),
( True, "M", "Used by the U.S.M.C." ),
], transform=_extract_extn_ma_notes )
# make sure we haven't incorrectly got the *American* multi-applicable notes
assert "and is available in all theaters" not in clipboard
# check the vehicle's Chapter H note
sortable = find_child( "#ob_vehicles-sortable_1" )
snippet = generate_sortable_entry_snippet( sortable, 0 )
assert "U.S.M.C. tankers gave the H5 the nickname" in snippet
# check the ordnance's OB snippet
btn = find_child( "button.generate[data-id='ob_ordnance_1']" )
btn.click()
wait_for_clipboard( 2, re.compile(
r'M20\(L\) 75mm Recoilless Rifle'
'.+<div class="note"'
'.+&#x2756;'
'.+25\u2020, K, M, O, P, R',
re.DOTALL
) )
# check the ordnance's multi-applicable notes
btn = find_child( "button.generate[data-id='ob_ordnance_ma_notes_1']" )
btn.click()
clipboard = wait_for_clipboard( 2, [
( True, "K", "Used by ROK Army for" ),
( True, "M", "Used by the U.S.M.C." ),
( True, "O", "Used by one or more " ),
( True, "P", "Used by the Korean M" ),
( True, "R", "Used by Royal Marine" ),
], transform=_extract_extn_ma_notes )
# check the ordnance's Chapter H note
sortable = find_child( "#ob_ordnance-sortable_1" )
snippet = generate_sortable_entry_snippet( sortable, 0 )
assert "The KMC received their M20's in August 1951." in snippet
# ---------------------------------------------------------------------
def _set_test_vasl_extn( webapp, build_info, build_info_fname="buildFile" ):
"""Install a test VASL extension file."""
with TempFile() as temp_file:

@ -12,7 +12,7 @@ import pytest
from vasl_templates.webapp.utils import TempFile, change_extn, compare_version_strings
from vasl_templates.webapp.tests.utils import \
init_webapp, select_menu_option, get_stored_msg, set_stored_msg, set_stored_msg_marker, wait_for, \
new_scenario, set_player
new_scenario, set_player, find_child
from vasl_templates.webapp.tests.test_scenario_persistence import load_scenario, load_scenario_params, save_scenario, \
assert_scenario_params_complete
@ -580,7 +580,7 @@ def test_analyze_vsav( webapp, webdriver ):
new_scenario()
set_player( 1, "german" )
set_player( 2, "russian" )
_analyze_vsav( "basic.vsav",
analyze_vsav( "basic.vsav",
[ [ "ge/v:033", "ge/v:066" ], [ "ge/o:029" ] ],
[ [ "ru/v:064" ], [ "ru/o:002", "ru/o:006" ] ],
[ "Imported 2 German vehicles and 1 ordnance.", "Imported 1 Russian vehicle and 2 ordnance." ]
@ -590,7 +590,7 @@ def test_analyze_vsav( webapp, webdriver ):
new_scenario()
set_player( 1, "french" )
set_player( 2, "british" )
_analyze_vsav( "basic.vsav",
analyze_vsav( "basic.vsav",
[ [], [] ],
[ [], [] ],
[ "No vehicles/ordnance were imported." ]
@ -600,7 +600,7 @@ def test_analyze_vsav( webapp, webdriver ):
new_scenario()
set_player( 1, "american" )
set_player( 2, "japanese" )
_analyze_vsav( "landing-craft.vsav",
analyze_vsav( "landing-craft.vsav",
[ [ ("sh/v:000","397/0"), ("sh/v:000","399/0"), ("sh/v:006","413/0"), ("sh/v:006","415/0") ], [] ],
[ [ "sh/v:007", "sh/v:008" ], [] ],
[ "Imported 4 American vehicles.", "Imported 2 Japanese vehicles." ]
@ -610,7 +610,7 @@ def test_analyze_vsav( webapp, webdriver ):
new_scenario()
set_player( 1, "belgian" )
set_player( 2, "romanian" )
_analyze_vsav( "common-vo.vsav",
analyze_vsav( "common-vo.vsav",
[ [ "be/v:000", "alc/v:011" ], [ "be/o:001", "alc/o:012" ] ],
[ [ "ro/v:000", "axc/v:027" ], [ "ro/o:003", "axc/o:002" ] ],
[ "Imported 2 Belgian vehicles and 2 ordnance.", "Imported 2 Romanian vehicles and 2 ordnance." ]
@ -619,14 +619,14 @@ def test_analyze_vsav( webapp, webdriver ):
new_scenario()
set_player( 1, "yugoslavian" )
set_player( 2, "croatian" )
_analyze_vsav( "common-vo.vsav",
analyze_vsav( "common-vo.vsav",
[ [ "alc/v:011" ], [ "alc/o:012" ] ],
[ [ "axc/v:027" ], [ "axc/o:002" ] ],
[ "Imported 1 Yugoslavian vehicle and 1 ordnance.", "Imported 1 Croatian vehicle and 1 ordnance." ]
)
# try again with the Germans/Russians
new_scenario()
_analyze_vsav( "common-vo.vsav",
analyze_vsav( "common-vo.vsav",
[ [], [] ],
[ [], [] ],
[ "No vehicles/ordnance were imported." ]
@ -636,7 +636,7 @@ def test_analyze_vsav( webapp, webdriver ):
new_scenario()
set_player( 1, "american" )
set_player( 2, "japanese" )
_analyze_vsav( "extensions-bfp.vsav",
analyze_vsav( "extensions-bfp.vsav",
[ [ "am/v:906" ], [ "am/o:900" ] ],
[ [ "ja/v:902" ], [ "ja/o:902" ] ],
[ "Imported 1 American vehicle and 1 ordnance.", "Imported 1 Japanese vehicle and 1 ordnance." ]
@ -660,7 +660,7 @@ def test_analyze_vsav_hip_concealed( webapp, webdriver ):
# 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",
analyze_vsav( "hip-concealed.vsav",
[ [], [] ],
[ [], [] ],
[ "No vehicles/ordnance were imported." ]
@ -684,7 +684,7 @@ def test_reverse_remapped_gpids( webapp, webdriver ):
new_scenario()
set_player( 1, "american" )
set_player( 2, "croatian" )
_analyze_vsav( "reverse-remapped-gpids-650.vsav",
analyze_vsav( "reverse-remapped-gpids-650.vsav",
[ ["am/v:044"], ["am/o:002","am/o:021"] ],
[ ["cr/v:002","cr/v:003"], ["cr/o:000"] ],
[ "Imported 1 American vehicle and 2 ordnance.", "Imported 2 Croatian vehicles and 1 ordnance." ]
@ -710,7 +710,7 @@ def test_vo_entry_selection_for_theater( webapp, webdriver ):
"SCENARIO_THEATER": theater,
"PLAYER_1": "american",
} } )
_analyze_vsav( "vo-entry-selection-for-theater.vsav",
analyze_vsav( "vo-entry-selection-for-theater.vsav",
[ [], expected ],
[ [], [] ],
[ "Imported 4 American ordnance." ]
@ -893,7 +893,7 @@ def _get_vsav_labels( vsav_dump ):
# ---------------------------------------------------------------------
def _analyze_vsav( fname, expected_ob1, expected_ob2, expected_report ):
def analyze_vsav( fname, expected_ob1, expected_ob2, expected_report ):
"""Analyze a VASL scenario."""
# read the VSAV data
@ -904,13 +904,12 @@ def _analyze_vsav( fname, expected_ob1, expected_ob2, expected_report ):
# send the VSAV data to the front-end to be analyzed
set_stored_msg( "_vsav-persistence_", base64.b64encode( vsav_data ).decode( "utf-8" ) )
prev_info_msg = set_stored_msg_marker( "_last-info_" )
prev_warning_msg = set_stored_msg_marker( "_last-warning_" )
set_stored_msg_marker( "_last-warning_" )
select_menu_option( "analyze_vsav" )
# wait for the analysis to finish
wait_for( 60,
lambda: get_stored_msg("_last-info_") != prev_info_msg or get_stored_msg("_last-warning_") != prev_warning_msg
)
wait_for( 2, lambda: find_child( "#please-wait" ).is_displayed() )
wait_for( 60, lambda: not find_child( "#please-wait" ).is_displayed() )
# check the results
saved_scenario = save_scenario()

@ -299,7 +299,7 @@ class VaslMod:
front_images, back_images = self._get_image_paths( gpid, node.text )
piece = {
"gpid": gpid,
"name": node.attrib["entryName"],
"name": node.attrib["entryName"].strip(),
"front_images": front_images,
"back_images": back_images,
"is_small": int(node.attrib["height"]) <= 48,
@ -382,7 +382,8 @@ class VaslMod:
# ignore dismantled ordnance
if len(front_images) > 1:
for pair in [
("dm","dmb"), ("dm.png","dmm.png"), ("-dm.png","-dm-malf.png"), ("(KFW)dm.png","(KFW)dmx.png")
("dm","dmb"), ("dm.png","dmm.png"), ("-dm.png","-dm-malf.png"),
("(KFW)dm.png","(KFW)dmx.png"), ("amrcl75-malf.png","dm-75rcl.gif")
]:
if check_pair( pair ):
_logger.debug( "Ignoring dismantled images: gpid=%s, front=%s, back=%s",

Loading…
Cancel
Save