2008-06-12 10:51:48 +00:00
GlobalIdCounter = 0
def GetID ( ) :
global GlobalIdCounter
GlobalIdCounter + = 1
return GlobalIdCounter
def GetUID ( ) :
return " x %d " % GetID ( )
2010-05-29 07:25:38 +00:00
def FixCasing ( Str ) :
NewStr = " "
NextUpperCase = True
for c in Str :
if NextUpperCase :
NextUpperCase = False
NewStr + = c . upper ( )
else :
if c == " _ " :
NextUpperCase = True
else :
NewStr + = c . lower ( )
return NewStr
2011-04-13 18:37:12 +00:00
2020-12-02 14:22:26 +00:00
def FormatName ( typ , name ) :
if " * " in typ :
2010-05-29 07:25:38 +00:00
return " m_p " + FixCasing ( name )
2020-12-02 14:22:26 +00:00
if " [] " in typ :
2010-05-29 07:25:38 +00:00
return " m_a " + FixCasing ( name )
return " m_ " + FixCasing ( name )
2008-06-12 10:51:48 +00:00
class BaseType :
def __init__ ( self , type_name ) :
self . _type_name = type_name
self . _target_name = " INVALID "
2011-01-05 23:51:31 +00:00
self . _id = GetID ( ) # this is used to remember what order the members have in structures etc
2011-04-13 18:37:12 +00:00
2020-12-02 14:22:26 +00:00
def Identifyer ( self ) :
return " x " + str ( self . _id )
def TargetName ( self ) :
return self . _target_name
def TypeName ( self ) :
return self . _type_name
def ID ( self ) :
return self . _id
2011-04-13 18:37:12 +00:00
2008-06-12 10:51:48 +00:00
def EmitDeclaration ( self , name ) :
2010-05-29 07:25:38 +00:00
return [ " %s %s ; " % ( self . TypeName ( ) , FormatName ( self . TypeName ( ) , name ) ) ]
2008-06-12 10:51:48 +00:00
def EmitPreDefinition ( self , target_name ) :
self . _target_name = target_name
return [ ]
2020-12-02 14:22:26 +00:00
def EmitDefinition ( self , _name ) :
2008-06-12 10:51:48 +00:00
return [ ]
class MemberType :
def __init__ ( self , name , var ) :
self . name = name
self . var = var
2011-04-13 18:37:12 +00:00
2008-06-12 10:51:48 +00:00
class Struct ( BaseType ) :
def __init__ ( self , type_name ) :
BaseType . __init__ ( self , type_name )
def Members ( self ) :
2011-01-05 23:51:31 +00:00
def sorter ( a ) :
return a . var . ID ( )
2008-06-12 10:51:48 +00:00
m = [ ]
for name in self . __dict__ :
if name [ 0 ] == " _ " :
continue
m + = [ MemberType ( name , self . __dict__ [ name ] ) ]
2020-12-02 14:22:26 +00:00
m . sort ( key = sorter )
2008-06-12 10:51:48 +00:00
return m
2011-04-13 18:37:12 +00:00
2020-12-02 14:22:26 +00:00
def EmitTypeDeclaration ( self , _name ) :
2008-06-12 10:51:48 +00:00
lines = [ ]
lines + = [ " struct " + self . TypeName ( ) ]
lines + = [ " { " ]
for member in self . Members ( ) :
lines + = [ " \t " + l for l in member . var . EmitDeclaration ( member . name ) ]
lines + = [ " }; " ]
return lines
def EmitPreDefinition ( self , target_name ) :
BaseType . EmitPreDefinition ( self , target_name )
lines = [ ]
for member in self . Members ( ) :
lines + = member . var . EmitPreDefinition ( target_name + " . " + member . name )
return lines
2020-12-02 14:22:26 +00:00
def EmitDefinition ( self , _name ) :
2008-06-12 10:51:48 +00:00
lines = [ " /* %s */ { " % self . TargetName ( ) ]
for member in self . Members ( ) :
lines + = [ " \t " + " " . join ( member . var . EmitDefinition ( " " ) ) + " , " ]
lines + = [ " } " ]
return lines
2011-04-13 18:37:12 +00:00
2008-06-12 10:51:48 +00:00
class Array ( BaseType ) :
2020-12-02 14:22:26 +00:00
def __init__ ( self , typ ) :
BaseType . __init__ ( self , typ . TypeName ( ) )
self . type = typ
2008-06-12 10:51:48 +00:00
self . items = [ ]
def Add ( self , instance ) :
if instance . TypeName ( ) != self . type . TypeName ( ) :
2020-12-02 14:22:26 +00:00
raise " bah "
2008-06-12 10:51:48 +00:00
self . items + = [ instance ]
def EmitDeclaration ( self , name ) :
2010-05-29 07:25:38 +00:00
return [ " int m_Num %s ; " % ( FixCasing ( name ) ) ,
" %s * %s ; " % ( self . TypeName ( ) , FormatName ( " [] " , name ) ) ]
2008-06-12 10:51:48 +00:00
def EmitPreDefinition ( self , target_name ) :
BaseType . EmitPreDefinition ( self , target_name )
lines = [ ]
i = 0
for item in self . items :
lines + = item . EmitPreDefinition ( " %s [ %d ] " % ( self . Identifyer ( ) , i ) )
i + = 1
2011-04-13 18:37:12 +00:00
2020-12-02 14:22:26 +00:00
if self . items :
2008-09-01 17:30:20 +00:00
lines + = [ " static %s %s [] = { " % ( self . TypeName ( ) , self . Identifyer ( ) ) ]
for item in self . items :
itemlines = item . EmitDefinition ( " " )
lines + = [ " \t " + " " . join ( itemlines ) . replace ( " \t " , " " ) + " , " ]
lines + = [ " }; " ]
else :
lines + = [ " static %s * %s = 0; " % ( self . TypeName ( ) , self . Identifyer ( ) ) ]
2011-04-13 18:37:12 +00:00
2008-06-12 10:51:48 +00:00
return lines
2020-12-02 14:22:26 +00:00
def EmitDefinition ( self , _name ) :
2008-06-12 10:51:48 +00:00
return [ str ( len ( self . items ) ) + " , " + self . Identifyer ( ) ]
# Basic Types
class Int ( BaseType ) :
def __init__ ( self , value ) :
BaseType . __init__ ( self , " int " )
self . value = value
def Set ( self , value ) :
self . value = value
2020-12-02 14:22:26 +00:00
def EmitDefinition ( self , _name ) :
2008-06-12 10:51:48 +00:00
return [ " %d " % self . value ]
#return ["%d /* %s */"%(self.value, self._target_name)]
2011-04-13 18:37:12 +00:00
2008-06-12 10:51:48 +00:00
class Float ( BaseType ) :
def __init__ ( self , value ) :
BaseType . __init__ ( self , " float " )
self . value = value
def Set ( self , value ) :
self . value = value
2020-12-02 14:22:26 +00:00
def EmitDefinition ( self , _name ) :
2015-12-09 20:33:06 +00:00
return [ " %f f " % self . value ]
2008-06-12 10:51:48 +00:00
#return ["%d /* %s */"%(self.value, self._target_name)]
2011-04-13 18:37:12 +00:00
2008-06-12 10:51:48 +00:00
class String ( BaseType ) :
def __init__ ( self , value ) :
BaseType . __init__ ( self , " const char* " )
self . value = value
def Set ( self , value ) :
self . value = value
2020-12-02 14:22:26 +00:00
def EmitDefinition ( self , _name ) :
2008-06-12 10:51:48 +00:00
return [ ' " ' + self . value + ' " ' ]
2011-04-13 18:37:12 +00:00
2008-06-12 10:51:48 +00:00
class Pointer ( BaseType ) :
2020-12-02 14:22:26 +00:00
def __init__ ( self , typ , target ) :
BaseType . __init__ ( self , " %s * " % typ ( ) . TypeName ( ) )
2008-06-12 10:51:48 +00:00
self . target = target
def Set ( self , target ) :
self . target = target
2020-12-02 14:22:26 +00:00
def EmitDefinition ( self , _name ) :
2008-06-12 10:51:48 +00:00
return [ " & " + self . target . TargetName ( ) ]
2012-08-12 10:41:50 +00:00
class TextureHandle ( BaseType ) :
def __init__ ( self ) :
BaseType . __init__ ( self , " IGraphics::CTextureHandle " )
2020-12-02 14:22:26 +00:00
def EmitDefinition ( self , _name ) :
2012-08-12 10:41:50 +00:00
return [ " IGraphics::CTextureHandle() " ]
2008-06-12 10:51:48 +00:00
# helper functions
def EmitTypeDeclaration ( root ) :
for l in root ( ) . EmitTypeDeclaration ( " " ) :
2011-01-05 23:51:31 +00:00
print ( l )
2008-06-12 10:51:48 +00:00
def EmitDefinition ( root , name ) :
for l in root . EmitPreDefinition ( name ) :
2011-01-05 23:51:31 +00:00
print ( l )
print ( " %s %s = " % ( root . TypeName ( ) , name ) )
2008-06-12 10:51:48 +00:00
for l in root . EmitDefinition ( name ) :
2011-01-05 23:51:31 +00:00
print ( l )
print ( " ; " )
2008-06-12 10:51:48 +00:00
# Network stuff after this
2008-04-27 05:59:38 +00:00
class Object :
pass
2008-10-19 16:50:57 +00:00
class Enum :
2008-04-27 05:59:38 +00:00
def __init__ ( self , name , values ) :
self . name = name
self . values = values
2008-10-19 16:50:57 +00:00
class Flags :
2008-08-27 15:51:09 +00:00
def __init__ ( self , name , values ) :
self . name = name
self . values = values
2008-04-27 05:59:38 +00:00
class NetObject :
2019-06-13 22:24:50 +00:00
def __init__ ( self , name , variables , ex = None , validate_size = True ) :
2008-04-27 05:59:38 +00:00
l = name . split ( " : " )
2010-05-29 07:25:38 +00:00
self . name = l [ 0 ]
2008-04-27 05:59:38 +00:00
self . base = " "
if len ( l ) > 1 :
self . base = l [ 1 ]
2010-05-29 07:25:38 +00:00
self . base_struct_name = " CNetObj_ %s " % self . base
self . struct_name = " CNetObj_ %s " % self . name
2008-04-27 05:59:38 +00:00
self . enum_name = " NETOBJTYPE_ %s " % self . name . upper ( )
self . variables = variables
2017-05-21 23:07:13 +00:00
self . ex = ex
2019-06-13 22:24:50 +00:00
self . validate_size = validate_size
2022-06-22 21:46:25 +00:00
2008-04-27 05:59:38 +00:00
def emit_declaration ( self ) :
2022-06-22 21:46:25 +00:00
lines = [ ]
2008-04-27 05:59:38 +00:00
if self . base :
2022-06-22 21:46:25 +00:00
lines + = [ " struct %s : public %s " % ( self . struct_name , self . base_struct_name ) , " { " ]
2008-04-27 05:59:38 +00:00
else :
2022-06-22 21:46:25 +00:00
lines + = [ " struct %s " % self . struct_name , " { " ]
2008-04-27 05:59:38 +00:00
for v in self . variables :
lines + = [ " \t " + line for line in v . emit_declaration ( ) ]
lines + = [ " }; " ]
return lines
2022-06-22 21:46:25 +00:00
def emit_uncompressed_unpack_and_validate ( self , base_item ) :
lines = [ ]
lines + = [ " case %s : " % self . enum_name ]
2008-04-27 05:59:38 +00:00
lines + = [ " { " ]
2022-06-22 21:46:25 +00:00
lines + = [ " \t %s *pData = ( %s *)m_aUnpackedData; " % ( self . struct_name , self . struct_name ) ]
unpack_lines = [ ]
2022-05-24 15:26:49 +00:00
2022-06-22 21:46:25 +00:00
variables = [ ]
2020-08-11 20:47:40 +00:00
if base_item :
variables + = base_item . variables
2022-06-22 21:46:25 +00:00
variables + = self . variables
2020-08-11 20:47:40 +00:00
for v in variables :
2022-06-22 21:46:25 +00:00
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. " )
unpack_lines + = [ " \t " + line for line in v . emit_uncompressed_unpack_obj ( ) ]
for v in variables :
unpack_lines + = [ " \t " + line for line in v . emit_validate_obj ( ) ]
if len ( unpack_lines ) > 0 :
lines + = unpack_lines
else :
lines + = [ " \t (void)pData; " ]
lines + = [ " } break; " ]
2008-04-27 05:59:38 +00:00
return lines
2011-04-13 18:37:12 +00:00
2008-04-27 05:59:38 +00:00
class NetEvent ( NetObject ) :
2017-05-21 23:07:13 +00:00
def __init__ ( self , name , variables , ex = None ) :
NetObject . __init__ ( self , name , variables , ex = ex )
2011-06-01 17:43:48 +00:00
self . base_struct_name = " CNetEvent_ %s " % self . base
self . struct_name = " CNetEvent_ %s " % self . name
2008-04-27 05:59:38 +00:00
self . enum_name = " NETEVENTTYPE_ %s " % self . name . upper ( )
class NetMessage ( NetObject ) :
2017-09-13 20:35:09 +00:00
def __init__ ( self , name , variables , ex = None , teehistorian = True ) :
2017-05-21 23:07:13 +00:00
NetObject . __init__ ( self , name , variables , ex = ex )
2010-05-29 07:25:38 +00:00
self . base_struct_name = " CNetMsg_ %s " % self . base
self . struct_name = " CNetMsg_ %s " % self . name
2008-04-27 05:59:38 +00:00
self . enum_name = " NETMSGTYPE_ %s " % self . name . upper ( )
2017-09-13 20:35:09 +00:00
self . teehistorian = teehistorian
2022-06-22 21:46:25 +00:00
def emit_unpack_msg ( self ) :
2008-06-12 10:51:48 +00:00
lines = [ ]
2010-05-29 07:25:38 +00:00
lines + = [ " case %s : " % self . enum_name ]
2008-06-12 10:51:48 +00:00
lines + = [ " { " ]
2022-06-22 21:46:25 +00:00
lines + = [ " \t %s *pData = ( %s *)m_aUnpackedData; " % ( self . struct_name , self . struct_name ) ]
unpack_lines = [ ]
2008-06-12 10:51:48 +00:00
for v in self . variables :
2022-06-22 21:46:25 +00:00
unpack_lines + = [ " \t " + line for line in v . emit_unpack_msg ( ) ]
2008-06-12 10:51:48 +00:00
for v in self . variables :
2022-06-22 21:46:25 +00:00
unpack_lines + = [ " \t " + line for line in v . emit_unpack_msg_check ( ) ]
if len ( unpack_lines ) > 0 :
lines + = unpack_lines
else :
lines + = [ " \t (void)pData; " ]
2010-05-29 07:25:38 +00:00
lines + = [ " } break; " ]
2008-06-12 10:51:48 +00:00
return lines
2022-06-22 21:46:25 +00:00
2008-06-12 10:51:48 +00:00
def emit_declaration ( self ) :
extra = [ ]
2010-05-29 07:25:38 +00:00
extra + = [ " \t int MsgID() const { return %s ; } " % self . enum_name ]
extra + = [ " \t " ]
extra + = [ " \t bool Pack(CMsgPacker *pPacker) " ]
2008-06-12 10:51:48 +00:00
extra + = [ " \t { " ]
2010-05-29 07:25:38 +00:00
#extra += ["\t\tmsg_pack_start(%s, flags);"%self.enum_name]
2008-06-12 10:51:48 +00:00
for v in self . variables :
extra + = [ " \t \t " + line for line in v . emit_pack ( ) ]
2010-05-29 07:25:38 +00:00
extra + = [ " \t \t return pPacker->Error() != 0; " ]
2008-06-12 10:51:48 +00:00
extra + = [ " \t } " ]
2011-04-13 18:37:12 +00:00
2008-06-12 10:51:48 +00:00
lines = NetObject . emit_declaration ( self )
lines = lines [ : - 1 ] + extra + lines [ - 1 : ]
return lines
2011-04-13 18:37:12 +00:00
2017-05-21 23:07:13 +00:00
class NetObjectEx ( NetObject ) :
2019-06-13 22:24:50 +00:00
def __init__ ( self , name , ex , variables , validate_size = True ) :
NetObject . __init__ ( self , name , variables , ex = ex , validate_size = validate_size )
2017-05-21 23:07:13 +00:00
class NetEventEx ( NetEvent ) :
def __init__ ( self , name , ex , variables ) :
NetEvent . __init__ ( self , name , variables , ex = ex )
class NetMessageEx ( NetMessage ) :
2017-09-13 20:35:09 +00:00
def __init__ ( self , name , ex , variables , teehistorian = True ) :
2017-05-21 23:07:13 +00:00
NetMessage . __init__ ( self , name , variables , ex = ex )
2008-04-27 05:59:38 +00:00
class NetVariable :
2022-05-24 15:26:49 +00:00
def __init__ ( self , name , default = None ) :
2008-04-27 05:59:38 +00:00
self . name = name
2022-05-24 15:26:49 +00:00
self . default = None if default is None else str ( default )
2008-04-27 05:59:38 +00:00
def emit_declaration ( self ) :
return [ ]
2022-06-22 21:46:25 +00:00
def emit_validate_obj ( self ) :
return [ ]
def emit_uncompressed_unpack_obj ( self ) :
2008-04-27 05:59:38 +00:00
return [ ]
2008-06-12 10:51:48 +00:00
def emit_pack ( self ) :
return [ ]
2022-06-22 21:46:25 +00:00
def emit_unpack_msg ( self ) :
2008-06-12 10:51:48 +00:00
return [ ]
2022-06-22 21:46:25 +00:00
def emit_unpack_msg_check ( self ) :
2008-06-12 10:51:48 +00:00
return [ ]
2008-04-27 05:59:38 +00:00
class NetString ( NetVariable ) :
def emit_declaration ( self ) :
return [ " const char * %s ; " % self . name ]
2022-06-22 21:46:25 +00:00
def emit_uncompressed_unpack_obj ( self ) :
return self . emit_unpack_msg ( )
def emit_unpack_msg ( self ) :
return [ " pData-> %s = pUnpacker->GetString(); " % self . name ]
2008-06-12 10:51:48 +00:00
def emit_pack ( self ) :
2010-05-29 07:25:38 +00:00
return [ " pPacker->AddString( %s , -1); " % self . name ]
2008-04-27 05:59:38 +00:00
2014-01-08 17:21:07 +00:00
class NetStringHalfStrict ( NetVariable ) :
def emit_declaration ( self ) :
return [ " const char * %s ; " % self . name ]
2022-06-22 21:46:25 +00:00
def emit_uncompressed_unpack_obj ( self ) :
return self . emit_unpack_msg ( )
def emit_unpack_msg ( self ) :
return [ " pData-> %s = pUnpacker->GetString(CUnpacker::SANITIZE_CC); " % self . name ]
2014-01-08 17:21:07 +00:00
def emit_pack ( self ) :
return [ " pPacker->AddString( %s , -1); " % self . name ]
2010-08-12 13:22:07 +00:00
class NetStringStrict ( NetVariable ) :
def emit_declaration ( self ) :
return [ " const char * %s ; " % self . name ]
2022-06-22 21:46:25 +00:00
def emit_uncompressed_unpack_obj ( self ) :
return self . emit_unpack_msg ( )
def emit_unpack_msg ( self ) :
return [ " pData-> %s = pUnpacker->GetString(CUnpacker::SANITIZE_CC|CUnpacker::SKIP_START_WHITESPACES); " % self . name ]
2010-08-12 13:22:07 +00:00
def emit_pack ( self ) :
return [ " pPacker->AddString( %s , -1); " % self . name ]
2008-04-27 05:59:38 +00:00
class NetIntAny ( NetVariable ) :
def emit_declaration ( self ) :
return [ " int %s ; " % self . name ]
2022-06-22 21:46:25 +00:00
def emit_uncompressed_unpack_obj ( self ) :
2022-05-24 15:26:49 +00:00
if self . default is None :
2022-06-22 21:46:25 +00:00
return [ " pData-> %s = pUnpacker->GetUncompressedInt(); " % self . name ]
return [ " pData-> %s = pUnpacker->GetUncompressedIntOrDefault( %s ); " % ( self . name , self . default ) ]
def emit_unpack_msg ( self ) :
if self . default is None :
return [ " pData-> %s = pUnpacker->GetInt(); " % self . name ]
return [ " pData-> %s = pUnpacker->GetIntOrDefault( %s ); " % ( self . name , self . default ) ]
2008-06-12 10:51:48 +00:00
def emit_pack ( self ) :
2010-05-29 07:25:38 +00:00
return [ " pPacker->AddInt( %s ); " % self . name ]
2008-04-27 05:59:38 +00:00
class NetIntRange ( NetIntAny ) :
2022-05-24 15:26:49 +00:00
def __init__ ( self , name , min_val , max_val , default = None ) :
NetIntAny . __init__ ( self , name , default = default )
2020-12-02 14:22:26 +00:00
self . min = str ( min_val )
self . max = str ( max_val )
2022-06-22 21:46:25 +00:00
def emit_validate_obj ( self ) :
return [ " pData-> %s = ClampInt( \" %s \" , pData-> %s , %s , %s ); " % ( self . name , self . name , self . name , self . min , self . max ) ]
def emit_unpack_msg_check ( self ) :
return [ " if(pData-> %s < %s || pData-> %s > %s ) { m_pMsgFailedOn = \" %s \" ; break; } " % ( self . name , self . min , self . name , self . max , self . name ) ]
2008-04-27 05:59:38 +00:00
class NetBool ( NetIntRange ) :
2022-05-24 15:26:49 +00:00
def __init__ ( self , name , default = None ) :
default = None if default is None else int ( default )
NetIntRange . __init__ ( self , name , 0 , 1 , default = default )
2008-04-27 05:59:38 +00:00
2014-09-12 10:13:46 +00:00
class NetTick ( NetIntAny ) :
2022-05-24 15:26:49 +00:00
def __init__ ( self , name , default = None ) :
NetIntAny . __init__ ( self , name , default = default )
2022-02-12 21:41:16 +00:00
class NetArray ( NetVariable ) :
def __init__ ( self , var , size ) :
2022-06-22 21:46:25 +00:00
NetVariable . __init__ ( self , var . name , var . default )
2022-02-12 21:41:16 +00:00
self . base_name = var . name
self . var = var
self . size = size
self . name = self . base_name + " [ %d ] " % self . size
def emit_declaration ( self ) :
self . var . name = self . name
return self . var . emit_declaration ( )
2022-06-22 21:46:25 +00:00
def emit_uncompressed_unpack_obj ( self ) :
lines = [ ]
for i in range ( self . size ) :
self . var . name = self . base_name + " [ %d ] " % i
lines + = self . var . emit_uncompressed_unpack_obj ( )
return lines
def emit_validate_obj ( self ) :
2022-02-12 21:41:16 +00:00
lines = [ ]
for i in range ( self . size ) :
self . var . name = self . base_name + " [ %d ] " % i
2022-06-22 21:46:25 +00:00
lines + = self . var . emit_validate_obj ( )
2022-02-12 21:41:16 +00:00
return lines
2022-06-22 21:46:25 +00:00
def emit_unpack_msg ( self ) :
2022-02-12 21:41:16 +00:00
lines = [ ]
for i in range ( self . size ) :
self . var . name = self . base_name + " [ %d ] " % i
2022-06-22 21:46:25 +00:00
lines + = self . var . emit_unpack_msg ( )
2022-02-12 21:41:16 +00:00
return lines
def emit_pack ( self ) :
lines = [ ]
for i in range ( self . size ) :
self . var . name = self . base_name + " [ %d ] " % i
lines + = self . var . emit_pack ( )
return lines
2022-06-22 21:46:25 +00:00
def emit_unpack_msg_check ( self ) :
2022-02-12 21:41:16 +00:00
lines = [ ]
for i in range ( self . size ) :
self . var . name = self . base_name + " [ %d ] " % i
2022-06-22 21:46:25 +00:00
lines + = self . var . emit_unpack_msg_check ( )
2022-02-12 21:41:16 +00:00
return lines