pywargame 0.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pywargame/__init__.py +2 -0
- pywargame/common/__init__.py +3 -0
- pywargame/common/collector.py +87 -0
- pywargame/common/dicedraw.py +363 -0
- pywargame/common/drawdice.py +40 -0
- pywargame/common/singleton.py +22 -0
- pywargame/common/test.py +25 -0
- pywargame/common/verbose.py +59 -0
- pywargame/common/verboseguard.py +53 -0
- pywargame/cyberboard/__init__.py +18 -0
- pywargame/cyberboard/archive.py +283 -0
- pywargame/cyberboard/base.py +63 -0
- pywargame/cyberboard/board.py +462 -0
- pywargame/cyberboard/cell.py +200 -0
- pywargame/cyberboard/collect.py +49 -0
- pywargame/cyberboard/collectgbx0pwd.py +30 -0
- pywargame/cyberboard/collectgbxext.py +30 -0
- pywargame/cyberboard/collectgsnexp.py +32 -0
- pywargame/cyberboard/collectgsnext.py +30 -0
- pywargame/cyberboard/draw.py +396 -0
- pywargame/cyberboard/exporter.py +1132 -0
- pywargame/cyberboard/extractor.py +240 -0
- pywargame/cyberboard/features.py +17 -0
- pywargame/cyberboard/gamebox.py +81 -0
- pywargame/cyberboard/gbxexp.py +76 -0
- pywargame/cyberboard/gbxext.py +64 -0
- pywargame/cyberboard/gsnexp.py +147 -0
- pywargame/cyberboard/gsnext.py +59 -0
- pywargame/cyberboard/head.py +111 -0
- pywargame/cyberboard/image.py +76 -0
- pywargame/cyberboard/main.py +47 -0
- pywargame/cyberboard/mark.py +102 -0
- pywargame/cyberboard/palette.py +36 -0
- pywargame/cyberboard/piece.py +169 -0
- pywargame/cyberboard/player.py +36 -0
- pywargame/cyberboard/scenario.py +115 -0
- pywargame/cyberboard/testgrid.py +156 -0
- pywargame/cyberboard/tile.py +121 -0
- pywargame/cyberboard/tray.py +68 -0
- pywargame/cyberboard/windows.py +41 -0
- pywargame/cyberboard/zeropwd.py +45 -0
- pywargame/cyberboard.py +2728 -0
- pywargame/gbx0pwd.py +2776 -0
- pywargame/gbxextract.py +2795 -0
- pywargame/gsnexport.py +16499 -0
- pywargame/gsnextract.py +2790 -0
- pywargame/latex/__init__.py +2 -0
- pywargame/latex/collect.py +34 -0
- pywargame/latex/latexexporter.py +4010 -0
- pywargame/latex/main.py +184 -0
- pywargame/vassal/__init__.py +66 -0
- pywargame/vassal/base.py +139 -0
- pywargame/vassal/board.py +243 -0
- pywargame/vassal/buildfile.py +60 -0
- pywargame/vassal/chart.py +79 -0
- pywargame/vassal/chessclock.py +197 -0
- pywargame/vassal/collect.py +98 -0
- pywargame/vassal/collectpatch.py +28 -0
- pywargame/vassal/command.py +21 -0
- pywargame/vassal/documentation.py +322 -0
- pywargame/vassal/dumpcollect.py +28 -0
- pywargame/vassal/dumpvsav.py +28 -0
- pywargame/vassal/element.py +439 -0
- pywargame/vassal/exporter.py +89 -0
- pywargame/vassal/extension.py +101 -0
- pywargame/vassal/folder.py +103 -0
- pywargame/vassal/game.py +940 -0
- pywargame/vassal/gameelements.py +1091 -0
- pywargame/vassal/globalkey.py +127 -0
- pywargame/vassal/globalproperty.py +433 -0
- pywargame/vassal/grid.py +573 -0
- pywargame/vassal/map.py +1061 -0
- pywargame/vassal/mapelements.py +1020 -0
- pywargame/vassal/merge.py +57 -0
- pywargame/vassal/merger.py +460 -0
- pywargame/vassal/moduledata.py +275 -0
- pywargame/vassal/mrgcollect.py +31 -0
- pywargame/vassal/patch.py +44 -0
- pywargame/vassal/patchcollect.py +28 -0
- pywargame/vassal/player.py +83 -0
- pywargame/vassal/save.py +495 -0
- pywargame/vassal/skel.py +380 -0
- pywargame/vassal/trait.py +224 -0
- pywargame/vassal/traits/__init__.py +36 -0
- pywargame/vassal/traits/area.py +50 -0
- pywargame/vassal/traits/basic.py +35 -0
- pywargame/vassal/traits/calculatedproperty.py +22 -0
- pywargame/vassal/traits/cargo.py +29 -0
- pywargame/vassal/traits/click.py +41 -0
- pywargame/vassal/traits/clone.py +28 -0
- pywargame/vassal/traits/delete.py +24 -0
- pywargame/vassal/traits/deselect.py +32 -0
- pywargame/vassal/traits/dynamicproperty.py +112 -0
- pywargame/vassal/traits/globalcommand.py +55 -0
- pywargame/vassal/traits/globalhotkey.py +26 -0
- pywargame/vassal/traits/globalproperty.py +54 -0
- pywargame/vassal/traits/hide.py +67 -0
- pywargame/vassal/traits/label.py +76 -0
- pywargame/vassal/traits/layer.py +105 -0
- pywargame/vassal/traits/mark.py +20 -0
- pywargame/vassal/traits/mask.py +85 -0
- pywargame/vassal/traits/mat.py +26 -0
- pywargame/vassal/traits/moved.py +35 -0
- pywargame/vassal/traits/movefixed.py +51 -0
- pywargame/vassal/traits/nonrect.py +95 -0
- pywargame/vassal/traits/nostack.py +55 -0
- pywargame/vassal/traits/place.py +104 -0
- pywargame/vassal/traits/prototype.py +20 -0
- pywargame/vassal/traits/report.py +34 -0
- pywargame/vassal/traits/restrictaccess.py +28 -0
- pywargame/vassal/traits/restrictcommand.py +32 -0
- pywargame/vassal/traits/return.py +40 -0
- pywargame/vassal/traits/rotate.py +62 -0
- pywargame/vassal/traits/sendto.py +59 -0
- pywargame/vassal/traits/sheet.py +129 -0
- pywargame/vassal/traits/skel.py +9 -0
- pywargame/vassal/traits/stack.py +28 -0
- pywargame/vassal/traits/submenu.py +27 -0
- pywargame/vassal/traits/trail.py +61 -0
- pywargame/vassal/traits/trigger.py +72 -0
- pywargame/vassal/turn.py +272 -0
- pywargame/vassal/upgrade.py +191 -0
- pywargame/vassal/vmod.py +323 -0
- pywargame/vassal/vsav.py +100 -0
- pywargame/vassal/widget.py +358 -0
- pywargame/vassal/withtraits.py +634 -0
- pywargame/vassal/xml.py +4 -0
- pywargame/vassal/zone.py +399 -0
- pywargame/vassal.py +12500 -0
- pywargame/vmodpatch.py +12548 -0
- pywargame/vsavdump.py +12533 -0
- pywargame/vslmerge.py +13015 -0
- pywargame/wgexport.py +16689 -0
- pywargame/ztexport.py +14351 -0
- pywargame/zuntzu/__init__.py +5 -0
- pywargame/zuntzu/base.py +82 -0
- pywargame/zuntzu/collect.py +38 -0
- pywargame/zuntzu/countersheet.py +250 -0
- pywargame/zuntzu/dicehand.py +48 -0
- pywargame/zuntzu/exporter.py +936 -0
- pywargame/zuntzu/gamebox.py +154 -0
- pywargame/zuntzu/map.py +36 -0
- pywargame/zuntzu/piece.py +37 -0
- pywargame/zuntzu/scenario.py +208 -0
- pywargame/zuntzu/ztexp.py +115 -0
- pywargame-0.3.1.dist-info/METADATA +353 -0
- pywargame-0.3.1.dist-info/RECORD +150 -0
- pywargame-0.3.1.dist-info/WHEEL +5 -0
- pywargame-0.3.1.dist-info/licenses/LICENSE +5 -0
- pywargame-0.3.1.dist-info/top_level.txt +1 -0
pywargame/vassal/vmod.py
ADDED
@@ -0,0 +1,323 @@
|
|
1
|
+
# ====================================================================
|
2
|
+
#
|
3
|
+
# Wrapper around a module
|
4
|
+
#
|
5
|
+
## BEGIN_IMPORT
|
6
|
+
from . xml import xmlns
|
7
|
+
## END_IMPORT
|
8
|
+
|
9
|
+
class VMod:
|
10
|
+
BUILD_FILE = 'buildFile.xml'
|
11
|
+
BUILD_FILE_SANS = 'buildFile'
|
12
|
+
MODULE_DATA = 'moduledata'
|
13
|
+
EXTENSION_DATA = 'extensiondata'
|
14
|
+
|
15
|
+
def __init__(self,filename,mode):
|
16
|
+
'''Interface to VASSAL Module (a Zip file)'''
|
17
|
+
self._mode = mode
|
18
|
+
self._vmod = self._open(filename,mode)
|
19
|
+
|
20
|
+
def __enter__(self):
|
21
|
+
'''Enter context'''
|
22
|
+
return self
|
23
|
+
|
24
|
+
def __exit__(self,*e):
|
25
|
+
'''Exit context'''
|
26
|
+
self._vmod.close()
|
27
|
+
return None
|
28
|
+
|
29
|
+
def _open(self,filename,mode):
|
30
|
+
'''Open a file in VMod'''
|
31
|
+
from zipfile import ZipFile, ZIP_DEFLATED
|
32
|
+
|
33
|
+
return ZipFile(filename,mode,compression=ZIP_DEFLATED)
|
34
|
+
|
35
|
+
def removeFiles(self,*filenames):
|
36
|
+
'''Open a temporary zip file, and copy content from there to
|
37
|
+
that file, excluding filenames mentioned in the arguments.
|
38
|
+
Then close current file, rename the temporary file to this,
|
39
|
+
and reopen in 'append' mode. The deleted files are returned
|
40
|
+
as a dictionary.
|
41
|
+
|
42
|
+
Parameters
|
43
|
+
----------
|
44
|
+
filenames : tuple
|
45
|
+
List of files to remove from the VMOD
|
46
|
+
|
47
|
+
Returns
|
48
|
+
-------
|
49
|
+
files : dict
|
50
|
+
Dictionary from filename to content of the removed files.
|
51
|
+
|
52
|
+
Note, the VMOD is re-opened in append mode after this
|
53
|
+
'''
|
54
|
+
from tempfile import mkdtemp
|
55
|
+
from zipfile import ZipFile
|
56
|
+
from shutil import move, rmtree
|
57
|
+
from os import path
|
58
|
+
|
59
|
+
tempdir = mkdtemp()
|
60
|
+
ret = {}
|
61
|
+
|
62
|
+
try:
|
63
|
+
tempname = path.join(tempdir, 'new.zip')
|
64
|
+
with self._open(tempname, 'w') as tmp:
|
65
|
+
|
66
|
+
for item in self._vmod.infolist():
|
67
|
+
data = self._vmod.read(item.filename)
|
68
|
+
|
69
|
+
if item.filename not in filenames:
|
70
|
+
tmp.writestr(item, data)
|
71
|
+
else:
|
72
|
+
ret[item.filename] = data
|
73
|
+
|
74
|
+
name = self._vmod.filename
|
75
|
+
self._vmod.close()
|
76
|
+
move(tempname, name)
|
77
|
+
|
78
|
+
self._mode = 'a'
|
79
|
+
self._vmod = self._open(name,'a')
|
80
|
+
finally:
|
81
|
+
rmtree(tempdir)
|
82
|
+
|
83
|
+
# Return the removed files
|
84
|
+
return ret
|
85
|
+
|
86
|
+
def clone(self,newname,mode='a',filter=lambda f:False):
|
87
|
+
'''Clones the VMod and returns new object.
|
88
|
+
|
89
|
+
This is done by first opening a temporary ZIP file, and then
|
90
|
+
copy all files of this module to that tempoary. Then the
|
91
|
+
temporary ZIP is closed and moved to its `newname`. After
|
92
|
+
that, we open it up as a VMod (write-enabled).
|
93
|
+
|
94
|
+
'''
|
95
|
+
from tempfile import mkdtemp
|
96
|
+
from zipfile import ZipFile
|
97
|
+
from shutil import move, rmtree
|
98
|
+
from os import path
|
99
|
+
|
100
|
+
tempdir = mkdtemp()
|
101
|
+
ret = None
|
102
|
+
|
103
|
+
try:
|
104
|
+
tempname = path.join(tempdir, 'new.zip')
|
105
|
+
with self._open(tempname, 'w') as tmp:
|
106
|
+
|
107
|
+
for item in self._vmod.infolist():
|
108
|
+
# Ignore some files, a given by filter functoin
|
109
|
+
if filter(item.filename):
|
110
|
+
continue
|
111
|
+
|
112
|
+
data = self._vmod.read(item.filename)
|
113
|
+
|
114
|
+
tmp.writestr(item, data)
|
115
|
+
|
116
|
+
move(tempname, newname)
|
117
|
+
|
118
|
+
ret = VMod(newname,mode)
|
119
|
+
finally:
|
120
|
+
rmtree(tempdir)
|
121
|
+
|
122
|
+
return ret
|
123
|
+
|
124
|
+
|
125
|
+
def fileName(self):
|
126
|
+
'''Get name of VMod file'''
|
127
|
+
return self._vmod.filename
|
128
|
+
|
129
|
+
def replaceFiles(self,**files):
|
130
|
+
'''Replace existing files with new files
|
131
|
+
|
132
|
+
Parameters
|
133
|
+
----------
|
134
|
+
files : dict
|
135
|
+
Dictionary that maps file name to content
|
136
|
+
'''
|
137
|
+
self.removeFiles(*list(files.keys()))
|
138
|
+
|
139
|
+
self.addFiles(**files);
|
140
|
+
|
141
|
+
def addFiles(self,**files):
|
142
|
+
'''Add a set of files to this
|
143
|
+
|
144
|
+
Parameters
|
145
|
+
----------
|
146
|
+
files : dict
|
147
|
+
Dictionary that maps file name to content.
|
148
|
+
'''
|
149
|
+
for filename,data in files.items():
|
150
|
+
self.addFile(filename,data)
|
151
|
+
|
152
|
+
def addFile(self,filename,content):
|
153
|
+
'''Add a file to this
|
154
|
+
|
155
|
+
Parameters
|
156
|
+
----------
|
157
|
+
filename : str
|
158
|
+
File name in module
|
159
|
+
content : str
|
160
|
+
File content
|
161
|
+
|
162
|
+
Returns
|
163
|
+
-------
|
164
|
+
element : File
|
165
|
+
The added element
|
166
|
+
'''
|
167
|
+
self._vmod.writestr(filename,content)
|
168
|
+
|
169
|
+
def addExternalFile(self,filename,target=None):
|
170
|
+
'''Add an external file element to this
|
171
|
+
|
172
|
+
Parameters
|
173
|
+
----------
|
174
|
+
kwargs : dict
|
175
|
+
Dictionary of attribute key-value pairs
|
176
|
+
|
177
|
+
Returns
|
178
|
+
-------
|
179
|
+
element : ExternalFile
|
180
|
+
The added element
|
181
|
+
'''
|
182
|
+
if target is None: target = filename
|
183
|
+
self._vmod.write(filename,target)
|
184
|
+
|
185
|
+
def getFileNames(self):
|
186
|
+
'''Get all filenames in module'''
|
187
|
+
return self._vmod.namelist()
|
188
|
+
|
189
|
+
def getFileMapping(self):
|
190
|
+
'''Get mapping from short name to full archive name'''
|
191
|
+
from pathlib import Path
|
192
|
+
|
193
|
+
names = self.getFileNames()
|
194
|
+
|
195
|
+
return {Path(p).stem: str(p) for p in names}
|
196
|
+
|
197
|
+
def getFiles(self,*filenames):
|
198
|
+
'''Return named files as a dictionary.
|
199
|
+
|
200
|
+
Parameters
|
201
|
+
----------
|
202
|
+
filenames : tuple
|
203
|
+
The files to get
|
204
|
+
|
205
|
+
Returns
|
206
|
+
-------
|
207
|
+
files : dict
|
208
|
+
Mapping of file name to file content
|
209
|
+
'''
|
210
|
+
fn = self.getFileNames()
|
211
|
+
ret = {}
|
212
|
+
for f in filenames:
|
213
|
+
if f not in fn:
|
214
|
+
continue
|
215
|
+
|
216
|
+
ret[f] = self._vmod.read(f)
|
217
|
+
|
218
|
+
return ret
|
219
|
+
|
220
|
+
def getDOM(self,filename):
|
221
|
+
'''Get content of a file decoded as XML DOM
|
222
|
+
|
223
|
+
Parameters
|
224
|
+
----------
|
225
|
+
filename : str
|
226
|
+
Name of file in module
|
227
|
+
'''
|
228
|
+
#from xmlns import parseString
|
229
|
+
|
230
|
+
r = self.getFiles(filename)
|
231
|
+
if filename not in r:
|
232
|
+
raise RuntimeError(f'No {filename} found!')
|
233
|
+
|
234
|
+
return xmlns.parseString(r[filename])
|
235
|
+
|
236
|
+
def getBuildFile(self):
|
237
|
+
'''Get the buildFile.xml decoded as a DOM tree'''
|
238
|
+
try:
|
239
|
+
return self.getDOM(VMod.BUILD_FILE)
|
240
|
+
except Exception as e:
|
241
|
+
print(e)
|
242
|
+
try:
|
243
|
+
return self.getDOM(VMod.BUILD_FILE_SANS)
|
244
|
+
except:
|
245
|
+
raise
|
246
|
+
|
247
|
+
def getModuleData(self):
|
248
|
+
'''Get the moduledata decoded as a DOM tree'''
|
249
|
+
return self.getDOM(VMod.MODULE_DATA)
|
250
|
+
|
251
|
+
def getExtensionData(self):
|
252
|
+
'''Get the moduledata decoded as a DOM tree'''
|
253
|
+
return self.getDOM(VMod.EXTENSION_DATA)
|
254
|
+
|
255
|
+
def isExtension(self):
|
256
|
+
return VMod.EXTENSION_DATA in self.getFileNames()
|
257
|
+
|
258
|
+
def getInternalFile(self,filename,mode):
|
259
|
+
return self._vmod.open(filename,mode)
|
260
|
+
|
261
|
+
def addVSav(self,build):
|
262
|
+
'''Add a `VSav` element to this
|
263
|
+
|
264
|
+
Parameters
|
265
|
+
----------
|
266
|
+
kwargs : dict
|
267
|
+
Dictionary of attribute key-value pairs
|
268
|
+
|
269
|
+
Returns
|
270
|
+
-------
|
271
|
+
element : VSav
|
272
|
+
The added element
|
273
|
+
'''
|
274
|
+
return VSav(build=build,vmod=self)
|
275
|
+
|
276
|
+
@classmethod
|
277
|
+
def patch(cls,vmod_filename,patch_name,verbose):
|
278
|
+
'''Patch a module with a Python script
|
279
|
+
|
280
|
+
Parameters
|
281
|
+
----------
|
282
|
+
vmod_filename : str
|
283
|
+
File name of module to patch. Will be overwritten
|
284
|
+
patch_name : str
|
285
|
+
File name of Python script to patch with
|
286
|
+
verbose : bool
|
287
|
+
Whether to be verbose or not
|
288
|
+
'''
|
289
|
+
## BEGIN_IMPORT
|
290
|
+
from common import VerboseGuard, Verbose
|
291
|
+
## END_IMPORT
|
292
|
+
|
293
|
+
with cls(vmod_filename,'r') as vmod:
|
294
|
+
buildFile = BuildFile(vmod.getBuildFile())
|
295
|
+
moduleData = ModuleData(vmod.getModuleData())
|
296
|
+
|
297
|
+
from importlib.util import spec_from_file_location, module_from_spec
|
298
|
+
from pathlib import Path
|
299
|
+
from sys import modules
|
300
|
+
|
301
|
+
p = Path(patch_name)
|
302
|
+
|
303
|
+
spec = spec_from_file_location(p.stem, p.absolute())
|
304
|
+
module = module_from_spec(spec)
|
305
|
+
spec.loader.exec_module(module)
|
306
|
+
|
307
|
+
modules[p.stem] = module
|
308
|
+
|
309
|
+
with cls(vmod_filename,'a') as vmod:
|
310
|
+
module.patch(buildFile,
|
311
|
+
moduleData,
|
312
|
+
vmod,
|
313
|
+
verbose)
|
314
|
+
|
315
|
+
vmod.replaceFiles(**{VMod.BUILD_FILE :
|
316
|
+
buildFile.encode(),
|
317
|
+
VMod.MODULE_DATA :
|
318
|
+
moduleData.encode()})
|
319
|
+
|
320
|
+
|
321
|
+
#
|
322
|
+
# EOF
|
323
|
+
#
|
pywargame/vassal/vsav.py
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
## BEGIN_IMPORT
|
2
|
+
from . save import SaveData, SaveFile, SaveIO
|
3
|
+
from . moduledata import ModuleData
|
4
|
+
from . vmod import VMod
|
5
|
+
## END_IMPORT
|
6
|
+
|
7
|
+
# --------------------------------------------------------------------
|
8
|
+
class VSav:
|
9
|
+
SAVE_DATA = 'savedata'
|
10
|
+
|
11
|
+
def __init__(self,build,vmod):
|
12
|
+
'''Create a VASSAL save file programmatically
|
13
|
+
|
14
|
+
Parameters
|
15
|
+
----------
|
16
|
+
build : xml.dom.Document
|
17
|
+
`buildFile.xml` as XML
|
18
|
+
vmod : VMod
|
19
|
+
Module file
|
20
|
+
'''
|
21
|
+
from time import time
|
22
|
+
self._vmod = vmod
|
23
|
+
self._game = build.getGame()
|
24
|
+
self._start = int(time()*1000)
|
25
|
+
|
26
|
+
|
27
|
+
def createSaveData(self,description=None):
|
28
|
+
'''Create `savedgame`'''
|
29
|
+
desc = (self._game['description']
|
30
|
+
if description is None else description)
|
31
|
+
self._saveData = SaveData(root=None)
|
32
|
+
data = self._saveData.addData()
|
33
|
+
data.addVersion (version =self._game['version'])
|
34
|
+
data.addVASSALVersion(version =self._game['VassalVersion'])
|
35
|
+
data.addDescription (description=desc)
|
36
|
+
data.addDateSaved (milisecondsSinceEpoch=self._start)
|
37
|
+
return self._saveData
|
38
|
+
|
39
|
+
def createModuleData(self):
|
40
|
+
'''Create `moduleData`'''
|
41
|
+
self._moduleData = ModuleData()
|
42
|
+
data = self._moduleData.addData()
|
43
|
+
data.addVersion (version =self._game['version'])
|
44
|
+
data.addVASSALVersion(version =self._game['VassalVersion'])
|
45
|
+
data.addName (name =self._game['name'])
|
46
|
+
data.addDescription (description=self._game['description'])
|
47
|
+
data.addDateSaved (milisecondsSinceEpoch=self._start)
|
48
|
+
return self._moduleData
|
49
|
+
|
50
|
+
def addSaveFile(self):
|
51
|
+
'''Add a save file to the module
|
52
|
+
|
53
|
+
Returns
|
54
|
+
-------
|
55
|
+
vsav : SaveFile
|
56
|
+
Save file to add content to
|
57
|
+
'''
|
58
|
+
self._saveFile = SaveFile(game=self._game,firstid=self._start)
|
59
|
+
return self._saveFile
|
60
|
+
|
61
|
+
def run(self,
|
62
|
+
savename = 'Save.vsav',
|
63
|
+
description = None,
|
64
|
+
update = None):
|
65
|
+
'''Run this to generate the save file
|
66
|
+
|
67
|
+
Parameters
|
68
|
+
----------
|
69
|
+
savename : str
|
70
|
+
Name of save file to write
|
71
|
+
description : str
|
72
|
+
Short description of the save file
|
73
|
+
update : callable or None
|
74
|
+
A callable that can update trait states after the piece
|
75
|
+
traits have been fully flattened. The callable should
|
76
|
+
adhere to the interface
|
77
|
+
|
78
|
+
update(name,traits)
|
79
|
+
|
80
|
+
where `name` is the name of the piece (entryName) and
|
81
|
+
`traits` is a list of unrolled traits.
|
82
|
+
|
83
|
+
'''
|
84
|
+
from zipfile import ZipFile, ZIP_DEFLATED
|
85
|
+
|
86
|
+
self.createSaveData(description=description)
|
87
|
+
self.createModuleData()
|
88
|
+
|
89
|
+
with self._vmod.getInternalFile(savename,'w') as vsav:
|
90
|
+
with ZipFile(vsav,'w',ZIP_DEFLATED) as zvsav:
|
91
|
+
# The key is set to 0xAA (alternating ones and zeros)
|
92
|
+
SaveIO.writeInZip(zvsav,0xAA,
|
93
|
+
self._saveFile.getLines(update=update))
|
94
|
+
|
95
|
+
zvsav.writestr(VMod.MODULE_DATA, self._moduleData.encode())
|
96
|
+
zvsav.writestr(VSav.SAVE_DATA, self._saveData.encode())
|
97
|
+
|
98
|
+
#
|
99
|
+
# EOF
|
100
|
+
#
|