#!/usr/bin/env python3 """ Prepare the piece info for a VASL module. The main program used to identify 5/8" counters by reading a module's buildFile and checking the height attribute of the PieceSlot nodes, but it turns out this is the wrong thing to do (this field actually controls the size of the piece's entry in the counter palette): https://github.com/vasl-developers/vasl/issues/1195 For each version of VASL supported, run vassal-shim (getPieceInfo command) to analyze the module's buildFile and get the correct counter sizes. Then pass the output into this script, to generate the final data file that should be saved in the $/data/vasl-$VERSION/ directory, where it will be read by the main program. NOTE: Introducing this process opens the possibility of also extracting the image file paths within the .vmod file, instead of the current messy parsing of the PieceSlot CDATA... :-/ """ import sys import os import json import xml.etree.ElementTree as ET # --------------------------------------------------------------------- # initialize report = {} # figure out which GPID's we're interested in gpids = set() def get_gpids( vo_type ): """Get the GPID's from our data files.""" dname = os.path.join( os.path.dirname(__file__), "../webapp/data", vo_type ) for root,_,fnames in os.walk( dname ): for fname in fnames: if os.path.splitext( fname )[1] != ".json": continue fname = os.path.join( root, fname ) with open( fname, "r", encoding="utf-8" ) as fp: entries = json.load( fp ) for entry in entries: entry_gpid = entry.get( "gpid" ) if not entry_gpid: continue if isinstance( entry_gpid, list ): gpids.update( str(g) for g in entry_gpid ) else: gpids.add( str( entry_gpid ) ) get_gpids( "vehicles" ) get_gpids( "ordnance" ) # parse the piece info generated by vassal-shim doc = ET.parse( sys.stdin ) for piece_info in doc.getroot(): gpid = piece_info.attrib["gpid"] if gpid not in gpids: continue info = {} # check if the next piece is small # FUDGE! We used to check for <= 48, but what we get is GamePiece.boundingBox(), which is # the click zone for the counter, not the actual size of the counter's image :-/ if int( piece_info.attrib["height"] ) <= 55: info["is_small"] = True if info: report[ gpid ] = info # output the final report print( "{" ) lines = [] for gpid, piece_info in report.items(): lines.append( "\"{}\": {}".format( gpid, json.dumps( piece_info ) ) ) print( ",\n".join( lines ) ) print( "}" )