2 from datatypes
import *
6 def create_enum_table(names
, num
):
9 lines
+= ["\t%s=0,"%names
[0]]
10 for name
in names
[1:]:
11 lines
+= ["\t%s,"%name
]
12 lines
+= ["\t%s" % num
, "};"]
15 def create_flags_table(names
):
17 lines
+= ["enum", "{"]
20 lines
+= ["\t%s = 1<<%d," % (name
,i
)]
25 def EmitEnum(names
, num
):
28 print("\t%s=0," % names
[0])
29 for name
in names
[1:]:
34 def EmitFlags(names
, num
):
39 print("\t%s = 1<<%d," % (name
,i
))
43 gen_network_header
= False
44 gen_network_source
= False
45 gen_client_content_header
= False
46 gen_client_content_source
= False
47 gen_server_content_header
= False
48 gen_server_content_source
= False
50 if "network_header" in sys
.argv
: gen_network_header
= True
51 if "network_source" in sys
.argv
: gen_network_source
= True
52 if "client_content_header" in sys
.argv
: gen_client_content_header
= True
53 if "client_content_source" in sys
.argv
: gen_client_content_source
= True
54 if "server_content_header" in sys
.argv
: gen_server_content_header
= True
55 if "server_content_source" in sys
.argv
: gen_server_content_source
= True
57 if gen_client_content_header
:
58 print("#ifndef CLIENT_CONTENT_HEADER")
59 print("#define CLIENT_CONTENT_HEADER")
61 if gen_server_content_header
:
62 print("#ifndef SERVER_CONTENT_HEADER")
63 print("#define SERVER_CONTENT_HEADER")
66 if gen_client_content_header
or gen_server_content_header
:
67 # emit the type declarations
68 contentlines
= open("datasrc/content.py", "rb").readlines()
70 for line
in contentlines
:
72 if line
[:6] == "class ".encode() and "(Struct)".encode() in line
:
73 order
+= [line
.split()[1].split("(".encode())[0].decode("ascii")]
75 EmitTypeDeclaration(content
.__dict
__[name
])
77 # the container pointer
78 print('extern CDataContainer *g_pData;')
81 EmitEnum(["IMAGE_%s"%i.name
.value
.upper() for i
in content
.container
.images
.items
], "NUM_IMAGES")
82 EmitEnum(["ANIM_%s"%i.name
.value
.upper() for i
in content
.container
.animations
.items
], "NUM_ANIMS")
83 EmitEnum(["SPRITE_%s"%i.name
.value
.upper() for i
in content
.container
.sprites
.items
], "NUM_SPRITES")
85 if gen_client_content_source
or gen_server_content_source
:
86 if gen_client_content_source
:
87 print('#include "client_data.h"')
88 if gen_server_content_source
:
89 print('#include "server_data.h"')
90 EmitDefinition(content
.container
, "datacontainer")
91 print('CDataContainer *g_pData = &datacontainer;')
94 if gen_network_header
:
96 print("#ifndef GAME_GENERATED_PROTOCOL_H")
97 print("#define GAME_GENERATED_PROTOCOL_H")
98 print(network
.RawHeader
)
100 for e
in network
.Enums
:
101 for l
in create_enum_table(["%s_%s"%(e
.name
, v
) for v
in e
.values
], 'NUM_%sS'%e.name
): print(l
)
104 for e
in network
.Flags
:
105 for l
in create_flags_table(["%s_%s" % (e
.name
, v
) for v
in e
.values
]): print(l
)
108 for l
in create_enum_table(["NETOBJ_INVALID"]+[o
.enum_name
for o
in network
.Objects
], "NUM_NETOBJTYPES"): print(l
)
110 for l
in create_enum_table(["NETMSG_INVALID"]+[o
.enum_name
for o
in network
.Messages
], "NUM_NETMSGTYPES"): print(l
)
113 for item
in network
.Objects
+ network
.Messages
:
114 for line
in item
.emit_declaration():
118 EmitEnum(["SOUND_%s"%i.name
.value
.upper() for i
in content
.container
.sounds
.items
], "NUM_SOUNDS")
119 EmitEnum(["WEAPON_%s"%i.name
.value
.upper() for i
in content
.container
.weapons
.id.items
], "NUM_WEAPONS")
125 const char *m_pMsgFailedOn;
126 const char *m_pObjCorrectedOn;
127 char m_aMsgData[1024];
128 int m_NumObjCorrections;
129 int ClampInt(const char *pErrorMsg, int Value, int Min, int Max);
131 static const char *ms_apObjNames[];
132 static int ms_aObjSizes[];
133 static const char *ms_apMsgNames[];
138 int ValidateObj(int Type, void *pData, int Size);
139 const char *GetObjName(int Type);
140 int GetObjSize(int Type);
141 int NumObjCorrections();
142 const char *CorrectedObjOn();
144 const char *GetMsgName(int Type);
145 void *SecureUnpackMsg(int Type, CUnpacker *pUnpacker);
146 const char *FailedMsgOn();
151 print("#endif // GAME_GENERATED_PROTOCOL_H")
154 if gen_network_source
:
158 lines
+= ['#include <engine/shared/protocol.h>']
159 lines
+= ['#include <engine/message.h>']
160 lines
+= ['#include "protocol.h"']
162 lines
+= ['CNetObjHandler::CNetObjHandler()']
164 lines
+= ['\tm_pMsgFailedOn = "";']
165 lines
+= ['\tm_pObjCorrectedOn = "";']
166 lines
+= ['\tm_NumObjCorrections = 0;']
169 lines
+= ['int CNetObjHandler::NumObjCorrections() { return m_NumObjCorrections; }']
170 lines
+= ['const char *CNetObjHandler::CorrectedObjOn() { return m_pObjCorrectedOn; }']
171 lines
+= ['const char *CNetObjHandler::FailedMsgOn() { return m_pMsgFailedOn; }']
178 lines
+= ['static const int max_int = 0x7fffffff;']
180 lines
+= ['int CNetObjHandler::ClampInt(const char *pErrorMsg, int Value, int Min, int Max)']
182 lines
+= ['\tif(Value < Min) { m_pObjCorrectedOn = pErrorMsg; m_NumObjCorrections++; return Min; }']
183 lines
+= ['\tif(Value > Max) { m_pObjCorrectedOn = pErrorMsg; m_NumObjCorrections++; return Max; }']
184 lines
+= ['\treturn Value;']
187 lines
+= ["const char *CNetObjHandler::ms_apObjNames[] = {"]
188 lines
+= ['\t"invalid",']
189 lines
+= ['\t"%s",' % o
.name
for o
in network
.Objects
]
190 lines
+= ['\t""', "};", ""]
192 lines
+= ["int CNetObjHandler::ms_aObjSizes[] = {"]
194 lines
+= ['\tsizeof(%s),' % o
.struct_name
for o
in network
.Objects
]
195 lines
+= ['\t0', "};", ""]
198 lines
+= ['const char *CNetObjHandler::ms_apMsgNames[] = {']
199 lines
+= ['\t"invalid",']
200 for msg
in network
.Messages
:
201 lines
+= ['\t"%s",' % msg
.name
]
206 lines
+= ['const char *CNetObjHandler::GetObjName(int Type)']
208 lines
+= ['\tif(Type < 0 || Type >= NUM_NETOBJTYPES) return "(out of range)";']
209 lines
+= ['\treturn ms_apObjNames[Type];']
213 lines
+= ['int CNetObjHandler::GetObjSize(int Type)']
215 lines
+= ['\tif(Type < 0 || Type >= NUM_NETOBJTYPES) return 0;']
216 lines
+= ['\treturn ms_aObjSizes[Type];']
221 lines
+= ['const char *CNetObjHandler::GetMsgName(int Type)']
223 lines
+= ['\tif(Type < 0 || Type >= NUM_NETMSGTYPES) return "(out of range)";']
224 lines
+= ['\treturn ms_apMsgNames[Type];']
233 for item
in network
.Objects
:
234 for line
in item
.emit_validate():
238 # create validate tables
240 lines
+= ['static int validate_invalid(void *data, int size) { return -1; }']
241 lines
+= ["typedef int(*VALIDATEFUNC)(void *data, int size);"]
242 lines
+= ["static VALIDATEFUNC validate_funcs[] = {"]
243 lines
+= ['\tvalidate_invalid,']
244 lines
+= ['\tvalidate_%s,' % o
.name
for o
in network
.Objects
]
245 lines
+= ["\t0x0", "};", ""]
247 lines
+= ["int netobj_validate(int type, void *data, int size)"]
249 lines
+= ["\tif(type < 0 || type >= NUM_NETOBJTYPES) return -1;"]
250 lines
+= ["\treturn validate_funcs[type](data, size);"]
254 lines
+= ['int CNetObjHandler::ValidateObj(int Type, void *pData, int Size)']
256 lines
+= ['\tswitch(Type)']
259 for item
in network
.Objects
:
260 for line
in item
.emit_validate():
261 lines
+= ["\t" + line
]
264 lines
+= ['\treturn -1;']
268 #int Validate(int Type, void *pData, int Size);
271 for item
in network
.Messages
:
272 for line
in item
.emit_unpack():
276 lines
+= ['static void *secure_unpack_invalid(CUnpacker *pUnpacker) { return 0; }']
277 lines
+= ['typedef void *(*SECUREUNPACKFUNC)(CUnpacker *pUnpacker);']
278 lines
+= ['static SECUREUNPACKFUNC secure_unpack_funcs[] = {']
279 lines
+= ['\tsecure_unpack_invalid,']
280 for msg
in network
.Messages
:
281 lines
+= ['\tsecure_unpack_%s,' % msg
.name
]
286 lines
+= ['void *CNetObjHandler::SecureUnpackMsg(int Type, CUnpacker *pUnpacker)']
288 lines
+= ['\tm_pMsgFailedOn = 0;']
289 lines
+= ['\tswitch(Type)']
293 for item
in network
.Messages
:
294 for line
in item
.emit_unpack():
295 lines
+= ["\t" + line
]
298 lines
+= ['\tdefault:']
299 lines
+= ['\t\tm_pMsgFailedOn = "(type out of range)";']
300 lines
+= ['\t\tbreak;']
303 lines
+= ['\tif(pUnpacker->Error())']
304 lines
+= ['\t\tm_pMsgFailedOn = "(unpack error)";']
306 lines
+= ['\tif(m_pMsgFailedOn)']
307 lines
+= ['\t\treturn 0;']
308 lines
+= ['\tm_pMsgFailedOn = "";']
309 lines
+= ['\treturn m_aMsgData;']
317 if gen_client_content_header
or gen_server_content_header
: