diff --git a/datasrc/compile.py b/datasrc/compile.py index 80cd10924..34dd1ea0b 100644 --- a/datasrc/compile.py +++ b/datasrc/compile.py @@ -263,10 +263,7 @@ void *CNetObjHandler::SecureUnpackObj(int Type, CUnpacker *pUnpacker) """] for item in network.Objects: - base_item = None - if item.base: - base_item = next(i for i in network.Objects if i.name == item.base) - for line in item.emit_uncompressed_unpack_and_validate(base_item): + for line in item.emit_uncompressed_unpack_and_validate(network.Objects): lines += ["\t" + line] lines += ['\t'] diff --git a/datasrc/datatypes.py b/datasrc/datatypes.py index 2c1ac80ba..bf8e77615 100644 --- a/datasrc/datatypes.py +++ b/datasrc/datatypes.py @@ -1,3 +1,8 @@ +def only(x): + if len(x) != 1: + raise ValueError + return list(x)[0] + GlobalIdCounter = 0 def GetID(): global GlobalIdCounter @@ -204,10 +209,11 @@ class NetObject: def __init__(self, name, variables, ex=None, validate_size=True): l = name.split(":") self.name = l[0] - self.base = "" + self.base = None + self.base_struct_name = None if len(l) > 1: self.base = l[1] - self.base_struct_name = f"CNetObj_{self.base}" + self.base_struct_name = f"CNetObj_{self.base}" self.struct_name = f"CNetObj_{self.name}" self.enum_name = f"NETOBJTYPE_{self.name.upper()}" self.variables = variables @@ -216,7 +222,7 @@ class NetObject: def emit_declaration(self): lines = [] - if self.base: + if self.base is not None: lines += [f"struct {self.struct_name} : public {self.base_struct_name}", "{"] else: lines += [f"struct {self.struct_name}", "{"] @@ -226,17 +232,19 @@ class NetObject: lines += ["};"] return lines - def emit_uncompressed_unpack_and_validate(self, base_item): + def emit_uncompressed_unpack_and_validate(self, objects): lines = [] lines += [f"case {self.enum_name}:"] lines += ["{"] lines += [f"\t{self.struct_name} *pData = ({self.struct_name} *)m_aUnpackedData;"] unpack_lines = [] - variables = [] - if base_item: - variables += base_item.variables - variables += self.variables + variables = self.variables + next_base_name = self.base + while next_base_name is not None: + base_item = only([i for i in objects if i.name == next_base_name]) + variables = base_item.variables + variables + next_base_name = base_item.base for v in variables: if not self.validate_size and v.default is None: raise ValueError(f"{v.name} in {self.name} has no default value. Member variables that do not have a default value cannot be used in a structure whose size is not validated.") @@ -254,14 +262,16 @@ class NetObject: class NetEvent(NetObject): def __init__(self, name, variables, ex=None): NetObject.__init__(self, name, variables, ex=ex) - self.base_struct_name = f"CNetEvent_{self.base}" + if self.base is not None: + self.base_struct_name = f"CNetEvent_{self.base}" self.struct_name = f"CNetEvent_{self.name}" self.enum_name = f"NETEVENTTYPE_{self.name.upper()}" class NetMessage(NetObject): def __init__(self, name, variables, ex=None, teehistorian=True): NetObject.__init__(self, name, variables, ex=ex) - self.base_struct_name = f"CNetMsg_{self.base}" + if self.base is not None: + self.base_struct_name = f"CNetMsg_{self.base}" self.struct_name = f"CNetMsg_{self.name}" self.enum_name = f"NETMSGTYPE_{self.name.upper()}" self.teehistorian = teehistorian diff --git a/datasrc/seven/compile.py b/datasrc/seven/compile.py index b24e2cdee..75616ca60 100644 --- a/datasrc/seven/compile.py +++ b/datasrc/seven/compile.py @@ -261,7 +261,7 @@ def main(): lines += ['\t{'] for item in network.Objects: - for line in item.emit_validate(): + for line in item.emit_validate(network.Objects): lines += ["\t" + line] lines += ['\t'] lines += ['\t}'] diff --git a/datasrc/seven/datatypes.py b/datasrc/seven/datatypes.py index d7f5d5a0f..709518a5a 100644 --- a/datasrc/seven/datatypes.py +++ b/datasrc/seven/datatypes.py @@ -1,3 +1,8 @@ +def only(x): + if len(x) != 1: + raise ValueError + return list(x)[0] + GlobalIdCounter = 0 def GetID(): global GlobalIdCounter @@ -210,15 +215,16 @@ class NetObject: def __init__(self, name, variables): l = name.split(":") self.name = l[0] - self.base = "" + self.base = None + self.base_struct_name = None if len(l) > 1: self.base = l[1] - self.base_struct_name = f"CNetObj_{self.base}" + self.base_struct_name = f"CNetObj_{self.base}" self.struct_name = f"CNetObj_{self.name}" self.enum_name = f"NETOBJTYPE_{self.name.upper()}" self.variables = variables def emit_declaration(self): - if self.base: + if self.base is not None: lines = [f"struct {self.struct_name} : public {self.base_struct_name}", "{"] else: lines = [f"struct {self.struct_name}", "{"] @@ -228,12 +234,20 @@ class NetObject: lines += ["\t"+line for line in v.emit_declaration()] lines += ["};"] return lines - def emit_validate(self): + def emit_validate(self, objects): lines = [f"case {self.enum_name}:"] lines += ["{"] lines += [f"\t{self.struct_name} *pObj = ({self.struct_name} *)pData;"] lines += ["\tif(sizeof(*pObj) != Size) return -1;"] - for v in self.variables: + + variables = self.variables + next_base_name = self.base + while next_base_name is not None: + base_item = only([i for i in objects if i.name == next_base_name]) + variables = base_item.variables + variables + next_base_name = base_item.base + + for v in variables: lines += ["\t"+line for line in v.emit_validate()] lines += ["\treturn 0;"] lines += ["}"] @@ -243,14 +257,16 @@ class NetObject: class NetEvent(NetObject): def __init__(self, name, variables): NetObject.__init__(self, name, variables) - self.base_struct_name = f"CNetEvent_{self.base}" + if self.base is not None: + self.base_struct_name = f"CNetEvent_{self.base}" self.struct_name = f"CNetEvent_{self.name}" self.enum_name = f"NETEVENTTYPE_{self.name.upper()}" class NetMessage(NetObject): def __init__(self, name, variables): NetObject.__init__(self, name, variables) - self.base_struct_name = f"CNetMsg_{self.base}" + if self.base is not None: + self.base_struct_name = f"CNetMsg_{self.base}" self.struct_name = f"CNetMsg_{self.name}" self.enum_name = f"NETMSGTYPE_{self.name.upper()}" def emit_unpack(self):