mirror of
https://github.com/lcdr/utils.git
synced 2024-08-30 17:32:16 +00:00
Added if, while and break statements to support more complex parsing logic.
This commit is contained in:
parent
3e10476cd6
commit
86dfe01355
@ -15,7 +15,7 @@ Index 3 ($+7DC480):
|
||||
[bit] - ???
|
||||
|
||||
Index 4 ($+8A3A40):
|
||||
[EVAL:creation]
|
||||
if creation:
|
||||
[bit] - flag
|
||||
[u64] - ???, could be "co" from xml data
|
||||
[bit] - flag
|
||||
|
@ -1,6 +1,6 @@
|
||||
Component 1 - ControllablePhysics (tested using LOT 1)
|
||||
Index 1 ($+845770):
|
||||
[EVAL:creation]
|
||||
if creation:
|
||||
[bit] - flag
|
||||
[u32] - ???
|
||||
[bit] - ???
|
||||
@ -50,5 +50,5 @@ Index 1 ($+845770):
|
||||
[float] - ???
|
||||
[float] - ???
|
||||
[float] - ???
|
||||
[EVAL:not creation]
|
||||
if not creation:
|
||||
[bit] - flag?
|
||||
|
@ -1,6 +1,6 @@
|
||||
Component 7 - Destructible (tested using LOT 1)
|
||||
Index 1 ($+939820):
|
||||
[EVAL:creation]
|
||||
if creation:
|
||||
[bit] - flag, expect == False
|
||||
[u32] - count for following structs
|
||||
[u32] - ???
|
||||
@ -16,7 +16,7 @@ Index 1 ($+939820):
|
||||
[bit] - ???
|
||||
trigger=[bit] - ???, seems to trigger [s64] below?
|
||||
[bit] - ???
|
||||
[EVAL:trigger]
|
||||
if trigger:
|
||||
[s64] - ???
|
||||
[u32] - ???
|
||||
[bit] - flag, expect == False
|
||||
@ -34,12 +34,12 @@ Index 1 ($+939820):
|
||||
[bit] - ???
|
||||
trigger=[bit] - ???, seems to trigger [s64] below?
|
||||
[bit] - ???
|
||||
[EVAL:trigger]
|
||||
if trigger:
|
||||
[s64] - ???
|
||||
[u32] - ???
|
||||
|
||||
Index 2 ($+92BBD0):
|
||||
[EVAL:creation]
|
||||
if creation:
|
||||
[bit] - flag
|
||||
[u32] - ???, assert == 0
|
||||
[u32] - ???, assert == 0
|
||||
@ -67,10 +67,10 @@ Index 2 ($+92BBD0):
|
||||
[u32] - count
|
||||
[s32] - faction id
|
||||
trigger=[bit] - flag
|
||||
[EVAL:creation]
|
||||
if creation:
|
||||
[bit] - flag, assert == False
|
||||
[bit] - flag, assert == False
|
||||
[EVAL:trigger]
|
||||
if trigger:
|
||||
[bit] - ???, assert == False
|
||||
[bit] - flag
|
||||
[u32] - ???
|
||||
|
@ -1,6 +1,6 @@
|
||||
Component 2 - Render (tested using LOT 1)
|
||||
Index 1 ($+840310):
|
||||
[EVAL:creation]
|
||||
if creation:
|
||||
[u32] - number of BehaviorEffects? (see BehaviorEffect table in cdclient), if this is -1 the client logs "Bad FX Unserialize", expect != -1
|
||||
[u8] - length
|
||||
[u8] - effectID string
|
||||
|
@ -1,6 +1,6 @@
|
||||
Component 5 - Script (tested using LOT 3495)
|
||||
Index 1 ($+87CDF0):
|
||||
[EVAL:creation]
|
||||
if creation:
|
||||
[bit] - flag
|
||||
[u32] - size of following struct
|
||||
[u8] - compressed data, x bytes according to prev struct
|
||||
|
@ -1,6 +1,6 @@
|
||||
Component 3 - SimplePhysics (tested using LOT 7701)
|
||||
Index 1 ($+7E4B00):
|
||||
[EVAL:creation]
|
||||
if creation:
|
||||
[bit] - ???
|
||||
[float] - ???
|
||||
[bit] - flag
|
||||
|
@ -1,6 +1,6 @@
|
||||
Component 9 - Skill (tested using LOT 1)
|
||||
Index 1 ($+806270):
|
||||
[EVAL:creation]
|
||||
if creation:
|
||||
[bit] - flag
|
||||
[u32] - count for following structs
|
||||
[u32] - ???
|
||||
|
@ -11,21 +11,29 @@ VAR_CHARS = r"[^ \t\[\]]+"
|
||||
BITSTREAM_TYPES = {"bit": c_bit, "float": c_float, "double": c_double, "s8": c_int8, "u8": c_uint8, "s16": c_int16, "u16": c_uint16, "s32": c_int32, "u32": c_uint32, "s64": c_int64, "u64": c_uint64}
|
||||
TYPES_RE = "("+"|".join(BITSTREAM_TYPES.keys())+")"
|
||||
|
||||
DEFINITION_SYNTAX = re.compile(r"""^
|
||||
(?P<indent>\t*) # Indentation
|
||||
((?P<var_assign>"""+VAR_CHARS+r""")=)? # Assign this struct a variable so the value can be back-referenced later
|
||||
\[(
|
||||
(EVAL:(?P<eval>.+)) # Expression to be evaluated, evaluated value acts like struct value, usually used for variables
|
||||
|
|
||||
(?P<type>"""+TYPES_RE+r""") # Struct type
|
||||
)\]
|
||||
(\ -\ (?P<description>.*?) # Description for the struct
|
||||
(,\ expect\ (?P<expect>(.+?)))? # Expect the value to be like this expression. Struct attribute 'unexpected' will be None if no expects, True if any expects are False, or False if all expects are True.
|
||||
(,\ assert\ (?P<assert>(.+?)))? # Assert the value to be like this expression, will raise AssertionError if not True.
|
||||
)?$
|
||||
DEFINITION_SYNTAX = re.compile(r"""
|
||||
^(?P<indent>\t*) # Indentation
|
||||
(if\ (?P<if_condition>.+):
|
||||
|
|
||||
while\ (?P<while_condition>.+):
|
||||
|
|
||||
(?P<break>break)
|
||||
|
|
||||
((?P<var_assign>"""+VAR_CHARS+r""")=)? # Assign this struct a variable so the value can be back-referenced later
|
||||
\[
|
||||
(?P<type>"""+TYPES_RE+r""") # Struct type
|
||||
\]
|
||||
\ -\ (?P<description>.*?) # Description for the struct
|
||||
(,\ expect\ (?P<expect>(.+?)))? # Expect the value to be like this expression. Struct attribute 'unexpected' will be None if no expects, True if any expects are False, or False if all expects are True.
|
||||
(,\ assert\ (?P<assert>(.+?)))? # Assert the value to be like this expression, will raise AssertionError if not True.
|
||||
)$
|
||||
""", re.VERBOSE)
|
||||
|
||||
Definition = namedtuple("Definition", ("var_assign", "eval", "type", "description", "expects", "asserts"))
|
||||
IfStatement = namedtuple("IfStatement", ("condition",))
|
||||
WhileStatement = namedtuple("WhileStatement", ("condition",))
|
||||
BreakStatement = namedtuple("BreakStatement", ())
|
||||
StructDefinition = namedtuple("struct_token", ("var_assign", "type", "description", "expects", "asserts"))
|
||||
|
||||
Structure = namedtuple("Structure", ("level", "description", "value", "unexpected"))
|
||||
|
||||
class StructParser:
|
||||
@ -95,12 +103,16 @@ class StructParser:
|
||||
|
||||
@staticmethod
|
||||
def _to_def_tuple(def_):
|
||||
if def_["eval"] is not None:
|
||||
eval_ = compile(def_["eval"], "<eval>", "eval")
|
||||
type_ = None
|
||||
else:
|
||||
eval_ = None
|
||||
type_ = BITSTREAM_TYPES[def_["type"]]
|
||||
if def_["if_condition"] is not None:
|
||||
condition = compile(def_["if_condition"], "<if_condition>", "eval")
|
||||
return IfStatement(condition)
|
||||
if def_["while_condition"] is not None:
|
||||
condition = compile(def_["while_condition"], "<while_condition>", "eval")
|
||||
return WhileStatement(condition)
|
||||
if def_["break"] is not None:
|
||||
return BreakStatement()
|
||||
|
||||
type_ = BITSTREAM_TYPES[def_["type"]]
|
||||
|
||||
if def_["expect"] is not None:
|
||||
expects = [compile("value "+i, "<expect>", "eval") for i in def_["expect"].split(" and ")]
|
||||
@ -111,13 +123,24 @@ class StructParser:
|
||||
else:
|
||||
asserts = ()
|
||||
|
||||
return Definition(def_["var_assign"], eval_, type_, def_["description"], expects, asserts)
|
||||
return StructDefinition(def_["var_assign"], type_, def_["description"], expects, asserts)
|
||||
|
||||
def _parse_struct_occurrences(self, stream, defs, stack_level=0, repeat_times=1):
|
||||
for _ in range(repeat_times):
|
||||
for def_, children in defs:
|
||||
if def_.eval is not None:
|
||||
value = self._eval(def_.eval)
|
||||
if isinstance(def_, IfStatement):
|
||||
if children and self._eval(def_.condition):
|
||||
break_ = yield from self._parse_struct_occurrences(stream, children, stack_level+1)
|
||||
if break_:
|
||||
return True
|
||||
elif isinstance(def_, WhileStatement):
|
||||
if children:
|
||||
while self._eval(def_.condition):
|
||||
break_ = yield from self._parse_struct_occurrences(stream, children, stack_level+1)
|
||||
if break_:
|
||||
break
|
||||
elif isinstance(def_, BreakStatement):
|
||||
return True
|
||||
else:
|
||||
value = stream.read(def_.type)
|
||||
|
||||
@ -138,8 +161,10 @@ class StructParser:
|
||||
self._variables[def_.var_assign] = value
|
||||
yield Structure(stack_level, def_.description, value, unexpected)
|
||||
|
||||
if children:
|
||||
yield from self._parse_struct_occurrences(stream, children, stack_level+1, value)
|
||||
if children and value:
|
||||
break_ = yield from self._parse_struct_occurrences(stream, children, stack_level+1, value)
|
||||
if break_:
|
||||
return True
|
||||
|
||||
def _eval(self, expression, value=None):
|
||||
globals_ = {"__builtins__": {}, "value": value}
|
||||
|
Loading…
Reference in New Issue
Block a user