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,30 +39,24 @@ 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:
if gen_client_content_header:
print("#ifndef CLIENT_CONTENT_HEADER")
print("#define CLIENT_CONTENT_HEADER")
if gen_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:
if gen_client_content_header or gen_server_content_header:
# print some includes
print('#include <engine/graphics.h>')
@ -85,7 +78,7 @@ if gen_client_content_header or gen_server_content_header:
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 or gen_server_content_source:
if gen_client_content_source:
print('#include "client_data.h"')
if gen_server_content_source:
@ -94,7 +87,7 @@ if gen_client_content_source or gen_server_content_source:
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")
@ -103,24 +96,30 @@ if gen_network_header:
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 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)
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)
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("")
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)
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)
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("")
for item in network.Objects + network.Messages:
@ -133,8 +132,8 @@ if gen_network_header:
print("""
class CNetObjHandler
{
class CNetObjHandler
{
const char *m_pMsgFailedOn;
const char *m_pObjCorrectedOn;
char m_aMsgData[1024];
@ -145,7 +144,7 @@ class CNetObjHandler
static int ms_aObjSizes[];
static const char *ms_apMsgNames[];
public:
public:
CNetObjHandler();
int ValidateObj(int Type, void *pData, int Size);
@ -158,14 +157,14 @@ public:
void *SecureUnpackMsg(int Type, CUnpacker *pUnpacker);
bool TeeHistorianRecordMsg(int Type);
const char *FailedMsgOn();
};
};
""")
""")
print("#endif // GAME_GENERATED_PROTOCOL_H")
if gen_network_source:
if gen_network_source:
# create names
lines = []
@ -246,12 +245,6 @@ if gen_network_source:
for l in lines:
print(l)
if 0:
for item in network.Objects:
for line in item.emit_validate():
print(line)
print("")
# create validate tables
lines = []
lines += ['static int validate_invalid(void *data, int size) { return -1; }']
@ -286,24 +279,6 @@ if gen_network_source:
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 += ['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;']
@ -360,5 +335,8 @@ if gen_network_source:
for l in lines:
print(l)
if gen_client_content_header or gen_server_content_header:
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,43 +1,34 @@
def get_msgs():
from datatypes import NetMessage
import network
import network
import seven.network
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]
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):
result = []
for m in a:
try:
map += [b.index(m)]
result += [b.index(m)]
except ValueError:
map += [-1]
result += [-1]
return map
return result
def output_map(name, map):
print("static const int gs_{}[{}] = {{".format(name, len(map)))
print(*map, sep=',')
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(map)))
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"

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)
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,30 +40,24 @@ 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:
if gen_client_content_header:
print("#ifndef CLIENT_CONTENT7_HEADER")
print("#define CLIENT_CONTENT7_HEADER")
if gen_server_content_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:
if gen_client_content_header or gen_server_content_header:
# print some includes
print('#include <engine/graphics.h>')
print('#include <engine/sound.h>')
@ -87,7 +81,7 @@ if gen_client_content_header or gen_server_content_header:
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 or gen_server_content_source:
if gen_client_content_source:
print('#include "client_data7.h"')
if gen_server_content_source:
@ -98,7 +92,7 @@ if gen_client_content_source or gen_server_content_source:
print("}")
# NETWORK
if gen_network_header:
if gen_network_header:
print("#ifndef GAME_GENERATED_PROTOCOL7_H")
print("#define GAME_GENERATED_PROTOCOL7_H")
@ -108,32 +102,36 @@ if gen_network_header:
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 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)
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)
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)
for l in create_enum_table(["NETMSG_INVALID"]+[o.enum_name for o in network.Messages], "NUM_NETMSGTYPES"):
print(l)
print("")
print("""
template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
template<typename... Ts> struct make_void { typedef void type;};
template<typename... Ts> using void_t = typename make_void<Ts...>::type;
template<typename T, typename = void>
struct is_sixup {
template<typename T, typename = void>
struct is_sixup {
constexpr static bool value = false;
};
};
template<typename T>
struct is_sixup<T, void_t<typename T::is_sixup>> {
template<typename T>
struct is_sixup<T, void_t<typename T::is_sixup>> {
constexpr static bool value = true;
};
""")
};
""")
for item in network.Objects + network.Messages:
for line in item.emit_declaration():
@ -145,8 +143,8 @@ struct is_sixup<T, void_t<typename T::is_sixup>> {
print("""
class CNetObjHandler
{
class CNetObjHandler
{
const char *m_pMsgFailedOn;
char m_aMsgData[1024];
const char *m_pObjFailedOn;
@ -158,7 +156,7 @@ class CNetObjHandler
static int ms_aObjSizes[];
static const char *ms_apMsgNames[];
public:
public:
CNetObjHandler();
int ValidateObj(int Type, const void *pData, int Size);
@ -170,15 +168,15 @@ public:
const char *GetMsgName(int Type) const;
void *SecureUnpackMsg(int Type, CUnpacker *pUnpacker);
const char *FailedMsgOn() const;
};
};
""")
""")
print("}")
print("#endif // GAME_GENERATED_PROTOCOL7_H")
if gen_network_source:
if gen_network_source:
# create names
lines = []
@ -265,27 +263,6 @@ if gen_network_source:
for l in lines:
print(l)
if 0:
for item in network.Objects:
for line in item.emit_validate():
print(line)
print("")
# 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, const void *pData, int Size)']
lines += ['{']
@ -301,24 +278,6 @@ if gen_network_source:
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 += ['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;']
@ -358,6 +317,9 @@ if gen_network_source:
for l in lines:
print(l)
if gen_client_content_header or gen_server_content_header:
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)
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,28 +153,28 @@ 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()"]
class SampleHandle(BaseType):
def __init__(self):
BaseType.__init__(self, "ISound::CSampleHandle")
def EmitDefinition(self, name):
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)]
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,18 +1,18 @@
import argparse
import csv
import sys
import re
def check_name(kind, qualifiers, type, name):
def check_name(kind, qualifiers, typ, name):
if kind == "variable":
return check_variable_name(qualifiers, type, name)
elif kind in "class struct".split():
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"
elif kind == "enum_constant":
if kind == "enum_constant":
if not name.isupper():
return "must only contain uppercase letters, digits and underscores"
return None
@ -28,10 +28,11 @@ ALLOW = set("""
x0 x1
y0 y1
""".split())
def check_variable_name(qualifiers, type, name):
if qualifiers == "" and type == "" and name == "argc":
def check_variable_name(qualifiers, typ, name):
if qualifiers == "" and typ == "" and name == "argc":
return None
if qualifiers == "" and type == "pp" and name == "argv":
if qualifiers == "" and typ == "pp" and name == "argv":
return None
if qualifiers == "cs":
# Allow all uppercase names for constant statics.
@ -41,7 +42,7 @@ def check_variable_name(qualifiers, type, name):
# 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])
prefix = "".join([qualifiers, "_" if qualifiers else "", typ])
if not name.startswith(prefix):
return "should start with {!r}".format(prefix)
if name in ALLOW:
@ -50,14 +51,12 @@ def check_variable_name(qualifiers, type, name):
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 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.parse_args()
identifiers = list(csv.DictReader(sys.stdin))

View file

@ -1,3 +1,4 @@
import argparse
import subprocess
import re
@ -16,7 +17,6 @@ def split_cmds(lines):
return cmds[1:]
def main():
import argparse
p = argparse.ArgumentParser(description="Strip LC_RPATH commands from executable")
p.add_argument('otool', help="Path to otool")
@ -31,7 +31,7 @@ def main():
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+\)$")
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:")

View file

@ -1,4 +1,5 @@
from collections import namedtuple
import argparse
import os
import shlex
import subprocess
@ -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,16 +1,16 @@
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
except ImportError:
def tqdm(it, *args, **kwargs):
def tqdm(it, *_args, **_kwargs):
return it
def traverse_namespaced(root, filter_files=None, skip_namespaces=1, namespace=()):
@ -38,31 +38,31 @@ INTERESTING_NODE_KINDS = {
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"):
def get_complex_type(typ):
if typ.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 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(type.element_type)
if type.kind == TypeKind.FUNCTIONPROTO:
return "a" + get_complex_type(typ.element_type)
if typ.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))
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):
@ -79,11 +79,11 @@ def is_static_member_definition_hack(node):
return False
return False
def is_const(type):
if type.is_const_qualified():
def is_const(typ):
if typ.is_const_qualified():
return True
if is_array_type(type):
return is_const(type.element_type)
return is_const(typ.element_type)
return False
class ParseError(RuntimeError):
@ -113,10 +113,10 @@ def process_source_file(out, file, extra_args, break_on):
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):
if cur_file is None or cur_file not in (file, header):
continue
if node.kind in INTERESTING_NODE_KINDS and node.spelling:
type = get_complex_type(node.type)
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}
@ -136,14 +136,13 @@ def process_source_file(out, file, extra_args, break_on):
"kind": INTERESTING_NODE_KINDS[node.kind],
"path": "::".join(namespace),
"qualifiers": qualifiers,
"type": type,
"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")

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

@ -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,6 +2,7 @@
from collections import namedtuple
from decimal import Decimal
import argparse
import os.path
import re
import sqlite3
@ -34,7 +35,6 @@ def read_records(file):
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")
@ -44,14 +44,14 @@ def main():
records = {}
for in_ in args.in_:
m = MAP_RE.match(os.path.basename(in_))
if not m:
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_))
map = m.group("map")
if map in records:
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[map] = read_records(f)
records[m] = read_records(f)
if not args.dry_run:
conn = sqlite3.connect(args.out)
@ -65,7 +65,7 @@ def main():
"".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)) +

View file

@ -1,8 +1,9 @@
#!/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)
@ -20,28 +21,28 @@ def copy_fix(infile, delete_unused, append_missing, delete_empty):
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]
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 i, miss in enumerate(missing):
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)
if __name__ == '__main__':
def main(argv):
os.chdir(os.path.dirname(__file__) + "/../..")
if len(sys.argv) < 3:
if len(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:]
infile = argv[1]
outfile = argv[2]
args = argv[3:]
delete_unused = False
append_missing = False
delete_empty = False
@ -60,3 +61,6 @@ if __name__ == '__main__':
open(outfile, "w").write("".join(content))
print("Successfully created '" + outfile + "'.")
if __name__ == '__main__':
main(sys.argv)

View file

@ -5,11 +5,11 @@ 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)
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
@ -27,10 +27,10 @@ def decode(fileobj, elements_per_key):
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]
context = ""
if line and line[-1] == "\r":
line = line[:-1]
if not line or line[:1] == "#":
@ -45,7 +45,7 @@ def decode(fileobj, elements_per_key):
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]
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)
@ -69,18 +69,18 @@ def decode(fileobj, elements_per_key):
def check_file(path):
with open(path) as fileobj:
matches = re.findall("Localize\s*\(\s*\"([^\"]+)\"(?:\s*,\s*\"([^\"]+)\")?\s*\)", fileobj.read())
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):
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(path, f)):
for sentence in check_file(os.path.join(path2, f)):
englishlist[sentence] = None
return englishlist
@ -92,8 +92,7 @@ def languages():
def translations(filename):
translations = decode(open(filename), 1)
return translations
return decode(open(filename), 1)
def localizes():

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,7 +203,7 @@ 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
@ -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")