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:
bors[bot] 2020-12-09 09:55:26 +00:00 committed by GitHub
commit d9bda64fdf
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 1225 additions and 1629 deletions

View file

@ -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
View 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

View file

@ -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()

View file

@ -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)))

View file

@ -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()

View file

@ -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):

View file

@ -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"]

View file

@ -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()

View file

@ -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)))

View file

@ -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

View file

@ -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"])

View file

@ -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

View file

@ -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)

View file

@ -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())

View file

@ -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()

View file

@ -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")

View file

@ -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())

View file

@ -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()

View file

@ -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()

View file

@ -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

View file

@ -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()

View file

@ -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()

View file

@ -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))

View file

@ -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.")

View file

@ -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())

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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):")

View file

@ -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">&nbsp;</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">&nbsp;</div></div></div>'
print '</div>'
print "</body>"

View file

@ -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")

View file

@ -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

View file

@ -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")