mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-20 06:58:20 +00:00
Merge #3371
3371: Add shellcheck & pylint r=heinrich5991 a=def- <!-- What is the motivation for the changes of this pull request --> ## Checklist - [ ] Tested the change ingame - [ ] Provided screenshots if it is a visual change - [ ] Tested in combination with possibly related configuration options - [ ] Written a unit test if it works standalone, system.c especially - [ ] Considered possible null pointers and out of bounds array indexing - [ ] Changed no physics that affect existing maps - [ ] Tested the change with [ASan+UBSan or valgrind's memcheck](https://github.com/ddnet/ddnet/#using-addresssanitizer--undefinedbehavioursanitizer-or-valgrinds-memcheck) (optional) Co-authored-by: def <dennis@felsin9.de> Co-authored-by: ChillerDragon <chillerdragon@gmail.com>
This commit is contained in:
commit
d9bda64fdf
31
.github/workflows/style.yml
vendored
31
.github/workflows/style.yml
vendored
|
@ -19,23 +19,24 @@ jobs:
|
|||
- name: Prepare
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install clang-format imagemagick ddnet-tools -y
|
||||
- name: Check style
|
||||
run: |
|
||||
clang-format -version
|
||||
scripts/fix_style.py --dry-run
|
||||
scripts/check_header_guards.py
|
||||
scripts/languages/update_all.py
|
||||
- name: Prepare build dilate
|
||||
run: |
|
||||
sudo apt-get update -y
|
||||
sudo apt-get install pkg-config cmake libfreetype6-dev libnotify-dev libsdl2-dev libsqlite3-dev -y
|
||||
- name: Build dilate
|
||||
run: |
|
||||
sudo apt-get install clang-format imagemagick ddnet-tools shellcheck pkg-config cmake libfreetype6-dev libnotify-dev libsdl2-dev libsqlite3-dev pylint3 python3-clang -y
|
||||
mkdir release
|
||||
cd release
|
||||
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release -DDOWNLOAD_GTEST=OFF -DCMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE=. ..
|
||||
cmake --build . --config Release --target dilate --parallel
|
||||
- name: Check if images are dilated
|
||||
- name: Check clang-format
|
||||
run: clang-format -version
|
||||
- name: Check fix_style
|
||||
run: scripts/fix_style.py --dry-run
|
||||
- name: Check header guards
|
||||
run: scripts/check_header_guards.py
|
||||
- name: Check languages
|
||||
run: scripts/languages/update_all.py
|
||||
- name: Check dilated images
|
||||
run: scripts/check_dilate.sh release data
|
||||
- name: Shellcheck
|
||||
run: find . -type f -name '*.sh' -print0 | xargs -0 shellcheck
|
||||
- name: Pylint
|
||||
run: |
|
||||
scripts/check_dilate.sh release data
|
||||
pylint --version
|
||||
find . -type f -name "*.py" -print0 | xargs -0 pylint
|
||||
|
|
24
.pylintrc
Normal file
24
.pylintrc
Normal file
|
@ -0,0 +1,24 @@
|
|||
[MESSAGES CONTROL]
|
||||
|
||||
indent-string=' '
|
||||
|
||||
disable=
|
||||
C0103, # invalid-name
|
||||
C0114, # missing-module-docstring
|
||||
C0115, # missing-class-docstring
|
||||
C0116, # missing-function-docstring
|
||||
C0301, # line-too-long
|
||||
C0326, # bad-whitespace
|
||||
C0330, # bad-continuation
|
||||
E0402, # relative-beyond-top-level
|
||||
R0201, # no-self-use
|
||||
R0801, # duplicate-code
|
||||
R0902, # too-many-instance-attributes
|
||||
R0903, # too-few-public-methods
|
||||
R0911, # too-many-return-statements
|
||||
R0912, # too-many-branches
|
||||
R0913, # too-many-arguments
|
||||
R0914, # too-many-locals
|
||||
R0915, # too-many-statements
|
||||
W0511, # fixme
|
||||
W0603, # global-statement
|
|
@ -1,6 +1,5 @@
|
|||
import os
|
||||
import sys
|
||||
from datatypes import *
|
||||
from datatypes import EmitDefinition, EmitTypeDeclaration
|
||||
import content
|
||||
import network
|
||||
|
||||
|
@ -31,7 +30,7 @@ def EmitEnum(names, num):
|
|||
print("\t%s" % num)
|
||||
print("};")
|
||||
|
||||
def EmitFlags(names, num):
|
||||
def EmitFlags(names):
|
||||
print("enum")
|
||||
print("{")
|
||||
i = 0
|
||||
|
@ -40,325 +39,304 @@ def EmitFlags(names, num):
|
|||
i += 1
|
||||
print("};")
|
||||
|
||||
gen_network_header = False
|
||||
gen_network_source = False
|
||||
gen_client_content_header = False
|
||||
gen_client_content_source = False
|
||||
gen_server_content_header = False
|
||||
gen_server_content_source = False
|
||||
def main():
|
||||
gen_network_header = "network_header" in sys.argv
|
||||
gen_network_source = "network_source" in sys.argv
|
||||
gen_client_content_header = "client_content_header" in sys.argv
|
||||
gen_client_content_source = "client_content_source" in sys.argv
|
||||
gen_server_content_header = "server_content_header" in sys.argv
|
||||
gen_server_content_source = "server_content_source" in sys.argv
|
||||
|
||||
if "network_header" in sys.argv: gen_network_header = True
|
||||
if "network_source" in sys.argv: gen_network_source = True
|
||||
if "client_content_header" in sys.argv: gen_client_content_header = True
|
||||
if "client_content_source" in sys.argv: gen_client_content_source = True
|
||||
if "server_content_header" in sys.argv: gen_server_content_header = True
|
||||
if "server_content_source" in sys.argv: gen_server_content_source = True
|
||||
if gen_client_content_header:
|
||||
print("#ifndef CLIENT_CONTENT_HEADER")
|
||||
print("#define CLIENT_CONTENT_HEADER")
|
||||
|
||||
if gen_client_content_header:
|
||||
print("#ifndef CLIENT_CONTENT_HEADER")
|
||||
print("#define CLIENT_CONTENT_HEADER")
|
||||
|
||||
if gen_server_content_header:
|
||||
print("#ifndef SERVER_CONTENT_HEADER")
|
||||
print("#define SERVER_CONTENT_HEADER")
|
||||
if gen_server_content_header:
|
||||
print("#ifndef SERVER_CONTENT_HEADER")
|
||||
print("#define SERVER_CONTENT_HEADER")
|
||||
|
||||
|
||||
if gen_client_content_header or gen_server_content_header:
|
||||
# print some includes
|
||||
print('#include <engine/graphics.h>')
|
||||
if gen_client_content_header or gen_server_content_header:
|
||||
# print some includes
|
||||
print('#include <engine/graphics.h>')
|
||||
|
||||
# emit the type declarations
|
||||
contentlines = open("datasrc/content.py", "rb").readlines()
|
||||
order = []
|
||||
for line in contentlines:
|
||||
line = line.strip()
|
||||
if line[:6] == "class ".encode() and "(Struct)".encode() in line:
|
||||
order += [line.split()[1].split("(".encode())[0].decode("ascii")]
|
||||
for name in order:
|
||||
EmitTypeDeclaration(content.__dict__[name])
|
||||
# emit the type declarations
|
||||
contentlines = open("datasrc/content.py", "rb").readlines()
|
||||
order = []
|
||||
for line in contentlines:
|
||||
line = line.strip()
|
||||
if line[:6] == "class ".encode() and "(Struct)".encode() in line:
|
||||
order += [line.split()[1].split("(".encode())[0].decode("ascii")]
|
||||
for name in order:
|
||||
EmitTypeDeclaration(content.__dict__[name])
|
||||
|
||||
# the container pointer
|
||||
print('extern CDataContainer *g_pData;')
|
||||
# the container pointer
|
||||
print('extern CDataContainer *g_pData;')
|
||||
|
||||
# enums
|
||||
EmitEnum(["IMAGE_%s"%i.name.value.upper() for i in content.container.images.items], "NUM_IMAGES")
|
||||
EmitEnum(["ANIM_%s"%i.name.value.upper() for i in content.container.animations.items], "NUM_ANIMS")
|
||||
EmitEnum(["SPRITE_%s"%i.name.value.upper() for i in content.container.sprites.items], "NUM_SPRITES")
|
||||
# enums
|
||||
EmitEnum(["IMAGE_%s"%i.name.value.upper() for i in content.container.images.items], "NUM_IMAGES")
|
||||
EmitEnum(["ANIM_%s"%i.name.value.upper() for i in content.container.animations.items], "NUM_ANIMS")
|
||||
EmitEnum(["SPRITE_%s"%i.name.value.upper() for i in content.container.sprites.items], "NUM_SPRITES")
|
||||
|
||||
if gen_client_content_source or gen_server_content_source:
|
||||
if gen_client_content_source:
|
||||
print('#include "client_data.h"')
|
||||
if gen_server_content_source:
|
||||
print('#include "server_data.h"')
|
||||
EmitDefinition(content.container, "datacontainer")
|
||||
print('CDataContainer *g_pData = &datacontainer;')
|
||||
if gen_client_content_source or gen_server_content_source:
|
||||
if gen_client_content_source:
|
||||
print('#include "client_data.h"')
|
||||
if gen_server_content_source:
|
||||
print('#include "server_data.h"')
|
||||
EmitDefinition(content.container, "datacontainer")
|
||||
print('CDataContainer *g_pData = &datacontainer;')
|
||||
|
||||
# NETWORK
|
||||
if gen_network_header:
|
||||
if gen_network_header:
|
||||
|
||||
print("#ifndef GAME_GENERATED_PROTOCOL_H")
|
||||
print("#define GAME_GENERATED_PROTOCOL_H")
|
||||
print("#include <engine/shared/protocol.h>")
|
||||
print("#include <engine/message.h>")
|
||||
print(network.RawHeader)
|
||||
print("#ifndef GAME_GENERATED_PROTOCOL_H")
|
||||
print("#define GAME_GENERATED_PROTOCOL_H")
|
||||
print("#include <engine/shared/protocol.h>")
|
||||
print("#include <engine/message.h>")
|
||||
print(network.RawHeader)
|
||||
|
||||
for e in network.Enums:
|
||||
for l in create_enum_table(["%s_%s"%(e.name, v) for v in e.values], 'NUM_%sS'%e.name): print(l)
|
||||
for e in network.Enums:
|
||||
for l in create_enum_table(["%s_%s"%(e.name, v) for v in e.values], 'NUM_%sS'%e.name): # pylint: disable=E1101
|
||||
print(l)
|
||||
print("")
|
||||
|
||||
for e in network.Flags:
|
||||
for l in create_flags_table(["%s_%s" % (e.name, v) for v in e.values]):
|
||||
print(l)
|
||||
print("")
|
||||
|
||||
non_extended = [o for o in network.Objects if o.ex is None]
|
||||
extended = [o for o in network.Objects if o.ex is not None]
|
||||
for l in create_enum_table(["NETOBJTYPE_EX"]+[o.enum_name for o in non_extended], "NUM_NETOBJTYPES"):
|
||||
print(l)
|
||||
for l in create_enum_table(["__NETOBJTYPE_UUID_HELPER=OFFSET_GAME_UUID-1"]+[o.enum_name for o in extended], "OFFSET_NETMSGTYPE_UUID"):
|
||||
print(l)
|
||||
print("")
|
||||
|
||||
for e in network.Flags:
|
||||
for l in create_flags_table(["%s_%s" % (e.name, v) for v in e.values]): print(l)
|
||||
non_extended = [o for o in network.Messages if o.ex is None]
|
||||
extended = [o for o in network.Messages if o.ex is not None]
|
||||
for l in create_enum_table(["NETMSGTYPE_EX"]+[o.enum_name for o in non_extended], "NUM_NETMSGTYPES"):
|
||||
print(l)
|
||||
print("")
|
||||
for l in create_enum_table(["__NETMSGTYPE_UUID_HELPER=OFFSET_NETMSGTYPE_UUID-1"]+[o.enum_name for o in extended], "OFFSET_MAPITEMTYPE_UUID"):
|
||||
print(l)
|
||||
print("")
|
||||
|
||||
non_extended = [o for o in network.Objects if o.ex is None]
|
||||
extended = [o for o in network.Objects if o.ex is not None]
|
||||
for l in create_enum_table(["NETOBJTYPE_EX"]+[o.enum_name for o in non_extended], "NUM_NETOBJTYPES"): print(l)
|
||||
for l in create_enum_table(["__NETOBJTYPE_UUID_HELPER=OFFSET_GAME_UUID-1"]+[o.enum_name for o in extended], "OFFSET_NETMSGTYPE_UUID"): print(l)
|
||||
print("")
|
||||
for item in network.Objects + network.Messages:
|
||||
for line in item.emit_declaration():
|
||||
print(line)
|
||||
print("")
|
||||
|
||||
non_extended = [o for o in network.Messages if o.ex is None]
|
||||
extended = [o for o in network.Messages if o.ex is not None]
|
||||
for l in create_enum_table(["NETMSGTYPE_EX"]+[o.enum_name for o in non_extended], "NUM_NETMSGTYPES"): print(l)
|
||||
print("")
|
||||
for l in create_enum_table(["__NETMSGTYPE_UUID_HELPER=OFFSET_NETMSGTYPE_UUID-1"]+[o.enum_name for o in extended], "OFFSET_MAPITEMTYPE_UUID"): print(l)
|
||||
print("")
|
||||
EmitEnum(["SOUND_%s"%i.name.value.upper() for i in content.container.sounds.items], "NUM_SOUNDS")
|
||||
EmitEnum(["WEAPON_%s"%i.name.value.upper() for i in content.container.weapons.id.items], "NUM_WEAPONS")
|
||||
|
||||
for item in network.Objects + network.Messages:
|
||||
for line in item.emit_declaration():
|
||||
print(line)
|
||||
print("")
|
||||
print("""
|
||||
|
||||
EmitEnum(["SOUND_%s"%i.name.value.upper() for i in content.container.sounds.items], "NUM_SOUNDS")
|
||||
EmitEnum(["WEAPON_%s"%i.name.value.upper() for i in content.container.weapons.id.items], "NUM_WEAPONS")
|
||||
class CNetObjHandler
|
||||
{
|
||||
const char *m_pMsgFailedOn;
|
||||
const char *m_pObjCorrectedOn;
|
||||
char m_aMsgData[1024];
|
||||
int m_NumObjCorrections;
|
||||
int ClampInt(const char *pErrorMsg, int Value, int Min, int Max);
|
||||
|
||||
print("""
|
||||
static const char *ms_apObjNames[];
|
||||
static int ms_aObjSizes[];
|
||||
static const char *ms_apMsgNames[];
|
||||
|
||||
class CNetObjHandler
|
||||
{
|
||||
const char *m_pMsgFailedOn;
|
||||
const char *m_pObjCorrectedOn;
|
||||
char m_aMsgData[1024];
|
||||
int m_NumObjCorrections;
|
||||
int ClampInt(const char *pErrorMsg, int Value, int Min, int Max);
|
||||
public:
|
||||
CNetObjHandler();
|
||||
|
||||
static const char *ms_apObjNames[];
|
||||
static int ms_aObjSizes[];
|
||||
static const char *ms_apMsgNames[];
|
||||
int ValidateObj(int Type, void *pData, int Size);
|
||||
const char *GetObjName(int Type);
|
||||
int GetObjSize(int Type);
|
||||
int NumObjCorrections();
|
||||
const char *CorrectedObjOn();
|
||||
|
||||
public:
|
||||
CNetObjHandler();
|
||||
const char *GetMsgName(int Type);
|
||||
void *SecureUnpackMsg(int Type, CUnpacker *pUnpacker);
|
||||
bool TeeHistorianRecordMsg(int Type);
|
||||
const char *FailedMsgOn();
|
||||
};
|
||||
|
||||
int ValidateObj(int Type, void *pData, int Size);
|
||||
const char *GetObjName(int Type);
|
||||
int GetObjSize(int Type);
|
||||
int NumObjCorrections();
|
||||
const char *CorrectedObjOn();
|
||||
""")
|
||||
|
||||
const char *GetMsgName(int Type);
|
||||
void *SecureUnpackMsg(int Type, CUnpacker *pUnpacker);
|
||||
bool TeeHistorianRecordMsg(int Type);
|
||||
const char *FailedMsgOn();
|
||||
};
|
||||
|
||||
""")
|
||||
|
||||
print("#endif // GAME_GENERATED_PROTOCOL_H")
|
||||
print("#endif // GAME_GENERATED_PROTOCOL_H")
|
||||
|
||||
|
||||
if gen_network_source:
|
||||
# create names
|
||||
lines = []
|
||||
if gen_network_source:
|
||||
# create names
|
||||
lines = []
|
||||
|
||||
lines += ['#include "protocol.h"']
|
||||
lines += ['#include <engine/shared/protocol.h>']
|
||||
lines += ['#include <engine/message.h>']
|
||||
lines += ['#include <game/mapitems_ex.h>']
|
||||
lines += ['#include "protocol.h"']
|
||||
lines += ['#include <engine/shared/protocol.h>']
|
||||
lines += ['#include <engine/message.h>']
|
||||
lines += ['#include <game/mapitems_ex.h>']
|
||||
|
||||
lines += ['CNetObjHandler::CNetObjHandler()']
|
||||
lines += ['{']
|
||||
lines += ['\tm_pMsgFailedOn = "";']
|
||||
lines += ['\tm_pObjCorrectedOn = "";']
|
||||
lines += ['\tm_NumObjCorrections = 0;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['int CNetObjHandler::NumObjCorrections() { return m_NumObjCorrections; }']
|
||||
lines += ['const char *CNetObjHandler::CorrectedObjOn() { return m_pObjCorrectedOn; }']
|
||||
lines += ['const char *CNetObjHandler::FailedMsgOn() { return m_pMsgFailedOn; }']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['CNetObjHandler::CNetObjHandler()']
|
||||
lines += ['{']
|
||||
lines += ['\tm_pMsgFailedOn = "";']
|
||||
lines += ['\tm_pObjCorrectedOn = "";']
|
||||
lines += ['\tm_NumObjCorrections = 0;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['int CNetObjHandler::NumObjCorrections() { return m_NumObjCorrections; }']
|
||||
lines += ['const char *CNetObjHandler::CorrectedObjOn() { return m_pObjCorrectedOn; }']
|
||||
lines += ['const char *CNetObjHandler::FailedMsgOn() { return m_pMsgFailedOn; }']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
|
||||
lines += ['static const int max_int = 0x7fffffff;']
|
||||
lines += ['static const int min_int = 0x80000000;']
|
||||
lines += ['static const int max_int = 0x7fffffff;']
|
||||
lines += ['static const int min_int = 0x80000000;']
|
||||
|
||||
lines += ['int CNetObjHandler::ClampInt(const char *pErrorMsg, int Value, int Min, int Max)']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Value < Min) { m_pObjCorrectedOn = pErrorMsg; m_NumObjCorrections++; return Min; }']
|
||||
lines += ['\tif(Value > Max) { m_pObjCorrectedOn = pErrorMsg; m_NumObjCorrections++; return Max; }']
|
||||
lines += ['\treturn Value;']
|
||||
lines += ['}']
|
||||
lines += ['int CNetObjHandler::ClampInt(const char *pErrorMsg, int Value, int Min, int Max)']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Value < Min) { m_pObjCorrectedOn = pErrorMsg; m_NumObjCorrections++; return Min; }']
|
||||
lines += ['\tif(Value > Max) { m_pObjCorrectedOn = pErrorMsg; m_NumObjCorrections++; return Max; }']
|
||||
lines += ['\treturn Value;']
|
||||
lines += ['}']
|
||||
|
||||
lines += ["const char *CNetObjHandler::ms_apObjNames[] = {"]
|
||||
lines += ['\t"invalid",']
|
||||
lines += ['\t"%s",' % o.name for o in network.Objects if o.ex is None]
|
||||
lines += ['\t""', "};", ""]
|
||||
lines += ["const char *CNetObjHandler::ms_apObjNames[] = {"]
|
||||
lines += ['\t"invalid",']
|
||||
lines += ['\t"%s",' % o.name for o in network.Objects if o.ex is None]
|
||||
lines += ['\t""', "};", ""]
|
||||
|
||||
lines += ["int CNetObjHandler::ms_aObjSizes[] = {"]
|
||||
lines += ['\t0,']
|
||||
lines += ['\tsizeof(%s),' % o.struct_name for o in network.Objects if o.ex is None]
|
||||
lines += ['\t0', "};", ""]
|
||||
lines += ["int CNetObjHandler::ms_aObjSizes[] = {"]
|
||||
lines += ['\t0,']
|
||||
lines += ['\tsizeof(%s),' % o.struct_name for o in network.Objects if o.ex is None]
|
||||
lines += ['\t0', "};", ""]
|
||||
|
||||
|
||||
lines += ['const char *CNetObjHandler::ms_apMsgNames[] = {']
|
||||
lines += ['\t"invalid",']
|
||||
for msg in network.Messages:
|
||||
if msg.ex is None:
|
||||
lines += ['\t"%s",' % msg.name]
|
||||
lines += ['\t""']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
lines += ['const char *CNetObjHandler::ms_apMsgNames[] = {']
|
||||
lines += ['\t"invalid",']
|
||||
for msg in network.Messages:
|
||||
if msg.ex is None:
|
||||
lines += ['\t"%s",' % msg.name]
|
||||
lines += ['\t""']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
|
||||
lines += ['const char *CNetObjHandler::GetObjName(int Type)']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETOBJTYPES) return "(out of range)";']
|
||||
lines += ['\treturn ms_apObjNames[Type];']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['const char *CNetObjHandler::GetObjName(int Type)']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETOBJTYPES) return "(out of range)";']
|
||||
lines += ['\treturn ms_apObjNames[Type];']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
|
||||
lines += ['int CNetObjHandler::GetObjSize(int Type)']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETOBJTYPES) return 0;']
|
||||
lines += ['\treturn ms_aObjSizes[Type];']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['int CNetObjHandler::GetObjSize(int Type)']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETOBJTYPES) return 0;']
|
||||
lines += ['\treturn ms_aObjSizes[Type];']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
|
||||
|
||||
lines += ['const char *CNetObjHandler::GetMsgName(int Type)']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETMSGTYPES) return "(out of range)";']
|
||||
lines += ['\treturn ms_apMsgNames[Type];']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['const char *CNetObjHandler::GetMsgName(int Type)']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETMSGTYPES) return "(out of range)";']
|
||||
lines += ['\treturn ms_apMsgNames[Type];']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
|
||||
|
||||
for l in lines:
|
||||
print(l)
|
||||
for l in lines:
|
||||
print(l)
|
||||
|
||||
# create validate tables
|
||||
lines = []
|
||||
lines += ['static int validate_invalid(void *data, int size) { return -1; }']
|
||||
lines += ["typedef int(*VALIDATEFUNC)(void *data, int size);"]
|
||||
lines += ["static VALIDATEFUNC validate_funcs[] = {"]
|
||||
lines += ['\tvalidate_invalid,']
|
||||
lines += ['\tvalidate_%s,' % o.name for o in network.Objects]
|
||||
lines += ["\t0x0", "};", ""]
|
||||
|
||||
lines += ["int netobj_validate(int type, void *data, int size)"]
|
||||
lines += ["{"]
|
||||
lines += ["\tif(type < 0 || type >= NUM_NETOBJTYPES) return -1;"]
|
||||
lines += ["\treturn validate_funcs[type](data, size);"]
|
||||
lines += ["};", ""]
|
||||
|
||||
lines = []
|
||||
lines += ['int CNetObjHandler::ValidateObj(int Type, void *pData, int Size)']
|
||||
lines += ['{']
|
||||
lines += ['\tswitch(Type)']
|
||||
lines += ['\t{']
|
||||
lines += ['\tcase NETOBJTYPE_EX:']
|
||||
lines += ['\t{']
|
||||
lines += ['\t\treturn 0;']
|
||||
lines += ['\t}']
|
||||
|
||||
if 0:
|
||||
for item in network.Objects:
|
||||
for line in item.emit_validate():
|
||||
print(line)
|
||||
print("")
|
||||
lines += ["\t" + line]
|
||||
lines += ['\t']
|
||||
lines += ['\t}']
|
||||
lines += ['\treturn -1;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
|
||||
# create validate tables
|
||||
lines = []
|
||||
lines += ['static int validate_invalid(void *data, int size) { return -1; }']
|
||||
lines += ["typedef int(*VALIDATEFUNC)(void *data, int size);"]
|
||||
lines += ["static VALIDATEFUNC validate_funcs[] = {"]
|
||||
lines += ['\tvalidate_invalid,']
|
||||
lines += ['\tvalidate_%s,' % o.name for o in network.Objects]
|
||||
lines += ["\t0x0", "};", ""]
|
||||
lines += ['void *CNetObjHandler::SecureUnpackMsg(int Type, CUnpacker *pUnpacker)']
|
||||
lines += ['{']
|
||||
lines += ['\tm_pMsgFailedOn = 0;']
|
||||
lines += ['\tswitch(Type)']
|
||||
lines += ['\t{']
|
||||
|
||||
lines += ["int netobj_validate(int type, void *data, int size)"]
|
||||
lines += ["{"]
|
||||
lines += ["\tif(type < 0 || type >= NUM_NETOBJTYPES) return -1;"]
|
||||
lines += ["\treturn validate_funcs[type](data, size);"]
|
||||
lines += ["};", ""]
|
||||
|
||||
lines = []
|
||||
lines += ['int CNetObjHandler::ValidateObj(int Type, void *pData, int Size)']
|
||||
lines += ['{']
|
||||
lines += ['\tswitch(Type)']
|
||||
lines += ['\t{']
|
||||
lines += ['\tcase NETOBJTYPE_EX:']
|
||||
lines += ['\t{']
|
||||
lines += ['\t\treturn 0;']
|
||||
lines += ['\t}']
|
||||
|
||||
for item in network.Objects:
|
||||
for line in item.emit_validate():
|
||||
lines += ["\t" + line]
|
||||
lines += ['\t']
|
||||
lines += ['\t}']
|
||||
lines += ['\treturn -1;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
|
||||
#int Validate(int Type, void *pData, int Size);
|
||||
|
||||
if 0:
|
||||
for item in network.Messages:
|
||||
for line in item.emit_unpack():
|
||||
print(line)
|
||||
print("")
|
||||
lines += ["\t" + line]
|
||||
lines += ['\t']
|
||||
|
||||
lines += ['static void *secure_unpack_invalid(CUnpacker *pUnpacker) { return 0; }']
|
||||
lines += ['typedef void *(*SECUREUNPACKFUNC)(CUnpacker *pUnpacker);']
|
||||
lines += ['static SECUREUNPACKFUNC secure_unpack_funcs[] = {']
|
||||
lines += ['\tsecure_unpack_invalid,']
|
||||
for msg in network.Messages:
|
||||
lines += ['\tsecure_unpack_%s,' % msg.name]
|
||||
lines += ['\t0x0']
|
||||
lines += ['};']
|
||||
|
||||
#
|
||||
lines += ['void *CNetObjHandler::SecureUnpackMsg(int Type, CUnpacker *pUnpacker)']
|
||||
lines += ['{']
|
||||
lines += ['\tm_pMsgFailedOn = 0;']
|
||||
lines += ['\tswitch(Type)']
|
||||
lines += ['\t{']
|
||||
|
||||
|
||||
for item in network.Messages:
|
||||
for line in item.emit_unpack():
|
||||
lines += ["\t" + line]
|
||||
lines += ['\tdefault:']
|
||||
lines += ['\t\tm_pMsgFailedOn = "(type out of range)";']
|
||||
lines += ['\t\tbreak;']
|
||||
lines += ['\t}']
|
||||
lines += ['\t']
|
||||
lines += ['\tif(pUnpacker->Error())']
|
||||
lines += ['\t\tm_pMsgFailedOn = "(unpack error)";']
|
||||
lines += ['\t']
|
||||
lines += ['\tif(m_pMsgFailedOn)']
|
||||
lines += ['\t\treturn 0;']
|
||||
lines += ['\tm_pMsgFailedOn = "";']
|
||||
lines += ['\treturn m_aMsgData;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
|
||||
lines += ['\tdefault:']
|
||||
lines += ['\t\tm_pMsgFailedOn = "(type out of range)";']
|
||||
lines += ['\t\tbreak;']
|
||||
lines += ['\t}']
|
||||
lines += ['\t']
|
||||
lines += ['\tif(pUnpacker->Error())']
|
||||
lines += ['\t\tm_pMsgFailedOn = "(unpack error)";']
|
||||
lines += ['\t']
|
||||
lines += ['\tif(m_pMsgFailedOn)']
|
||||
lines += ['\t\treturn 0;']
|
||||
lines += ['\tm_pMsgFailedOn = "";']
|
||||
lines += ['\treturn m_aMsgData;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['bool CNetObjHandler::TeeHistorianRecordMsg(int Type)']
|
||||
lines += ['{']
|
||||
lines += ['\tswitch(Type)']
|
||||
lines += ['\t{']
|
||||
empty = True
|
||||
for msg in network.Messages:
|
||||
if not msg.teehistorian:
|
||||
lines += ['\tcase %s:' % msg.enum_name]
|
||||
empty = False
|
||||
if not empty:
|
||||
lines += ['\t\treturn false;']
|
||||
lines += ['\tdefault:']
|
||||
lines += ['\t\treturn true;']
|
||||
lines += ['\t}']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
|
||||
lines += ['bool CNetObjHandler::TeeHistorianRecordMsg(int Type)']
|
||||
lines += ['{']
|
||||
lines += ['\tswitch(Type)']
|
||||
lines += ['\t{']
|
||||
empty = True
|
||||
for msg in network.Messages:
|
||||
if not msg.teehistorian:
|
||||
lines += ['\tcase %s:' % msg.enum_name]
|
||||
empty = False
|
||||
if not empty:
|
||||
lines += ['\t\treturn false;']
|
||||
lines += ['\tdefault:']
|
||||
lines += ['\t\treturn true;']
|
||||
lines += ['\t}']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['void RegisterGameUuids(CUuidManager *pManager)']
|
||||
lines += ['{']
|
||||
|
||||
lines += ['void RegisterGameUuids(CUuidManager *pManager)']
|
||||
lines += ['{']
|
||||
for item in network.Objects + network.Messages:
|
||||
if item.ex is not None:
|
||||
lines += ['\tpManager->RegisterName(%s, "%s");' % (item.enum_name, item.ex)]
|
||||
lines += ['\tRegisterMapItemTypeUuids(pManager);']
|
||||
lines += ['}']
|
||||
|
||||
for item in network.Objects + network.Messages:
|
||||
if item.ex is not None:
|
||||
lines += ['\tpManager->RegisterName(%s, "%s");' % (item.enum_name, item.ex)]
|
||||
lines += ['\tRegisterMapItemTypeUuids(pManager);']
|
||||
lines += ['}']
|
||||
for l in lines:
|
||||
print(l)
|
||||
|
||||
for l in lines:
|
||||
print(l)
|
||||
if gen_client_content_header or gen_server_content_header:
|
||||
print("#endif")
|
||||
|
||||
if gen_client_content_header or gen_server_content_header:
|
||||
print("#endif")
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import copy
|
||||
from datatypes import *
|
||||
from datatypes import Array, Float, Int, Pointer, String, Struct, TextureHandle
|
||||
|
||||
class Sound(Struct):
|
||||
def __init__(self, filename=""):
|
||||
|
@ -8,13 +7,13 @@ class Sound(Struct):
|
|||
self.filename = String(filename)
|
||||
|
||||
class SoundSet(Struct):
|
||||
def __init__(self, name="", files=[]):
|
||||
def __init__(self, name="", files=()):
|
||||
Struct.__init__(self, "CDataSoundset")
|
||||
self.name = String(name)
|
||||
self.sounds = Array(Sound())
|
||||
self.last = Int(-1)
|
||||
for name in files:
|
||||
self.sounds.Add(Sound(name))
|
||||
for filename in files:
|
||||
self.sounds.Add(Sound(filename))
|
||||
|
||||
class Image(Struct):
|
||||
def __init__(self, name="", filename=""):
|
||||
|
@ -24,7 +23,7 @@ class Image(Struct):
|
|||
self.id = TextureHandle()
|
||||
|
||||
class SpriteSet(Struct):
|
||||
def __init__(self, name="", image=None, gridx=0, gridy=0):
|
||||
def __init__(self, _name="", image=None, gridx=0, gridy=0):
|
||||
Struct.__init__(self, "CDataSpriteset")
|
||||
self.image = Pointer(Image, image) # TODO
|
||||
self.gridx = Int(gridx)
|
||||
|
@ -70,7 +69,7 @@ class Animation(Struct):
|
|||
self.attach = AnimSequence()
|
||||
|
||||
class WeaponSpec(Struct):
|
||||
def __init__(self, container=None, name=""):
|
||||
def __init__(self, cont=None, name=""):
|
||||
Struct.__init__(self, "CDataWeaponspec")
|
||||
self.name = String(name)
|
||||
self.sprite_body = Pointer(Sprite, Sprite())
|
||||
|
@ -91,11 +90,14 @@ class WeaponSpec(Struct):
|
|||
self.muzzleduration = Float(5)
|
||||
|
||||
# dig out sprites if we have a container
|
||||
if container:
|
||||
for sprite in container.sprites.items:
|
||||
if sprite.name.value == "weapon_"+name+"_body": self.sprite_body.Set(sprite)
|
||||
elif sprite.name.value == "weapon_"+name+"_cursor": self.sprite_cursor.Set(sprite)
|
||||
elif sprite.name.value == "weapon_"+name+"_proj": self.sprite_proj.Set(sprite)
|
||||
if cont:
|
||||
for sprite in cont.sprites.items:
|
||||
if sprite.name.value == "weapon_"+name+"_body":
|
||||
self.sprite_body.Set(sprite)
|
||||
elif sprite.name.value == "weapon_"+name+"_cursor":
|
||||
self.sprite_cursor.Set(sprite)
|
||||
elif sprite.name.value == "weapon_"+name+"_proj":
|
||||
self.sprite_proj.Set(sprite)
|
||||
elif "weapon_"+name+"_muzzle" in sprite.name.value:
|
||||
self.sprite_muzzles.Add(Pointer(Sprite, sprite))
|
||||
|
||||
|
@ -168,8 +170,8 @@ class DataContainer(Struct):
|
|||
self.animations = Array(Animation())
|
||||
self.weapons = Weapons()
|
||||
|
||||
def FileList(format, num):
|
||||
return [format%(x+1) for x in range(0,num)]
|
||||
def FileList(fmt, num):
|
||||
return [fmt%(x+1) for x in range(0,num)]
|
||||
|
||||
container = DataContainer()
|
||||
container.sounds.Add(SoundSet("gun_fire", FileList("audio/wp_gun_fire-%02d.wv", 3)))
|
||||
|
|
|
@ -1,61 +1,52 @@
|
|||
def get_msgs():
|
||||
from datatypes import NetMessage
|
||||
import network
|
||||
import network
|
||||
import seven.network
|
||||
|
||||
return ["NETMSG_INVALID"] + [m.enum_name for m in network.Messages]
|
||||
def get_msgs():
|
||||
return ["NETMSG_INVALID"] + [m.enum_name for m in network.Messages]
|
||||
|
||||
def get_msgs_7():
|
||||
from seven.datatypes import NetMessage
|
||||
import seven.network as network
|
||||
|
||||
return ["NETMSG_INVALID"] + [m.enum_name for m in network.Messages]
|
||||
return ["NETMSG_INVALID"] + [m.enum_name for m in seven.network.Messages]
|
||||
|
||||
def get_objs():
|
||||
from datatypes import NetObject
|
||||
import network
|
||||
|
||||
return ["NETOBJ_INVALID"] + [m.enum_name for m in network.Objects if m.ex is None]
|
||||
return ["NETOBJ_INVALID"] + [m.enum_name for m in network.Objects if m.ex is None]
|
||||
|
||||
def get_objs_7():
|
||||
from seven.datatypes import NetObject
|
||||
import seven.network as network
|
||||
|
||||
return ["NETOBJ_INVALID"] + [m.enum_name for m in network.Objects]
|
||||
return ["NETOBJ_INVALID"] + [m.enum_name for m in seven.network.Objects]
|
||||
|
||||
def generate_map(a, b):
|
||||
map = []
|
||||
for i, m in enumerate(a):
|
||||
try:
|
||||
map += [b.index(m)]
|
||||
except ValueError:
|
||||
map += [-1]
|
||||
result = []
|
||||
for m in a:
|
||||
try:
|
||||
result += [b.index(m)]
|
||||
except ValueError:
|
||||
result += [-1]
|
||||
|
||||
return map
|
||||
return result
|
||||
|
||||
|
||||
def output_map(name, map):
|
||||
print("static const int gs_{}[{}] = {{".format(name, len(map)))
|
||||
print(*map, sep=',')
|
||||
print("};")
|
||||
print("inline int {0}(int a) {{ if(a < 0 || a >= {1}) return -1; return gs_{0}[a]; }}".format(name, len(map)))
|
||||
def output_map(name, m):
|
||||
print("static const int gs_{}[{}] = {{".format(name, len(m)))
|
||||
print(*m, sep=',')
|
||||
print("};")
|
||||
print("inline int {0}(int a) {{ if(a < 0 || a >= {1}) return -1; return gs_{0}[a]; }}".format(name, len(m)))
|
||||
|
||||
def main():
|
||||
guard = "GAME_GENERATED_PROTOCOLGLUE"
|
||||
print("#ifndef " + guard)
|
||||
print("#define " + guard)
|
||||
guard = "GAME_GENERATED_PROTOCOLGLUE"
|
||||
print("#ifndef " + guard)
|
||||
print("#define " + guard)
|
||||
|
||||
msgs = get_msgs()
|
||||
msgs7 = get_msgs_7()
|
||||
msgs = get_msgs()
|
||||
msgs7 = get_msgs_7()
|
||||
|
||||
output_map("Msg_SixToSeven", generate_map(msgs, msgs7))
|
||||
output_map("Msg_SevenToSix", generate_map(msgs7, msgs))
|
||||
output_map("Msg_SixToSeven", generate_map(msgs, msgs7))
|
||||
output_map("Msg_SevenToSix", generate_map(msgs7, msgs))
|
||||
|
||||
objs = get_objs()
|
||||
objs7 = get_objs_7()
|
||||
output_map("Obj_SixToSeven", generate_map(objs, objs7))
|
||||
output_map("Obj_SevenToSix", generate_map(objs7, objs))
|
||||
objs = get_objs()
|
||||
objs7 = get_objs_7()
|
||||
output_map("Obj_SixToSeven", generate_map(objs, objs7))
|
||||
output_map("Obj_SevenToSix", generate_map(objs7, objs))
|
||||
|
||||
print("#endif //" + guard)
|
||||
print("#endif //" + guard)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import sys
|
||||
|
||||
GlobalIdCounter = 0
|
||||
def GetID():
|
||||
global GlobalIdCounter
|
||||
|
@ -22,10 +20,10 @@ def FixCasing(Str):
|
|||
NewStr += c.lower()
|
||||
return NewStr
|
||||
|
||||
def FormatName(type, name):
|
||||
if "*" in type:
|
||||
def FormatName(typ, name):
|
||||
if "*" in typ:
|
||||
return "m_p" + FixCasing(name)
|
||||
if "[]" in type:
|
||||
if "[]" in typ:
|
||||
return "m_a" + FixCasing(name)
|
||||
return "m_" + FixCasing(name)
|
||||
|
||||
|
@ -35,17 +33,21 @@ class BaseType:
|
|||
self._target_name = "INVALID"
|
||||
self._id = GetID() # this is used to remember what order the members have in structures etc
|
||||
|
||||
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;
|
||||
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
|
||||
|
||||
def EmitDeclaration(self, name):
|
||||
return ["%s %s;"%(self.TypeName(), FormatName(self.TypeName(), name))]
|
||||
def EmitPreDefinition(self, target_name):
|
||||
self._target_name = target_name
|
||||
return []
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return []
|
||||
|
||||
class MemberType:
|
||||
|
@ -64,15 +66,10 @@ class Struct(BaseType):
|
|||
if name[0] == "_":
|
||||
continue
|
||||
m += [MemberType(name, self.__dict__[name])]
|
||||
try:
|
||||
m.sort(key = sorter)
|
||||
except:
|
||||
for v in m:
|
||||
print(v.name, v.var)
|
||||
sys.exit(-1)
|
||||
m.sort(key = sorter)
|
||||
return m
|
||||
|
||||
def EmitTypeDeclaration(self, name):
|
||||
def EmitTypeDeclaration(self, _name):
|
||||
lines = []
|
||||
lines += ["struct " + self.TypeName()]
|
||||
lines += ["{"]
|
||||
|
@ -87,7 +84,7 @@ class Struct(BaseType):
|
|||
for member in self.Members():
|
||||
lines += member.var.EmitPreDefinition(target_name+"."+member.name)
|
||||
return lines
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
lines = ["/* %s */ {" % self.TargetName()]
|
||||
for member in self.Members():
|
||||
lines += ["\t" + " ".join(member.var.EmitDefinition("")) + ","]
|
||||
|
@ -95,13 +92,13 @@ class Struct(BaseType):
|
|||
return lines
|
||||
|
||||
class Array(BaseType):
|
||||
def __init__(self, type):
|
||||
BaseType.__init__(self, type.TypeName())
|
||||
self.type = type
|
||||
def __init__(self, typ):
|
||||
BaseType.__init__(self, typ.TypeName())
|
||||
self.type = typ
|
||||
self.items = []
|
||||
def Add(self, instance):
|
||||
if instance.TypeName() != self.type.TypeName():
|
||||
error("bah")
|
||||
raise "bah"
|
||||
self.items += [instance]
|
||||
def EmitDeclaration(self, name):
|
||||
return ["int m_Num%s;"%(FixCasing(name)),
|
||||
|
@ -115,7 +112,7 @@ class Array(BaseType):
|
|||
lines += item.EmitPreDefinition("%s[%d]"%(self.Identifyer(), i))
|
||||
i += 1
|
||||
|
||||
if len(self.items):
|
||||
if self.items:
|
||||
lines += ["static %s %s[] = {"%(self.TypeName(), self.Identifyer())]
|
||||
for item in self.items:
|
||||
itemlines = item.EmitDefinition("")
|
||||
|
@ -125,7 +122,7 @@ class Array(BaseType):
|
|||
lines += ["static %s *%s = 0;"%(self.TypeName(), self.Identifyer())]
|
||||
|
||||
return lines
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return [str(len(self.items))+","+self.Identifyer()]
|
||||
|
||||
# Basic Types
|
||||
|
@ -136,7 +133,7 @@ class Int(BaseType):
|
|||
self.value = value
|
||||
def Set(self, value):
|
||||
self.value = value
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return ["%d"%self.value]
|
||||
#return ["%d /* %s */"%(self.value, self._target_name)]
|
||||
|
||||
|
@ -146,7 +143,7 @@ class Float(BaseType):
|
|||
self.value = value
|
||||
def Set(self, value):
|
||||
self.value = value
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return ["%ff"%self.value]
|
||||
#return ["%d /* %s */"%(self.value, self._target_name)]
|
||||
|
||||
|
@ -156,22 +153,22 @@ class String(BaseType):
|
|||
self.value = value
|
||||
def Set(self, value):
|
||||
self.value = value
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return ['"'+self.value+'"']
|
||||
|
||||
class Pointer(BaseType):
|
||||
def __init__(self, type, target):
|
||||
BaseType.__init__(self, "%s*"%type().TypeName())
|
||||
def __init__(self, typ, target):
|
||||
BaseType.__init__(self, "%s*"%typ().TypeName())
|
||||
self.target = target
|
||||
def Set(self, target):
|
||||
self.target = target
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return ["&"+self.target.TargetName()]
|
||||
|
||||
class TextureHandle(BaseType):
|
||||
def __init__(self):
|
||||
BaseType.__init__(self, "IGraphics::CTextureHandle")
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return ["IGraphics::CTextureHandle()"]
|
||||
|
||||
# helper functions
|
||||
|
@ -343,10 +340,10 @@ class NetIntAny(NetVariable):
|
|||
return ["pPacker->AddInt(%s);" % self.name]
|
||||
|
||||
class NetIntRange(NetIntAny):
|
||||
def __init__(self, name, min, max):
|
||||
def __init__(self, name, min_val, max_val):
|
||||
NetIntAny.__init__(self,name)
|
||||
self.min = str(min)
|
||||
self.max = str(max)
|
||||
self.min = str(min_val)
|
||||
self.max = str(max_val)
|
||||
def emit_validate(self):
|
||||
return ["pObj->%s = ClampInt(\"%s\", pObj->%s, %s, %s);"%(self.name, self.name, self.name, self.min, self.max)]
|
||||
def emit_unpack_check(self):
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from datatypes import *
|
||||
from datatypes import Enum, Flags, NetBool, NetEvent, NetIntAny, NetIntRange, NetMessage, NetMessageEx, NetObject, NetObjectEx, NetString, NetStringHalfStrict, NetStringStrict, NetTick
|
||||
|
||||
Emotes = ["NORMAL", "PAIN", "HAPPY", "SURPRISE", "ANGRY", "BLINK"]
|
||||
PlayerFlags = ["PLAYING", "IN_MENU", "CHATTING", "SCOREBOARD", "AIM"]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import sys
|
||||
from .datatypes import *
|
||||
from .datatypes import EmitDefinition, EmitTypeDeclaration
|
||||
from . import content
|
||||
from . import network
|
||||
|
||||
|
@ -31,7 +31,7 @@ def EmitEnum(names, num):
|
|||
print("\t%s" % num)
|
||||
print("};")
|
||||
|
||||
def EmitFlags(names, num):
|
||||
def EmitFlags(names):
|
||||
print("enum")
|
||||
print("{")
|
||||
i = 0
|
||||
|
@ -40,324 +40,286 @@ def EmitFlags(names, num):
|
|||
i += 1
|
||||
print("};")
|
||||
|
||||
gen_network_header = False
|
||||
gen_network_source = False
|
||||
gen_client_content_header = False
|
||||
gen_client_content_source = False
|
||||
gen_server_content_header = False
|
||||
gen_server_content_source = False
|
||||
def main():
|
||||
gen_network_header = "network_header" in sys.argv
|
||||
gen_network_source = "network_source" in sys.argv
|
||||
gen_client_content_header = "client_content_header" in sys.argv
|
||||
gen_client_content_source = "client_content_source" in sys.argv
|
||||
gen_server_content_header = "server_content_header" in sys.argv
|
||||
gen_server_content_source = "server_content_source" in sys.argv
|
||||
|
||||
if "network_header" in sys.argv: gen_network_header = True
|
||||
if "network_source" in sys.argv: gen_network_source = True
|
||||
if "client_content_header" in sys.argv: gen_client_content_header = True
|
||||
if "client_content_source" in sys.argv: gen_client_content_source = True
|
||||
if "server_content_header" in sys.argv: gen_server_content_header = True
|
||||
if "server_content_source" in sys.argv: gen_server_content_source = True
|
||||
if gen_client_content_header:
|
||||
print("#ifndef CLIENT_CONTENT7_HEADER")
|
||||
print("#define CLIENT_CONTENT7_HEADER")
|
||||
|
||||
if gen_client_content_header:
|
||||
print("#ifndef CLIENT_CONTENT7_HEADER")
|
||||
print("#define CLIENT_CONTENT7_HEADER")
|
||||
|
||||
if gen_server_content_header:
|
||||
print("#ifndef SERVER_CONTENT7_HEADER")
|
||||
print("#define SERVER_CONTENT7_HEADER")
|
||||
if gen_server_content_header:
|
||||
print("#ifndef SERVER_CONTENT7_HEADER")
|
||||
print("#define SERVER_CONTENT7_HEADER")
|
||||
|
||||
|
||||
if gen_client_content_header or gen_server_content_header:
|
||||
# print some includes
|
||||
print('#include <engine/graphics.h>')
|
||||
print('#include <engine/sound.h>')
|
||||
print("namespace client_data7 {")
|
||||
if gen_client_content_header or gen_server_content_header:
|
||||
# print some includes
|
||||
print('#include <engine/graphics.h>')
|
||||
print('#include <engine/sound.h>')
|
||||
print("namespace client_data7 {")
|
||||
|
||||
# emit the type declarations
|
||||
contentlines = open("datasrc/content.py", "rb").readlines()
|
||||
order = []
|
||||
for line in contentlines:
|
||||
line = line.strip()
|
||||
if line[:6] == "class ".encode() and "(Struct)".encode() in line:
|
||||
order += [line.split()[1].split("(".encode())[0].decode("ascii")]
|
||||
for name in order:
|
||||
EmitTypeDeclaration(content.__dict__[name])
|
||||
# emit the type declarations
|
||||
contentlines = open("datasrc/content.py", "rb").readlines()
|
||||
order = []
|
||||
for line in contentlines:
|
||||
line = line.strip()
|
||||
if line[:6] == "class ".encode() and "(Struct)".encode() in line:
|
||||
order += [line.split()[1].split("(".encode())[0].decode("ascii")]
|
||||
for name in order:
|
||||
EmitTypeDeclaration(content.__dict__[name])
|
||||
|
||||
# the container pointer
|
||||
print('extern CDataContainer *g_pData;')
|
||||
# the container pointer
|
||||
print('extern CDataContainer *g_pData;')
|
||||
|
||||
# enums
|
||||
EmitEnum(["IMAGE_%s"%i.name.value.upper() for i in content.container.images.items], "NUM_IMAGES")
|
||||
EmitEnum(["ANIM_%s"%i.name.value.upper() for i in content.container.animations.items], "NUM_ANIMS")
|
||||
EmitEnum(["SPRITE_%s"%i.name.value.upper() for i in content.container.sprites.items], "NUM_SPRITES")
|
||||
# enums
|
||||
EmitEnum(["IMAGE_%s"%i.name.value.upper() for i in content.container.images.items], "NUM_IMAGES")
|
||||
EmitEnum(["ANIM_%s"%i.name.value.upper() for i in content.container.animations.items], "NUM_ANIMS")
|
||||
EmitEnum(["SPRITE_%s"%i.name.value.upper() for i in content.container.sprites.items], "NUM_SPRITES")
|
||||
|
||||
if gen_client_content_source or gen_server_content_source:
|
||||
if gen_client_content_source:
|
||||
print('#include "client_data7.h"')
|
||||
if gen_server_content_source:
|
||||
print('#include "server_data.h"')
|
||||
print("namespace client_data7 {")
|
||||
EmitDefinition(content.container, "datacontainer")
|
||||
print('CDataContainer *g_pData = &datacontainer;')
|
||||
print("}")
|
||||
if gen_client_content_source or gen_server_content_source:
|
||||
if gen_client_content_source:
|
||||
print('#include "client_data7.h"')
|
||||
if gen_server_content_source:
|
||||
print('#include "server_data.h"')
|
||||
print("namespace client_data7 {")
|
||||
EmitDefinition(content.container, "datacontainer")
|
||||
print('CDataContainer *g_pData = &datacontainer;')
|
||||
print("}")
|
||||
|
||||
# NETWORK
|
||||
if gen_network_header:
|
||||
if gen_network_header:
|
||||
|
||||
print("#ifndef GAME_GENERATED_PROTOCOL7_H")
|
||||
print("#define GAME_GENERATED_PROTOCOL7_H")
|
||||
print("#include <engine/shared/protocol.h>")
|
||||
print("#include <engine/message.h>")
|
||||
print("namespace protocol7 {")
|
||||
print(network.RawHeader)
|
||||
print("#ifndef GAME_GENERATED_PROTOCOL7_H")
|
||||
print("#define GAME_GENERATED_PROTOCOL7_H")
|
||||
print("#include <engine/shared/protocol.h>")
|
||||
print("#include <engine/message.h>")
|
||||
print("namespace protocol7 {")
|
||||
print(network.RawHeader)
|
||||
|
||||
for e in network.Enums:
|
||||
for l in create_enum_table(["%s_%s"%(e.name, v) for v in e.values], 'NUM_%sS'%e.name): print(l)
|
||||
for e in network.Enums:
|
||||
for l in create_enum_table(["%s_%s"%(e.name, v) for v in e.values], 'NUM_%sS'%e.name):
|
||||
print(l)
|
||||
print("")
|
||||
|
||||
for e in network.Flags:
|
||||
for l in create_flags_table(["%s_%s" % (e.name, v) for v in e.values]):
|
||||
print(l)
|
||||
print("")
|
||||
|
||||
for l in create_enum_table(["NETOBJ_INVALID"]+[o.enum_name for o in network.Objects], "NUM_NETOBJTYPES"):
|
||||
print(l)
|
||||
print("")
|
||||
for l in create_enum_table(["NETMSG_INVALID"]+[o.enum_name for o in network.Messages], "NUM_NETMSGTYPES"):
|
||||
print(l)
|
||||
print("")
|
||||
|
||||
for e in network.Flags:
|
||||
for l in create_flags_table(["%s_%s" % (e.name, v) for v in e.values]): print(l)
|
||||
print("")
|
||||
print("""
|
||||
template<typename... Ts> struct make_void { typedef void type;};
|
||||
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
|
||||
|
||||
for l in create_enum_table(["NETOBJ_INVALID"]+[o.enum_name for o in network.Objects], "NUM_NETOBJTYPES"): print(l)
|
||||
print("")
|
||||
for l in create_enum_table(["NETMSG_INVALID"]+[o.enum_name for o in network.Messages], "NUM_NETMSGTYPES"): print(l)
|
||||
print("")
|
||||
template<typename T, typename = void>
|
||||
struct is_sixup {
|
||||
constexpr static bool value = false;
|
||||
};
|
||||
|
||||
print("""
|
||||
template<typename... Ts> struct make_void { typedef void type;};
|
||||
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
|
||||
template<typename T>
|
||||
struct is_sixup<T, void_t<typename T::is_sixup>> {
|
||||
constexpr static bool value = true;
|
||||
};
|
||||
""")
|
||||
|
||||
template<typename T, typename = void>
|
||||
struct is_sixup {
|
||||
constexpr static bool value = false;
|
||||
};
|
||||
for item in network.Objects + network.Messages:
|
||||
for line in item.emit_declaration():
|
||||
print(line)
|
||||
print("")
|
||||
|
||||
template<typename T>
|
||||
struct is_sixup<T, void_t<typename T::is_sixup>> {
|
||||
constexpr static bool value = true;
|
||||
};
|
||||
""")
|
||||
EmitEnum(["SOUND_%s"%i.name.value.upper() for i in content.container.sounds.items], "NUM_SOUNDS")
|
||||
EmitEnum(["WEAPON_%s"%i.name.value.upper() for i in content.container.weapons.id.items], "NUM_WEAPONS")
|
||||
|
||||
for item in network.Objects + network.Messages:
|
||||
for line in item.emit_declaration():
|
||||
print(line)
|
||||
print("")
|
||||
print("""
|
||||
|
||||
EmitEnum(["SOUND_%s"%i.name.value.upper() for i in content.container.sounds.items], "NUM_SOUNDS")
|
||||
EmitEnum(["WEAPON_%s"%i.name.value.upper() for i in content.container.weapons.id.items], "NUM_WEAPONS")
|
||||
class CNetObjHandler
|
||||
{
|
||||
const char *m_pMsgFailedOn;
|
||||
char m_aMsgData[1024];
|
||||
const char *m_pObjFailedOn;
|
||||
int m_NumObjFailures;
|
||||
bool CheckInt(const char *pErrorMsg, int Value, int Min, int Max);
|
||||
bool CheckFlag(const char *pErrorMsg, int Value, int Mask);
|
||||
|
||||
print("""
|
||||
static const char *ms_apObjNames[];
|
||||
static int ms_aObjSizes[];
|
||||
static const char *ms_apMsgNames[];
|
||||
|
||||
class CNetObjHandler
|
||||
{
|
||||
const char *m_pMsgFailedOn;
|
||||
char m_aMsgData[1024];
|
||||
const char *m_pObjFailedOn;
|
||||
int m_NumObjFailures;
|
||||
bool CheckInt(const char *pErrorMsg, int Value, int Min, int Max);
|
||||
bool CheckFlag(const char *pErrorMsg, int Value, int Mask);
|
||||
public:
|
||||
CNetObjHandler();
|
||||
|
||||
static const char *ms_apObjNames[];
|
||||
static int ms_aObjSizes[];
|
||||
static const char *ms_apMsgNames[];
|
||||
int ValidateObj(int Type, const void *pData, int Size);
|
||||
const char *GetObjName(int Type) const;
|
||||
int GetObjSize(int Type) const;
|
||||
const char *FailedObjOn() const;
|
||||
int NumObjFailures() const;
|
||||
|
||||
public:
|
||||
CNetObjHandler();
|
||||
const char *GetMsgName(int Type) const;
|
||||
void *SecureUnpackMsg(int Type, CUnpacker *pUnpacker);
|
||||
const char *FailedMsgOn() const;
|
||||
};
|
||||
|
||||
int ValidateObj(int Type, const void *pData, int Size);
|
||||
const char *GetObjName(int Type) const;
|
||||
int GetObjSize(int Type) const;
|
||||
const char *FailedObjOn() const;
|
||||
int NumObjFailures() const;
|
||||
""")
|
||||
|
||||
const char *GetMsgName(int Type) const;
|
||||
void *SecureUnpackMsg(int Type, CUnpacker *pUnpacker);
|
||||
const char *FailedMsgOn() const;
|
||||
};
|
||||
|
||||
""")
|
||||
|
||||
print("}")
|
||||
print("#endif // GAME_GENERATED_PROTOCOL7_H")
|
||||
print("}")
|
||||
print("#endif // GAME_GENERATED_PROTOCOL7_H")
|
||||
|
||||
|
||||
if gen_network_source:
|
||||
# create names
|
||||
lines = []
|
||||
if gen_network_source:
|
||||
# create names
|
||||
lines = []
|
||||
|
||||
lines += ['#include "protocol7.h"']
|
||||
lines += ['#include <engine/shared/protocol.h>']
|
||||
lines += ['#include <engine/message.h>']
|
||||
lines += ['#include "protocol7.h"']
|
||||
lines += ['#include <engine/shared/protocol.h>']
|
||||
lines += ['#include <engine/message.h>']
|
||||
|
||||
lines += ['namespace protocol7 {']
|
||||
lines += ['namespace protocol7 {']
|
||||
|
||||
lines += ['CNetObjHandler::CNetObjHandler()']
|
||||
lines += ['{']
|
||||
lines += ['\tm_pMsgFailedOn = "";']
|
||||
lines += ['\tm_pObjFailedOn = "";']
|
||||
lines += ['\tm_NumObjFailures = 0;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['const char *CNetObjHandler::FailedObjOn() const { return m_pObjFailedOn; }']
|
||||
lines += ['int CNetObjHandler::NumObjFailures() const { return m_NumObjFailures; }']
|
||||
lines += ['const char *CNetObjHandler::FailedMsgOn() const { return m_pMsgFailedOn; }']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['CNetObjHandler::CNetObjHandler()']
|
||||
lines += ['{']
|
||||
lines += ['\tm_pMsgFailedOn = "";']
|
||||
lines += ['\tm_pObjFailedOn = "";']
|
||||
lines += ['\tm_NumObjFailures = 0;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['const char *CNetObjHandler::FailedObjOn() const { return m_pObjFailedOn; }']
|
||||
lines += ['int CNetObjHandler::NumObjFailures() const { return m_NumObjFailures; }']
|
||||
lines += ['const char *CNetObjHandler::FailedMsgOn() const { return m_pMsgFailedOn; }']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
lines += ['']
|
||||
|
||||
lines += ['static const int max_int = 0x7fffffff;']
|
||||
lines += ['']
|
||||
lines += ['static const int max_int = 0x7fffffff;']
|
||||
lines += ['']
|
||||
|
||||
lines += ['bool CNetObjHandler::CheckInt(const char *pErrorMsg, int Value, int Min, int Max)']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Value < Min || Value > Max) { m_pObjFailedOn = pErrorMsg; m_NumObjFailures++; return false; }']
|
||||
lines += ['\treturn true;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['bool CNetObjHandler::CheckInt(const char *pErrorMsg, int Value, int Min, int Max)']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Value < Min || Value > Max) { m_pObjFailedOn = pErrorMsg; m_NumObjFailures++; return false; }']
|
||||
lines += ['\treturn true;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
|
||||
lines += ['bool CNetObjHandler::CheckFlag(const char *pErrorMsg, int Value, int Mask)']
|
||||
lines += ['{']
|
||||
lines += ['\tif((Value&Mask) != Value) { m_pObjFailedOn = pErrorMsg; m_NumObjFailures++; return false; }']
|
||||
lines += ['\treturn true;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['bool CNetObjHandler::CheckFlag(const char *pErrorMsg, int Value, int Mask)']
|
||||
lines += ['{']
|
||||
lines += ['\tif((Value&Mask) != Value) { m_pObjFailedOn = pErrorMsg; m_NumObjFailures++; return false; }']
|
||||
lines += ['\treturn true;']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
|
||||
lines += ["const char *CNetObjHandler::ms_apObjNames[] = {"]
|
||||
lines += ['\t"invalid",']
|
||||
lines += ['\t"%s",' % o.name for o in network.Objects]
|
||||
lines += ['\t""', "};", ""]
|
||||
lines += ["const char *CNetObjHandler::ms_apObjNames[] = {"]
|
||||
lines += ['\t"invalid",']
|
||||
lines += ['\t"%s",' % o.name for o in network.Objects]
|
||||
lines += ['\t""', "};", ""]
|
||||
|
||||
lines += ["int CNetObjHandler::ms_aObjSizes[] = {"]
|
||||
lines += ['\t0,']
|
||||
lines += ['\tsizeof(%s),' % o.struct_name for o in network.Objects]
|
||||
lines += ['\t0', "};", ""]
|
||||
lines += ["int CNetObjHandler::ms_aObjSizes[] = {"]
|
||||
lines += ['\t0,']
|
||||
lines += ['\tsizeof(%s),' % o.struct_name for o in network.Objects]
|
||||
lines += ['\t0', "};", ""]
|
||||
|
||||
|
||||
lines += ['const char *CNetObjHandler::ms_apMsgNames[] = {']
|
||||
lines += ['\t"invalid",']
|
||||
for msg in network.Messages:
|
||||
lines += ['\t"%s",' % msg.name]
|
||||
lines += ['\t""']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
lines += ['const char *CNetObjHandler::ms_apMsgNames[] = {']
|
||||
lines += ['\t"invalid",']
|
||||
for msg in network.Messages:
|
||||
lines += ['\t"%s",' % msg.name]
|
||||
lines += ['\t""']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
|
||||
lines += ['const char *CNetObjHandler::GetObjName(int Type) const']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETOBJTYPES) return "(out of range)";']
|
||||
lines += ['\treturn ms_apObjNames[Type];']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
lines += ['const char *CNetObjHandler::GetObjName(int Type) const']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETOBJTYPES) return "(out of range)";']
|
||||
lines += ['\treturn ms_apObjNames[Type];']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
|
||||
lines += ['int CNetObjHandler::GetObjSize(int Type) const']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETOBJTYPES) return 0;']
|
||||
lines += ['\treturn ms_aObjSizes[Type];']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
lines += ['int CNetObjHandler::GetObjSize(int Type) const']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETOBJTYPES) return 0;']
|
||||
lines += ['\treturn ms_aObjSizes[Type];']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
|
||||
|
||||
lines += ['const char *CNetObjHandler::GetMsgName(int Type) const']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETMSGTYPES) return "(out of range)";']
|
||||
lines += ['\treturn ms_apMsgNames[Type];']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
lines += ['const char *CNetObjHandler::GetMsgName(int Type) const']
|
||||
lines += ['{']
|
||||
lines += ['\tif(Type < 0 || Type >= NUM_NETMSGTYPES) return "(out of range)";']
|
||||
lines += ['\treturn ms_apMsgNames[Type];']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
|
||||
|
||||
for l in lines:
|
||||
print(l)
|
||||
for l in lines:
|
||||
print(l)
|
||||
|
||||
lines = []
|
||||
lines += ['int CNetObjHandler::ValidateObj(int Type, const void *pData, int Size)']
|
||||
lines += ['{']
|
||||
lines += ['\tswitch(Type)']
|
||||
lines += ['\t{']
|
||||
|
||||
if 0:
|
||||
for item in network.Objects:
|
||||
for line in item.emit_validate():
|
||||
print(line)
|
||||
print("")
|
||||
lines += ["\t" + line]
|
||||
lines += ['\t']
|
||||
lines += ['\t}']
|
||||
lines += ['\treturn -1;']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
|
||||
# create validate tables
|
||||
lines = []
|
||||
lines += ['static int validate_invalid(void *data, int size) { return -1; }']
|
||||
lines += ["typedef int(*VALIDATEFUNC)(void *data, int size);"]
|
||||
lines += ["static VALIDATEFUNC validate_funcs[] = {"]
|
||||
lines += ['\tvalidate_invalid,']
|
||||
lines += ['\tvalidate_%s,' % o.name for o in network.Objects]
|
||||
lines += ["\t0x0", "};", ""]
|
||||
lines += ['void *CNetObjHandler::SecureUnpackMsg(int Type, CUnpacker *pUnpacker)']
|
||||
lines += ['{']
|
||||
lines += ['\tm_pMsgFailedOn = 0;']
|
||||
lines += ['\tm_pObjFailedOn = 0;']
|
||||
lines += ['\tswitch(Type)']
|
||||
lines += ['\t{']
|
||||
|
||||
lines += ["int netobj_validate(int type, void *data, int size)"]
|
||||
lines += ["{"]
|
||||
lines += ["\tif(type < 0 || type >= NUM_NETOBJTYPES) return -1;"]
|
||||
lines += ["\treturn validate_funcs[type](data, size);"]
|
||||
lines += ["};", ""]
|
||||
|
||||
lines = []
|
||||
lines += ['int CNetObjHandler::ValidateObj(int Type, const void *pData, int Size)']
|
||||
lines += ['{']
|
||||
lines += ['\tswitch(Type)']
|
||||
lines += ['\t{']
|
||||
|
||||
for item in network.Objects:
|
||||
for line in item.emit_validate():
|
||||
lines += ["\t" + line]
|
||||
lines += ['\t']
|
||||
lines += ['\t}']
|
||||
lines += ['\treturn -1;']
|
||||
lines += ['};']
|
||||
lines += ['']
|
||||
|
||||
#int Validate(int Type, void *pData, int Size);
|
||||
|
||||
if 0:
|
||||
for item in network.Messages:
|
||||
for line in item.emit_unpack():
|
||||
print(line)
|
||||
print("")
|
||||
lines += ["\t" + line]
|
||||
lines += ['\t']
|
||||
|
||||
lines += ['static void *secure_unpack_invalid(CUnpacker *pUnpacker) { return 0; }']
|
||||
lines += ['typedef void *(*SECUREUNPACKFUNC)(CUnpacker *pUnpacker);']
|
||||
lines += ['static SECUREUNPACKFUNC secure_unpack_funcs[] = {']
|
||||
lines += ['\tsecure_unpack_invalid,']
|
||||
for msg in network.Messages:
|
||||
lines += ['\tsecure_unpack_%s,' % msg.name]
|
||||
lines += ['\t0x0']
|
||||
lines += ['};']
|
||||
|
||||
#
|
||||
lines += ['void *CNetObjHandler::SecureUnpackMsg(int Type, CUnpacker *pUnpacker)']
|
||||
lines += ['{']
|
||||
lines += ['\tm_pMsgFailedOn = 0;']
|
||||
lines += ['\tm_pObjFailedOn = 0;']
|
||||
lines += ['\tswitch(Type)']
|
||||
lines += ['\t{']
|
||||
|
||||
|
||||
for item in network.Messages:
|
||||
for line in item.emit_unpack():
|
||||
lines += ["\t" + line]
|
||||
lines += ['\tdefault:']
|
||||
lines += ['\t\tm_pMsgFailedOn = "(type out of range)";']
|
||||
lines += ['\t\tbreak;']
|
||||
lines += ['\t}']
|
||||
lines += ['\t']
|
||||
|
||||
lines += ['\tdefault:']
|
||||
lines += ['\t\tm_pMsgFailedOn = "(type out of range)";']
|
||||
lines += ['\t\tbreak;']
|
||||
lines += ['\t}']
|
||||
lines += ['\t']
|
||||
lines += ['\tif(pUnpacker->Error())']
|
||||
lines += ['\t\tm_pMsgFailedOn = "(unpack error)";']
|
||||
lines += ['\t']
|
||||
lines += ['\tif(m_pMsgFailedOn || m_pObjFailedOn) {']
|
||||
lines += ['\t\tif(!m_pMsgFailedOn)']
|
||||
lines += ['\t\t\tm_pMsgFailedOn = "";']
|
||||
lines += ['\t\tif(!m_pObjFailedOn)']
|
||||
lines += ['\t\t\tm_pObjFailedOn = "";']
|
||||
lines += ['\t\treturn 0;']
|
||||
lines += ['\t}']
|
||||
lines += ['\tm_pMsgFailedOn = "";']
|
||||
lines += ['\tm_pObjFailedOn = "";']
|
||||
lines += ['\treturn m_aMsgData;']
|
||||
lines += ['};']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
lines += ['\tif(pUnpacker->Error())']
|
||||
lines += ['\t\tm_pMsgFailedOn = "(unpack error)";']
|
||||
lines += ['\t']
|
||||
lines += ['\tif(m_pMsgFailedOn || m_pObjFailedOn) {']
|
||||
lines += ['\t\tif(!m_pMsgFailedOn)']
|
||||
lines += ['\t\t\tm_pMsgFailedOn = "";']
|
||||
lines += ['\t\tif(!m_pObjFailedOn)']
|
||||
lines += ['\t\t\tm_pObjFailedOn = "";']
|
||||
lines += ['\t\treturn 0;']
|
||||
lines += ['\t}']
|
||||
lines += ['\tm_pMsgFailedOn = "";']
|
||||
lines += ['\tm_pObjFailedOn = "";']
|
||||
lines += ['\treturn m_aMsgData;']
|
||||
lines += ['};']
|
||||
lines += ['}']
|
||||
lines += ['']
|
||||
|
||||
|
||||
for l in lines:
|
||||
print(l)
|
||||
for l in lines:
|
||||
print(l)
|
||||
|
||||
if gen_client_content_header or gen_server_content_header:
|
||||
print("}")
|
||||
print("#endif")
|
||||
if gen_client_content_header or gen_server_content_header:
|
||||
print("}")
|
||||
print("#endif")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from .datatypes import *
|
||||
from .datatypes import Array, Float, Int, Pointer, SampleHandle, String, Struct, TextureHandle
|
||||
|
||||
class Sound(Struct):
|
||||
def __init__(self, filename=""):
|
||||
|
@ -7,13 +7,13 @@ class Sound(Struct):
|
|||
self.filename = String(filename)
|
||||
|
||||
class SoundSet(Struct):
|
||||
def __init__(self, name="", files=[]):
|
||||
def __init__(self, name="", files=()):
|
||||
Struct.__init__(self, "CDataSoundset")
|
||||
self.name = String(name)
|
||||
self.sounds = Array(Sound())
|
||||
self.last = Int(-1)
|
||||
for name in files:
|
||||
self.sounds.Add(Sound(name))
|
||||
for filename in files:
|
||||
self.sounds.Add(Sound(filename))
|
||||
|
||||
class Image(Struct):
|
||||
def __init__(self, name="", filename="", linear_mapping=0):
|
||||
|
@ -24,7 +24,7 @@ class Image(Struct):
|
|||
self.id = TextureHandle()
|
||||
|
||||
class SpriteSet(Struct):
|
||||
def __init__(self, name="", image=None, gridx=0, gridy=0):
|
||||
def __init__(self, _name="", image=None, gridx=0, gridy=0):
|
||||
Struct.__init__(self, "CDataSpriteset")
|
||||
self.image = Pointer(Image, image) # TODO
|
||||
self.gridx = Int(gridx)
|
||||
|
@ -70,7 +70,7 @@ class Animation(Struct):
|
|||
self.attach = AnimSequence()
|
||||
|
||||
class WeaponSpec(Struct):
|
||||
def __init__(self, container=None, name=""):
|
||||
def __init__(self, cont=None, name=""):
|
||||
Struct.__init__(self, "CDataWeaponspec")
|
||||
self.name = String(name)
|
||||
self.sprite_body = Pointer(Sprite, Sprite())
|
||||
|
@ -91,11 +91,14 @@ class WeaponSpec(Struct):
|
|||
self.muzzleduration = Float(5)
|
||||
|
||||
# dig out sprites if we have a container
|
||||
if container:
|
||||
for sprite in container.sprites.items:
|
||||
if sprite.name.value == "weapon_"+name+"_body": self.sprite_body.Set(sprite)
|
||||
elif sprite.name.value == "weapon_"+name+"_cursor": self.sprite_cursor.Set(sprite)
|
||||
elif sprite.name.value == "weapon_"+name+"_proj": self.sprite_proj.Set(sprite)
|
||||
if cont:
|
||||
for sprite in cont.sprites.items:
|
||||
if sprite.name.value == "weapon_"+name+"_body":
|
||||
self.sprite_body.Set(sprite)
|
||||
elif sprite.name.value == "weapon_"+name+"_cursor":
|
||||
self.sprite_cursor.Set(sprite)
|
||||
elif sprite.name.value == "weapon_"+name+"_proj":
|
||||
self.sprite_proj.Set(sprite)
|
||||
elif "weapon_"+name+"_muzzle" in sprite.name.value:
|
||||
self.sprite_muzzles.Add(Pointer(Sprite, sprite))
|
||||
|
||||
|
@ -175,8 +178,8 @@ class DataContainer(Struct):
|
|||
self.weapons = Weapons()
|
||||
#self.explosion = Explosion()
|
||||
|
||||
def FileList(format, num):
|
||||
return [format%(x+1) for x in range(0,num)]
|
||||
def FileList(fmt, num):
|
||||
return [fmt%(x+1) for x in range(0,num)]
|
||||
|
||||
container = DataContainer()
|
||||
container.sounds.Add(SoundSet("gun_fire", FileList("audio/wp_gun_fire-%02d.wv", 3)))
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
import sys
|
||||
|
||||
GlobalIdCounter = 0
|
||||
def GetID():
|
||||
global GlobalIdCounter
|
||||
|
@ -22,10 +20,10 @@ def FixCasing(Str):
|
|||
NewStr += c.lower()
|
||||
return NewStr
|
||||
|
||||
def FormatName(type, name):
|
||||
if "*" in type:
|
||||
def FormatName(typ, name):
|
||||
if "*" in typ:
|
||||
return "m_p" + FixCasing(name)
|
||||
if "[]" in type:
|
||||
if "[]" in typ:
|
||||
return "m_a" + FixCasing(name)
|
||||
return "m_" + FixCasing(name)
|
||||
|
||||
|
@ -35,17 +33,21 @@ class BaseType:
|
|||
self._target_name = "INVALID"
|
||||
self._id = GetID() # this is used to remember what order the members have in structures etc
|
||||
|
||||
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;
|
||||
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
|
||||
|
||||
def EmitDeclaration(self, name):
|
||||
return ["%s %s;"%(self.TypeName(), FormatName(self.TypeName(), name))]
|
||||
def EmitPreDefinition(self, target_name):
|
||||
self._target_name = target_name
|
||||
return []
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return []
|
||||
|
||||
class MemberType:
|
||||
|
@ -64,15 +66,10 @@ class Struct(BaseType):
|
|||
if name[0] == "_":
|
||||
continue
|
||||
m += [MemberType(name, self.__dict__[name])]
|
||||
try:
|
||||
m.sort(key = sorter)
|
||||
except:
|
||||
for v in m:
|
||||
print(v.name, v.var)
|
||||
sys.exit(-1)
|
||||
m.sort(key = sorter)
|
||||
return m
|
||||
|
||||
def EmitTypeDeclaration(self, name):
|
||||
def EmitTypeDeclaration(self, _name):
|
||||
lines = []
|
||||
lines += ["struct " + self.TypeName()]
|
||||
lines += ["{"]
|
||||
|
@ -87,7 +84,7 @@ class Struct(BaseType):
|
|||
for member in self.Members():
|
||||
lines += member.var.EmitPreDefinition(target_name+"."+member.name)
|
||||
return lines
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
lines = ["/* %s */ {" % self.TargetName()]
|
||||
for member in self.Members():
|
||||
lines += ["\t" + " ".join(member.var.EmitDefinition("")) + ","]
|
||||
|
@ -95,13 +92,13 @@ class Struct(BaseType):
|
|||
return lines
|
||||
|
||||
class Array(BaseType):
|
||||
def __init__(self, type):
|
||||
BaseType.__init__(self, type.TypeName())
|
||||
self.type = type
|
||||
def __init__(self, typ):
|
||||
BaseType.__init__(self, typ.TypeName())
|
||||
self.type = typ
|
||||
self.items = []
|
||||
def Add(self, instance):
|
||||
if instance.TypeName() != self.type.TypeName():
|
||||
error("bah")
|
||||
raise "bah"
|
||||
self.items += [instance]
|
||||
def EmitDeclaration(self, name):
|
||||
return ["int m_Num%s;"%(FixCasing(name)),
|
||||
|
@ -115,7 +112,7 @@ class Array(BaseType):
|
|||
lines += item.EmitPreDefinition("%s[%d]"%(self.Identifyer(), i))
|
||||
i += 1
|
||||
|
||||
if len(self.items):
|
||||
if self.items:
|
||||
lines += ["static %s %s[] = {"%(self.TypeName(), self.Identifyer())]
|
||||
for item in self.items:
|
||||
itemlines = item.EmitDefinition("")
|
||||
|
@ -125,7 +122,7 @@ class Array(BaseType):
|
|||
lines += ["static %s *%s = 0;"%(self.TypeName(), self.Identifyer())]
|
||||
|
||||
return lines
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return [str(len(self.items))+","+self.Identifyer()]
|
||||
|
||||
# Basic Types
|
||||
|
@ -136,7 +133,7 @@ class Int(BaseType):
|
|||
self.value = value
|
||||
def Set(self, value):
|
||||
self.value = value
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return ["%d"%self.value]
|
||||
#return ["%d /* %s */"%(self.value, self._target_name)]
|
||||
|
||||
|
@ -146,7 +143,7 @@ class Float(BaseType):
|
|||
self.value = value
|
||||
def Set(self, value):
|
||||
self.value = value
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return ["%ff"%self.value]
|
||||
#return ["%d /* %s */"%(self.value, self._target_name)]
|
||||
|
||||
|
@ -156,29 +153,29 @@ class String(BaseType):
|
|||
self.value = value
|
||||
def Set(self, value):
|
||||
self.value = value
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return ['"'+self.value+'"']
|
||||
|
||||
class Pointer(BaseType):
|
||||
def __init__(self, type, target):
|
||||
BaseType.__init__(self, "%s*"%type().TypeName())
|
||||
def __init__(self, typ, target):
|
||||
BaseType.__init__(self, "%s*"%typ().TypeName())
|
||||
self.target = target
|
||||
def Set(self, target):
|
||||
self.target = target
|
||||
def EmitDefinition(self, name):
|
||||
def EmitDefinition(self, _name):
|
||||
return ["&"+self.target.TargetName()]
|
||||
|
||||
class TextureHandle(BaseType):
|
||||
def __init__(self):
|
||||
BaseType.__init__(self, "IGraphics::CTextureHandle")
|
||||
def EmitDefinition(self, name):
|
||||
return ["IGraphics::CTextureHandle()"]
|
||||
def EmitDefinition(self, _name):
|
||||
return ["IGraphics::CTextureHandle()"]
|
||||
|
||||
class SampleHandle(BaseType):
|
||||
def __init__(self):
|
||||
BaseType.__init__(self, "ISound::CSampleHandle")
|
||||
def EmitDefinition(self, name):
|
||||
return ["ISound::CSampleHandle()"]
|
||||
def EmitDefinition(self, _name):
|
||||
return ["ISound::CSampleHandle()"]
|
||||
|
||||
# helper functions
|
||||
|
||||
|
@ -322,16 +319,15 @@ class NetIntAny(NetVariable):
|
|||
def emit_unpack(self):
|
||||
if self.default is None:
|
||||
return ["pMsg->%s = pUnpacker->GetInt();" % self.name]
|
||||
else:
|
||||
return ["pMsg->%s = pUnpacker->GetIntOrDefault(%s);" % (self.name, self.default)]
|
||||
return ["pMsg->%s = pUnpacker->GetIntOrDefault(%s);" % (self.name, self.default)]
|
||||
def emit_pack(self):
|
||||
return ["pPacker->AddInt(%s);" % self.name]
|
||||
|
||||
class NetIntRange(NetIntAny):
|
||||
def __init__(self, name, min, max, default=None):
|
||||
def __init__(self, name, min_val, max_val, default=None):
|
||||
NetIntAny.__init__(self,name,default=default)
|
||||
self.min = str(min)
|
||||
self.max = str(max)
|
||||
self.min = str(min_val)
|
||||
self.max = str(max_val)
|
||||
def emit_validate(self):
|
||||
return ["if(!CheckInt(\"%s\", pObj->%s, %s, %s)) return -1;"%(self.name, self.name, self.min, self.max)]
|
||||
def emit_unpack_check(self):
|
||||
|
@ -366,6 +362,7 @@ class NetTick(NetIntRange):
|
|||
|
||||
class NetArray(NetVariable):
|
||||
def __init__(self, var, size):
|
||||
NetVariable.__init__(self,var.name)
|
||||
self.base_name = var.name
|
||||
self.var = var
|
||||
self.size = size
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
from .datatypes import *
|
||||
from .datatypes import Enum, Flags, NetArray, NetBool, NetEnum, NetEvent, NetFlag, NetIntAny, NetIntRange, NetMessage, NetObject, NetString, NetStringStrict, NetTick
|
||||
|
||||
Pickups = Enum("PICKUP", ["HEALTH", "ARMOR", "GRENADE", "SHOTGUN", "LASER", "NINJA", "GUN", "HAMMER"])
|
||||
Emotes = Enum("EMOTE", ["NORMAL", "PAIN", "HAPPY", "SURPRISE", "ANGRY", "BLINK"])
|
||||
|
|
|
@ -4,24 +4,24 @@ result=
|
|||
|
||||
dil_path=$1
|
||||
|
||||
result=$(find $2 -iname '*.png' -print0 | while IFS= read -r -d $'\0' file; do
|
||||
result=$(find "$2" -iname '*.png' -print0 | while IFS= read -r -d $'\0' file; do
|
||||
new_file=$(mktemp --tmpdir "$(basename "$file" .png).XXX.png")
|
||||
cp "$file" "$new_file"
|
||||
convert "$new_file" "${new_file}_old.bmp" >> /dev/null
|
||||
${dil_path}/dilate "$new_file" >> /dev/null
|
||||
convert "$new_file" "${new_file}_new.bmp" >> /dev/null
|
||||
convert "$new_file" "${new_file}_old.bmp" > /dev/null
|
||||
"${dil_path}"/dilate "$new_file" > /dev/null
|
||||
convert "$new_file" "${new_file}_new.bmp" > /dev/null
|
||||
orig_hash=$(identify -quiet -format "%#" "${new_file}_old.bmp")
|
||||
new_hash=$(identify -quiet -format "%#" "${new_file}_new.bmp")
|
||||
rm "$new_file"
|
||||
rm "${new_file}_old.bmp"
|
||||
rm "${new_file}_new.bmp"
|
||||
if [ "$orig_hash" != "$new_hash" ]; then
|
||||
printf "$file is not dilated\n"
|
||||
echo "$file is not dilated"
|
||||
fi
|
||||
done)
|
||||
|
||||
if [[ "$result" != "" ]]; then
|
||||
printf "$result"
|
||||
echo -n "$result"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@ def check_file(filename):
|
|||
if line[0] == "/" or line[0] == "*" or line[0] == "\r" or line[0] == "\n" or line[0] == "\t":
|
||||
continue
|
||||
if line.startswith("#ifndef"):
|
||||
hg = "#ifndef " + ("_".join(filename.split(PATH)[1].split("/"))[:-2]).upper() + "_H"
|
||||
if line[:-1] != hg:
|
||||
header_guard = "#ifndef " + ("_".join(filename.split(PATH)[1].split("/"))[:-2]).upper() + "_H"
|
||||
if line[:-1] != header_guard:
|
||||
error = True
|
||||
print("Wrong header guard in {}".format(filename))
|
||||
else:
|
||||
|
@ -32,13 +32,13 @@ def check_file(filename):
|
|||
break
|
||||
return error
|
||||
|
||||
def check_dir(dir):
|
||||
def check_dir(directory):
|
||||
errors = 0
|
||||
list = os.listdir(dir)
|
||||
for file in list:
|
||||
path = dir + file
|
||||
file_list = os.listdir(directory)
|
||||
for file in file_list:
|
||||
path = directory + file
|
||||
if os.path.isdir(path):
|
||||
if file != "external" and file != "generated":
|
||||
if file not in ("external", "generated"):
|
||||
errors += check_dir(path + "/")
|
||||
elif file.endswith(".h") and file != "keynames.h":
|
||||
errors += check_file(path)
|
||||
|
|
|
@ -1,73 +1,72 @@
|
|||
import argparse
|
||||
import csv
|
||||
import sys
|
||||
import re
|
||||
|
||||
def check_name(kind, qualifiers, type, name):
|
||||
if kind == "variable":
|
||||
return check_variable_name(qualifiers, type, name)
|
||||
elif kind in "class struct".split():
|
||||
if name[0] not in "CI":
|
||||
return "should start with 'C' (or 'I' for interfaces)"
|
||||
if len(name) < 2:
|
||||
return "must be at least two characters long"
|
||||
if not name[1].isupper():
|
||||
return "must start with an uppercase letter"
|
||||
elif kind == "enum_constant":
|
||||
if not name.isupper():
|
||||
return "must only contain uppercase letters, digits and underscores"
|
||||
return None
|
||||
def check_name(kind, qualifiers, typ, name):
|
||||
if kind == "variable":
|
||||
return check_variable_name(qualifiers, typ, name)
|
||||
if kind in "class struct".split():
|
||||
if name[0] not in "CI":
|
||||
return "should start with 'C' (or 'I' for interfaces)"
|
||||
if len(name) < 2:
|
||||
return "must be at least two characters long"
|
||||
if not name[1].isupper():
|
||||
return "must start with an uppercase letter"
|
||||
if kind == "enum_constant":
|
||||
if not name.isupper():
|
||||
return "must only contain uppercase letters, digits and underscores"
|
||||
return None
|
||||
|
||||
ALLOW = set("""
|
||||
dx dy
|
||||
fx fy
|
||||
mx my
|
||||
ix iy
|
||||
px py
|
||||
sx sy
|
||||
wx wy
|
||||
x0 x1
|
||||
y0 y1
|
||||
dx dy
|
||||
fx fy
|
||||
mx my
|
||||
ix iy
|
||||
px py
|
||||
sx sy
|
||||
wx wy
|
||||
x0 x1
|
||||
y0 y1
|
||||
""".split())
|
||||
def check_variable_name(qualifiers, type, name):
|
||||
if qualifiers == "" and type == "" and name == "argc":
|
||||
return None
|
||||
if qualifiers == "" and type == "pp" and name == "argv":
|
||||
return None
|
||||
if qualifiers == "cs":
|
||||
# Allow all uppercase names for constant statics.
|
||||
if name.isupper():
|
||||
return None
|
||||
qualifiers = "s"
|
||||
# Allow single lowercase letters as member and variable names.
|
||||
if qualifiers in ["m", ""] and len(name) == 1 and name.islower():
|
||||
return None
|
||||
prefix = "".join([qualifiers, "_" if qualifiers else "", type])
|
||||
if not name.startswith(prefix):
|
||||
return "should start with {!r}".format(prefix)
|
||||
if name in ALLOW:
|
||||
return None
|
||||
name = name[len(prefix):]
|
||||
if not name[0].isupper():
|
||||
if prefix:
|
||||
return "should start with an uppercase letter after the prefix {!r}".format(prefix)
|
||||
else:
|
||||
return "should start with an uppercase letter"
|
||||
return None
|
||||
|
||||
def check_variable_name(qualifiers, typ, name):
|
||||
if qualifiers == "" and typ == "" and name == "argc":
|
||||
return None
|
||||
if qualifiers == "" and typ == "pp" and name == "argv":
|
||||
return None
|
||||
if qualifiers == "cs":
|
||||
# Allow all uppercase names for constant statics.
|
||||
if name.isupper():
|
||||
return None
|
||||
qualifiers = "s"
|
||||
# Allow single lowercase letters as member and variable names.
|
||||
if qualifiers in ["m", ""] and len(name) == 1 and name.islower():
|
||||
return None
|
||||
prefix = "".join([qualifiers, "_" if qualifiers else "", typ])
|
||||
if not name.startswith(prefix):
|
||||
return "should start with {!r}".format(prefix)
|
||||
if name in ALLOW:
|
||||
return None
|
||||
name = name[len(prefix):]
|
||||
if not name[0].isupper():
|
||||
if prefix:
|
||||
return "should start with an uppercase letter after the prefix {!r}".format(prefix)
|
||||
return "should start with an uppercase letter"
|
||||
return None
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
p = argparse.ArgumentParser(description="Check identifiers (input via stdin in CSV format from extract_identifiers.py) for naming style in DDNet code")
|
||||
args = p.parse_args()
|
||||
p = argparse.ArgumentParser(description="Check identifiers (input via stdin in CSV format from extract_identifiers.py) for naming style in DDNet code")
|
||||
p.parse_args()
|
||||
|
||||
identifiers = list(csv.DictReader(sys.stdin))
|
||||
identifiers = list(csv.DictReader(sys.stdin))
|
||||
|
||||
unclean = False
|
||||
for i in identifiers:
|
||||
error = check_name(i["kind"], i["qualifiers"], i["type"], i["name"])
|
||||
if error:
|
||||
unclean = True
|
||||
print("{}:{}:{}: {}: {}".format(i["file"], i["line"], i["column"], i["name"], error))
|
||||
return unclean
|
||||
unclean = False
|
||||
for i in identifiers:
|
||||
error = check_name(i["kind"], i["qualifiers"], i["type"], i["name"])
|
||||
if error:
|
||||
unclean = True
|
||||
print("{}:{}:{}: {}: {}".format(i["file"], i["line"], i["column"], i["name"], error))
|
||||
return unclean
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
sys.exit(main())
|
||||
|
|
|
@ -1,43 +1,43 @@
|
|||
import argparse
|
||||
import subprocess
|
||||
import re
|
||||
|
||||
def split_cmds(lines):
|
||||
cmds = []
|
||||
current = []
|
||||
load_cmd_regex = re.compile(r"^Load command \d+$")
|
||||
for line in lines:
|
||||
if load_cmd_regex.match(line):
|
||||
cmds.append(current)
|
||||
current = []
|
||||
continue
|
||||
cmds = []
|
||||
current = []
|
||||
load_cmd_regex = re.compile(r"^Load command \d+$")
|
||||
for line in lines:
|
||||
if load_cmd_regex.match(line):
|
||||
cmds.append(current)
|
||||
current = []
|
||||
continue
|
||||
|
||||
current.append(line.strip())
|
||||
current.append(line.strip())
|
||||
|
||||
return cmds[1:]
|
||||
return cmds[1:]
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
p = argparse.ArgumentParser(description="Strip LC_RPATH commands from executable")
|
||||
p = argparse.ArgumentParser(description="Strip LC_RPATH commands from executable")
|
||||
|
||||
p.add_argument('otool', help="Path to otool")
|
||||
p.add_argument('install_name_tool', help="Path to install_name_tool")
|
||||
p.add_argument('executable', metavar="EXECUTABLE", help="The executable to strip")
|
||||
args = p.parse_args()
|
||||
p.add_argument('otool', help="Path to otool")
|
||||
p.add_argument('install_name_tool', help="Path to install_name_tool")
|
||||
p.add_argument('executable', metavar="EXECUTABLE", help="The executable to strip")
|
||||
args = p.parse_args()
|
||||
|
||||
otool = args.otool
|
||||
install_name_tool = args.install_name_tool
|
||||
executable = args.executable
|
||||
otool = args.otool
|
||||
install_name_tool = args.install_name_tool
|
||||
executable = args.executable
|
||||
|
||||
cmds = split_cmds(subprocess.check_output([otool, "-l", executable]).decode().splitlines())
|
||||
lc_rpath_cmds = [cmd for cmd in cmds if cmd[0] == "cmd LC_RPATH"]
|
||||
cmds = split_cmds(subprocess.check_output([otool, "-l", executable]).decode().splitlines())
|
||||
lc_rpath_cmds = [cmd for cmd in cmds if cmd[0] == "cmd LC_RPATH"]
|
||||
|
||||
path_regex = re.compile("^path (.*) \(offset \d+\)$")
|
||||
rpaths = [k[0] for k in [[path_regex.match(part).group(1) for part in cmd if path_regex.match(part)] for cmd in lc_rpath_cmds]]
|
||||
print("Found paths:")
|
||||
path_regex = re.compile(r"^path (.*) \(offset \d+\)$")
|
||||
rpaths = [k[0] for k in [[path_regex.match(part).group(1) for part in cmd if path_regex.match(part)] for cmd in lc_rpath_cmds]]
|
||||
print("Found paths:")
|
||||
|
||||
for path in rpaths:
|
||||
print("\t" + path)
|
||||
subprocess.check_call([install_name_tool, "-delete_rpath", path, executable])
|
||||
for path in rpaths:
|
||||
print("\t" + path)
|
||||
subprocess.check_call([install_name_tool, "-delete_rpath", path, executable])
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
from collections import namedtuple
|
||||
import argparse
|
||||
import os
|
||||
import shlex
|
||||
import subprocess
|
||||
|
@ -10,7 +11,7 @@ ConfigHdiutil = namedtuple('Config', 'hdiutil verbose')
|
|||
def chunks(l, n):
|
||||
"""
|
||||
Yield successive n-sized chunks from l.
|
||||
|
||||
|
||||
From https://stackoverflow.com/a/312464.
|
||||
"""
|
||||
for i in range(0, len(l), n):
|
||||
|
@ -74,7 +75,6 @@ class Hdiutil(Dmg):
|
|||
self._hdiutil('create', '-volname', volume_name, '-srcdir', directory, dmg)
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
p = argparse.ArgumentParser(description="Manipulate dmg archives")
|
||||
|
||||
subcommands = p.add_subparsers(help="Subcommand", dest='command', metavar="COMMAND")
|
||||
|
|
|
@ -1,170 +1,169 @@
|
|||
import clang.cindex
|
||||
import argparse
|
||||
import csv
|
||||
import enum
|
||||
import os
|
||||
import sys
|
||||
|
||||
import clang.cindex
|
||||
|
||||
from clang.cindex import CursorKind, LinkageKind, StorageClass, TypeKind
|
||||
from collections import Counter
|
||||
|
||||
try:
|
||||
from tqdm import tqdm
|
||||
from tqdm import tqdm
|
||||
except ImportError:
|
||||
def tqdm(it, *args, **kwargs):
|
||||
return it
|
||||
def tqdm(it, *_args, **_kwargs):
|
||||
return it
|
||||
|
||||
def traverse_namespaced(root, filter_files=None, skip_namespaces=1, namespace=()):
|
||||
if root.location.file is not None and root.location.file.name not in filter_files:
|
||||
return
|
||||
yield namespace, root
|
||||
if root.displayname != "":
|
||||
if skip_namespaces > 0:
|
||||
skip_namespaces -= 1
|
||||
else:
|
||||
namespace += (root.spelling,)
|
||||
for node in root.get_children():
|
||||
yield from traverse_namespaced(node, filter_files, skip_namespaces, namespace)
|
||||
if root.location.file is not None and root.location.file.name not in filter_files:
|
||||
return
|
||||
yield namespace, root
|
||||
if root.displayname != "":
|
||||
if skip_namespaces > 0:
|
||||
skip_namespaces -= 1
|
||||
else:
|
||||
namespace += (root.spelling,)
|
||||
for node in root.get_children():
|
||||
yield from traverse_namespaced(node, filter_files, skip_namespaces, namespace)
|
||||
|
||||
INTERESTING_NODE_KINDS = {
|
||||
CursorKind.CLASS_DECL: "class",
|
||||
CursorKind.CLASS_TEMPLATE: "class",
|
||||
CursorKind.ENUM_DECL: "enum",
|
||||
CursorKind.ENUM_CONSTANT_DECL: "enum_constant",
|
||||
CursorKind.FIELD_DECL: "variable",
|
||||
CursorKind.PARM_DECL: "variable",
|
||||
CursorKind.STRUCT_DECL: "struct",
|
||||
CursorKind.UNION_DECL: "union",
|
||||
CursorKind.VAR_DECL: "variable",
|
||||
CursorKind.FUNCTION_DECL: "function",
|
||||
CursorKind.CLASS_DECL: "class",
|
||||
CursorKind.CLASS_TEMPLATE: "class",
|
||||
CursorKind.ENUM_DECL: "enum",
|
||||
CursorKind.ENUM_CONSTANT_DECL: "enum_constant",
|
||||
CursorKind.FIELD_DECL: "variable",
|
||||
CursorKind.PARM_DECL: "variable",
|
||||
CursorKind.STRUCT_DECL: "struct",
|
||||
CursorKind.UNION_DECL: "union",
|
||||
CursorKind.VAR_DECL: "variable",
|
||||
CursorKind.FUNCTION_DECL: "function",
|
||||
}
|
||||
|
||||
def is_array_type(type):
|
||||
return type.kind in (TypeKind.CONSTANTARRAY, TypeKind.DEPENDENTSIZEDARRAY, TypeKind.INCOMPLETEARRAY)
|
||||
def is_array_type(typ):
|
||||
return typ.kind in (TypeKind.CONSTANTARRAY, TypeKind.DEPENDENTSIZEDARRAY, TypeKind.INCOMPLETEARRAY)
|
||||
|
||||
def get_complex_type(type):
|
||||
if type.spelling in ("IOHANDLE", "LOCK"):
|
||||
return ""
|
||||
if type.kind == TypeKind.AUTO:
|
||||
return get_complex_type(type.get_canonical())
|
||||
if type.kind == TypeKind.LVALUEREFERENCE:
|
||||
return get_complex_type(type.get_pointee())
|
||||
if type.kind == TypeKind.POINTER:
|
||||
return "p" + get_complex_type(type.get_pointee())
|
||||
if is_array_type(type):
|
||||
return "a" + get_complex_type(type.element_type)
|
||||
if type.kind == TypeKind.FUNCTIONPROTO:
|
||||
return "fn"
|
||||
if type.kind == TypeKind.TYPEDEF:
|
||||
return get_complex_type(type.get_declaration().underlying_typedef_type)
|
||||
if type.kind == TypeKind.ELABORATED:
|
||||
return get_complex_type(type.get_named_type())
|
||||
if type.kind in (TypeKind.UNEXPOSED, TypeKind.RECORD):
|
||||
if type.get_declaration().spelling in "shared_ptr unique_ptr".split():
|
||||
return "p" + get_complex_type(type.get_template_argument_type(0))
|
||||
if type.get_declaration().spelling in "array sorted_array".split():
|
||||
return "a" + get_complex_type(type.get_template_argument_type(0))
|
||||
return ""
|
||||
def get_complex_type(typ):
|
||||
if typ.spelling in ("IOHANDLE", "LOCK"):
|
||||
return ""
|
||||
if typ.kind == TypeKind.AUTO:
|
||||
return get_complex_type(typ.get_canonical())
|
||||
if typ.kind == TypeKind.LVALUEREFERENCE:
|
||||
return get_complex_type(typ.get_pointee())
|
||||
if typ.kind == TypeKind.POINTER:
|
||||
return "p" + get_complex_type(typ.get_pointee())
|
||||
if is_array_type(type):
|
||||
return "a" + get_complex_type(typ.element_type)
|
||||
if typ.kind == TypeKind.FUNCTIONPROTO:
|
||||
return "fn"
|
||||
if typ.kind == TypeKind.TYPEDEF:
|
||||
return get_complex_type(typ.get_declaration().underlying_typedef_type)
|
||||
if typ.kind == TypeKind.ELABORATED:
|
||||
return get_complex_type(typ.get_named_type())
|
||||
if typ.kind in (TypeKind.UNEXPOSED, TypeKind.RECORD):
|
||||
if typ.get_declaration().spelling in "shared_ptr unique_ptr".split():
|
||||
return "p" + get_complex_type(typ.get_template_argument_type(0))
|
||||
if typ.get_declaration().spelling in "array sorted_array".split():
|
||||
return "a" + get_complex_type(typ.get_template_argument_type(0))
|
||||
return ""
|
||||
|
||||
def is_static_member_definition_hack(node):
|
||||
last_colons = False
|
||||
for t in node.get_tokens():
|
||||
t = t.spelling
|
||||
if t == "::":
|
||||
last_colons = True
|
||||
elif last_colons:
|
||||
if t.startswith("ms_"):
|
||||
return True
|
||||
last_colons = False
|
||||
if t == "=":
|
||||
return False
|
||||
return False
|
||||
last_colons = False
|
||||
for t in node.get_tokens():
|
||||
t = t.spelling
|
||||
if t == "::":
|
||||
last_colons = True
|
||||
elif last_colons:
|
||||
if t.startswith("ms_"):
|
||||
return True
|
||||
last_colons = False
|
||||
if t == "=":
|
||||
return False
|
||||
return False
|
||||
|
||||
def is_const(type):
|
||||
if type.is_const_qualified():
|
||||
return True
|
||||
if is_array_type(type):
|
||||
return is_const(type.element_type)
|
||||
return False
|
||||
def is_const(typ):
|
||||
if typ.is_const_qualified():
|
||||
return True
|
||||
if is_array_type(type):
|
||||
return is_const(typ.element_type)
|
||||
return False
|
||||
|
||||
class ParseError(RuntimeError):
|
||||
pass
|
||||
pass
|
||||
|
||||
def process_source_file(out, file, extra_args, break_on):
|
||||
args = extra_args + ["-Isrc"]
|
||||
if file.endswith(".c"):
|
||||
header = "{}.h".format(file[:-2])
|
||||
elif file.endswith(".cpp"):
|
||||
header = "{}.h".format(file[:-4])
|
||||
else:
|
||||
raise ValueError("unrecognized source file: {}".format(file))
|
||||
args = extra_args + ["-Isrc"]
|
||||
if file.endswith(".c"):
|
||||
header = "{}.h".format(file[:-2])
|
||||
elif file.endswith(".cpp"):
|
||||
header = "{}.h".format(file[:-4])
|
||||
else:
|
||||
raise ValueError("unrecognized source file: {}".format(file))
|
||||
|
||||
index = clang.cindex.Index.create()
|
||||
unit = index.parse(file, args=args)
|
||||
errors = list(unit.diagnostics)
|
||||
if errors:
|
||||
for error in errors:
|
||||
print("{}: {}".format(file, error.format()), file=sys.stderr)
|
||||
print(args, file=sys.stderr)
|
||||
raise ParseError("failed parsing {}".format(file))
|
||||
index = clang.cindex.Index.create()
|
||||
unit = index.parse(file, args=args)
|
||||
errors = list(unit.diagnostics)
|
||||
if errors:
|
||||
for error in errors:
|
||||
print("{}: {}".format(file, error.format()), file=sys.stderr)
|
||||
print(args, file=sys.stderr)
|
||||
raise ParseError("failed parsing {}".format(file))
|
||||
|
||||
filter_files = frozenset([file, header])
|
||||
filter_files = frozenset([file, header])
|
||||
|
||||
for namespace, node in traverse_namespaced(unit.cursor, filter_files=filter_files):
|
||||
cur_file = None
|
||||
if node.location.file is not None:
|
||||
cur_file = node.location.file.name
|
||||
if cur_file is None or (cur_file != file and cur_file != header):
|
||||
continue
|
||||
if node.kind in INTERESTING_NODE_KINDS and node.spelling:
|
||||
type = get_complex_type(node.type)
|
||||
qualifiers = ""
|
||||
if INTERESTING_NODE_KINDS[node.kind] in {"variable", "function"}:
|
||||
is_member = node.semantic_parent.kind in {CursorKind.CLASS_DECL, CursorKind.CLASS_TEMPLATE, CursorKind.STRUCT_DECL, CursorKind.UNION_DECL}
|
||||
is_static = node.storage_class == StorageClass.STATIC or is_static_member_definition_hack(node)
|
||||
if is_static:
|
||||
qualifiers = "s" + qualifiers
|
||||
if is_member:
|
||||
qualifiers = "m" + qualifiers
|
||||
if is_static and not is_member and is_const(node.type):
|
||||
qualifiers = "c" + qualifiers
|
||||
if node.linkage == LinkageKind.EXTERNAL and not is_member:
|
||||
qualifiers = "g" + qualifiers
|
||||
out.writerow({
|
||||
"file": cur_file,
|
||||
"line": node.location.line,
|
||||
"column": node.location.column,
|
||||
"kind": INTERESTING_NODE_KINDS[node.kind],
|
||||
"path": "::".join(namespace),
|
||||
"qualifiers": qualifiers,
|
||||
"type": type,
|
||||
"name": node.spelling,
|
||||
})
|
||||
if node.spelling == break_on:
|
||||
breakpoint()
|
||||
for namespace, node in traverse_namespaced(unit.cursor, filter_files=filter_files):
|
||||
cur_file = None
|
||||
if node.location.file is not None:
|
||||
cur_file = node.location.file.name
|
||||
if cur_file is None or cur_file not in (file, header):
|
||||
continue
|
||||
if node.kind in INTERESTING_NODE_KINDS and node.spelling:
|
||||
typ = get_complex_type(node.type)
|
||||
qualifiers = ""
|
||||
if INTERESTING_NODE_KINDS[node.kind] in {"variable", "function"}:
|
||||
is_member = node.semantic_parent.kind in {CursorKind.CLASS_DECL, CursorKind.CLASS_TEMPLATE, CursorKind.STRUCT_DECL, CursorKind.UNION_DECL}
|
||||
is_static = node.storage_class == StorageClass.STATIC or is_static_member_definition_hack(node)
|
||||
if is_static:
|
||||
qualifiers = "s" + qualifiers
|
||||
if is_member:
|
||||
qualifiers = "m" + qualifiers
|
||||
if is_static and not is_member and is_const(node.type):
|
||||
qualifiers = "c" + qualifiers
|
||||
if node.linkage == LinkageKind.EXTERNAL and not is_member:
|
||||
qualifiers = "g" + qualifiers
|
||||
out.writerow({
|
||||
"file": cur_file,
|
||||
"line": node.location.line,
|
||||
"column": node.location.column,
|
||||
"kind": INTERESTING_NODE_KINDS[node.kind],
|
||||
"path": "::".join(namespace),
|
||||
"qualifiers": qualifiers,
|
||||
"type": typ,
|
||||
"name": node.spelling,
|
||||
})
|
||||
if node.spelling == break_on:
|
||||
breakpoint()
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
p = argparse.ArgumentParser(description="Extracts identifier data from a Teeworlds source file and its header, outputting the data as CSV to stdout")
|
||||
p.add_argument("file", metavar="FILE", nargs="+", help="Source file to analyze")
|
||||
p.add_argument("--break-on", help="Break on a specific variable name, useful to debug issues with the script")
|
||||
args = p.parse_args()
|
||||
p = argparse.ArgumentParser(description="Extracts identifier data from a Teeworlds source file and its header, outputting the data as CSV to stdout")
|
||||
p.add_argument("file", metavar="FILE", nargs="+", help="Source file to analyze")
|
||||
p.add_argument("--break-on", help="Break on a specific variable name, useful to debug issues with the script")
|
||||
args = p.parse_args()
|
||||
|
||||
extra_args = []
|
||||
if "CXXFLAGS" in os.environ:
|
||||
extra_args = os.environ["CXXFLAGS"].split()
|
||||
extra_args = []
|
||||
if "CXXFLAGS" in os.environ:
|
||||
extra_args = os.environ["CXXFLAGS"].split()
|
||||
|
||||
out = csv.DictWriter(sys.stdout, "file line column kind path qualifiers type name".split())
|
||||
out.writeheader()
|
||||
files = args.file
|
||||
if len(files) > 1:
|
||||
files = tqdm(files, leave=False)
|
||||
error = False
|
||||
for file in files:
|
||||
try:
|
||||
process_source_file(out, file, extra_args, args.break_on)
|
||||
except ParseError:
|
||||
error = True
|
||||
return int(error)
|
||||
out = csv.DictWriter(sys.stdout, "file line column kind path qualifiers type name".split())
|
||||
out.writeheader()
|
||||
files = args.file
|
||||
if len(files) > 1:
|
||||
files = tqdm(files, leave=False)
|
||||
error = False
|
||||
for file in files:
|
||||
try:
|
||||
process_source_file(out, file, extra_args, args.break_on)
|
||||
except ParseError:
|
||||
error = True
|
||||
return int(error)
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
sys.exit(main())
|
||||
|
|
|
@ -1,16 +1,15 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
from collections import defaultdict
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
import argparse
|
||||
|
||||
os.chdir(os.path.dirname(__file__) + "/..")
|
||||
|
||||
def recursive_file_list(path):
|
||||
result = []
|
||||
for dirpath, dirnames, filenames in os.walk(path):
|
||||
for dirpath, _, filenames in os.walk(path):
|
||||
result += [os.path.join(dirpath, filename) for filename in filenames]
|
||||
return result
|
||||
|
||||
|
@ -34,7 +33,6 @@ def warn(filenames):
|
|||
return subprocess.call(["clang-format", "-Werror", "--dry-run"] + filenames)
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
p = argparse.ArgumentParser(description="Check and fix style of changed files")
|
||||
p.add_argument("-n", "--dry-run", action="store_true", help="Don't fix, only warn")
|
||||
args = p.parse_args()
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import sys, os
|
||||
|
||||
# pylint: skip-file
|
||||
# generate keys.h file
|
||||
f = file("src/engine/keys.h", "w")
|
||||
|
||||
|
@ -74,4 +73,3 @@ print >>f, "};"
|
|||
print >>f, ""
|
||||
|
||||
f.close()
|
||||
|
||||
|
|
|
@ -13,12 +13,12 @@ CURL_RE=re.compile(r"\bcurl_\w*")
|
|||
|
||||
def get_curl_calls(path):
|
||||
names = set()
|
||||
for dir, _, files in os.walk(path):
|
||||
for directory, _, files in os.walk(path):
|
||||
for filename in files:
|
||||
if (filename.endswith(".cpp") or
|
||||
filename.endswith(".c") or
|
||||
filename.endswith(".h")):
|
||||
with open(os.path.join(dir, filename)) as f:
|
||||
with open(os.path.join(directory, filename)) as f:
|
||||
contents = f.read()
|
||||
names = names.union(CURL_RE.findall(contents))
|
||||
return names
|
||||
|
|
|
@ -10,60 +10,60 @@
|
|||
import unicode
|
||||
|
||||
def generate_decompositions():
|
||||
ud = unicode.data()
|
||||
con = unicode.confusables()
|
||||
ud = unicode.data()
|
||||
con = unicode.confusables()
|
||||
|
||||
category = lambda x: {unicode.unhex(u["Value"]) for u in ud if u["General_Category"].startswith(x)}
|
||||
category = lambda x: {unicode.unhex(u["Value"]) for u in ud if u["General_Category"].startswith(x)}
|
||||
|
||||
# TODO: Is this correct? They changed the decompositioning format
|
||||
nfd = {unicode.unhex(u["Value"]): unicode.unhex_sequence(u["Decomposition_Type"]) for u in ud}
|
||||
nfd = {k: v for k, v in nfd.items() if v}
|
||||
con = {unicode.unhex(c["Value"]): unicode.unhex_sequence(c["Target"]) for c in con}
|
||||
# TODO: Is this correct? They changed the decompositioning format
|
||||
nfd = {unicode.unhex(u["Value"]): unicode.unhex_sequence(u["Decomposition_Type"]) for u in ud}
|
||||
nfd = {k: v for k, v in nfd.items() if v}
|
||||
con = {unicode.unhex(c["Value"]): unicode.unhex_sequence(c["Target"]) for c in con}
|
||||
|
||||
# C: Control
|
||||
# M: Combining
|
||||
# Z: Space
|
||||
ignore = category("C") | category("M") | category("Z")
|
||||
# C: Control
|
||||
# M: Combining
|
||||
# Z: Space
|
||||
ignore = category("C") | category("M") | category("Z")
|
||||
|
||||
con[0x006C] = [0x0069] # LATIN SMALL LETTER L -> LATIN SMALL LETTER I
|
||||
con[0x2800] = [] # BRAILLE PATTERN BLANK
|
||||
con[0xFFFC] = [] # OBJECT REPLACEMENT CHARACTER
|
||||
con[0x006C] = [0x0069] # LATIN SMALL LETTER L -> LATIN SMALL LETTER I
|
||||
con[0x2800] = [] # BRAILLE PATTERN BLANK
|
||||
con[0xFFFC] = [] # OBJECT REPLACEMENT CHARACTER
|
||||
|
||||
interesting = ignore | set(nfd) | set(con)
|
||||
interesting = ignore | set(nfd) | set(con)
|
||||
|
||||
def apply(l, replacements):
|
||||
return [d for c in l for d in replacements.get(c, [c])]
|
||||
def apply(l, replacements):
|
||||
return [d for c in l for d in replacements.get(c, [c])]
|
||||
|
||||
def gen(c):
|
||||
result = [c]
|
||||
while True:
|
||||
first = apply(result, nfd)
|
||||
second = apply(first, con)
|
||||
# Apply substitutions until convergence.
|
||||
if result == first and result == second:
|
||||
break
|
||||
result = second
|
||||
return [c for c in result if c not in ignore]
|
||||
def gen(c):
|
||||
result = [c]
|
||||
while True:
|
||||
first = apply(result, nfd)
|
||||
second = apply(first, con)
|
||||
# Apply substitutions until convergence.
|
||||
if result == first and result == second:
|
||||
break
|
||||
result = second
|
||||
return [c for c in result if c not in ignore]
|
||||
|
||||
return {c: gen(c) for c in interesting}
|
||||
return {c: gen(c) for c in interesting}
|
||||
|
||||
def main():
|
||||
decompositions = generate_decompositions()
|
||||
decompositions = generate_decompositions()
|
||||
|
||||
# Deduplicate
|
||||
decomposition_set = sorted(set(tuple(x) for x in decompositions.values()))
|
||||
len_set = sorted(set(len(x) for x in decomposition_set))
|
||||
# Deduplicate
|
||||
decomposition_set = sorted(set(tuple(x) for x in decompositions.values()))
|
||||
len_set = sorted(set(len(x) for x in decomposition_set))
|
||||
|
||||
if len(len_set) > 8:
|
||||
raise ValueError("Can't pack offset (13 bit) together with len (>3bit)")
|
||||
if len(len_set) > 8:
|
||||
raise ValueError("Can't pack offset (13 bit) together with len (>3bit)")
|
||||
|
||||
cur_offset = 0
|
||||
decomposition_offsets = []
|
||||
for d in decomposition_set:
|
||||
decomposition_offsets.append(cur_offset)
|
||||
cur_offset += len(d)
|
||||
cur_offset = 0
|
||||
decomposition_offsets = []
|
||||
for d in decomposition_set:
|
||||
decomposition_offsets.append(cur_offset)
|
||||
cur_offset += len(d)
|
||||
|
||||
print("""\
|
||||
print("""\
|
||||
#include <stdint.h>
|
||||
|
||||
struct DECOMP_SLICE
|
||||
|
@ -72,39 +72,39 @@ struct DECOMP_SLICE
|
|||
\tuint16_t length : 3;
|
||||
};
|
||||
""")
|
||||
print("enum")
|
||||
print("{")
|
||||
print("\tNUM_DECOMP_LENGTHS={},".format(len(len_set)))
|
||||
print("\tNUM_DECOMPS={},".format(len(decompositions)))
|
||||
print("};")
|
||||
print()
|
||||
print("enum")
|
||||
print("{")
|
||||
print("\tNUM_DECOMP_LENGTHS={},".format(len(len_set)))
|
||||
print("\tNUM_DECOMPS={},".format(len(decompositions)))
|
||||
print("};")
|
||||
print()
|
||||
|
||||
print("static const uint8_t decomp_lengths[NUM_DECOMP_LENGTHS] = {")
|
||||
for l in len_set:
|
||||
print("\t{},".format(l))
|
||||
print("};")
|
||||
print()
|
||||
print("static const uint8_t decomp_lengths[NUM_DECOMP_LENGTHS] = {")
|
||||
for l in len_set:
|
||||
print("\t{},".format(l))
|
||||
print("};")
|
||||
print()
|
||||
|
||||
print("static const int32_t decomp_chars[NUM_DECOMPS] = {")
|
||||
for k in sorted(decompositions):
|
||||
print("\t0x{:x},".format(k))
|
||||
print("};")
|
||||
print()
|
||||
print("static const int32_t decomp_chars[NUM_DECOMPS] = {")
|
||||
for k in sorted(decompositions):
|
||||
print("\t0x{:x},".format(k))
|
||||
print("};")
|
||||
print()
|
||||
|
||||
print("static const struct DECOMP_SLICE decomp_slices[NUM_DECOMPS] = {")
|
||||
for k in sorted(decompositions):
|
||||
d = decompositions[k]
|
||||
i = decomposition_set.index(tuple(d))
|
||||
l = len_set.index(len(d))
|
||||
print("\t{{{}, {}}},".format(decomposition_offsets[i], l))
|
||||
print("};")
|
||||
print()
|
||||
print("static const struct DECOMP_SLICE decomp_slices[NUM_DECOMPS] = {")
|
||||
for k in sorted(decompositions):
|
||||
d = decompositions[k]
|
||||
i = decomposition_set.index(tuple(d))
|
||||
l = len_set.index(len(d))
|
||||
print("\t{{{}, {}}},".format(decomposition_offsets[i], l))
|
||||
print("};")
|
||||
print()
|
||||
|
||||
print("static const int32_t decomp_data[] = {")
|
||||
for d in decomposition_set:
|
||||
for c in d:
|
||||
print("\t0x{:x},".format(c))
|
||||
print("};")
|
||||
print("static const int32_t decomp_data[] = {")
|
||||
for d in decomposition_set:
|
||||
for c in d:
|
||||
print("\t0x{:x},".format(c))
|
||||
print("};")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -9,13 +9,13 @@
|
|||
import unicode
|
||||
|
||||
def generate_cases():
|
||||
ud = unicode.data()
|
||||
return [(unicode.unhex(u["Value"]), unicode.unhex(u["Simple_Lowercase_Mapping"])) for u in ud if u["Simple_Lowercase_Mapping"]]
|
||||
ud = unicode.data()
|
||||
return [(unicode.unhex(u["Value"]), unicode.unhex(u["Simple_Lowercase_Mapping"])) for u in ud if u["Simple_Lowercase_Mapping"]]
|
||||
|
||||
def main():
|
||||
cases = generate_cases()
|
||||
cases = generate_cases()
|
||||
|
||||
print("""\
|
||||
print("""\
|
||||
#include <stdint.h>
|
||||
|
||||
struct UPPER_LOWER
|
||||
|
@ -30,9 +30,9 @@ enum
|
|||
}};
|
||||
|
||||
static const struct UPPER_LOWER tolower[NUM_TOLOWER] = {{""".format(len(cases)))
|
||||
for upper_code, lower_code in cases:
|
||||
print("\t{{{}, {}}},".format(upper_code, lower_code))
|
||||
print("};")
|
||||
for upper_code, lower_code in cases:
|
||||
print("\t{{{}, {}}},".format(upper_code, lower_code))
|
||||
print("};")
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
main()
|
||||
|
|
|
@ -5,10 +5,6 @@ try:
|
|||
except ImportError:
|
||||
import os
|
||||
DEVNULL = open(os.devnull, 'wb')
|
||||
try:
|
||||
FileNotFoundError
|
||||
except NameError:
|
||||
FileNotFoundError = OSError
|
||||
try:
|
||||
git_hash = subprocess.check_output(["git", "rev-parse", "--short=16", "HEAD"], stderr=DEVNULL).decode().strip()
|
||||
definition = '"{}"'.format(git_hash)
|
||||
|
@ -17,5 +13,5 @@ except FileNotFoundError as e:
|
|||
raise
|
||||
definition = "0"
|
||||
except subprocess.CalledProcessError:
|
||||
definition = "0";
|
||||
definition = "0"
|
||||
print("const char *GIT_SHORTREV_HASH = {};".format(definition))
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
import argparse
|
||||
import tempfile
|
||||
import binascii
|
||||
import hashlib
|
||||
import os
|
||||
|
@ -38,16 +40,13 @@ def parse_line(line):
|
|||
if AUTH_ADD_PRESENT_REGEX.search(line):
|
||||
print("Warning: Funny-looking line with 'auth_add', not touching it:")
|
||||
print(line, end="")
|
||||
return
|
||||
return None
|
||||
password = m.group('password')
|
||||
if password.startswith('"'):
|
||||
password = password[1:-1] # Strip quotes.
|
||||
return m.group('username'), m.group('level'), password
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
import tempfile
|
||||
|
||||
p = argparse.ArgumentParser(description="Hash passwords in a way suitable for DDNet configs.")
|
||||
p.add_argument('--new', '-n', nargs=3, metavar=("USERNAME", "LEVEL", "PASSWORD"), action='append', default=[], help="username, level and password of the new user")
|
||||
p.add_argument('config', nargs='?', metavar="CONFIG", help="config file to update.")
|
||||
|
|
|
@ -2,83 +2,83 @@
|
|||
|
||||
from collections import namedtuple
|
||||
from decimal import Decimal
|
||||
import argparse
|
||||
import os.path
|
||||
import re
|
||||
import sqlite3
|
||||
import sys
|
||||
|
||||
def chunks(l, n):
|
||||
for i in range(0, len(l), n):
|
||||
yield l[i:i+n]
|
||||
for i in range(0, len(l), n):
|
||||
yield l[i:i+n]
|
||||
|
||||
class Record(namedtuple('Record', 'name time checkpoints')):
|
||||
@staticmethod
|
||||
def parse(lines):
|
||||
if len(lines) != 3:
|
||||
raise ValueError("wrong amount of lines for record")
|
||||
name = lines[0]
|
||||
time = Decimal(lines[1])
|
||||
checkpoints_str = lines[2].split(' ')
|
||||
if len(checkpoints_str) != 26 or checkpoints_str[25] != "":
|
||||
raise ValueError("wrong amount of checkpoint times: {}".format(len(checkpoints_str)))
|
||||
checkpoints_str = checkpoints_str[:25]
|
||||
checkpoints = tuple(Decimal(c) for c in checkpoints_str)
|
||||
return Record(name=name, time=time, checkpoints=checkpoints)
|
||||
@staticmethod
|
||||
def parse(lines):
|
||||
if len(lines) != 3:
|
||||
raise ValueError("wrong amount of lines for record")
|
||||
name = lines[0]
|
||||
time = Decimal(lines[1])
|
||||
checkpoints_str = lines[2].split(' ')
|
||||
if len(checkpoints_str) != 26 or checkpoints_str[25] != "":
|
||||
raise ValueError("wrong amount of checkpoint times: {}".format(len(checkpoints_str)))
|
||||
checkpoints_str = checkpoints_str[:25]
|
||||
checkpoints = tuple(Decimal(c) for c in checkpoints_str)
|
||||
return Record(name=name, time=time, checkpoints=checkpoints)
|
||||
|
||||
def unparse(self):
|
||||
return "\n".join([self.name, str(self.time), " ".join([str(cp) for cp in self.checkpoints] + [""]), ""])
|
||||
def unparse(self):
|
||||
return "\n".join([self.name, str(self.time), " ".join([str(cp) for cp in self.checkpoints] + [""]), ""])
|
||||
|
||||
def read_records(file):
|
||||
contents = file.read().splitlines()
|
||||
return [Record.parse(c) for c in chunks(contents, 3)]
|
||||
contents = file.read().splitlines()
|
||||
return [Record.parse(c) for c in chunks(contents, 3)]
|
||||
|
||||
MAP_RE=re.compile(r"^(?P<map>.*)_record\.dtb$")
|
||||
def main():
|
||||
import argparse
|
||||
p = argparse.ArgumentParser(description="Merge multiple DDNet race database files", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
p.add_argument("--out", default="ddnet-server.sqlite", help="Output SQLite database")
|
||||
p.add_argument("in_", metavar="IN", nargs='+', help="Text score databases to import; must have the format MAPNAME_record.dtb")
|
||||
p.add_argument("--dry-run", "-n", action='store_true', help="Don't write out the resulting SQLite database")
|
||||
p.add_argument("--stats", action='store_true', help="Display some stats at the end of the import process")
|
||||
args = p.parse_args()
|
||||
p = argparse.ArgumentParser(description="Merge multiple DDNet race database files", formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
p.add_argument("--out", default="ddnet-server.sqlite", help="Output SQLite database")
|
||||
p.add_argument("in_", metavar="IN", nargs='+', help="Text score databases to import; must have the format MAPNAME_record.dtb")
|
||||
p.add_argument("--dry-run", "-n", action='store_true', help="Don't write out the resulting SQLite database")
|
||||
p.add_argument("--stats", action='store_true', help="Display some stats at the end of the import process")
|
||||
args = p.parse_args()
|
||||
|
||||
records = {}
|
||||
for in_ in args.in_:
|
||||
m = MAP_RE.match(os.path.basename(in_))
|
||||
if not m:
|
||||
raise ValueError("Invalid text score database name, does not end in '_record.dtb': {}".format(in_))
|
||||
map = m.group("map")
|
||||
if map in records:
|
||||
raise ValueError("Two text score databases refer to the same map: {}".format(in_))
|
||||
with open(in_) as f:
|
||||
records[map] = read_records(f)
|
||||
records = {}
|
||||
for in_ in args.in_:
|
||||
match = MAP_RE.match(os.path.basename(in_))
|
||||
if not match:
|
||||
raise ValueError("Invalid text score database name, does not end in '_record.dtb': {}".format(in_))
|
||||
m = match.group("map")
|
||||
if m in records:
|
||||
raise ValueError("Two text score databases refer to the same map: {}".format(in_))
|
||||
with open(in_) as f:
|
||||
records[m] = read_records(f)
|
||||
|
||||
if not args.dry_run:
|
||||
conn = sqlite3.connect(args.out)
|
||||
c = conn.cursor()
|
||||
c.execute("CREATE TABLE IF NOT EXISTS record_race ("
|
||||
"Map VARCHAR(128) COLLATE BINARY NOT NULL, "
|
||||
"Name VARCHAR(16) COLLATE BINARY NOT NULL, "
|
||||
"Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "
|
||||
"Time FLOAT DEFAULT 0, "
|
||||
"Server CHAR(4), " +
|
||||
"".join("cp{} FLOAT DEFAULT 0, ".format(i + 1) for i in range(25)) +
|
||||
"GameID VARCHAR(64), "
|
||||
"DDNet7 BOOL DEFAULT FALSE"
|
||||
");");
|
||||
c.executemany(
|
||||
"INSERT INTO record_race (Map, Name, Time, Server, " +
|
||||
"".join("cp{}, ".format(i + 1) for i in range(25)) +
|
||||
"GameID, DDNet7) " +
|
||||
"VALUES ({})".format(",".join("?" * 31)),
|
||||
[(map, r.name, float(r.time), "TEXT", *[float(c) for c in r.checkpoints], None, False) for map in records for r in records[map]]
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
if not args.dry_run:
|
||||
conn = sqlite3.connect(args.out)
|
||||
c = conn.cursor()
|
||||
c.execute("CREATE TABLE IF NOT EXISTS record_race ("
|
||||
"Map VARCHAR(128) COLLATE BINARY NOT NULL, "
|
||||
"Name VARCHAR(16) COLLATE BINARY NOT NULL, "
|
||||
"Timestamp TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "
|
||||
"Time FLOAT DEFAULT 0, "
|
||||
"Server CHAR(4), " +
|
||||
"".join("cp{} FLOAT DEFAULT 0, ".format(i + 1) for i in range(25)) +
|
||||
"GameID VARCHAR(64), "
|
||||
"DDNet7 BOOL DEFAULT FALSE"
|
||||
");")
|
||||
c.executemany(
|
||||
"INSERT INTO record_race (Map, Name, Time, Server, " +
|
||||
"".join("cp{}, ".format(i + 1) for i in range(25)) +
|
||||
"GameID, DDNet7) " +
|
||||
"VALUES ({})".format(",".join("?" * 31)),
|
||||
[(map, r.name, float(r.time), "TEXT", *[float(c) for c in r.checkpoints], None, False) for map in records for r in records[map]]
|
||||
)
|
||||
conn.commit()
|
||||
conn.close()
|
||||
|
||||
if args.stats:
|
||||
print("Number of imported text databases: {}".format(len(records)), file=sys.stderr)
|
||||
print("Number of imported ranks: {}".format(sum(len(r) for r in records.values()), file=sys.stderr))
|
||||
if args.stats:
|
||||
print("Number of imported text databases: {}".format(len(records)), file=sys.stderr)
|
||||
print("Number of imported ranks: {}".format(sum(len(r) for r in records.values()), file=sys.stderr))
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
||||
sys.exit(main())
|
||||
|
|
|
@ -6,25 +6,25 @@ import twlang
|
|||
os.chdir(os.path.dirname(__file__) + "/../..")
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
langs = sys.argv[1:]
|
||||
langs = sys.argv[1:]
|
||||
else:
|
||||
langs = twlang.languages()
|
||||
langs = twlang.languages()
|
||||
local = twlang.localizes()
|
||||
table = []
|
||||
for lang in langs:
|
||||
trans = twlang.translations(lang)
|
||||
empty = 0
|
||||
supported = 0
|
||||
unused = 0
|
||||
for tran, (_, expr, _) in trans.items():
|
||||
if not expr:
|
||||
empty += 1
|
||||
else:
|
||||
if tran in local:
|
||||
supported += 1
|
||||
else:
|
||||
unused += 1
|
||||
table.append([lang, len(trans), empty, len(local)-supported, unused])
|
||||
trans = twlang.translations(lang)
|
||||
empty = 0
|
||||
supported = 0
|
||||
unused = 0
|
||||
for tran, (_, expr, _) in trans.items():
|
||||
if not expr:
|
||||
empty += 1
|
||||
else:
|
||||
if tran in local:
|
||||
supported += 1
|
||||
else:
|
||||
unused += 1
|
||||
table.append([lang, len(trans), empty, len(local)-supported, unused])
|
||||
|
||||
table.sort(key=lambda l: l[3])
|
||||
table = [["filename", "total", "empty", "missing", "unused"]] + table
|
||||
|
|
|
@ -1,62 +1,66 @@
|
|||
#!/usr/bin/env python3
|
||||
import twlang
|
||||
import os
|
||||
import sys
|
||||
|
||||
import twlang
|
||||
|
||||
def copy_fix(infile, delete_unused, append_missing, delete_empty):
|
||||
content = open(infile).readlines()
|
||||
trans = twlang.translations(infile)
|
||||
if delete_unused or append_missing:
|
||||
local = twlang.localizes()
|
||||
if append_missing:
|
||||
supported = []
|
||||
for tran, (start, expr, end) in trans.items():
|
||||
if delete_unused and tran not in local:
|
||||
content[start:end] = [None]*(end-start)
|
||||
if append_missing and tran in local:
|
||||
if expr or (not expr and delete_empty):
|
||||
supported.append(local.index(tran))
|
||||
else:
|
||||
content[start:end] = [None]*(end-start)
|
||||
if delete_empty and not expr:
|
||||
content[start:end] = [None]*(end-start)
|
||||
content = [line for line in content if line != None]
|
||||
if append_missing:
|
||||
missing = [index for index in range(len(local)) if index not in supported]
|
||||
if missing:
|
||||
if content[-1] != "\n":
|
||||
content.append("\n")
|
||||
for i, miss in enumerate(missing):
|
||||
if local[miss][1] != "":
|
||||
content.append("["+local[miss][1]+"]\n")
|
||||
content.append(local[miss][0]+"\n== \n\n")
|
||||
content[-1] = content[-1][:-1]
|
||||
return "".join(content)
|
||||
content = open(infile).readlines()
|
||||
trans = twlang.translations(infile)
|
||||
if delete_unused or append_missing:
|
||||
local = twlang.localizes()
|
||||
if append_missing:
|
||||
supported = []
|
||||
for tran, (start, expr, end) in trans.items():
|
||||
if delete_unused and tran not in local:
|
||||
content[start:end] = [None]*(end-start)
|
||||
if append_missing and tran in local:
|
||||
if expr or (not expr and delete_empty):
|
||||
supported.append(local.index(tran))
|
||||
else:
|
||||
content[start:end] = [None]*(end-start)
|
||||
if delete_empty and not expr:
|
||||
content[start:end] = [None]*(end-start)
|
||||
content = [line for line in content if line is not None]
|
||||
if append_missing:
|
||||
missing = [index for index in range(len(local)) if index not in supported]
|
||||
if missing:
|
||||
if content[-1] != "\n":
|
||||
content.append("\n")
|
||||
for miss in missing:
|
||||
if local[miss][1] != "":
|
||||
content.append("["+local[miss][1]+"]\n")
|
||||
content.append(local[miss][0]+"\n== \n\n")
|
||||
content[-1] = content[-1][:-1]
|
||||
return "".join(content)
|
||||
|
||||
def main(argv):
|
||||
os.chdir(os.path.dirname(__file__) + "/../..")
|
||||
|
||||
if len(argv) < 3:
|
||||
print("usage: python copy_fix.py <infile> <outfile> [--delete-unused] [--append-missing] [--delete-empty]")
|
||||
sys.exit()
|
||||
infile = argv[1]
|
||||
outfile = argv[2]
|
||||
args = argv[3:]
|
||||
delete_unused = False
|
||||
append_missing = False
|
||||
delete_empty = False
|
||||
for arg in args:
|
||||
if arg == "--delete-unused":
|
||||
delete_unused = True
|
||||
elif arg == "--append-missing":
|
||||
append_missing = True
|
||||
elif arg == "--delete-empty":
|
||||
delete_empty = True
|
||||
else:
|
||||
print("No such argument '"+arg+"'.")
|
||||
sys.exit()
|
||||
|
||||
content = copy_fix(infile, delete_unused, append_missing, delete_empty)
|
||||
|
||||
open(outfile, "w").write("".join(content))
|
||||
print("Successfully created '" + outfile + "'.")
|
||||
|
||||
if __name__ == '__main__':
|
||||
os.chdir(os.path.dirname(__file__) + "/../..")
|
||||
|
||||
if len(sys.argv) < 3:
|
||||
print("usage: python copy_fix.py <infile> <outfile> [--delete-unused] [--append-missing] [--delete-empty]")
|
||||
sys.exit()
|
||||
infile = sys.argv[1]
|
||||
outfile = sys.argv[2]
|
||||
args = sys.argv[3:]
|
||||
delete_unused = False
|
||||
append_missing = False
|
||||
delete_empty = False
|
||||
for arg in args:
|
||||
if arg == "--delete-unused":
|
||||
delete_unused = True
|
||||
elif arg == "--append-missing":
|
||||
append_missing = True
|
||||
elif arg == "--delete-empty":
|
||||
delete_empty = True
|
||||
else:
|
||||
print("No such argument '"+arg+"'.")
|
||||
sys.exit()
|
||||
|
||||
content = copy_fix(infile, delete_unused, append_missing, delete_empty)
|
||||
|
||||
open(outfile, "w").write("".join(content))
|
||||
print("Successfully created '" + outfile + "'.")
|
||||
main(sys.argv)
|
||||
|
|
|
@ -6,11 +6,11 @@ import twlang
|
|||
os.chdir(os.path.dirname(__file__) + "/../..")
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("usage: python find_unchanged.py <file>")
|
||||
sys.exit()
|
||||
print("usage: python find_unchanged.py <file>")
|
||||
sys.exit()
|
||||
infile = sys.argv[1]
|
||||
|
||||
trans = twlang.translations(infile)
|
||||
for tran, (_, expr, _) in trans.items():
|
||||
if tran == expr:
|
||||
print(tran)
|
||||
if tran == expr:
|
||||
print(tran)
|
||||
|
|
|
@ -3,13 +3,13 @@ import re
|
|||
from collections import OrderedDict
|
||||
|
||||
class LanguageDecodeError(Exception):
|
||||
def __init__(self, message, filename, line):
|
||||
error = "File \"{1}\", line {2}: {0}".format(message, filename, line+1)
|
||||
super(LanguageDecodeError, self).__init__(error)
|
||||
def __init__(self, message, filename, line):
|
||||
error = "File \"{1}\", line {2}: {0}".format(message, filename, line+1)
|
||||
super().__init__(error)
|
||||
|
||||
|
||||
# Taken from https://stackoverflow.com/questions/30011379/how-can-i-parse-a-c-format-string-in-python
|
||||
cfmt = '''\
|
||||
cfmt = r'''\
|
||||
( # start of capture group 1
|
||||
% # literal "%"
|
||||
(?: # first option
|
||||
|
@ -24,78 +24,77 @@ cfmt = '''\
|
|||
|
||||
|
||||
def decode(fileobj, elements_per_key):
|
||||
data = {}
|
||||
current_context = ""
|
||||
current_key = None
|
||||
for index, line in enumerate(fileobj):
|
||||
line = line.encode("utf-8").decode("utf-8-sig")
|
||||
line = line[:-1]
|
||||
context = ""
|
||||
if line and line[-1] == "\r":
|
||||
line = line[:-1]
|
||||
if not line or line[:1] == "#":
|
||||
current_context = ""
|
||||
continue
|
||||
data = {}
|
||||
current_context = ""
|
||||
current_key = None
|
||||
index = -1
|
||||
for index, line in enumerate(fileobj):
|
||||
line = line.encode("utf-8").decode("utf-8-sig")
|
||||
line = line[:-1]
|
||||
if line and line[-1] == "\r":
|
||||
line = line[:-1]
|
||||
if not line or line[:1] == "#":
|
||||
current_context = ""
|
||||
continue
|
||||
|
||||
if line[0] == "[":
|
||||
if line[-1] != "]":
|
||||
raise LanguageDecodeError("Invalid context string", fileobj.name, index)
|
||||
current_context = line[1:-1]
|
||||
elif line[:3] == "== ":
|
||||
if len(data[current_key]) >= 1+elements_per_key:
|
||||
raise LanguageDecodeError("Wrong number of elements per key", fileobj.name, index)
|
||||
if current_key:
|
||||
original = current_key[0]
|
||||
translation = line[3:]
|
||||
if translation and [m.group(1) for m in re.finditer(cfmt, original, flags=re.X)] != [m.group(1) for m in re.finditer(cfmt, translation, flags=re.X)]:
|
||||
raise LanguageDecodeError("Non-matching formatting string", fileobj.name, index)
|
||||
data[current_key].extend([translation])
|
||||
else:
|
||||
raise LanguageDecodeError("Element before key given", fileobj.name, index)
|
||||
else:
|
||||
if current_key:
|
||||
if len(data[current_key]) != 1+elements_per_key:
|
||||
raise LanguageDecodeError("Wrong number of elements per key", fileobj.name, index)
|
||||
data[current_key].append(index)
|
||||
if line in data:
|
||||
raise LanguageDecodeError("Key defined multiple times: " + line, fileobj.name, index)
|
||||
data[(line, current_context)] = [index]
|
||||
current_key = (line, current_context)
|
||||
if len(data[current_key]) != 1+elements_per_key:
|
||||
raise LanguageDecodeError("Wrong number of elements per key", fileobj.name, index)
|
||||
data[current_key].append(index+1)
|
||||
return data
|
||||
if line[0] == "[":
|
||||
if line[-1] != "]":
|
||||
raise LanguageDecodeError("Invalid context string", fileobj.name, index)
|
||||
current_context = line[1:-1]
|
||||
elif line[:3] == "== ":
|
||||
if len(data[current_key]) >= 1+elements_per_key:
|
||||
raise LanguageDecodeError("Wrong number of elements per key", fileobj.name, index)
|
||||
if current_key:
|
||||
original = current_key[0] # pylint: disable=E1136
|
||||
translation = line[3:]
|
||||
if translation and [m.group(1) for m in re.finditer(cfmt, original, flags=re.X)] != [m.group(1) for m in re.finditer(cfmt, translation, flags=re.X)]:
|
||||
raise LanguageDecodeError("Non-matching formatting string", fileobj.name, index)
|
||||
data[current_key].extend([translation])
|
||||
else:
|
||||
raise LanguageDecodeError("Element before key given", fileobj.name, index)
|
||||
else:
|
||||
if current_key:
|
||||
if len(data[current_key]) != 1+elements_per_key:
|
||||
raise LanguageDecodeError("Wrong number of elements per key", fileobj.name, index)
|
||||
data[current_key].append(index)
|
||||
if line in data:
|
||||
raise LanguageDecodeError("Key defined multiple times: " + line, fileobj.name, index)
|
||||
data[(line, current_context)] = [index]
|
||||
current_key = (line, current_context)
|
||||
if len(data[current_key]) != 1+elements_per_key:
|
||||
raise LanguageDecodeError("Wrong number of elements per key", fileobj.name, index)
|
||||
data[current_key].append(index+1)
|
||||
return data
|
||||
|
||||
|
||||
def check_file(path):
|
||||
with open(path) as fileobj:
|
||||
matches = re.findall("Localize\s*\(\s*\"([^\"]+)\"(?:\s*,\s*\"([^\"]+)\")?\s*\)", fileobj.read())
|
||||
return matches
|
||||
with open(path) as fileobj:
|
||||
matches = re.findall(r"Localize\s*\(\s*\"([^\"]+)\"(?:\s*,\s*\"([^\"]+)\")?\s*\)", fileobj.read())
|
||||
return matches
|
||||
|
||||
|
||||
def check_folder(path):
|
||||
englishlist = OrderedDict()
|
||||
for path, dirs, files in os.walk(path):
|
||||
dirs.sort()
|
||||
for f in sorted(files):
|
||||
if not any(f.endswith(x) for x in ".cpp .c .h".split()):
|
||||
continue
|
||||
for sentence in check_file(os.path.join(path, f)):
|
||||
englishlist[sentence] = None
|
||||
return englishlist
|
||||
englishlist = OrderedDict()
|
||||
for path2, dirs, files in os.walk(path):
|
||||
dirs.sort()
|
||||
for f in sorted(files):
|
||||
if not any(f.endswith(x) for x in ".cpp .c .h".split()):
|
||||
continue
|
||||
for sentence in check_file(os.path.join(path2, f)):
|
||||
englishlist[sentence] = None
|
||||
return englishlist
|
||||
|
||||
|
||||
def languages():
|
||||
index = decode(open("data/languages/index.txt"), 2)
|
||||
langs = {"data/languages/"+key[0]+".txt" : [key[0]]+elements for key, elements in index.items()}
|
||||
return langs
|
||||
index = decode(open("data/languages/index.txt"), 2)
|
||||
langs = {"data/languages/"+key[0]+".txt" : [key[0]]+elements for key, elements in index.items()}
|
||||
return langs
|
||||
|
||||
|
||||
def translations(filename):
|
||||
translations = decode(open(filename), 1)
|
||||
return translations
|
||||
return decode(open(filename), 1)
|
||||
|
||||
|
||||
def localizes():
|
||||
englishlist = list(check_folder("src"))
|
||||
return englishlist
|
||||
englishlist = list(check_folder("src"))
|
||||
return englishlist
|
||||
|
|
|
@ -6,5 +6,5 @@ import twlang
|
|||
os.chdir(os.path.dirname(__file__) + "/../..")
|
||||
|
||||
for lang in twlang.languages():
|
||||
content = copy_fix(lang, delete_unused=True, append_missing=True, delete_empty=False)
|
||||
open(lang, "w").write(content)
|
||||
content = copy_fix(lang, delete_unused=True, append_missing=True, delete_empty=False)
|
||||
open(lang, "w").write(content)
|
||||
|
|
|
@ -80,7 +80,7 @@ def main():
|
|||
|
||||
print('{} new entries in backup database found ({} ranks, {} teamranks, {} saves'.format(num, num_ranks, num_teamranks, num_saves))
|
||||
print('Moving entries from {} to {}'.format(
|
||||
os.path.abspath(args.f),
|
||||
os.path.abspath(args.f),
|
||||
os.path.abspath(args.to)))
|
||||
sql_file = 'ddnet-server-' + strftime('%Y-%m-%d') + '.sql'
|
||||
print("You can use the following commands to import the entries to MySQL (use sed 's/record_/prefix_/' for other database prefixes):")
|
||||
|
|
|
@ -1,351 +0,0 @@
|
|||
import os, re, sys
|
||||
|
||||
alphanum = "0123456789abcdefghijklmnopqrstuvwzyxABCDEFGHIJKLMNOPQRSTUVWXYZ_"
|
||||
cpp_keywords = ["auto", "const", "double", "float", "int", "short", "struct", "unsigned", # C
|
||||
"break", "continue", "else", "for", "long", "signed", "switch", "void",
|
||||
"case", "default", "enum", "goto", "register", "sizeof", "typedef", "volatile",
|
||||
"char", "do", "extern", "if", "return", "static", "union", "while",
|
||||
|
||||
"asm", "dynamic_cast", "namespace", "reinterpret_cast", "try", # C++
|
||||
"bool", "explicit", "new", "static_cast", "typeid",
|
||||
"catch", "false", "operator", "template", "typename",
|
||||
"class", "friend", "private", "this", "using",
|
||||
"const_cast", "inline", "public", "throw", "virtual",
|
||||
"delete", "mutable", "protected", "true", "wchar_t"]
|
||||
|
||||
allowed_words = []
|
||||
|
||||
#allowed_words += ["bitmap_left", "advance", "glyph"] # ft2
|
||||
|
||||
|
||||
allowed_words += ["qsort"] # stdio / stdlib
|
||||
allowed_words += ["size_t", "cosf", "sinf", "asinf", "acosf", "atanf", "powf", "fabs", "rand", "powf", "fmod", "sqrtf"] # math.h
|
||||
allowed_words += ["time_t", "time", "strftime", "localtime"] # time.h
|
||||
allowed_words += [ # system.h
|
||||
"int64",
|
||||
"dbg_assert", "dbg_msg", "dbg_break", "dbg_logger_stdout", "dbg_logger_debugger", "dbg_logger_file",
|
||||
"mem_alloc", "mem_zero", "mem_free", "mem_copy", "mem_move", "mem_comp", "mem_stats", "total_allocations", "allocated",
|
||||
"thread_create", "thread_sleep", "lock_wait", "lock_create", "lock_release", "lock_destroy", "swap_endian",
|
||||
"io_open", "io_read", "io_read", "io_write", "io_flush", "io_close", "io_seek", "io_skip", "io_tell", "io_length",
|
||||
"str_comp", "str_length", "str_quickhash", "str_format", "str_copy", "str_comp_nocase", "str_sanitize", "str_append",
|
||||
"str_comp_num", "str_find_nocase", "str_sanitize_strong", "str_uppercase", "str_toint", "str_tofloat",
|
||||
"str_utf8_encode", "str_utf8_rewind", "str_utf8_forward", "str_utf8_decode", "str_sanitize_cc", "str_skip_whitespaces",
|
||||
"fs_makedir", "fs_listdir", "fs_storage_path", "fs_is_dir",
|
||||
"net_init", "net_addr_comp", "net_host_lookup", "net_addr_str", "type", "port", "net_addr_from_str",
|
||||
"net_udp_create", "net_udp_send", "net_udp_recv", "net_udp_close", "net_socket_read_wait",
|
||||
"net_stats", "sent_bytes", "recv_bytes", "recv_packets", "sent_packets",
|
||||
"time_get", "time_freq", "time_timestamp"]
|
||||
|
||||
allowed_words += ["vec2", "vec3", "vec4", "round", "clamp", "length", "dot", "normalize", "frandom", "mix", "distance", "min",
|
||||
"closest_point_on_line", "max", "absolute"] # math.hpp
|
||||
allowed_words += [ # tl
|
||||
"array", "sorted_array", "string",
|
||||
"all", "sort", "add", "remove_index", "remove", "delete_all", "set_size",
|
||||
"base_ptr", "size", "swap", "empty", "front", "pop_front", "find_binary", "find_linear", "clear", "range", "end", "cstr",
|
||||
"partition_linear", "partition_binary"]
|
||||
allowed_words += ["fx2f", "f2fx"] # fixed point math
|
||||
|
||||
def CheckIdentifier(ident):
|
||||
return False
|
||||
|
||||
class Checker:
|
||||
def CheckStart(self, checker, filename):
|
||||
pass
|
||||
def CheckLine(self, checker, line):
|
||||
pass
|
||||
def CheckEnd(self, checker):
|
||||
pass
|
||||
|
||||
class FilenameExtentionChecker(Checker):
|
||||
def __init__(self):
|
||||
self.allowed = [".cpp", ".h"]
|
||||
def CheckStart(self, checker, filename):
|
||||
ext = os.path.splitext(filename)[1]
|
||||
if not ext in self.allowed:
|
||||
checker.Error("file extension '%s' is not allowed" % ext)
|
||||
|
||||
class IncludeChecker(Checker):
|
||||
def __init__(self):
|
||||
self.disallowed_headers = ["stdio.h", "stdlib.h", "string.h", "memory.h"]
|
||||
def CheckLine(self, checker, line):
|
||||
if "#include" in line:
|
||||
include_file = ""
|
||||
if '<' in line:
|
||||
include_file = line.split('<')[1].split(">")[0]
|
||||
#if not "/" in include_file:
|
||||
# checker.Error("%s is not allowed" % include_file)
|
||||
elif '"' in line:
|
||||
include_file = line.split('"')[1]
|
||||
|
||||
#print include_file
|
||||
if include_file in self.disallowed_headers:
|
||||
checker.Error("%s is not allowed" % include_file)
|
||||
|
||||
class HeaderGuardChecker(Checker):
|
||||
def CheckStart(self, checker, filename):
|
||||
self.check = ".h" in filename
|
||||
self.guard = "#ifndef " + filename[4:].replace("/", "_").replace(".hpp", "").replace(".h", "").upper() + "_H"
|
||||
def CheckLine(self, checker, line):
|
||||
if self.check:
|
||||
#if "#" in line:
|
||||
self.check = False
|
||||
#if not self.check:
|
||||
if line.strip() == self.guard:
|
||||
pass
|
||||
else:
|
||||
checker.Error("malformed or missing header guard. Should be '%s'" % self.guard)
|
||||
|
||||
class CommentChecker(Checker):
|
||||
def CheckLine(self, checker, line):
|
||||
if line.strip()[-2:] == "*/" and "/*" in line:
|
||||
checker.Error("single line multiline comment")
|
||||
|
||||
class FileChecker:
|
||||
def __init__(self):
|
||||
self.checkers = []
|
||||
self.checkers += [FilenameExtentionChecker()]
|
||||
self.checkers += [HeaderGuardChecker()]
|
||||
self.checkers += [IncludeChecker()]
|
||||
self.checkers += [CommentChecker()]
|
||||
|
||||
def Error(self, errormessage):
|
||||
self.current_errors += [(self.current_line, errormessage)]
|
||||
|
||||
def CheckLine(self, line):
|
||||
for c in self.checkers:
|
||||
c.CheckLine(self, line)
|
||||
return True
|
||||
|
||||
def CheckFile(self, filename):
|
||||
self.current_file = filename
|
||||
self.current_line = 0
|
||||
self.current_errors = []
|
||||
for c in self.checkers:
|
||||
c.CheckStart(self, filename)
|
||||
|
||||
for line in file(filename).readlines():
|
||||
self.current_line += 1
|
||||
if "ignore_check" in line:
|
||||
continue
|
||||
self.CheckLine(line)
|
||||
|
||||
for c in self.checkers:
|
||||
c.CheckEnd(self)
|
||||
|
||||
def GetErrors(self):
|
||||
return self.current_errors
|
||||
|
||||
def cstrip(lines):
|
||||
d = ""
|
||||
for l in lines:
|
||||
if "ignore_convention" in l:
|
||||
continue
|
||||
l = re.sub("^[\t ]*#.*", "", l)
|
||||
l = re.sub("//.*", "", l)
|
||||
l = re.sub('\".*?\"', '"String"', l) # remove strings
|
||||
d += l.strip() + " "
|
||||
d = re.sub('\/\*.*?\*\/', "", d) # remove /* */ comments
|
||||
d = d.replace("\t", " ") # tab to space
|
||||
d = re.sub(" *", " ", d) # remove double spaces
|
||||
#d = re.sub("", "", d) # remove /* */ comments
|
||||
|
||||
d = d.strip()
|
||||
|
||||
# this eats up cases like 'n {'
|
||||
i = 1
|
||||
while i < len(d)-2:
|
||||
if d[i] == ' ':
|
||||
if not (d[i-1] in alphanum and d[i+1] in alphanum):
|
||||
d = d[:i] + d[i+1:]
|
||||
i += 1
|
||||
return d
|
||||
|
||||
#def stripstrings(data):
|
||||
# return re.sub('\".*?\"', 'STRING', data)
|
||||
|
||||
def get_identifiers(data):
|
||||
idents = {}
|
||||
data = " "+data+" "
|
||||
regexp = re.compile("[^a-zA-Z0-9_][a-zA-Z_][a-zA-Z0-9_]+[^a-zA-Z0-9_]")
|
||||
start = 0
|
||||
while 1:
|
||||
m = regexp.search(data, start)
|
||||
|
||||
if m == None:
|
||||
break
|
||||
start = m.end()-1
|
||||
name = data[m.start()+1:m.end()-1]
|
||||
if name in idents:
|
||||
idents[name] += 1
|
||||
else:
|
||||
idents[name] = 1
|
||||
return idents
|
||||
|
||||
grand_total = 0
|
||||
grand_offenders = 0
|
||||
|
||||
gen_html = 1
|
||||
|
||||
if gen_html:
|
||||
print "<head>"
|
||||
print '<link href="/style.css" rel="stylesheet" type="text/css" />'
|
||||
print "</head>"
|
||||
print "<body>"
|
||||
|
||||
|
||||
|
||||
print '<div id="outer">'
|
||||
|
||||
print '<div id="top_left"><div id="top_right"><div id="top_mid">'
|
||||
print '<a href="/"><img src="/images/twlogo.png" alt="teeworlds logo" /></a>'
|
||||
print '</div></div></div>'
|
||||
|
||||
print '<div id="menu_left"><div id="menu_right"><div id="menu_mid">'
|
||||
print '</div></div></div>'
|
||||
|
||||
print '<div id="tlc"><div id="trc"><div id="tb"> </div></div></div>'
|
||||
print '<div id="lb"><div id="rb"><div id="mid">'
|
||||
print '<div id="container">'
|
||||
|
||||
print '<p class="topic_text">'
|
||||
print '<h1>Code Refactoring Progress</h1>'
|
||||
print '''This is generated by a script that find identifiers in the code
|
||||
that doesn't conform to the code standard. Right now it only shows headers
|
||||
because they need to be fixed before we can do the rest of the source.
|
||||
This is a ROUGH estimate of the progress'''
|
||||
print '</p>'
|
||||
|
||||
print '<p class="topic_text">'
|
||||
print '<table>'
|
||||
#print "<tr><td><b>%</b></td><td><b>#</b></td><td><b>File</b></td><td><b>Offenders</b></td></tr>"
|
||||
|
||||
line_order = 1
|
||||
total_files = 0
|
||||
complete_files = 0
|
||||
total_errors = 0
|
||||
|
||||
for (root,dirs,files) in os.walk("src"):
|
||||
for filename in files:
|
||||
filename = os.path.join(root, filename)
|
||||
if "/." in filename or "/external/" in filename or "/base/" in filename or "/generated/" in filename:
|
||||
continue
|
||||
if "src/osxlaunch/client.h" in filename: # ignore this file, ObjC file
|
||||
continue
|
||||
if "e_config_variables.h" in filename: # ignore config files
|
||||
continue
|
||||
if "src/game/variables.hpp" in filename: # ignore config files
|
||||
continue
|
||||
|
||||
if not (".hpp" in filename or ".h" in filename or ".cpp" in filename):
|
||||
continue
|
||||
|
||||
#total_files += 1
|
||||
|
||||
#if not "src/engine/client/ec_client.cpp" in filename:
|
||||
# continue
|
||||
|
||||
f = FileChecker()
|
||||
f.CheckFile(filename)
|
||||
num_errors = len(f.GetErrors())
|
||||
total_errors += num_errors
|
||||
|
||||
if num_errors:
|
||||
print '<tr style="background: #e0e0e0"><td colspan="2">%s, %d errors</td></tr>' % (filename, num_errors),
|
||||
for line, msg in f.GetErrors():
|
||||
print '<tr"><td>%d</td><td>%s</td></tr>' % (line, msg)
|
||||
#print '<table>'
|
||||
#GetErrors()
|
||||
|
||||
|
||||
|
||||
|
||||
if 0:
|
||||
text = cstrip(file(filename).readlines()) # remove all preprocessor stuff and comments
|
||||
#text = stripstrings(text) # remove strings (does not solve all cases however)
|
||||
#print text
|
||||
|
||||
idents = get_identifiers(text)
|
||||
offenders = 0
|
||||
total = 0
|
||||
offender_list = {}
|
||||
for name in idents:
|
||||
#print name
|
||||
if len(name) <= 2: # skip things that are too small
|
||||
continue
|
||||
if name in cpp_keywords: # skip keywords
|
||||
continue
|
||||
if name in allowed_words: # skip allowed keywords
|
||||
continue
|
||||
|
||||
total += idents[name]
|
||||
if name != name.lower(): # strip names that are not only lower case
|
||||
continue
|
||||
offender_list[name] = idents[name]
|
||||
if not gen_html:
|
||||
print "[%d] %s"%(idents[name], name)
|
||||
offenders += idents[name]
|
||||
|
||||
grand_total += total
|
||||
grand_offenders += offenders
|
||||
|
||||
if total == 0:
|
||||
total = 1
|
||||
|
||||
line_order = -line_order
|
||||
|
||||
|
||||
done = int((1-(offenders / float(total))) * 100)
|
||||
if done == 100:
|
||||
complete_files += 1
|
||||
|
||||
if done != 100 and gen_html:
|
||||
color = "#ffa0a0"
|
||||
if done > 20:
|
||||
color = "#ffd080"
|
||||
if done > 50:
|
||||
color = "#ffff80"
|
||||
if done > 75:
|
||||
color = "#e0ff80"
|
||||
if done == 100:
|
||||
color = "#80ff80"
|
||||
|
||||
line_color = "#f0efd5"
|
||||
if line_order > 0:
|
||||
line_color = "#ffffff"
|
||||
|
||||
offender_string = ""
|
||||
count = 0
|
||||
for name in offender_list:
|
||||
count += 1
|
||||
offender_string += "[%d]%s " % (offender_list[name], name)
|
||||
|
||||
if count%5 == 0:
|
||||
offender_string += "<br/>"
|
||||
|
||||
print '<tr style="background: %s">' % line_color,
|
||||
print '<td style="text-align: right; background: %s"><b>%d%%</b></td><td style="text-align: center">%d</td><td>%s</td>' % (color, done, offenders, filename),
|
||||
print '<td style="text-align: right">%s</td>' % offender_string
|
||||
print "</tr>"
|
||||
count = 0
|
||||
|
||||
if gen_html:
|
||||
print "</table>"
|
||||
|
||||
print "<h1>%d errors</h1>" % total_errors
|
||||
|
||||
|
||||
if 0:
|
||||
print "<h1>%.1f%% Identifiers done</h1>" % ((1-(grand_offenders / float(grand_total))) * 100)
|
||||
print "%d left of %d" % (grand_offenders, grand_total)
|
||||
print "<h1>%.1f%% Files done</h1>" % ((complete_files / float(total_files)) * 100)
|
||||
print "%d left of %d" % (total_files-complete_files, total_files)
|
||||
|
||||
print "</p>"
|
||||
print "<div style='clear:both;'></div>"
|
||||
print '</div>'
|
||||
print '</div></div></div>'
|
||||
|
||||
print '<div id="blc"><div id="brc"><div id="bb"> </div></div></div>'
|
||||
print '</div>'
|
||||
|
||||
print "</body>"
|
|
@ -1,6 +1,6 @@
|
|||
# coding: utf-8
|
||||
from socket import *
|
||||
import struct
|
||||
# pylint: skip-file
|
||||
from socket import socket, AF_INET, SOCK_DGRAM
|
||||
import sys
|
||||
import threading
|
||||
import time
|
||||
|
@ -25,9 +25,9 @@ PACKET_GETINFO3 = "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xffgie3" + "\x00"
|
|||
|
||||
class Server_Info(threading.Thread):
|
||||
|
||||
def __init__(self, address, type):
|
||||
def __init__(self, address, typ):
|
||||
self.address = address
|
||||
self.type = type
|
||||
self.type = typ
|
||||
self.finished = False
|
||||
threading.Thread.__init__(self, target = self.run)
|
||||
|
||||
|
@ -45,9 +45,9 @@ class Server_Info(threading.Thread):
|
|||
def get_server_info(address):
|
||||
try:
|
||||
sock = socket(AF_INET, SOCK_DGRAM)
|
||||
sock.settimeout(TIMEOUT);
|
||||
sock.settimeout(TIMEOUT)
|
||||
sock.sendto(PACKET_GETINFO, address)
|
||||
data, addr = sock.recvfrom(1024)
|
||||
data, _addr = sock.recvfrom(1024)
|
||||
sock.close()
|
||||
|
||||
data = data[14:] # skip header
|
||||
|
@ -64,7 +64,7 @@ def get_server_info(address):
|
|||
server_info["max_players"] = int(slots[7])
|
||||
server_info["players"] = []
|
||||
|
||||
for i in xrange(0, server_info["num_players"]):
|
||||
for i in range(0, server_info["num_players"]):
|
||||
player = {}
|
||||
player["name"] = slots[8+i*2]
|
||||
player["score"] = int(slots[8+i*2+1])
|
||||
|
@ -80,9 +80,9 @@ def get_server_info(address):
|
|||
def get_server_info2(address):
|
||||
try:
|
||||
sock = socket(AF_INET, SOCK_DGRAM)
|
||||
sock.settimeout(TIMEOUT);
|
||||
sock.settimeout(TIMEOUT)
|
||||
sock.sendto(PACKET_GETINFO2, address)
|
||||
data, addr = sock.recvfrom(1024)
|
||||
data, _addr = sock.recvfrom(1024)
|
||||
sock.close()
|
||||
|
||||
data = data[14:] # skip header
|
||||
|
@ -100,7 +100,7 @@ def get_server_info2(address):
|
|||
server_info["max_players"] = int(slots[8])
|
||||
server_info["players"] = []
|
||||
|
||||
for i in xrange(0, server_info["num_players"]):
|
||||
for i in range(0, server_info["num_players"]):
|
||||
player = {}
|
||||
player["name"] = slots[9+i*2]
|
||||
player["score"] = int(slots[9+i*2+1])
|
||||
|
@ -116,7 +116,7 @@ def get_server_info2(address):
|
|||
def get_server_info3(address):
|
||||
try:
|
||||
sock = socket(AF_INET, SOCK_DGRAM)
|
||||
sock.settimeout(TIMEOUT);
|
||||
sock.settimeout(TIMEOUT)
|
||||
sock.sendto(PACKET_GETINFO3, address)
|
||||
data, addr = sock.recvfrom(1400)
|
||||
sock.close()
|
||||
|
@ -137,7 +137,7 @@ def get_server_info3(address):
|
|||
server_info["max_clients"] = int(slots[9])
|
||||
server_info["players"] = []
|
||||
|
||||
for i in xrange(0, server_info["num_clients"]):
|
||||
for i in range(0, server_info["num_clients"]):
|
||||
player = {}
|
||||
player["name"] = slots[10+i*5]
|
||||
player["clan"] = slots[10+i*5+1]
|
||||
|
@ -178,7 +178,7 @@ def get_list(address):
|
|||
sock.sendto(PACKET_GETLIST, address)
|
||||
|
||||
while 1:
|
||||
data, addr = sock.recvfrom(1024)
|
||||
data, _addr = sock.recvfrom(1024)
|
||||
|
||||
data = data[14:]
|
||||
num_servers = len(data) / 6
|
||||
|
@ -203,12 +203,12 @@ def get_list2(address):
|
|||
sock.sendto(PACKET_GETLIST2, address)
|
||||
|
||||
while 1:
|
||||
data, addr = sock.recvfrom(1400)
|
||||
|
||||
data, _addr = sock.recvfrom(1400)
|
||||
|
||||
data = data[14:]
|
||||
num_servers = len(data) / 18
|
||||
|
||||
for n in range(0, num_servers):
|
||||
for n in range(0, num_servers):
|
||||
if data[n*18:n*18+12] == "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff":
|
||||
ip = ".".join(map(str, map(ord, data[n*18+12:n*18+16])))
|
||||
else:
|
||||
|
@ -234,7 +234,7 @@ for i in range(1, NUM_MASTERSERVERS+1):
|
|||
servers = []
|
||||
|
||||
while len(master_servers) != 0:
|
||||
if master_servers[0].finished == True:
|
||||
if master_servers[0].finished:
|
||||
if master_servers[0].servers:
|
||||
servers += master_servers[0].servers
|
||||
del master_servers[0]
|
||||
|
@ -242,7 +242,7 @@ while len(master_servers) != 0:
|
|||
|
||||
servers_info = []
|
||||
|
||||
print str(len(servers)) + " servers"
|
||||
print(str(len(servers)) + " servers")
|
||||
|
||||
for server in servers:
|
||||
s = Server_Info(server[0], server[1])
|
||||
|
@ -254,7 +254,7 @@ num_players = 0
|
|||
num_clients = 0
|
||||
|
||||
while len(servers_info) != 0:
|
||||
if servers_info[0].finished == True:
|
||||
if servers_info[0].finished:
|
||||
|
||||
if servers_info[0].info:
|
||||
num_players += servers_info[0].info["num_players"]
|
||||
|
@ -267,4 +267,4 @@ while len(servers_info) != 0:
|
|||
|
||||
time.sleep(0.001) # be nice
|
||||
|
||||
print str(num_players) + " players and " + str(num_clients-num_players) + " spectators"
|
||||
print(str(num_players) + " players and " + str(num_clients-num_players) + " spectators")
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
import csv
|
||||
|
||||
def confusables():
|
||||
with open('confusables.txt', encoding='utf-8-sig') as f:
|
||||
# Filter comments
|
||||
f = map(lambda line: line.split('#')[0], f)
|
||||
return list(csv.DictReader(f, fieldnames=['Value', 'Target', 'Category'], delimiter=';'))
|
||||
with open('confusables.txt', encoding='utf-8-sig') as f:
|
||||
# Filter comments
|
||||
f = map(lambda line: line.split('#')[0], f)
|
||||
return list(csv.DictReader(f, fieldnames=['Value', 'Target', 'Category'], delimiter=';'))
|
||||
|
||||
UNICODEDATA_FIELDS = (
|
||||
"Value",
|
||||
"Name",
|
||||
"General_Category",
|
||||
"Canonical_Combining_Class",
|
||||
"Bidi_Class",
|
||||
"Decomposition_Type",
|
||||
"Decomposition_Mapping",
|
||||
"Numeric_Type",
|
||||
"Numeric_Mapping",
|
||||
"Bidi_Mirrored",
|
||||
"Unicode_1_Name",
|
||||
"ISO_Comment",
|
||||
"Simple_Uppercase_Mapping",
|
||||
"Simple_Lowercase_Mapping",
|
||||
"Simple_Titlecase_Mapping",
|
||||
"Value",
|
||||
"Name",
|
||||
"General_Category",
|
||||
"Canonical_Combining_Class",
|
||||
"Bidi_Class",
|
||||
"Decomposition_Type",
|
||||
"Decomposition_Mapping",
|
||||
"Numeric_Type",
|
||||
"Numeric_Mapping",
|
||||
"Bidi_Mirrored",
|
||||
"Unicode_1_Name",
|
||||
"ISO_Comment",
|
||||
"Simple_Uppercase_Mapping",
|
||||
"Simple_Lowercase_Mapping",
|
||||
"Simple_Titlecase_Mapping",
|
||||
)
|
||||
|
||||
def data():
|
||||
with open('UnicodeData.txt') as f:
|
||||
return list(csv.DictReader(f, fieldnames=UNICODEDATA_FIELDS, delimiter=';'))
|
||||
with open('UnicodeData.txt') as f:
|
||||
return list(csv.DictReader(f, fieldnames=UNICODEDATA_FIELDS, delimiter=';'))
|
||||
|
||||
def unhex(s):
|
||||
return int(s, 16)
|
||||
return int(s, 16)
|
||||
|
||||
def unhex_sequence(s):
|
||||
return [unhex(x) for x in s.split()] if '<' not in s else None
|
||||
return [unhex(x) for x in s.split()] if '<' not in s else None
|
||||
|
|
|
@ -2,8 +2,8 @@ print("#ifndef GENERATED_WORDLIST_H")
|
|||
print("#define GENERATED_WORDLIST_H")
|
||||
print("const char g_aFallbackWordlist[][32] = {")
|
||||
with open("data/wordlist.txt") as f:
|
||||
for line in f:
|
||||
word = line.strip().split("\t")[1]
|
||||
print("\t\"%s\", " % word)
|
||||
for line in f:
|
||||
word = line.strip().split("\t")[1]
|
||||
print("\t\"%s\", " % word)
|
||||
print("};")
|
||||
print("#endif // GENERATED_WORDLIST_H")
|
||||
|
|
Loading…
Reference in a new issue