diff --git a/.gitignore b/.gitignore index fa921d3..8875d37 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,7 @@ config.ini filters.txt .data -.idea \ No newline at end of file +.idea +common_funzia +common_refractor +common_memato diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..bd430e5 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "common"] + path = common + url = git@git.zxq.co:ripple/ripple-python-common.git diff --git a/common b/common new file mode 160000 index 0000000..1d3a6a0 --- /dev/null +++ b/common @@ -0,0 +1 @@ +Subproject commit 1d3a6a0020a73f4baedc68a879821f10431e4bfc diff --git a/constants/actions.py b/constants/actions.py deleted file mode 100644 index 50e4bf8..0000000 --- a/constants/actions.py +++ /dev/null @@ -1,16 +0,0 @@ -"""Contains user actions""" -IDLE = 0 -AFK = 1 -PLAYING = 2 -EDITING = 3 -MODDING = 4 -MULTIPLAYER = 5 -WATCHING = 6 -UNKNOWN = 7 -TESTING = 8 -SUBMITTING = 9 -PAUSED = 10 -LOBBY = 11 -MULTIPLAYING= 12 -OSU_DIRECT = 13 -NONE = 14 diff --git a/constants/bcolors.py b/constants/bcolors.py deleted file mode 100644 index b0514a3..0000000 --- a/constants/bcolors.py +++ /dev/null @@ -1,9 +0,0 @@ -"""Console colors""" -PINK = '\033[95m' -BLUE = '\033[94m' -GREEN = '\033[92m' -YELLOW = '\033[93m' -RED = '\033[91m' -ENDC = '\033[0m' -BOLD = '\033[1m' -UNDERLINE = '\033[4m' diff --git a/constants/fokabotCommands.py b/constants/fokabotCommands.py index fc9b033..41150d6 100644 --- a/constants/fokabotCommands.py +++ b/constants/fokabotCommands.py @@ -1,17 +1,19 @@ -from objects import fokabot -import random -from objects import glob -from constants import serverPackets -from constants import exceptions -from helpers import userHelper -from helpers import systemHelper -import requests import json -from constants import mods -from helpers import generalFunctions -from helpers import logHelper as log -from constants import gameModes -from constants import privileges +import random + +import requests + +from common import generalUtils +from common.constants import mods +from common.log import logUtils as log +from common.ripple import userUtils +from constants import exceptions +from common.constants import gameModes +from common.constants import privileges +from constants import serverPackets +from helpers import systemHelper +from objects import fokabot +from objects import glob """ Commands callbacks @@ -147,8 +149,8 @@ def silence(fro, chan, message): reason = ' '.join(message[3:]) # Get target user ID - targetUserID = userHelper.getID(target) - userID = userHelper.getID(fro) + targetUserID = userUtils.getID(target) + userID = userUtils.getID(fro) # Make sure the user exists if not targetUserID: @@ -177,7 +179,7 @@ def silence(fro, chan, message): targetToken.silence(silenceTime, reason, userID) else: # User offline, silence user only in db - userHelper.silence(targetUserID, silenceTime, reason, userID) + userUtils.silence(targetUserID, silenceTime, reason, userID) # Log message msg = "{} has been silenced for the following reason: {}".format(target, reason) @@ -190,8 +192,8 @@ def removeSilence(fro, chan, message): target = message[0].replace("_", " ") # Make sure the user exists - targetUserID = userHelper.getID(target) - userID = userHelper.getID(fro) + targetUserID = userUtils.getID(target) + userID = userUtils.getID(fro) if not targetUserID: return "{}: user not found".format(target) @@ -202,7 +204,7 @@ def removeSilence(fro, chan, message): targetToken.silence(0, "", userID) else: # user offline, remove islene ofnlt from db - userHelper.silence(targetUserID, 0, "", userID) + userUtils.silence(targetUserID, 0, "", userID) return "{}'s silence reset".format(target) @@ -213,13 +215,13 @@ def ban(fro, chan, message): target = message[0].replace("_", " ") # Make sure the user exists - targetUserID = userHelper.getID(target) - userID = userHelper.getID(fro) + targetUserID = userUtils.getID(target) + userID = userUtils.getID(fro) if not targetUserID: return "{}: user not found".format(target) # Set allowed to 0 - userHelper.ban(targetUserID) + userUtils.ban(targetUserID) # Send ban packet to the user if he's online targetToken = glob.tokens.getTokenFromUsername(target) @@ -236,13 +238,13 @@ def unban(fro, chan, message): target = message[0].replace("_", " ") # Make sure the user exists - targetUserID = userHelper.getID(target) - userID = userHelper.getID(fro) + targetUserID = userUtils.getID(target) + userID = userUtils.getID(fro) if not targetUserID: return "{}: user not found".format(target) # Set allowed to 1 - userHelper.unban(targetUserID) + userUtils.unban(targetUserID) log.rap(userID, "has unbanned {}".format(target), True) return "Welcome back {}!".format(target) @@ -254,13 +256,13 @@ def restrict(fro, chan, message): target = message[0].replace("_", " ") # Make sure the user exists - targetUserID = userHelper.getID(target) - userID = userHelper.getID(fro) + targetUserID = userUtils.getID(target) + userID = userUtils.getID(fro) if not targetUserID: return "{}: user not found".format(target) # Put this user in restricted mode - userHelper.restrict(targetUserID) + userUtils.restrict(targetUserID) # Send restricted mode packet to this user if he's online targetToken = glob.tokens.getTokenFromUsername(target) @@ -277,13 +279,13 @@ def unrestrict(fro, chan, message): target = message[0].replace("_", " ") # Make sure the user exists - targetUserID = userHelper.getID(target) - userID = userHelper.getID(fro) + targetUserID = userUtils.getID(target) + userID = userUtils.getID(fro) if not targetUserID: return "{}: user not found".format(target) # Set allowed to 1 - userHelper.unrestrict(targetUserID) + userUtils.unrestrict(targetUserID) log.rap(userID, "has removed restricted mode from {}".format(target), True) return "Welcome back {}!".format(target) @@ -386,7 +388,7 @@ def getPPMessage(userID, just_data = False): currentAcc = token.tillerino[2] # Send request to LETS api - resp = requests.get("http://127.0.0.1:5002/api/v1/pp?b={}&m={}&a={}".format(currentMap, currentMods, currentAcc), timeout=10).text + resp = requests.get("http://127.0.0.1:5002/api/v1/pp?b={}&m={}".format(currentMap, currentMods, currentAcc), timeout=10).text data = json.loads(resp) # Make sure status is in response data @@ -405,23 +407,23 @@ def getPPMessage(userID, just_data = False): # Return response in chat # Song name and mods - msg = "{song}{plus}{mods} ".format(song=data["song_name"], plus="+" if currentMods > 0 else "", mods=generalFunctions.readableMods(currentMods)) + msg = "{song}{plus}{mods} ".format(song=data["song_name"], plus="+" if currentMods > 0 else "", mods=generalUtils.readableMods(currentMods)) # PP values if currentAcc == -1: msg += "95%: {pp95}pp | 98%: {pp98}pp | 99% {pp99}pp | 100%: {pp100}pp".format(pp100=data["pp"][0], pp99=data["pp"][1], pp98=data["pp"][2], pp95=data["pp"][3]) else: msg += "{acc:.2f}%: {pp}pp".format(acc=token.tillerino[2], pp=data["pp"][0]) - + originalAR = data["ar"] # calc new AR if HR/EZ is on - if (currentMods & mods.Easy) > 0: + if (currentMods & mods.EASY) > 0: data["ar"] = max(0, data["ar"] / 2) - if (currentMods & mods.HardRock) > 0: + if (currentMods & mods.HARDROCK) > 0: data["ar"] = min(10, data["ar"] * 1.4) - + arstr = " ({})".format(originalAR) if originalAR != data["ar"] else "" - + # Beatmap info msg += " | {bpm} BPM | AR {ar}{arstr} | {stars:.2f} stars".format(bpm=data["bpm"], stars=data["stars"], ar=data["ar"], arstr=arstr) @@ -433,10 +435,10 @@ def getPPMessage(userID, just_data = False): except exceptions.apiException: # API error return "Unknown error in LETS API call. Please tell this to a dev." - except: + #except: # Unknown exception # TODO: print exception - return False + # return False def tillerinoNp(fro, chan, message): try: @@ -455,15 +457,15 @@ def tillerinoNp(fro, chan, message): modsEnum = 0 mapping = { - "-Easy": mods.Easy, - "-NoFail": mods.NoFail, - "+Hidden": mods.Hidden, - "+HardRock": mods.HardRock, - "+Nightcore": mods.Nightcore, - "+DoubleTime": mods.DoubleTime, - "-HalfTime": mods.HalfTime, - "+Flashlight": mods.Flashlight, - "-SpunOut": mods.SpunOut + "-Easy": mods.EASY, + "-NoFail": mods.NOFAIL, + "+Hidden": mods.HIDDEN, + "+HardRock": mods.HARDROCK, + "+Nightcore": mods.NIGHTCORE, + "+DoubleTime": mods.DOUBLETIME, + "-HalfTime": mods.HALFTIME, + "+Flashlight": mods.FLASHLIGHT, + "-SpunOut": mods.SPUNOUT } if playWatch: @@ -513,23 +515,23 @@ def tillerinoMods(fro, chan, message): modsEnum = 0 break elif i == "NF": - modsEnum += mods.NoFail + modsEnum += mods.NOFAIL elif i == "EZ": - modsEnum += mods.Easy + modsEnum += mods.EASY elif i == "HD": - modsEnum += mods.Hidden + modsEnum += mods.HIDDEN elif i == "HR": - modsEnum += mods.HardRock + modsEnum += mods.HARDROCK elif i == "DT": - modsEnum += mods.DoubleTime + modsEnum += mods.DOUBLETIME elif i == "HT": - modsEnum += mods.HalfTime + modsEnum += mods.HALFTIME elif i == "NC": - modsEnum += mods.Nightcore + modsEnum += mods.NIGHTCORE elif i == "FL": - modsEnum += mods.Flashlight + modsEnum += mods.FLASHLIGHT elif i == "SO": - modsEnum += mods.SpunOut + modsEnum += mods.SPUNOUT # Set mods token.tillerino[1] = modsEnum @@ -582,22 +584,22 @@ def tillerinoLast(fro, chan, message): return False diffString = "difficulty_{}".format(gameModes.getGameModeForDB(data["play_mode"])) - rank = generalFunctions.getRank(data["play_mode"], data["mods"], data["accuracy"], - data["300_count"], data["100_count"], data["50_count"], data["misses_count"]) + rank = generalUtils.getRank(data["play_mode"], data["mods"], data["accuracy"], + data["300_count"], data["100_count"], data["50_count"], data["misses_count"]) ifPlayer = "{0} | ".format(fro) if chan != "FokaBot" else "" ifFc = " (FC)" if data["max_combo"] == data["fc"] else " {0}x/{1}x".format(data["max_combo"], data["fc"]) beatmapLink = "[http://osu.ppy.sh/b/{1} {0}]".format(data["sn"], data["bid"]) - hasPP = data["play_mode"] == gameModes.std or data["play_mode"] == gameModes.mania + hasPP = data["play_mode"] == gameModes.STD or data["play_mode"] == gameModes.MANIA msg = ifPlayer msg += beatmapLink - if data["play_mode"] != gameModes.std: + if data["play_mode"] != gameModes.STD: msg += " <{0}>".format(gameModes.getGameModeForPrinting(data["play_mode"])) if data["mods"]: - msg += ' +' + generalFunctions.readableMods(data["mods"]) + msg += ' +' + generalUtils.readableMods(data["mods"]) if not hasPP: msg += " | {0:,}".format(data["score"]) @@ -657,9 +659,9 @@ def pp(fro, chan, message): return False if gameMode is None: gameMode = token.gameMode - if gameMode == gameModes.taiko or gameMode == gameModes.ctb: + if gameMode == gameModes.TAIKO or gameMode == gameModes.CTB: return "PP for your current game mode is not supported yet." - pp = userHelper.getPP(token.userID, gameMode) + pp = userUtils.getPP(token.userID, gameMode) return "You have {:,} pp".format(pp) diff --git a/constants/gameModes.py b/constants/gameModes.py deleted file mode 100644 index c5a118f..0000000 --- a/constants/gameModes.py +++ /dev/null @@ -1,36 +0,0 @@ -std = 0 -taiko = 1 -ctb = 2 -mania = 3 - -def getGameModeForDB(gameMode): - """ - Convert a gamemode number to string for database table/column - - gameMode -- gameMode int or variable (ex: gameMode.std) - return -- game mode readable string for db - """ - if gameMode == std: - return "std" - elif gameMode == taiko: - return "taiko" - elif gameMode == ctb: - return "ctb" - else: - return "mania" - -def getGameModeForPrinting(gameMode): - """ - Convert a gamemode number to string for showing to a user (e.g. !last) - - gameMode -- gameMode int or variable (ex: gameMode.std) - return -- game mode readable string for a human - """ - if gameMode == std: - return "osu!" - elif gameMode == taiko: - return "Taiko" - elif gameMode == ctb: - return "CatchTheBeat" - else: - return "osu!mania" \ No newline at end of file diff --git a/constants/mods.py b/constants/mods.py deleted file mode 100644 index ee305dd..0000000 --- a/constants/mods.py +++ /dev/null @@ -1,30 +0,0 @@ -Nomod = 0 -NoFail = 1 -Easy = 2 -NoVideo = 4 -Hidden = 8 -HardRock = 16 -SuddenDeath = 32 -DoubleTime = 64 -Relax = 128 -HalfTime = 256 -Nightcore = 512 -Flashlight = 1024 -Autoplay = 2048 -SpunOut = 4096 -Relax2 = 8192 -Perfect = 16384 -Key4 = 32768 -Key5 = 65536 -Key6 = 131072 -Key7 = 262144 -Key8 = 524288 -keyMod = 1015808 -FadeIn = 1048576 -Random = 2097152 -LastMod = 4194304 -Key9 = 16777216 -Key10 = 33554432 -Key1 = 67108864 -Key3 = 134217728 -Key2 = 268435456 diff --git a/constants/privileges.py b/constants/privileges.py deleted file mode 100644 index 13a007b..0000000 --- a/constants/privileges.py +++ /dev/null @@ -1,21 +0,0 @@ -USER_PUBLIC = 1 -USER_NORMAL = 2 << 0 -USER_DONOR = 2 << 1 -ADMIN_ACCESS_RAP = 2 << 2 -ADMIN_MANAGE_USERS = 2 << 3 -ADMIN_BAN_USERS = 2 << 4 -ADMIN_SILENCE_USERS = 2 << 5 -ADMIN_WIPE_USERS = 2 << 6 -ADMIN_MANAGE_BEATMAPS = 2 << 7 -ADMIN_MANAGE_SERVERS = 2 << 8 -ADMIN_MANAGE_SETTINGS = 2 << 9 -ADMIN_MANAGE_BETAKEYS = 2 << 10 -ADMIN_MANAGE_REPORTS = 2 << 11 -ADMIN_MANAGE_DOCS = 2 << 12 -ADMIN_MANAGE_BADGES = 2 << 13 -ADMIN_VIEW_RAP_LOGS = 2 << 14 -ADMIN_MANAGE_PRIVILEGES = 2 << 15 -ADMIN_SEND_ALERTS = 2 << 16 -ADMIN_CHAT_MOD = 2 << 17 -ADMIN_KICK_USERS = 2 << 18 -USER_PENDING_VERIFICATION = 2 << 19 diff --git a/constants/serverPackets.py b/constants/serverPackets.py index 3ebd2ee..07d27e9 100644 --- a/constants/serverPackets.py +++ b/constants/serverPackets.py @@ -1,11 +1,11 @@ """ Contains functions used to write specific server packets to byte streams """ -from helpers import packetHelper +from common.constants import privileges +from common.ripple import userUtils from constants import dataTypes -from helpers import userHelper -from objects import glob -from constants import userRanks from constants import packetIDs -from constants import privileges +from constants import userRanks +from helpers import packetHelper +from objects import glob """ Login errors packets """ def loginFailed(): @@ -56,7 +56,7 @@ def userSupporterGMT(supporter, GMT): return packetHelper.buildPacket(packetIDs.server_supporterGMT, [[result, dataTypes.UINT32]]) def friendList(userID): - friends = userHelper.getFriendList(userID) + friends = userUtils.getFriendList(userID) return packetHelper.buildPacket(packetIDs.server_friendsList, [[friends, dataTypes.INT_LIST]]) def onlineUsers(): @@ -95,9 +95,9 @@ def userPanel(userID, force = False): # Only admins and normal users are currently supported if username == "FokaBot": userRank = userRanks.MOD - elif userHelper.isInPrivilegeGroup(userID, "community manager"): + elif userUtils.isInPrivilegeGroup(userID, "community manager"): userRank = userRanks.MOD - elif userHelper.isInPrivilegeGroup(userID, "developer"): + elif userUtils.isInPrivilegeGroup(userID, "developer"): userRank = userRanks.ADMIN elif (userToken.privileges & privileges.USER_DONOR) > 0: userRank = userRanks.SUPPORTER @@ -150,7 +150,7 @@ def sendMessage(fro, to, message): [fro, dataTypes.STRING], [message, dataTypes.STRING], [to, dataTypes.STRING], - [userHelper.getID(fro), dataTypes.SINT32] + [userUtils.getID(fro), dataTypes.SINT32] ]) def channelJoinSuccess(userID, chan): diff --git a/events/cantSpectateEvent.py b/events/cantSpectateEvent.py index 862bdbf..b43550e 100644 --- a/events/cantSpectateEvent.py +++ b/events/cantSpectateEvent.py @@ -1,7 +1,8 @@ -from objects import glob -from constants import serverPackets +from common.log import logUtils as log from constants import exceptions -from helpers import logHelper as log +from constants import serverPackets +from objects import glob + def handle(userToken, _): # get usertoken data diff --git a/events/changeActionEvent.py b/events/changeActionEvent.py index 884bddf..81b27be 100644 --- a/events/changeActionEvent.py +++ b/events/changeActionEvent.py @@ -1,9 +1,10 @@ -from objects import glob +from common.constants import actions +from common.log import logUtils as log +from common.ripple import userUtils from constants import clientPackets from constants import serverPackets -from helpers import userHelper -from helpers import logHelper as log -from constants import actions +from objects import glob + def handle(userToken, packetData): # Get usertoken data @@ -11,13 +12,13 @@ def handle(userToken, packetData): username = userToken.username # Make sure we are not banned - if userHelper.isBanned(userID): + if userUtils.isBanned(userID): userToken.enqueue(serverPackets.loginBanned()) return # Send restricted message if needed if not userToken.restricted: - if userHelper.isRestricted(userID): + if userUtils.isRestricted(userID): userToken.setRestricted() # Change action packet @@ -34,7 +35,7 @@ if userToken.matchID != -1 and userToken.actionID != actions.MULTIPLAYING and us ''' # Update cached stats if our pp changedm if we've just submitted a score or we've changed gameMode - if (userToken.actionID == actions.PLAYING or userToken.actionID == actions.MULTIPLAYING) or (userToken.pp != userHelper.getPP(userID, userToken.gameMode)) or (userToken.gameMode != packetData["gameMode"]): + if (userToken.actionID == actions.PLAYING or userToken.actionID == actions.MULTIPLAYING) or (userToken.pp != userUtils.getPP(userID, userToken.gameMode)) or (userToken.gameMode != packetData["gameMode"]): # Always update game mode, or we'll cache stats from the wrong game mode if we've changed it userToken.gameMode = packetData["gameMode"] userToken.updateCachedStats() diff --git a/events/changeMatchModsEvent.py b/events/changeMatchModsEvent.py index 3d63dd8..f520d7c 100644 --- a/events/changeMatchModsEvent.py +++ b/events/changeMatchModsEvent.py @@ -1,7 +1,8 @@ -from objects import glob +from common.constants import mods from constants import clientPackets from constants import matchModModes -from constants import mods +from objects import glob + def handle(userToken, packetData): # Get token data @@ -22,13 +23,13 @@ def handle(userToken, packetData): # Host can set global DT/HT if userID == match.hostUserID: # If host has selected DT/HT and Freemod is enabled, set DT/HT as match mod - if (packetData["mods"] & mods.DoubleTime) > 0: - match.changeMatchMods(mods.DoubleTime) + if (packetData["mods"] & mods.DOUBLETIME) > 0: + match.changeMatchMods(mods.DOUBLETIME) # Nightcore - if (packetData["mods"] & mods.Nightcore) > 0: - match.changeMatchMods(match.mods+mods.Nightcore) - elif (packetData["mods"] & mods.HalfTime) > 0: - match.changeMatchMods(mods.HalfTime) + if (packetData["mods"] & mods.NIGHTCORE) > 0: + match.changeMatchMods(match.mods + mods.NIGHTCORE) + elif (packetData["mods"] & mods.HALFTIME) > 0: + match.changeMatchMods(mods.HALFTIME) else: # No DT/HT, set global mods to 0 (we are in freemod mode) match.changeMatchMods(0) diff --git a/events/changeMatchSettingsEvent.py b/events/changeMatchSettingsEvent.py index 93451c8..e497457 100644 --- a/events/changeMatchSettingsEvent.py +++ b/events/changeMatchSettingsEvent.py @@ -1,12 +1,14 @@ -from objects import glob +import random + +from common import generalUtils +from common.log import logUtils as log from constants import clientPackets from constants import matchModModes -import random from constants import matchTeamTypes from constants import matchTeams from constants import slotStatuses -from helpers import logHelper as log -from helpers import generalFunctions +from objects import glob + def handle(userToken, packetData): # Read new settings @@ -59,7 +61,7 @@ def handle(userToken, packetData): # Update match settings match.inProgress = packetData["inProgress"] if packetData["matchPassword"] != "": - match.matchPassword = generalFunctions.stringMd5(packetData["matchPassword"]) + match.matchPassword = generalUtils.stringMd5(packetData["matchPassword"]) else: match.matchPassword = "" match.beatmapName = packetData["beatmapName"] diff --git a/events/createMatchEvent.py b/events/createMatchEvent.py index 3bca2db..4940ec2 100644 --- a/events/createMatchEvent.py +++ b/events/createMatchEvent.py @@ -1,9 +1,10 @@ -from constants import serverPackets +from common.log import logUtils as log from constants import clientPackets -from objects import glob -from events import joinMatchEvent from constants import exceptions -from helpers import logHelper as log +from constants import serverPackets +from events import joinMatchEvent +from objects import glob + def handle(userToken, packetData): try: diff --git a/events/friendAddEvent.py b/events/friendAddEvent.py index add353b..a9bd0e7 100644 --- a/events/friendAddEvent.py +++ b/events/friendAddEvent.py @@ -1,11 +1,12 @@ -from helpers import userHelper +from common.log import logUtils as log +from common.ripple import userUtils from constants import clientPackets -from helpers import logHelper as log + def handle(userToken, packetData): # Friend add packet packetData = clientPackets.addRemoveFriend(packetData) - userHelper.addFriend(userToken.userID, packetData["friendID"]) + userUtils.addFriend(userToken.userID, packetData["friendID"]) # Console output log.info("{} have added {} to their friends".format(userToken.username, str(packetData["friendID"]))) diff --git a/events/friendRemoveEvent.py b/events/friendRemoveEvent.py index 757a834..a184470 100644 --- a/events/friendRemoveEvent.py +++ b/events/friendRemoveEvent.py @@ -1,11 +1,12 @@ -from helpers import userHelper +from common.log import logUtils as log +from common.ripple import userUtils from constants import clientPackets -from helpers import logHelper as log + def handle(userToken, packetData): # Friend remove packet packetData = clientPackets.addRemoveFriend(packetData) - userHelper.removeFriend(userToken.userID, packetData["friendID"]) + userUtils.removeFriend(userToken.userID, packetData["friendID"]) # Console output log.info("{} have removed {} from their friends".format(userToken.username, str(packetData["friendID"]))) diff --git a/events/joinLobbyEvent.py b/events/joinLobbyEvent.py index fc3eb7a..c130f03 100644 --- a/events/joinLobbyEvent.py +++ b/events/joinLobbyEvent.py @@ -1,6 +1,7 @@ +from common.log import logUtils as log from constants import serverPackets from objects import glob -from helpers import logHelper as log + def handle(userToken, _): # Get userToken data diff --git a/events/joinMatchEvent.py b/events/joinMatchEvent.py index 7397e6a..c84db7d 100644 --- a/events/joinMatchEvent.py +++ b/events/joinMatchEvent.py @@ -1,10 +1,11 @@ +from common import generalUtils +from common.log import logUtils as log from constants import clientPackets -from constants import serverPackets -from objects import glob from constants import exceptions -from helpers import logHelper as log +from constants import serverPackets from helpers import chatHelper as chat -from helpers import generalFunctions +from objects import glob + def handle(userToken, packetData): # read packet data @@ -34,7 +35,7 @@ def joinMatch(userToken, matchID, password, isPasswordHashed = False): # Hash password if needed if isPasswordHashed == False and password != "": - password = generalFunctions.stringMd5(password) + password = generalUtils.stringMd5(password) # Check password # TODO: Admins can enter every match diff --git a/events/loginEvent.py b/events/loginEvent.py index b4ec689..0d4cf5a 100644 --- a/events/loginEvent.py +++ b/events/loginEvent.py @@ -1,15 +1,17 @@ -from helpers import userHelper -from constants import serverPackets -from constants import exceptions -from objects import glob -from helpers import locationHelper -from helpers import countryHelper import sys -import traceback -from helpers import logHelper as log -from helpers import chatHelper as chat -from constants import privileges import time +import traceback + +from common.constants import privileges +from common.log import logUtils as log +from common.ripple import userUtils +from constants import exceptions +from constants import serverPackets +from helpers import chatHelper as chat +from helpers import countryHelper +from helpers import locationHelper +from objects import glob + def handle(tornadoRequest): # Data to return @@ -51,24 +53,24 @@ def handle(tornadoRequest): # Try to get the ID from username username = str(loginData[0]) - userID = userHelper.getID(username) + userID = userUtils.getID(username) if not userID: # Invalid username raise exceptions.loginFailedException() - if not userHelper.checkLogin(userID, loginData[1]): + if not userUtils.checkLogin(userID, loginData[1]): # Invalid password raise exceptions.loginFailedException() # Make sure we are not banned or locked - priv = userHelper.getPrivileges(userID) - if userHelper.isBanned(userID) == True and priv & privileges.USER_PENDING_VERIFICATION == 0: + priv = userUtils.getPrivileges(userID) + if userUtils.isBanned(userID) == True and priv & privileges.USER_PENDING_VERIFICATION == 0: raise exceptions.loginBannedException() - if userHelper.isLocked(userID) == True and priv & privileges.USER_PENDING_VERIFICATION == 0: + if userUtils.isLocked(userID) == True and priv & privileges.USER_PENDING_VERIFICATION == 0: raise exceptions.loginLockedException() # 2FA check - if userHelper.check2FA(userID, requestIP): + if userUtils.check2FA(userID, requestIP): log.warning("Need 2FA check for user {}".format(loginData[0])) raise exceptions.need2FAException() @@ -76,8 +78,8 @@ def handle(tornadoRequest): # Verify this user (if pending activation) firstLogin = False - if priv & privileges.USER_PENDING_VERIFICATION > 0 or userHelper.hasVerifiedHardware(userID) == False: - if userHelper.verifyUser(userID, clientData): + if priv & privileges.USER_PENDING_VERIFICATION > 0 or userUtils.hasVerifiedHardware(userID) == False: + if userUtils.verifyUser(userID, clientData): # Valid account log.info("Account {} verified successfully!".format(userID)) glob.verifiedCache[str(userID)] = 1 @@ -90,7 +92,7 @@ def handle(tornadoRequest): # Save HWID in db for multiaccount detection - hwAllowed = userHelper.logHardware(userID, clientData, firstLogin) + hwAllowed = userUtils.logHardware(userID, clientData, firstLogin) # This is false only if HWID is empty # if HWID is banned, we get restricted so there's no @@ -99,7 +101,7 @@ def handle(tornadoRequest): raise exceptions.haxException() # Log user IP - userHelper.logIP(userID, requestIP) + userUtils.logIP(userID, requestIP) # Delete old tokens for that user and generate a new one glob.tokens.deleteOldTokens(userID) @@ -111,7 +113,7 @@ def handle(tornadoRequest): # Send message if donor expires soon if responseToken.privileges & privileges.USER_DONOR > 0: - expireDate = userHelper.getDonorExpire(responseToken.userID) + expireDate = userUtils.getDonorExpire(responseToken.userID) if expireDate-int(time.time()) <= 86400*3: expireDays = round((expireDate-int(time.time()))/86400) expireIn = "{} days".format(expireDays) if expireDays > 1 else "less than 24 hours" @@ -119,7 +121,7 @@ def handle(tornadoRequest): # Set silence end UNIX time in token - responseToken.silenceEndTime = userHelper.getSilenceEnd(userID) + responseToken.silenceEndTime = userUtils.getSilenceEnd(userID) # Get only silence remaining seconds silenceSeconds = responseToken.getSilenceSecondsLeft() @@ -193,15 +195,15 @@ def handle(tornadoRequest): log.warning("Location skipped") location = [0,0] countryLetters = "XX" - country = countryHelper.getCountryID(userHelper.getCountry(userID)) + country = countryHelper.getCountryID(userUtils.getCountry(userID)) # Set location and country responseToken.setLocation(location) responseToken.setCountry(country) # Set country in db if user has no country (first bancho login) - if userHelper.getCountry(userID) == "XX": - userHelper.setCountry(userID, countryLetters) + if userUtils.getCountry(userID) == "XX": + userUtils.setCountry(userID, countryLetters) # Send to everyone our userpanel if we are not restricted if not responseToken.restricted: diff --git a/events/logoutEvent.py b/events/logoutEvent.py index 1a8753b..a7d0148 100644 --- a/events/logoutEvent.py +++ b/events/logoutEvent.py @@ -1,8 +1,10 @@ -from objects import glob -from constants import serverPackets import time -from helpers import logHelper as log + +from common.log import logUtils as log +from constants import serverPackets from helpers import chatHelper as chat +from objects import glob + def handle(userToken, _=None): # get usertoken data diff --git a/events/partLobbyEvent.py b/events/partLobbyEvent.py index 22f9f27..a4367b5 100644 --- a/events/partLobbyEvent.py +++ b/events/partLobbyEvent.py @@ -1,6 +1,7 @@ -from objects import glob -from helpers import logHelper as log +from common.log import logUtils as log from helpers import chatHelper as chat +from objects import glob + def handle(userToken, _): # Get usertoken data diff --git a/events/requestStatusUpdateEvent.py b/events/requestStatusUpdateEvent.py index 318ea9a..959a5f5 100644 --- a/events/requestStatusUpdateEvent.py +++ b/events/requestStatusUpdateEvent.py @@ -1,5 +1,5 @@ from constants import serverPackets -from helpers import logHelper as log + def handle(userToken, packetData): # Update cache and send new stats diff --git a/events/setAwayMessageEvent.py b/events/setAwayMessageEvent.py index 4adabf7..a1edcc2 100644 --- a/events/setAwayMessageEvent.py +++ b/events/setAwayMessageEvent.py @@ -1,6 +1,7 @@ +from common.log import logUtils as log from constants import clientPackets from constants import serverPackets -from helpers import logHelper as log + def handle(userToken, packetData): # get token data diff --git a/events/startSpectatingEvent.py b/events/startSpectatingEvent.py index 4cd82df..b67b3bf 100644 --- a/events/startSpectatingEvent.py +++ b/events/startSpectatingEvent.py @@ -1,10 +1,11 @@ +from common.log import logUtils as log +from common.ripple import userUtils from constants import clientPackets -from constants import serverPackets from constants import exceptions -from objects import glob -from helpers import userHelper -from helpers import logHelper as log +from constants import serverPackets from helpers import chatHelper as chat +from objects import glob + def handle(userToken, packetData): try: @@ -50,7 +51,7 @@ def handle(userToken, packetData): c.enqueue(serverPackets.fellowSpectatorJoined(userID)) # Console output - log.info("{} are spectating {}".format(username, userHelper.getUsername(packetData["userID"]))) + log.info("{} are spectating {}".format(username, userUtils.getUsername(packetData["userID"]))) except exceptions.tokenNotFoundException: # Stop spectating if token not found log.warning("Spectator start: token not found") diff --git a/events/userPanelRequestEvent.py b/events/userPanelRequestEvent.py index c097646..f1bc14c 100644 --- a/events/userPanelRequestEvent.py +++ b/events/userPanelRequestEvent.py @@ -1,6 +1,7 @@ +from common.log import logUtils as log from constants import clientPackets from constants import serverPackets -from helpers import logHelper as log + def handle(userToken, packetData): # Read userIDs list diff --git a/events/userStatsRequestEvent.py b/events/userStatsRequestEvent.py index d3a2e88..4b569cd 100644 --- a/events/userStatsRequestEvent.py +++ b/events/userStatsRequestEvent.py @@ -1,6 +1,7 @@ +from common.log import logUtils as log from constants import clientPackets from constants import serverPackets -from helpers import logHelper as log + def handle(userToken, packetData): # Read userIDs list diff --git a/handlers/apiFokabotMessageHandler.py b/handlers/apiFokabotMessageHandler.py index 3314ef9..bfa854f 100644 --- a/handlers/apiFokabotMessageHandler.py +++ b/handlers/apiFokabotMessageHandler.py @@ -1,17 +1,19 @@ -from helpers import requestHelper -from constants import exceptions import json -from objects import glob -from helpers import chatHelper -from helpers import logHelper as log -class handler(requestHelper.asyncRequestHandler): +from common.log import logUtils as log +from common.web import requestsManager +from constants import exceptions +from helpers import chatHelper +from objects import glob + + +class handler(requestsManager.asyncRequestHandler): def asyncGet(self): statusCode = 400 data = {"message": "unknown error"} try: # Check arguments - if not requestHelper.checkArguments(self.request.arguments, ["k", "to", "msg"]): + if not requestsManager.checkArguments(self.request.arguments, ["k", "to", "msg"]): raise exceptions.invalidArgumentsException() # Check ci key diff --git a/handlers/apiIsOnlineHandler.py b/handlers/apiIsOnlineHandler.py index e62cc0b..2db7295 100644 --- a/handlers/apiIsOnlineHandler.py +++ b/handlers/apiIsOnlineHandler.py @@ -1,9 +1,11 @@ -from helpers import requestHelper -from constants import exceptions import json + +from common.web import requestsManager +from constants import exceptions from objects import glob -class handler(requestHelper.asyncRequestHandler): + +class handler(requestsManager.asyncRequestHandler): def asyncGet(self): statusCode = 400 data = {"message": "unknown error"} diff --git a/handlers/apiOnlineUsersHandler.py b/handlers/apiOnlineUsersHandler.py index d40f17b..6e6cb76 100644 --- a/handlers/apiOnlineUsersHandler.py +++ b/handlers/apiOnlineUsersHandler.py @@ -1,8 +1,10 @@ -from helpers import requestHelper import json + +from common.web import requestsManager from objects import glob -class handler(requestHelper.asyncRequestHandler): + +class handler(requestsManager.asyncRequestHandler): def asyncGet(self): statusCode = 400 data = {"message": "unknown error"} diff --git a/handlers/apiServerStatusHandler.py b/handlers/apiServerStatusHandler.py index 38471bc..0ad753f 100644 --- a/handlers/apiServerStatusHandler.py +++ b/handlers/apiServerStatusHandler.py @@ -1,8 +1,10 @@ -from helpers import requestHelper import json + +from common.web import requestsManager from objects import glob -class handler(requestHelper.asyncRequestHandler): + +class handler(requestsManager.asyncRequestHandler): def asyncGet(self): statusCode = 400 data = {"message": "unknown error"} diff --git a/handlers/apiVerifiedStatusHandler.py b/handlers/apiVerifiedStatusHandler.py index 35f0994..a68aaf4 100644 --- a/handlers/apiVerifiedStatusHandler.py +++ b/handlers/apiVerifiedStatusHandler.py @@ -1,16 +1,17 @@ -from helpers import requestHelper -from helpers import logHelper as log import json -from objects import glob -from constants import exceptions -class handler(requestHelper.asyncRequestHandler): +from common.web import requestsManager +from constants import exceptions +from objects import glob + + +class handler(requestsManager.asyncRequestHandler): def asyncGet(self): statusCode = 400 data = {"message": "unknown error"} try: # Check arguments - if not requestHelper.checkArguments(self.request.arguments, ["u"]): + if not requestsManager.checkArguments(self.request.arguments, ["u"]): raise exceptions.invalidArgumentsException() # Get userID and its verified cache thing diff --git a/handlers/ciTriggerHandler.py b/handlers/ciTriggerHandler.py index 3724baf..a866afa 100644 --- a/handlers/ciTriggerHandler.py +++ b/handlers/ciTriggerHandler.py @@ -1,17 +1,19 @@ -from helpers import requestHelper -from constants import exceptions import json -from objects import glob -from helpers import systemHelper -from helpers import logHelper as log -class handler(requestHelper.asyncRequestHandler): +from common.log import logUtils as log +from common.web import requestsManager +from constants import exceptions +from helpers import systemHelper +from objects import glob + + +class handler(requestsManager.asyncRequestHandler): def asyncGet(self): statusCode = 400 data = {"message": "unknown error"} try: # Check arguments - if not requestHelper.checkArguments(self.request.arguments, ["k"]): + if not requestsManager.checkArguments(self.request.arguments, ["k"]): raise exceptions.invalidArgumentsException() # Check ci key diff --git a/handlers/mainHandler.py b/handlers/mainHandler.py index 7a79bea..9db07ca 100644 --- a/handlers/mainHandler.py +++ b/handlers/mainHandler.py @@ -1,60 +1,61 @@ import datetime import gzip -from helpers import requestHelper -from objects import glob -from constants import exceptions -from constants import packetIDs -from helpers import packetHelper -from constants import serverPackets -from events import sendPublicMessageEvent -from events import sendPrivateMessageEvent -from events import channelJoinEvent -from events import channelPartEvent -from events import changeActionEvent -from events import cantSpectateEvent -from events import startSpectatingEvent -from events import stopSpectatingEvent -from events import spectateFramesEvent -from events import friendAddEvent -from events import friendRemoveEvent -from events import logoutEvent -from events import loginEvent -from events import setAwayMessageEvent -from events import joinLobbyEvent -from events import createMatchEvent -from events import partLobbyEvent -from events import changeSlotEvent -from events import joinMatchEvent -from events import partMatchEvent -from events import changeMatchSettingsEvent -from events import changeMatchPasswordEvent -from events import changeMatchModsEvent -from events import matchReadyEvent -from events import matchLockEvent -from events import matchStartEvent -from events import matchPlayerLoadEvent -from events import matchSkipEvent -from events import matchFramesEvent -from events import matchCompleteEvent -from events import matchNoBeatmapEvent -from events import matchHasBeatmapEvent -from events import matchTransferHostEvent -from events import matchFailedEvent -from events import matchInviteEvent -from events import matchChangeTeamEvent -from events import userStatsRequestEvent -from events import requestStatusUpdateEvent -from events import userPanelRequestEvent - -# Exception tracking -import tornado.web -import tornado.gen import sys import traceback -from raven.contrib.tornado import SentryMixin -from helpers import logHelper as log -class handler(SentryMixin, requestHelper.asyncRequestHandler): +import tornado.gen +import tornado.web +from raven.contrib.tornado import SentryMixin + +from common.log import logUtils as log +from common.web import requestsManager +from constants import exceptions +from constants import packetIDs +from constants import serverPackets +from events import cantSpectateEvent +from events import changeActionEvent +from events import changeMatchModsEvent +from events import changeMatchPasswordEvent +from events import changeMatchSettingsEvent +from events import changeSlotEvent +from events import channelJoinEvent +from events import channelPartEvent +from events import createMatchEvent +from events import friendAddEvent +from events import friendRemoveEvent +from events import joinLobbyEvent +from events import joinMatchEvent +from events import loginEvent +from events import logoutEvent +from events import matchChangeTeamEvent +from events import matchCompleteEvent +from events import matchFailedEvent +from events import matchFramesEvent +from events import matchHasBeatmapEvent +from events import matchInviteEvent +from events import matchLockEvent +from events import matchNoBeatmapEvent +from events import matchPlayerLoadEvent +from events import matchReadyEvent +from events import matchSkipEvent +from events import matchStartEvent +from events import matchTransferHostEvent +from events import partLobbyEvent +from events import partMatchEvent +from events import requestStatusUpdateEvent +from events import sendPrivateMessageEvent +from events import sendPublicMessageEvent +from events import setAwayMessageEvent +from events import spectateFramesEvent +from events import startSpectatingEvent +from events import stopSpectatingEvent +from events import userPanelRequestEvent +from events import userStatsRequestEvent +from helpers import packetHelper +from objects import glob + + +class handler(SentryMixin, requestsManager.asyncRequestHandler): @tornado.web.asynchronous @tornado.gen.engine def asyncPost(self): diff --git a/helpers/chatHelper.py b/helpers/chatHelper.py index 7d9997d..feb3140 100644 --- a/helpers/chatHelper.py +++ b/helpers/chatHelper.py @@ -1,12 +1,12 @@ -from objects import glob -from helpers import logHelper as log +from common.log import logUtils as log +from common.ripple import userUtils from constants import exceptions -from constants import serverPackets -from objects import fokabot -from helpers import discordBotHelper -from helpers import userHelper -from events import logoutEvent from constants import messageTemplates +from constants import serverPackets +from events import logoutEvent +from objects import fokabot +from objects import glob + def joinChannel(userID = 0, channel = "", token = None, toIRC = True): """ @@ -272,7 +272,7 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True): # File and discord logs (public chat only) if to.startswith("#"): log.chat("{fro} @ {to}: {message}".format(fro=username, to=to, message=str(message.encode("utf-8")))) - discordBotHelper.sendChatlog("**{fro} @ {to}:** {message}".format(fro=username, to=to, message=str(message.encode("utf-8"))[2:-1])) + glob.schiavo.sendChatlog("**{fro} @ {to}:** {message}".format(fro=username, to=to, message=str(message.encode("utf-8"))[2:-1])) return 0 except exceptions.userSilencedException: token.enqueue(serverPackets.silenceEndTime(token.getSilenceSecondsLeft())) @@ -314,7 +314,7 @@ def fixUsernameForIRC(username): return username.replace(" ", "_") def IRCConnect(username): - userID = userHelper.getID(username) + userID = userUtils.getID(username) if not userID: log.warning("{} doesn't exist".format(username)) return @@ -332,7 +332,7 @@ def IRCDisconnect(username): log.info("{} disconnected from IRC".format(username)) def IRCJoinChannel(username, channel): - userID = userHelper.getID(username) + userID = userUtils.getID(username) if not userID: log.warning("{} doesn't exist".format(username)) return @@ -342,7 +342,7 @@ def IRCJoinChannel(username, channel): return joinChannel(userID, channel) def IRCPartChannel(username, channel): - userID = userHelper.getID(username) + userID = userUtils.getID(username) if not userID: log.warning("{} doesn't exist".format(username)) return diff --git a/helpers/consoleHelper.py b/helpers/consoleHelper.py index cccf12e..268fe99 100644 --- a/helpers/consoleHelper.py +++ b/helpers/consoleHelper.py @@ -1,4 +1,4 @@ -from constants import bcolors +from common.constants import bcolors from objects import glob def printServerStartHeader(asciiArt): @@ -28,7 +28,7 @@ def printServerStartHeader(asciiArt): printColored("> Welcome to pep.py osu!bancho server v{}".format(glob.VERSION), bcolors.GREEN) printColored("> Made by the Ripple team", bcolors.GREEN) printColored("> {}https://git.zxq.co/ripple/pep.py".format(bcolors.UNDERLINE), bcolors.GREEN) - printColored("> Press CTRL+C to exit\n",bcolors.GREEN) + printColored("> Press CTRL+C to exit\n", bcolors.GREEN) def printNoNl(string): """ diff --git a/helpers/databaseHelperNew.py b/helpers/databaseHelperNew.py deleted file mode 100644 index 47e4ec4..0000000 --- a/helpers/databaseHelperNew.py +++ /dev/null @@ -1,222 +0,0 @@ -import queue -import MySQLdb -from helpers import logHelper as log - -class worker(): - """ - A single MySQL worker - """ - def __init__(self, connection, temporary=False): - """ - Initialize a MySQL worker - - :param connection: database connection object - :param temporary: if True, this worker will be flagged as temporary - """ - self.connection = connection - self.temporary = temporary - log.debug("Created MySQL worker. Temporary: {}".format(self.temporary)) - - def ping(self): - """ - Ping MySQL server using this worker. - - :return: True if connected, False if error occured. - """ - try: - self.connection.cursor(MySQLdb.cursors.DictCursor).execute("SELECT 1+1") - return True - except: - return False - - def __del__(self): - """ - Close connection to the server - - :return: - """ - self.connection.close() - log.debug("Destroyed MySQL worker.") - -class connectionsPool(): - """ - A MySQL workers pool - """ - def __init__(self, host, username, password, database, initialSize=16): - """ - Initialize a MySQL connections pool - - :param host: MySQL host - :param username: MySQL username - :param password: MySQL password - :param database: MySQL database name - :param initialSize: initial pool size - """ - self.config = (host, username, password, database) - self.maxSize = initialSize - self.pool = queue.Queue(0) - self.consecutiveEmptyPool = 0 - self.fillPool() - - def newWorker(self, temporary=False): - """ - Create a new worker. - - :param temporary: if True, flag the worker as temporary - :return: instance of worker class - """ - db = MySQLdb.connect(*self.config) - db.autocommit(True) - conn = worker(db, temporary) - return conn - - def expandPool(self, newWorkers=5): - """ - Add some new workers to the pool - - :param newWorkers: number of new workers - :return: - """ - self.maxSize += newWorkers - self.fillPool() - - def fillPool(self): - """ - Fill the queue with workers until its maxSize - - :return: - """ - size = self.pool.qsize() - if self.maxSize > 0 and size >= self.maxSize: - return - newConnections = self.maxSize-size - for _ in range(0, newConnections): - self.pool.put_nowait(self.newWorker()) - - def getWorker(self): - """ - Get a MySQL connection worker from the pool. - If the pool is empty, a new temporary worker is created. - - :return: instance of worker class - """ - - if self.pool.empty(): - # The pool is empty. Spawn a new temporary worker - log.warning("Using temporary worker") - worker = self.newWorker(True) - - # Increment saturation - self.consecutiveEmptyPool += 1 - - # If the pool is usually empty, expand it - if self.consecutiveEmptyPool >= 5: - log.warning("MySQL connections pool is saturated. Filling connections pool.") - self.expandPool() - else: - # The pool is not empty. Get worker from the pool - # and reset saturation counter - worker = self.pool.get() - self.consecutiveEmptyPool = 0 - - # Return the connection - return worker - - def putWorker(self, worker): - """ - Put the worker back in the pool. - If the worker is temporary, close the connection - and destroy the object - - :param worker: worker object - :return: - """ - if worker.temporary: - del worker - else: - self.pool.put_nowait(worker) - -class db: - """ - A MySQL helper with multiple workers - """ - def __init__(self, host, username, password, database, initialSize): - """ - Initialize a new MySQL database helper with multiple workers. - This class is thread safe. - - :param host: MySQL host - :param username: MySQL username - :param password: MySQL password - :param database: MySQL database name - :param initialSize: initial pool size - """ - self.pool = connectionsPool(host, username, password, database, initialSize) - - def execute(self, query, params = ()): - """ - Executes a query - - :param query: query to execute. You can bind parameters with %s - :param params: parameters list. First element replaces first %s and so on - """ - cursor = None - worker = self.pool.getWorker() - - try: - # Create cursor, execute query and commit - cursor = worker.connection.cursor(MySQLdb.cursors.DictCursor) - cursor.execute(query, params) - log.debug(query) - return cursor.lastrowid - except MySQLdb.OperationalError: - del worker - worker = None - return self.execute(query, params) - finally: - # Close the cursor and release worker's lock - if cursor is not None: - cursor.close() - if worker is not None: - self.pool.putWorker(worker) - - def fetch(self, query, params = (), all = False): - """ - Fetch a single value from db that matches given query - - :param query: query to execute. You can bind parameters with %s - :param params: parameters list. First element replaces first %s and so on - :param all: fetch one or all values. Used internally. Use fetchAll if you want to fetch all values - """ - cursor = None - worker = self.pool.getWorker() - - try: - # Create cursor, execute the query and fetch one/all result(s) - cursor = worker.connection.cursor(MySQLdb.cursors.DictCursor) - cursor.execute(query, params) - log.debug(query) - if all == True: - return cursor.fetchall() - else: - return cursor.fetchone() - except MySQLdb.OperationalError: - del worker - worker = None - return self.fetch(query, params, all) - finally: - # Close the cursor and release worker's lock - if cursor is not None: - cursor.close() - if worker is not None: - self.pool.putWorker(worker) - - def fetchAll(self, query, params = ()): - """ - Fetch all values from db that matche given query. - Calls self.fetch with all = True. - - :param query: query to execute. You can bind parameters with %s - :param params: parameters list. First element replaces first %s and so on - """ - return self.fetch(query, params, True) diff --git a/helpers/generalFunctions.py b/helpers/generalFunctions.py deleted file mode 100644 index da00010..0000000 --- a/helpers/generalFunctions.py +++ /dev/null @@ -1,136 +0,0 @@ -from constants import mods -from time import gmtime, strftime -import hashlib - -def stringMd5(string): - """ - Return string's md5 - - string -- string to hash - return -- string's md5 hash - """ - d = hashlib.md5() - d.update(string.encode("utf-8")) - return d.hexdigest() - -def stringToBool(s): - """ - Convert a string (True/true/1) to bool - - s -- string/int value - return -- True/False - """ - return s == "True" or s == "true" or s == "1" or s == 1 - -def hexString(s): - """ - Output s' bytes in HEX - - s -- string - return -- string with hex value - """ - return ":".join("{:02x}".format(ord(str(c))) for c in s) - -def readableMods(__mods): - """ - Return a string with readable std mods. - Used to convert a mods number for oppai - - __mods -- mods bitwise number - return -- readable mods string, eg HDDT - """ - r = "" - if __mods == 0: - return r - if __mods & mods.NoFail > 0: - r += "NF" - if __mods & mods.Easy > 0: - r += "EZ" - if __mods & mods.Hidden > 0: - r += "HD" - if __mods & mods.HardRock > 0: - r += "HR" - if __mods & mods.DoubleTime > 0: - r += "DT" - if __mods & mods.HalfTime > 0: - r += "HT" - if __mods & mods.Flashlight > 0: - r += "FL" - if __mods & mods.SpunOut > 0: - r += "SO" - - return r - -def getRank(gameMode, __mods, acc, c300, c100, c50, cmiss): - """ - Return a string with rank/grade for a given score. - Used mainly for "tillerino" - - gameMode -- mode (0 = osu!, 1 = Taiko, 2 = CtB, 3 = osu!mania) - __mods -- mods bitwise number - acc -- accuracy - c300 -- 300 hit count - c100 -- 100 hit count - c50 -- 50 hit count - cmiss -- miss count - return -- rank/grade string - """ - total = c300 + c100 + c50 + cmiss - hdfl = (__mods & (mods.Hidden | mods.Flashlight | mods.FadeIn)) > 0 - - ss = "sshd" if hdfl else "ss" - s = "shd" if hdfl else "s" - - if gameMode == 0 or gameMode == 1: - # osu!std / taiko - ratio300 = c300 / total - ratio50 = c50 / total - if ratio300 == 1: - return ss - if ratio300 > 0.9 and ratio50 <= 0.01 and cmiss == 0: - return s - if (ratio300 > 0.8 and cmiss == 0) or (ratio300 > 0.9): - return "a" - if (ratio300 > 0.7 and cmiss == 0) or (ratio300 > 0.8): - return "b" - if ratio300 > 0.6: - return "c" - return "d" - elif gameMode == 2: - # CtB - if acc == 100: - return ss - if acc > 98: - return s - if acc > 94: - return "a" - if acc > 90: - return "b" - if acc > 85: - return "c" - return "d" - elif gameMode == 3: - # osu!mania - if acc == 100: - return ss - if acc > 95: - return s - if acc > 90: - return "a" - if acc > 80: - return "b" - if acc > 70: - return "c" - return "d" - - return "a" - -def strContains(s, w): - return (' ' + w + ' ') in (' ' + s + ' ') - -def getTimestamp(): - """ - Return current time in YYYY-MM-DD HH:MM:SS format. - Used in logs. - """ - return strftime("%Y-%m-%d %H:%M:%S", gmtime()) diff --git a/helpers/locationHelper.py b/helpers/locationHelper.py index 985676b..eba28a4 100644 --- a/helpers/locationHelper.py +++ b/helpers/locationHelper.py @@ -1,8 +1,9 @@ -import urllib.request import json +import urllib.request + +from common.log import logUtils as log from objects import glob -from helpers import logHelper as log def getCountry(ip): """ diff --git a/helpers/logHelper.py b/helpers/logHelper.py deleted file mode 100644 index 77ee10b..0000000 --- a/helpers/logHelper.py +++ /dev/null @@ -1,135 +0,0 @@ -from constants import bcolors -from helpers import discordBotHelper -from helpers import generalFunctions -from objects import glob -from helpers import userHelper -import time -import os -ENDL = "\n" if os.name == "posix" else "\r\n" - -def logMessage(message, alertType = "INFO", messageColor = bcolors.ENDC, discord = None, alertDev = False, of = None, stdout = True): - """ - Logs a message to stdout/discord/file - - message -- message to log - alertType -- can be any string. Standard types: INFO, WARNING and ERRORS. Defalt: INFO - messageColor -- message color (see constants.bcolors). Default = bcolots.ENDC (no color) - discord -- discord channel (bunker/cm/staff/general). Optional. Default = None - alertDev -- if True, devs will receive an hl on discord. Default: False - of -- if not None but a string, log the message to that file (inside .data folder). Eg: "warnings.txt" Default: None (don't log to file) - stdout -- if True, print the message to stdout. Default: True - """ - # Get type color from alertType - if alertType == "INFO": - typeColor = bcolors.GREEN - elif alertType == "WARNING": - typeColor = bcolors.YELLOW - elif alertType == "ERROR": - typeColor = bcolors.RED - elif alertType == "CHAT": - typeColor = bcolors.BLUE - elif alertType == "DEBUG": - typeColor = bcolors.PINK - else: - typeColor = bcolors.ENDC - - # Message without colors - finalMessage = "[{time}] {type} - {message}".format(time=generalFunctions.getTimestamp(), type=alertType, message=message) - - # Message with colors - finalMessageConsole = "{typeColor}[{time}] {type}{endc} - {messageColor}{message}{endc}".format( - time=generalFunctions.getTimestamp(), - type=alertType, - message=message, - - typeColor=typeColor, - messageColor=messageColor, - endc=bcolors.ENDC) - - # Log to console - if stdout: - print(finalMessageConsole) - - # Log to discord if needed - if discord is not None: - if discord == "bunker": - discordBotHelper.sendConfidential(message, alertDev) - elif discord == "cm": - discordBotHelper.sendCM(message) - elif discord == "staff": - discordBotHelper.sendStaff(message) - elif discord == "general": - discordBotHelper.sendGeneral(message) - - # Log to file if needed - if of is not None: - glob.fileBuffers.write(".data/"+of, finalMessage+ENDL) - -def warning(message, discord = None, alertDev = False): - """ - Log a warning to stdout (always) and discord (optional) - - message -- warning message - discord -- if not None, send message to that discord channel through schiavo. Optional. Default = None - alertDev -- if True, send al hl to devs on discord. Optional. Default = False. - """ - logMessage(message, "WARNING", bcolors.YELLOW, discord, alertDev) - -def error(message, discord = None, alertDev = True): - """ - Log an error to stdout (always) and discord (optional) - - message -- error message - discord -- if not None, send message to that discord channel through schiavo. Optional. Default = None - alertDev -- if True, send al hl to devs on discord. Optional. Default = False. - """ - logMessage(message, "ERROR", bcolors.RED, discord, alertDev) - -def info(message, discord = None, alertDev = False): - """ - Log an info message to stdout - - message -- info message - discord -- if not None, send message to that discord channel through schiavo. Optional. Default = None - alertDev -- if True, send al hl to devs on discord. Optional. Default = False. - """ - logMessage(message, "INFO", bcolors.ENDC, discord, alertDev) - -def debug(message): - """ - Log a debug message to stdout if server is running in debug mode - - message -- debug message - """ - if glob.debug: - logMessage(message, "DEBUG", bcolors.PINK) - -def chat(message): - """ - Log public messages to stdout and chatlog_public.txt - - message -- chat message - """ - logMessage(message, "CHAT", bcolors.BLUE, of="chatlog_public.txt") - -def pm(message): - """ - Log private messages to stdout and chatlog_private.txt - - message -- chat message - """ - logMessage(message, "CHAT", bcolors.BLUE, of="chatlog_private.txt") - -def rap(userID, message, discord=False, through="FokaBot"): - """ - Log a private message to Admin logs - - userID -- userID of who made the action - message -- message without subject (eg: "is a meme" becomes "user is a meme") - discord -- if True, send message to discord - through -- "through" thing string. Optional. Default: "FokaBot" - """ - glob.db.execute("INSERT INTO rap_logs (id, userid, text, datetime, through) VALUES (NULL, %s, %s, %s, %s)", [userID, message, int(time.time()), through]) - if discord: - username = userHelper.getUsername(userID) - logMessage("{} {}".format(username, message), discord=True) diff --git a/helpers/passwordHelper.py b/helpers/passwordHelper.py deleted file mode 100644 index b45f982..0000000 --- a/helpers/passwordHelper.py +++ /dev/null @@ -1,35 +0,0 @@ -from helpers import cryptHelper -import base64 -import bcrypt - -def checkOldPassword(password, salt, rightPassword): - """ - Check if password+salt corresponds to rightPassword - - password -- input password - salt -- password's salt - rightPassword -- right password - return -- bool - """ - return rightPassword == cryptHelper.crypt(password, "$2y$" + str(base64.b64decode(salt))) - -def checkNewPassword(password, dbPassword): - """ - Check if a password (version 2) is right. - - password -- input password - dbPassword -- the password in the database - return -- bool - """ - password = password.encode("utf8") - dbPassword = dbPassword.encode("utf8") - return bcrypt.hashpw(password, dbPassword) == dbPassword - -def genBcrypt(password): - """ - Bcrypts a password. - - password -- the password to hash. - return -- bytestring - """ - return bcrypt.hashpw(password.encode("utf8"), bcrypt.gensalt(10, b'2a')) diff --git a/helpers/requestHelper.py b/helpers/requestHelper.py deleted file mode 100644 index 660bfb4..0000000 --- a/helpers/requestHelper.py +++ /dev/null @@ -1,101 +0,0 @@ -import tornado -import tornado.web -import tornado.gen -from tornado.ioloop import IOLoop -from objects import glob -import threading -from helpers import logHelper as log - -class asyncRequestHandler(tornado.web.RequestHandler): - """ - Tornado asynchronous request handler - create a class that extends this one (requestHelper.asyncRequestHandler) - use asyncGet() and asyncPost() instad of get() and post(). - Done. I'm not kidding. - """ - @tornado.web.asynchronous - @tornado.gen.engine - def get(self, *args, **kwargs): - try: - yield tornado.gen.Task(runBackground, (self.asyncGet, tuple(args), dict(kwargs))) - except Exception as e: - yield tornado.gen.Task(self.captureException, exc_info=True) - finally: - if not self._finished: - self.finish() - - @tornado.web.asynchronous - @tornado.gen.engine - def post(self, *args, **kwargs): - try: - yield tornado.gen.Task(runBackground, (self.asyncPost, tuple(args), dict(kwargs))) - except Exception as e: - yield tornado.gen.Task(self.captureException, exc_info=True) - finally: - if not self._finished: - self.finish() - - def asyncGet(self, *args, **kwargs): - self.send_error(405) - self.finish() - - def asyncPost(self, *args, **kwargs): - self.send_error(405) - self.finish() - - def getRequestIP(self): - realIP = self.request.headers.get("X-Forwarded-For") if glob.cloudflare == True else self.request.headers.get("X-Real-IP") - if realIP is not None: - return realIP - return self.request.remote_ip - -def runBackground(data, callback): - """ - Run a function in the background. - Used to handle multiple requests at the same time - """ - func, args, kwargs = data - def _callback(result): - #glob.busyThreads -= 1 - IOLoop.instance().add_callback(lambda: callback(result)) - glob.pool.apply_async(func, args, kwargs, _callback) - #threading.Thread(target=checkPoolSaturation).start() - #glob.busyThreads += 1 - -def checkPoolSaturation(): - """ - Check the number of busy threads in connections pool. - If the pool is 100% busy, log a message to sentry - """ - size = int(glob.conf.config["server"]["threads"]) - if glob.busyThreads >= size: - msg = "Connections threads pool is saturated!" - log.warning(msg) - glob.application.sentry_client.captureMessage(msg, level="warning", extra={ - "workersBusy": glob.busyThreads, - "workersTotal": size - }) - -def checkArguments(arguments, requiredArguments): - """ - Check that every requiredArguments elements are in arguments - - arguments -- full argument list, from tornado - requiredArguments -- required arguments list es: ["u", "ha"] - handler -- handler string name to print in exception. Optional - return -- True if all arguments are passed, none if not - """ - for i in requiredArguments: - if i not in arguments: - return False - return True - -def printArguments(t): - """ - Print passed arguments, for debug purposes - - t -- tornado object (self) - """ - print("ARGS::") - for i in t.request.arguments: - print ("{}={}".format(i, t.get_argument(i))) \ No newline at end of file diff --git a/helpers/systemHelper.py b/helpers/systemHelper.py index f570c8a..560c63b 100644 --- a/helpers/systemHelper.py +++ b/helpers/systemHelper.py @@ -1,15 +1,18 @@ -from objects import glob -from constants import serverPackets -from helpers import consoleHelper -import psutil +import math import os +import signal import sys import threading -import signal -from helpers import logHelper as log -from constants import bcolors import time -import math + +import psutil + +from common.constants import bcolors +from common.log import logUtils as log +from constants import serverPackets +from helpers import consoleHelper +from objects import glob + def dispose(): """ diff --git a/helpers/userHelper.py b/helpers/userHelper.py deleted file mode 100644 index 7be8373..0000000 --- a/helpers/userHelper.py +++ /dev/null @@ -1,640 +0,0 @@ -from helpers import passwordHelper -from constants import gameModes -from constants import privileges -from helpers import generalFunctions -from objects import glob -from helpers import logHelper as log -import time -from constants import privileges - -def getID(username): - """ - Get username's user ID from userID cache (if cache hit) - or from db (and cache it for other requests) if cache miss - - username -- user - return -- user id or 0 - """ - # Add to cache if needed - if username not in glob.userIDCache: - userID = glob.db.fetch("SELECT id FROM users WHERE username = %s LIMIT 1", [username]) - if userID == None: - return 0 - glob.userIDCache[username] = userID["id"] - - # Get userID from cache - return glob.userIDCache[username] - -def checkLogin(userID, password): - """ - Check userID's login with specified password - - db -- database connection - userID -- user id - password -- plain md5 password - return -- True or False - """ - # Get password data - passwordData = glob.db.fetch("SELECT password_md5, salt, password_version FROM users WHERE id = %s LIMIT 1", [userID]) - - # Make sure the query returned something - if passwordData is None: - return False - - - # Return valid/invalid based on the password version. - if passwordData["password_version"] == 2: - return passwordHelper.checkNewPassword(password, passwordData["password_md5"]) - if passwordData["password_version"] == 1: - ok = passwordHelper.checkOldPassword(password, passwordData["salt"], passwordData["password_md5"]) - if not ok: return False - newpass = passwordHelper.genBcrypt(password) - glob.db.execute("UPDATE users SET password_md5=%s, salt='', password_version='2' WHERE id = %s LIMIT 1", [newpass, userID]) - -def exists(userID): - """ - Check if userID exists - - userID -- user ID to check - return -- bool - """ - result = glob.db.fetch("SELECT id FROM users WHERE id = %s LIMIT 1", [userID]) - if result is None: - return False - else: - return True - -def getSilenceEnd(userID): - """ - Get userID's **ABSOLUTE** silence end UNIX time - Remember to subtract time.time() to get the actual silence time - - userID -- userID - return -- UNIX time - """ - return glob.db.fetch("SELECT silence_end FROM users WHERE id = %s LIMIT 1", [userID])["silence_end"] - - -def silence(userID, seconds, silenceReason, author = 999): - """ - Silence someone - - userID -- userID - seconds -- silence length in seconds - silenceReason -- Silence reason shown on website - author -- userID of who silenced the user. Default: 999 - """ - # db qurey - silenceEndTime = int(time.time())+seconds - glob.db.execute("UPDATE users SET silence_end = %s, silence_reason = %s WHERE id = %s LIMIT 1", [silenceEndTime, silenceReason, userID]) - - # Loh - targetUsername = getUsername(userID) - # TODO: exists check im drunk rn i need to sleep (stampa piede ubriaco confirmed) - if seconds > 0: - log.rap(author, "has silenced {} for {} seconds for the following reason: \"{}\"".format(targetUsername, seconds, silenceReason), True) - else: - log.rap(author, "has removed {}'s silence".format(targetUsername), True) - -def getRankedScore(userID, gameMode): - """ - Get userID's ranked score relative to gameMode - - userID -- userID - gameMode -- int value, see gameModes - return -- ranked score - """ - modeForDB = gameModes.getGameModeForDB(gameMode) - return glob.db.fetch("SELECT ranked_score_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["ranked_score_"+modeForDB] - - -def getTotalScore(userID, gameMode): - """ - Get userID's total score relative to gameMode - - userID -- userID - gameMode -- int value, see gameModes - return -- total score - """ - modeForDB = gameModes.getGameModeForDB(gameMode) - return glob.db.fetch("SELECT total_score_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["total_score_"+modeForDB] - -def getAccuracy(userID, gameMode): - """ - Get userID's average accuracy relative to gameMode - - userID -- userID - gameMode -- int value, see gameModes - return -- accuracy - """ - modeForDB = gameModes.getGameModeForDB(gameMode) - return glob.db.fetch("SELECT avg_accuracy_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["avg_accuracy_"+modeForDB] - -def getGameRank(userID, gameMode): - """ - Get userID's **in-game rank** (eg: #1337) relative to gameMode - - userID -- userID - gameMode -- int value, see gameModes - return -- game rank - """ - - modeForDB = gameModes.getGameModeForDB(gameMode) - result = glob.db.fetch("SELECT position FROM leaderboard_"+modeForDB+" WHERE user = %s LIMIT 1", [userID]) - if result is None: - return 0 - else: - return result["position"] - -def getPlaycount(userID, gameMode): - """ - Get userID's playcount relative to gameMode - - userID -- userID - gameMode -- int value, see gameModes - return -- playcount - """ - - modeForDB = gameModes.getGameModeForDB(gameMode) - return glob.db.fetch("SELECT playcount_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["playcount_"+modeForDB] - -def getUsername(userID): - """ - Get userID's username - - userID -- userID - return -- username - """ - - return glob.db.fetch("SELECT username FROM users WHERE id = %s LIMIT 1", [userID])["username"] - -def getFriendList(userID): - """ - Get userID's friendlist - - userID -- userID - return -- list with friends userIDs. [0] if no friends. - """ - - # Get friends from db - friends = glob.db.fetchAll("SELECT user2 FROM users_relationships WHERE user1 = %s", [userID]) - - if friends is None or len(friends) == 0: - # We have no friends, return 0 list - return [0] - else: - # Get only friends - friends = [i["user2"] for i in friends] - - # Return friend IDs - return friends - -def addFriend(userID, friendID): - """ - Add friendID to userID's friend list - - userID -- user - friendID -- new friend - """ - - # Make sure we aren't adding us to our friends - if userID == friendID: - return - - # check user isn't already a friend of ours - if glob.db.fetch("SELECT id FROM users_relationships WHERE user1 = %s AND user2 = %s LIMIT 1", [userID, friendID]) is not None: - return - - # Set new value - glob.db.execute("INSERT INTO users_relationships (user1, user2) VALUES (%s, %s)", [userID, friendID]) - - -def removeFriend(userID, friendID): - """ - Remove friendID from userID's friend list - - userID -- user - friendID -- old friend - """ - # Delete user relationship. We don't need to check if the relationship was there, because who gives a shit, - # if they were not friends and they don't want to be anymore, be it. ¯\_(ツ)_/¯ - glob.db.execute("DELETE FROM users_relationships WHERE user1 = %s AND user2 = %s", [userID, friendID]) - - -def getCountry(userID): - """ - Get userID's country **(two letters)**. - Use countryHelper.getCountryID with what that function returns - to get osu! country ID relative to that user - - userID -- user - return -- country code (two letters) - """ - return glob.db.fetch("SELECT country FROM users_stats WHERE id = %s LIMIT 1", [userID])["country"] - -def getPP(userID, gameMode): - """ - Get userID's PP relative to gameMode - - userID -- user - return -- PP - """ - - modeForDB = gameModes.getGameModeForDB(gameMode) - return glob.db.fetch("SELECT pp_{} FROM users_stats WHERE id = %s LIMIT 1".format(modeForDB), [userID])["pp_{}".format(modeForDB)] - -def setCountry(userID, country): - """ - Set userID's country (two letters) - - userID -- userID - country -- country letters - """ - glob.db.execute("UPDATE users_stats SET country = %s WHERE id = %s LIMIT 1", [country, userID]) - -def logIP(userID, ip): - """ - User IP log - USED FOR MULTIACCOUNT DETECTION - """ - glob.db.execute("""INSERT INTO ip_user (userid, ip, occurencies) VALUES (%s, %s, 1) - ON DUPLICATE KEY UPDATE occurencies = occurencies + 1""", [userID, ip]) - -def saveBanchoSession(userID, ip): - """ - Save userid and ip of this token in bancho_sessions table. - Used to cache logins on LETS requests - - userID -- - ip -- user's ip address - """ - glob.db.execute("INSERT INTO bancho_sessions (id, userid, ip) VALUES (NULL, %s, %s)", [userID, ip]) - -def deleteBanchoSessions(userID, ip): - """ - Delete this bancho session from DB - - userID -- - ip -- user's IP address - """ - try: - glob.db.execute("DELETE FROM bancho_sessions WHERE userid = %s AND ip = %s", [userID, ip]) - except: - log.warning("Token for user: {} ip: {} doesn't exist".format(userID, ip)) - -def is2FAEnabled(userID): - """ - Check if 2FA is enabled on an account - - userID -- - return -- True if 2FA is enabled, False if 2FA is disabled - """ - result = glob.db.fetch("SELECT id FROM 2fa_telegram WHERE userid = %s LIMIT 1", [userID]) - return True if result is not None else False - -def check2FA(userID, ip): - """ - Check if an ip is trusted - - userID -- - ip -- user's IP address - return -- True if the IP is untrusted, False if it's trusted - """ - if not is2FAEnabled(userID): - return False - - result = glob.db.fetch("SELECT id FROM ip_user WHERE userid = %s AND ip = %s", [userID, ip]) - return True if result is None else False - -def getUserStats(userID, gameMode): - """ - Get all user stats relative to gameMode with only two queries - - userID -- - gameMode -- gameMode number - return -- dictionary with results - """ - modeForDB = gameModes.getGameModeForDB(gameMode) - - # Get stats - stats = glob.db.fetch("""SELECT - ranked_score_{gm} AS rankedScore, - avg_accuracy_{gm} AS accuracy, - playcount_{gm} AS playcount, - total_score_{gm} AS totalScore, - pp_{gm} AS pp - FROM users_stats WHERE id = %s LIMIT 1""".format(gm=modeForDB), [userID]) - - # Get game rank - result = glob.db.fetch("SELECT position FROM leaderboard_{} WHERE user = %s LIMIT 1".format(modeForDB), [userID]) - if result is None: - stats["gameRank"] = 0 - else: - stats["gameRank"] = result["position"] - - # Return stats + game rank - return stats - -def isAllowed(userID): - """ - Check if userID is not banned or restricted - - userID -- id of the user - return -- True if not banned or restricted, otherwise false. - """ - result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID]) - if result is not None: - return (result["privileges"] & privileges.USER_NORMAL) and (result["privileges"] & privileges.USER_PUBLIC) - else: - return False - -def isRestricted(userID): - """ - Check if userID is restricted - - userID -- id of the user - return -- True if not restricted, otherwise false. - """ - result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID]) - if result is not None: - return (result["privileges"] & privileges.USER_NORMAL) and not (result["privileges"] & privileges.USER_PUBLIC) - else: - return False - -def isBanned(userID): - """ - Check if userID is banned - - userID -- id of the user - return -- True if not banned, otherwise false. - """ - result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID]) - if result is not None: - return not (result["privileges"] & 3 > 0) - else: - return True - -def isLocked(userID): - """ - Check if userID is locked - - userID -- id of the user - return -- True if not locked, otherwise false. - """ - result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID]) - if result != None: - return ((result["privileges"] & privileges.USER_PUBLIC > 0) and (result["privileges"] & privileges.USER_NORMAL == 0)) - else: - return True - -def ban(userID): - """ - Ban userID - - userID -- id of user - """ - banDateTime = int(time.time()) - glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s LIMIT 1", [ ~(privileges.USER_NORMAL | privileges.USER_PUBLIC | privileges.USER_PENDING_VERIFICATION) , banDateTime, userID]) - -def unban(userID): - """ - Unban userID - - userID -- id of user - """ - glob.db.execute("UPDATE users SET privileges = privileges | %s, ban_datetime = 0 WHERE id = %s LIMIT 1", [ (privileges.USER_NORMAL | privileges.USER_PUBLIC) , userID]) - -def restrict(userID): - """ - Put userID in restricted mode - - userID -- id of user - """ - banDateTime = int(time.time()) - glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s LIMIT 1", [~privileges.USER_PUBLIC, banDateTime, userID]) - -def unrestrict(userID): - """ - Remove restricted mode from userID. - Same as unban(). - - userID -- id of user - """ - unban(userID) - -def getPrivileges(userID): - """ - Return privileges for userID - - userID -- id of user - return -- privileges number - """ - result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID]) - if result is not None: - return result["privileges"] - else: - return 0 - -def setPrivileges(userID, priv): - """ - Set userID's privileges in db - - userID -- id of user - priv -- privileges number - """ - glob.db.execute("UPDATE users SET privileges = %s WHERE id = %s LIMIT 1", [priv, userID]) - -def isInPrivilegeGroup(userID, groupName): - groupPrivileges = glob.db.fetch("SELECT privileges FROM privileges_groups WHERE name = %s LIMIT 1", [groupName]) - if groupPrivileges is None: - return False - groupPrivileges = groupPrivileges["privileges"] - userToken = glob.tokens.getTokenFromUserID(userID) - if userToken is not None: - userPrivileges = userToken.privileges - else: - userPrivileges = getPrivileges(userID) - return (userPrivileges == groupPrivileges) or (userPrivileges == (groupPrivileges | privileges.USER_DONOR)) - - -def appendNotes(userID, notes, addNl = True): - """ - Append "notes" to current userID's "notes for CM" - - userID -- id of user - notes -- text to append - addNl -- if True, prepend \n to notes. Optional. Default: True. - """ - if addNl: - notes = "\n"+notes - glob.db.execute("UPDATE users SET notes=CONCAT(COALESCE(notes, ''),%s) WHERE id = %s LIMIT 1", [notes, userID]) - - -def logHardware(userID, hashes, activation = False): - """ - Hardware log - USED FOR MULTIACCOUNT DETECTION - - Peppy's botnet (client data) structure (new line = "|", already split) - [0] osu! version - [1] plain mac addressed, separated by "." - [2] mac addresses hash set - [3] unique ID - [4] disk ID - - return -- True if hw is not banned, otherwise false - """ - # Make sure the strings are not empty - for i in hashes[2:5]: - if i == "": - log.warning("Invalid hash set ({}) for user {} in HWID check".format(hashes, userID), "bunk") - return False - - # Run some HWID checks on that user if he is not restricted - if not isRestricted(userID): - # Get username - username = getUsername(userID) - - # Get the list of banned or restricted users that have logged in from this or similar HWID hash set - banned = glob.db.fetchAll("""SELECT users.id as userid, hw_user.occurencies, users.username FROM hw_user - LEFT JOIN users ON users.id = hw_user.userid - WHERE hw_user.userid != %(userid)s - AND (IF(%(mac)s!='b4ec3c4334a0249dae95c284ec5983df', hw_user.mac = %(mac)s, 1) AND hw_user.unique_id = %(uid)s AND hw_user.disk_id = %(diskid)s) - AND (users.privileges & 3 != 3)""", { - "userid": userID, - "mac": hashes[2], - "uid": hashes[3], - "diskid": hashes[4], - }) - - for i in banned: - # Get the total numbers of logins - total = glob.db.fetch("SELECT COUNT(*) AS count FROM hw_user WHERE userid = %s LIMIT 1", [userID]) - # and make sure it is valid - if total is None: - continue - total = total["count"] - - # Calculate 10% of total - perc = (total*10)/100 - - if i["occurencies"] >= perc: - # If the banned user has logged in more than 10% of the times from this user, restrict this user - restrict(userID) - appendNotes(userID, "-- Logged in from HWID ({hwid}) used more than 10% from user {banned} ({bannedUserID}), who is banned/restricted.".format( - hwid=hashes[2:5], - banned=i["username"], - bannedUserID=i["userid"] - )) - log.warning("**{user}** ({userID}) has been restricted because he has logged in from HWID _({hwid})_ used more than 10% from banned/restricted user **{banned}** ({bannedUserID}), **possible multiaccount**.".format( - user=username, - userID=userID, - hwid=hashes[2:5], - banned=i["username"], - bannedUserID=i["userid"] - ), "cm") - - # Update hash set occurencies - glob.db.execute(""" - INSERT INTO hw_user (id, userid, mac, unique_id, disk_id, occurencies) VALUES (NULL, %s, %s, %s, %s, 1) - ON DUPLICATE KEY UPDATE occurencies = occurencies + 1 - """, [userID, hashes[2], hashes[3], hashes[4]]) - - # Optionally, set this hash as 'used for activation' - if activation: - glob.db.execute("UPDATE hw_user SET activated = 1 WHERE userid = %s AND mac = %s AND unique_id = %s AND disk_id = %s", [userID, hashes[2], hashes[3], hashes[4]]) - - # Access granted, abbiamo impiegato 3 giorni - # We grant access even in case of login from banned HWID - # because we call restrict() above so there's no need to deny the access. - return True - - -def resetPendingFlag(userID, success=True): - """ - Remove pending flag from an user. - - userID -- ID of the user - success -- if True, set USER_PUBLIC and USER_NORMAL flags too - """ - glob.db.execute("UPDATE users SET privileges = privileges & %s WHERE id = %s LIMIT 1", [~privileges.USER_PENDING_VERIFICATION, userID]) - if success: - glob.db.execute("UPDATE users SET privileges = privileges | %s WHERE id = %s LIMIT 1", [(privileges.USER_PUBLIC | privileges.USER_NORMAL), userID]) - -def verifyUser(userID, hashes): - # Check for valid hash set - for i in hashes[2:5]: - if i == "": - log.warning("Invalid hash set ({}) for user {} while verifying the account".format(str(hashes), userID), "bunk") - return False - - # Get username - username = getUsername(userID) - - # Make sure there are no other accounts activated with this exact mac/unique id/hwid - match = glob.db.fetchAll("SELECT userid FROM hw_user WHERE (IF(%(mac)s != 'b4ec3c4334a0249dae95c284ec5983df', mac = %(mac)s, 1) AND unique_id = %(uid)s AND disk_id = %(diskid)s) AND userid != %(userid)s AND activated = 1 LIMIT 1", { - "mac": hashes[2], - "uid": hashes[3], - "diskid": hashes[4], - "userid": userID - }) - - if match: - # This is a multiaccount, restrict other account and ban this account - - # Get original userID and username (lowest ID) - originalUserID = match[0]["userid"] - originalUsername = getUsername(originalUserID) - - # Ban this user and append notes - ban(userID) # this removes the USER_PENDING_VERIFICATION flag too - appendNotes(userID, "-- {}'s multiaccount ({}), found HWID match while verifying account ({})".format(originalUsername, originalUserID, hashes[2:5])) - appendNotes(originalUserID, "-- Has created multiaccount {} ({})".format(username, userID)) - - # Restrict the original - restrict(originalUserID) - - # Discord message - log.warning("User **{originalUsername}** ({originalUserID}) has been restricted because he has created multiaccount **{username}** ({userID}). The multiaccount has been banned.".format( - originalUsername=originalUsername, - originalUserID=originalUserID, - username=username, - userID=userID - ), "cm") - - # Disallow login - return False - else: - # No matches found, set USER_PUBLIC and USER_NORMAL flags and reset USER_PENDING_VERIFICATION flag - resetPendingFlag(userID) - log.info("User **{}** ({}) has verified his account with hash set _{}_".format(username, userID, hashes[2:5]), "cm") - - # Allow login - return True - -def hasVerifiedHardware(userID): - """ - userID -- id of the user - return -- True if hwid activation data is in db, otherwise false - """ - data = glob.db.fetch("SELECT id FROM hw_user WHERE userid = %s AND activated = 1 LIMIT 1", [userID]) - if data is not None: - return True - return False - -def cacheUserIDs(): - """Cache userIDs in glob.userIDCache, used later with getID().""" - data = glob.db.fetchAll("SELECT id, username FROM users WHERE privileges & {} > 0".format(privileges.USER_NORMAL)) - for i in data: - glob.userIDCache[i["username"]] = i["id"] - -def getDonorExpire(userID): - """ - Return userID's donor expiration UNIX timestamp - :param userID: - :return: donor expiration UNIX timestamp - """ - data = glob.db.fetch("SELECT donor_expire FROM users WHERE id = %s LIMIT 1", [userID]) - if data is not None: - return data["donor_expire"] - return 0 \ No newline at end of file diff --git a/irc/ircserver.py b/irc/ircserver.py index 1412ad6..ada0f3d 100644 --- a/irc/ircserver.py +++ b/irc/ircserver.py @@ -6,19 +6,21 @@ by Joel Rosdahl, licensed under the GNU GPL 2 License. Most of the reference code from miniircd was used for the low-level logic. The high-level code has been rewritten to make it compatible with pep.py. """ -import sys -import traceback -import socket -import select -import time -import re import hashlib -from helpers import logHelper as log +import re +import select +import socket +import sys +import time +import traceback -from objects import glob -from helpers import chatHelper as chat import raven +from common.log import logUtils as log +from helpers import chatHelper as chat +from objects import glob + + class Client: """ IRC Client object diff --git a/objects/banchoConfig.py b/objects/banchoConfig.py index bb96439..ca13de9 100644 --- a/objects/banchoConfig.py +++ b/objects/banchoConfig.py @@ -1,6 +1,7 @@ # TODO: Rewrite this shit +from common import generalUtils from objects import glob -from helpers import generalFunctions + class banchoConfig: """ @@ -26,8 +27,8 @@ class banchoConfig: """ (re)load bancho_settings from DB and set values in config array """ - self.config["banchoMaintenance"] = generalFunctions.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'bancho_maintenance'")["value_int"]) - self.config["freeDirect"] = generalFunctions.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'free_direct'")["value_int"]) + self.config["banchoMaintenance"] = generalUtils.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'bancho_maintenance'")["value_int"]) + self.config["freeDirect"] = generalUtils.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'free_direct'")["value_int"]) self.config["menuIcon"] = glob.db.fetch("SELECT value_string FROM bancho_settings WHERE name = 'menu_icon'")["value_string"] self.config["loginNotification"] = glob.db.fetch("SELECT value_string FROM bancho_settings WHERE name = 'login_notification'")["value_string"] diff --git a/objects/channelList.py b/objects/channelList.py index c7908b3..aefb66f 100644 --- a/objects/channelList.py +++ b/objects/channelList.py @@ -1,6 +1,7 @@ -from objects import glob +from common.log import logUtils as log from objects import channel -from helpers import logHelper as log +from objects import glob + class channelList: """ diff --git a/objects/fileBuffer.py b/objects/fileBuffer.py deleted file mode 100644 index 83a6d16..0000000 --- a/objects/fileBuffer.py +++ /dev/null @@ -1,79 +0,0 @@ -from objects import glob - -class buffer(): - """ - A file buffer object. - This buffer caches data in memory and when it's full, it writes the content to a file. - """ - def __init__(self, fileName, writeType="a", maxLength=512): - """ - A file buffer object - - :param fileName: Path and name of file on disk . - :param writeType: File write type. Optional. Default: "a" . - :param maxLength: Max length before writing buffer to disk. Optional. Default: 512. - """ - self.content = "" - self.length = 0 - self.fileName = fileName - self.writeType = writeType - self.maxLength = maxLength - - def write(self, newData): - """ - Add data to buffer. - If the total length of the data in buffer is greater than or equal to self.maxLength, - the content is written on the disk and the buffer resets - - :param newData: Data to append to buffer - :return: - """ - self.content += newData - self.length += len(newData) - if self.length >= self.maxLength: - self.flush() - - def flush(self): - """ - Write buffer content to disk and reset its content - - :return: - """ - try: - glob.fLocks.lockFile(self.fileName) - with open(self.fileName, self.writeType) as f: - f.write(self.content) - finally: - glob.fLocks.unlockFile(self.fileName) - - self.content = "" - self.length = 0 - -class buffersList(): - """ - A list of buffers - """ - def __init__(self): - self.buffers = {} - - def write(self, fileName, content): - """ - Write some data to an existing buffer in this list (or create a new one if it doesn't exist). - If the buffer is full, the data is written to the file and the buffer resets. - - :param fileName: Path of file/buffer - :param content: New content - :return: - """ - if fileName not in self.buffers: - self.buffers[fileName] = buffer(fileName) - self.buffers[fileName].write(content) - - def flushAll(self): - """ - Write all buffers to file and flush them - - :return: - """ - for _, value in self.buffers.items(): - value.flush() \ No newline at end of file diff --git a/objects/fileLocks.py b/objects/fileLocks.py deleted file mode 100644 index 38f90ff..0000000 --- a/objects/fileLocks.py +++ /dev/null @@ -1,20 +0,0 @@ -import threading - -class fileLocks: - def __init__(self): - # Dictionary containing threading.Lock s - self.locks = {} - - def lockFile(self, fileName): - if fileName in self.locks: - # Acquire existing lock - self.locks[fileName].acquire() - else: - # Create new lock and acquire it - self.locks[fileName] = threading.Lock() - self.locks[fileName].acquire() - - def unlockFile(self, fileName): - if fileName in self.locks: - # Release lock if it exists - self.locks[fileName].release() diff --git a/objects/fokabot.py b/objects/fokabot.py index 73054ef..c8497fb 100644 --- a/objects/fokabot.py +++ b/objects/fokabot.py @@ -1,11 +1,12 @@ """FokaBot related functions""" -from helpers import userHelper -from objects import glob -from constants import actions -from constants import serverPackets -from constants import fokabotCommands import re -from helpers import generalFunctions + +from common import generalUtils +from common.constants import actions +from common.ripple import userUtils +from constants import fokabotCommands +from constants import serverPackets +from objects import glob # Tillerino np regex, compiled only once to increase performance npRegex = re.compile("^https?:\\/\\/osu\\.ppy\\.sh\\/b\\/(\\d*)") @@ -34,13 +35,13 @@ def fokabotResponse(fro, chan, message): for i in fokabotCommands.commands: # Loop though all commands #if i["trigger"] in message: - if generalFunctions.strContains(message, i["trigger"]): + if generalUtils.strContains(message, i["trigger"]): # message has triggered a command # Make sure the user has right permissions if i["privileges"] is not None: # Rank = x - if userHelper.getPrivileges(userHelper.getID(fro)) & i["privileges"] == 0: + if userUtils.getPrivileges(userUtils.getID(fro)) & i["privileges"] == 0: return False # Check argument number diff --git a/objects/glob.py b/objects/glob.py index 3bb7abb..4ae1e10 100644 --- a/objects/glob.py +++ b/objects/glob.py @@ -1,12 +1,14 @@ """Global objects and variables""" -from objects import tokenList +import time + +from common.ddog import datadogClient +from common.files import fileBuffer, fileLocks from objects import channelList from objects import matchList -from objects import fileLocks -from objects import fileBuffer from objects import streamList -import time +from objects import tokenList +from common.web import schiavo try: with open("version") as f: @@ -16,6 +18,7 @@ try: except: VERSION = "¯\_(xd)_/¯" +DATADOG_PREFIX = "peppy" application = None db = None conf = None @@ -26,6 +29,8 @@ matches = matchList.matchList() restarting = False fLocks = fileLocks.fileLocks() fileBuffers = fileBuffer.buffersList() +schiavo = schiavo.schiavo() +dog = datadogClient.datadogClient() verifiedCache = {} cloudflare = False chatFilters = None @@ -36,7 +41,6 @@ busyThreads = 0 debug = False outputRequestTime = False outputPackets = False -discord = False gzip = False localize = False sentry = False diff --git a/objects/match.py b/objects/match.py index 337a2dc..15cd8fe 100644 --- a/objects/match.py +++ b/objects/match.py @@ -1,17 +1,19 @@ # TODO: Enqueue all -from constants import gameModes +import copy + +from common import generalUtils +from common.constants import gameModes +from common.log import logUtils as log +from constants import dataTypes +from constants import matchModModes from constants import matchScoringTypes from constants import matchTeamTypes -from constants import matchModModes -from constants import slotStatuses -from objects import glob -from constants import serverPackets -from constants import dataTypes from constants import matchTeams -from helpers import logHelper as log +from constants import serverPackets +from constants import slotStatuses from helpers import chatHelper as chat -from helpers import generalFunctions -import copy +from objects import glob + class slot: def __init__(self): @@ -35,7 +37,7 @@ class match: beatmapMD5 = "" slots = [] hostUserID = 0 - gameMode = gameModes.std + gameMode = gameModes.STD matchScoringType = matchScoringTypes.score matchTeamType = matchTeamTypes.headToHead matchModMode = matchModModes.normal @@ -59,7 +61,7 @@ class match: self.mods = 0 self.matchName = matchName if matchPassword != "": - self.matchPassword = generalFunctions.stringMd5(matchPassword) + self.matchPassword = generalUtils.stringMd5(matchPassword) else: self.matchPassword = "" self.beatmapID = beatmapID @@ -487,7 +489,7 @@ class match: newPassword -- new password string """ if newPassword != "": - self.matchPassword = generalFunctions.stringMd5(newPassword) + self.matchPassword = generalUtils.stringMd5(newPassword) else: self.matchPassword = "" diff --git a/objects/osuToken.py b/objects/osuToken.py index ee1607d..00f0900 100644 --- a/objects/osuToken.py +++ b/objects/osuToken.py @@ -1,14 +1,15 @@ -from constants import actions -from constants import gameModes -from helpers import userHelper +import threading +import time +import uuid + +from common.constants import gameModes, actions +from common.log import logUtils as log +from common.ripple import userUtils from constants import serverPackets from events import logoutEvent -from helpers import logHelper as log -from objects import glob -import uuid -import time -import threading from helpers import chatHelper as chat +from objects import glob + class token: @@ -25,11 +26,11 @@ class token: """ # Set stuff self.userID = userID - self.username = userHelper.getUsername(self.userID) - self.privileges = userHelper.getPrivileges(self.userID) - self.admin = userHelper.isInPrivilegeGroup(self.userID, "developer") or userHelper.isInPrivilegeGroup(self.userID, "community manager") + self.username = userUtils.getUsername(self.userID) + self.privileges = userUtils.getPrivileges(self.userID) + self.admin = userUtils.isInPrivilegeGroup(self.userID, "developer") or userUtils.isInPrivilegeGroup(self.userID, "community manager") self.irc = irc - self.restricted = userHelper.isRestricted(self.userID) + self.restricted = userUtils.isRestricted(self.userID) self.loginTime = int(time.time()) self.pingTime = self.loginTime self.timeOffset = timeOffset @@ -58,7 +59,7 @@ class token: self.actionText = "" self.actionMd5 = "" self.actionMods = 0 - self.gameMode = gameModes.std + self.gameMode = gameModes.STD self.beatmapID = 0 self.rankedScore = 0 self.accuracy = 0.0 @@ -78,7 +79,7 @@ class token: # If we have a valid ip, save bancho session in DB so we can cache LETS logins if ip != "": - userHelper.saveBanchoSession(self.userID, self.ip) + userUtils.saveBanchoSession(self.userID, self.ip) # Join main stream self.joinStream("main") @@ -275,7 +276,7 @@ class token: """ # Silence in db and token self.silenceEndTime = int(time.time())+seconds - userHelper.silence(self.userID, seconds, reason, author) + userUtils.silence(self.userID, seconds, reason, author) # Send silence packet to target self.enqueue(serverPackets.silenceEndTime(seconds)) @@ -316,7 +317,7 @@ class token: def updateCachedStats(self): """Update all cached stats for this token""" - stats = userHelper.getUserStats(self.userID, self.gameMode) + stats = userUtils.getUserStats(self.userID, self.gameMode) log.debug(str(stats)) if stats is None: log.warning("Stats query returned None") @@ -336,7 +337,7 @@ class token: If false, get the cached one. Optional. Default: False """ if force: - self.restricted = userHelper.isRestricted(self.userID) + self.restricted = userUtils.isRestricted(self.userID) if self.restricted: self.setRestricted() diff --git a/objects/tokenList.py b/objects/tokenList.py index 45ecaa8..1f6c149 100644 --- a/objects/tokenList.py +++ b/objects/tokenList.py @@ -1,9 +1,11 @@ -from objects import osuToken -from objects import glob -import time import threading +import time + +from common.ripple import userUtils from events import logoutEvent -from helpers import userHelper +from objects import glob +from objects import osuToken + class tokenList: """ @@ -39,7 +41,7 @@ class tokenList: if token in self.tokens: # Delete session from DB if self.tokens[token].ip != "": - userHelper.deleteBanchoSessions(self.tokens[token].userID, self.tokens[token].ip) + userUtils.deleteBanchoSessions(self.tokens[token].userID, self.tokens[token].ip) # Pop token from list self.tokens.pop(token) diff --git a/pep.py b/pep.py index 47155ba..271401d 100644 --- a/pep.py +++ b/pep.py @@ -2,39 +2,36 @@ import os import sys import threading +from multiprocessing.pool import ThreadPool import tornado.gen import tornado.httpserver import tornado.ioloop import tornado.web -from multiprocessing.pool import ThreadPool - -# Raven from raven.contrib.tornado import AsyncSentryClient -# pep.py files -from constants import bcolors -from helpers import configHelper -from objects import glob -from objects import fokabot -from objects import banchoConfig -from objects import chatFilters -from helpers import consoleHelper -from helpers import databaseHelperNew -from helpers import generalFunctions -from helpers import logHelper as log -from helpers import userHelper -from helpers import systemHelper as system - -from handlers import mainHandler +from common import generalUtils +from common.constants import bcolors +from common.db import dbConnector +from common.log import logUtils as log +from common.ripple import userUtils +from common.web import schiavo +from handlers import apiFokabotMessageHandler from handlers import apiIsOnlineHandler from handlers import apiOnlineUsersHandler from handlers import apiServerStatusHandler -from handlers import ciTriggerHandler from handlers import apiVerifiedStatusHandler -from handlers import apiFokabotMessageHandler - +from handlers import ciTriggerHandler +from handlers import mainHandler +from helpers import configHelper +from helpers import consoleHelper +from helpers import systemHelper as system from irc import ircserver +from objects import banchoConfig +from objects import chatFilters +from objects import fokabot +from objects import glob + def make_app(): return tornado.web.Application([ @@ -83,7 +80,7 @@ if __name__ == "__main__": # Connect to db try: consoleHelper.printNoNl("> Connecting to MySQL database...") - glob.db = databaseHelperNew.db(glob.conf.config["db"]["host"], glob.conf.config["db"]["username"], glob.conf.config["db"]["password"], glob.conf.config["db"]["database"], int(glob.conf.config["db"]["workers"])) + glob.db = dbConnector.db(glob.conf.config["db"]["host"], glob.conf.config["db"]["username"], glob.conf.config["db"]["password"], glob.conf.config["db"]["database"], int(glob.conf.config["db"]["workers"])) consoleHelper.printNoNl(" ") consoleHelper.printDone() except: @@ -152,29 +149,30 @@ if __name__ == "__main__": # Cache user ids consoleHelper.printNoNl("> Caching user IDs... ") - userHelper.cacheUserIDs() + userUtils.cacheUserIDs() consoleHelper.printDone() # Localize warning - glob.localize = generalFunctions.stringToBool(glob.conf.config["localize"]["enable"]) + glob.localize = generalUtils.stringToBool(glob.conf.config["localize"]["enable"]) if not glob.localize: consoleHelper.printColored("[!] Warning! Users localization is disabled!", bcolors.YELLOW) # Discord - glob.discord = generalFunctions.stringToBool(glob.conf.config["discord"]["enable"]) - if not glob.discord: + if generalUtils.stringToBool(glob.conf.config["discord"]["enable"]): + glob.schiavo = schiavo.schiavo(glob.conf.config["discord"]["boturl"]) + else: consoleHelper.printColored("[!] Warning! Discord logging is disabled!", bcolors.YELLOW) # Gzip - glob.gzip = generalFunctions.stringToBool(glob.conf.config["server"]["gzip"]) + glob.gzip = generalUtils.stringToBool(glob.conf.config["server"]["gzip"]) glob.gziplevel = int(glob.conf.config["server"]["gziplevel"]) if not glob.gzip: consoleHelper.printColored("[!] Warning! Gzip compression is disabled!", bcolors.YELLOW) # Debug mode - glob.debug = generalFunctions.stringToBool(glob.conf.config["debug"]["enable"]) - glob.outputPackets = generalFunctions.stringToBool(glob.conf.config["debug"]["packets"]) - glob.outputRequestTime = generalFunctions.stringToBool(glob.conf.config["debug"]["time"]) + glob.debug = generalUtils.stringToBool(glob.conf.config["debug"]["enable"]) + glob.outputPackets = generalUtils.stringToBool(glob.conf.config["debug"]["packets"]) + glob.outputRequestTime = generalUtils.stringToBool(glob.conf.config["debug"]["time"]) if glob.debug: consoleHelper.printColored("[!] Warning! Server running in debug mode!", bcolors.YELLOW) @@ -183,7 +181,7 @@ if __name__ == "__main__": # Set up sentry try: - glob.sentry = generalFunctions.stringToBool(glob.conf.config["sentry"]["enable"]) + glob.sentry = generalUtils.stringToBool(glob.conf.config["sentry"]["enable"]) if glob.sentry: glob.application.sentry_client = AsyncSentryClient(glob.conf.config["sentry"]["banchodns"], release=glob.VERSION) else: @@ -192,10 +190,10 @@ if __name__ == "__main__": consoleHelper.printColored("[!] Error while starting sentry client! Please check your config.ini and run the server again", bcolors.RED) # Cloudflare memes - glob.cloudflare = generalFunctions.stringToBool(glob.conf.config["server"]["cloudflare"]) + glob.cloudflare = generalUtils.stringToBool(glob.conf.config["server"]["cloudflare"]) # IRC start message and console output - glob.irc = generalFunctions.stringToBool(glob.conf.config["irc"]["enable"]) + glob.irc = generalUtils.stringToBool(glob.conf.config["irc"]["enable"]) if glob.irc: # IRC port try: