Add submodules
This commit is contained in:
parent
40264ceffe
commit
88c80a4080
5
.gitignore
vendored
5
.gitignore
vendored
|
@ -2,4 +2,7 @@
|
||||||
config.ini
|
config.ini
|
||||||
filters.txt
|
filters.txt
|
||||||
.data
|
.data
|
||||||
.idea
|
.idea
|
||||||
|
common_funzia
|
||||||
|
common_refractor
|
||||||
|
common_memato
|
||||||
|
|
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "common"]
|
||||||
|
path = common
|
||||||
|
url = git@git.zxq.co:ripple/ripple-python-common.git
|
1
common
Submodule
1
common
Submodule
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 1d3a6a0020a73f4baedc68a879821f10431e4bfc
|
|
@ -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
|
|
|
@ -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'
|
|
|
@ -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
|
import json
|
||||||
from constants import mods
|
import random
|
||||||
from helpers import generalFunctions
|
|
||||||
from helpers import logHelper as log
|
import requests
|
||||||
from constants import gameModes
|
|
||||||
from constants import privileges
|
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
|
Commands callbacks
|
||||||
|
@ -147,8 +149,8 @@ def silence(fro, chan, message):
|
||||||
reason = ' '.join(message[3:])
|
reason = ' '.join(message[3:])
|
||||||
|
|
||||||
# Get target user ID
|
# Get target user ID
|
||||||
targetUserID = userHelper.getID(target)
|
targetUserID = userUtils.getID(target)
|
||||||
userID = userHelper.getID(fro)
|
userID = userUtils.getID(fro)
|
||||||
|
|
||||||
# Make sure the user exists
|
# Make sure the user exists
|
||||||
if not targetUserID:
|
if not targetUserID:
|
||||||
|
@ -177,7 +179,7 @@ def silence(fro, chan, message):
|
||||||
targetToken.silence(silenceTime, reason, userID)
|
targetToken.silence(silenceTime, reason, userID)
|
||||||
else:
|
else:
|
||||||
# User offline, silence user only in db
|
# User offline, silence user only in db
|
||||||
userHelper.silence(targetUserID, silenceTime, reason, userID)
|
userUtils.silence(targetUserID, silenceTime, reason, userID)
|
||||||
|
|
||||||
# Log message
|
# Log message
|
||||||
msg = "{} has been silenced for the following reason: {}".format(target, reason)
|
msg = "{} has been silenced for the following reason: {}".format(target, reason)
|
||||||
|
@ -190,8 +192,8 @@ def removeSilence(fro, chan, message):
|
||||||
target = message[0].replace("_", " ")
|
target = message[0].replace("_", " ")
|
||||||
|
|
||||||
# Make sure the user exists
|
# Make sure the user exists
|
||||||
targetUserID = userHelper.getID(target)
|
targetUserID = userUtils.getID(target)
|
||||||
userID = userHelper.getID(fro)
|
userID = userUtils.getID(fro)
|
||||||
if not targetUserID:
|
if not targetUserID:
|
||||||
return "{}: user not found".format(target)
|
return "{}: user not found".format(target)
|
||||||
|
|
||||||
|
@ -202,7 +204,7 @@ def removeSilence(fro, chan, message):
|
||||||
targetToken.silence(0, "", userID)
|
targetToken.silence(0, "", userID)
|
||||||
else:
|
else:
|
||||||
# user offline, remove islene ofnlt from db
|
# user offline, remove islene ofnlt from db
|
||||||
userHelper.silence(targetUserID, 0, "", userID)
|
userUtils.silence(targetUserID, 0, "", userID)
|
||||||
|
|
||||||
return "{}'s silence reset".format(target)
|
return "{}'s silence reset".format(target)
|
||||||
|
|
||||||
|
@ -213,13 +215,13 @@ def ban(fro, chan, message):
|
||||||
target = message[0].replace("_", " ")
|
target = message[0].replace("_", " ")
|
||||||
|
|
||||||
# Make sure the user exists
|
# Make sure the user exists
|
||||||
targetUserID = userHelper.getID(target)
|
targetUserID = userUtils.getID(target)
|
||||||
userID = userHelper.getID(fro)
|
userID = userUtils.getID(fro)
|
||||||
if not targetUserID:
|
if not targetUserID:
|
||||||
return "{}: user not found".format(target)
|
return "{}: user not found".format(target)
|
||||||
|
|
||||||
# Set allowed to 0
|
# Set allowed to 0
|
||||||
userHelper.ban(targetUserID)
|
userUtils.ban(targetUserID)
|
||||||
|
|
||||||
# Send ban packet to the user if he's online
|
# Send ban packet to the user if he's online
|
||||||
targetToken = glob.tokens.getTokenFromUsername(target)
|
targetToken = glob.tokens.getTokenFromUsername(target)
|
||||||
|
@ -236,13 +238,13 @@ def unban(fro, chan, message):
|
||||||
target = message[0].replace("_", " ")
|
target = message[0].replace("_", " ")
|
||||||
|
|
||||||
# Make sure the user exists
|
# Make sure the user exists
|
||||||
targetUserID = userHelper.getID(target)
|
targetUserID = userUtils.getID(target)
|
||||||
userID = userHelper.getID(fro)
|
userID = userUtils.getID(fro)
|
||||||
if not targetUserID:
|
if not targetUserID:
|
||||||
return "{}: user not found".format(target)
|
return "{}: user not found".format(target)
|
||||||
|
|
||||||
# Set allowed to 1
|
# Set allowed to 1
|
||||||
userHelper.unban(targetUserID)
|
userUtils.unban(targetUserID)
|
||||||
|
|
||||||
log.rap(userID, "has unbanned {}".format(target), True)
|
log.rap(userID, "has unbanned {}".format(target), True)
|
||||||
return "Welcome back {}!".format(target)
|
return "Welcome back {}!".format(target)
|
||||||
|
@ -254,13 +256,13 @@ def restrict(fro, chan, message):
|
||||||
target = message[0].replace("_", " ")
|
target = message[0].replace("_", " ")
|
||||||
|
|
||||||
# Make sure the user exists
|
# Make sure the user exists
|
||||||
targetUserID = userHelper.getID(target)
|
targetUserID = userUtils.getID(target)
|
||||||
userID = userHelper.getID(fro)
|
userID = userUtils.getID(fro)
|
||||||
if not targetUserID:
|
if not targetUserID:
|
||||||
return "{}: user not found".format(target)
|
return "{}: user not found".format(target)
|
||||||
|
|
||||||
# Put this user in restricted mode
|
# Put this user in restricted mode
|
||||||
userHelper.restrict(targetUserID)
|
userUtils.restrict(targetUserID)
|
||||||
|
|
||||||
# Send restricted mode packet to this user if he's online
|
# Send restricted mode packet to this user if he's online
|
||||||
targetToken = glob.tokens.getTokenFromUsername(target)
|
targetToken = glob.tokens.getTokenFromUsername(target)
|
||||||
|
@ -277,13 +279,13 @@ def unrestrict(fro, chan, message):
|
||||||
target = message[0].replace("_", " ")
|
target = message[0].replace("_", " ")
|
||||||
|
|
||||||
# Make sure the user exists
|
# Make sure the user exists
|
||||||
targetUserID = userHelper.getID(target)
|
targetUserID = userUtils.getID(target)
|
||||||
userID = userHelper.getID(fro)
|
userID = userUtils.getID(fro)
|
||||||
if not targetUserID:
|
if not targetUserID:
|
||||||
return "{}: user not found".format(target)
|
return "{}: user not found".format(target)
|
||||||
|
|
||||||
# Set allowed to 1
|
# Set allowed to 1
|
||||||
userHelper.unrestrict(targetUserID)
|
userUtils.unrestrict(targetUserID)
|
||||||
|
|
||||||
log.rap(userID, "has removed restricted mode from {}".format(target), True)
|
log.rap(userID, "has removed restricted mode from {}".format(target), True)
|
||||||
return "Welcome back {}!".format(target)
|
return "Welcome back {}!".format(target)
|
||||||
|
@ -386,7 +388,7 @@ def getPPMessage(userID, just_data = False):
|
||||||
currentAcc = token.tillerino[2]
|
currentAcc = token.tillerino[2]
|
||||||
|
|
||||||
# Send request to LETS api
|
# 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)
|
data = json.loads(resp)
|
||||||
|
|
||||||
# Make sure status is in response data
|
# Make sure status is in response data
|
||||||
|
@ -405,23 +407,23 @@ def getPPMessage(userID, just_data = False):
|
||||||
|
|
||||||
# Return response in chat
|
# Return response in chat
|
||||||
# Song name and mods
|
# 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
|
# PP values
|
||||||
if currentAcc == -1:
|
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])
|
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:
|
else:
|
||||||
msg += "{acc:.2f}%: {pp}pp".format(acc=token.tillerino[2], pp=data["pp"][0])
|
msg += "{acc:.2f}%: {pp}pp".format(acc=token.tillerino[2], pp=data["pp"][0])
|
||||||
|
|
||||||
originalAR = data["ar"]
|
originalAR = data["ar"]
|
||||||
# calc new AR if HR/EZ is on
|
# 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)
|
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)
|
data["ar"] = min(10, data["ar"] * 1.4)
|
||||||
|
|
||||||
arstr = " ({})".format(originalAR) if originalAR != data["ar"] else ""
|
arstr = " ({})".format(originalAR) if originalAR != data["ar"] else ""
|
||||||
|
|
||||||
# Beatmap info
|
# Beatmap info
|
||||||
msg += " | {bpm} BPM | AR {ar}{arstr} | {stars:.2f} stars".format(bpm=data["bpm"], stars=data["stars"], ar=data["ar"], arstr=arstr)
|
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:
|
except exceptions.apiException:
|
||||||
# API error
|
# API error
|
||||||
return "Unknown error in LETS API call. Please tell this to a dev."
|
return "Unknown error in LETS API call. Please tell this to a dev."
|
||||||
except:
|
#except:
|
||||||
# Unknown exception
|
# Unknown exception
|
||||||
# TODO: print exception
|
# TODO: print exception
|
||||||
return False
|
# return False
|
||||||
|
|
||||||
def tillerinoNp(fro, chan, message):
|
def tillerinoNp(fro, chan, message):
|
||||||
try:
|
try:
|
||||||
|
@ -455,15 +457,15 @@ def tillerinoNp(fro, chan, message):
|
||||||
|
|
||||||
modsEnum = 0
|
modsEnum = 0
|
||||||
mapping = {
|
mapping = {
|
||||||
"-Easy": mods.Easy,
|
"-Easy": mods.EASY,
|
||||||
"-NoFail": mods.NoFail,
|
"-NoFail": mods.NOFAIL,
|
||||||
"+Hidden": mods.Hidden,
|
"+Hidden": mods.HIDDEN,
|
||||||
"+HardRock": mods.HardRock,
|
"+HardRock": mods.HARDROCK,
|
||||||
"+Nightcore": mods.Nightcore,
|
"+Nightcore": mods.NIGHTCORE,
|
||||||
"+DoubleTime": mods.DoubleTime,
|
"+DoubleTime": mods.DOUBLETIME,
|
||||||
"-HalfTime": mods.HalfTime,
|
"-HalfTime": mods.HALFTIME,
|
||||||
"+Flashlight": mods.Flashlight,
|
"+Flashlight": mods.FLASHLIGHT,
|
||||||
"-SpunOut": mods.SpunOut
|
"-SpunOut": mods.SPUNOUT
|
||||||
}
|
}
|
||||||
|
|
||||||
if playWatch:
|
if playWatch:
|
||||||
|
@ -513,23 +515,23 @@ def tillerinoMods(fro, chan, message):
|
||||||
modsEnum = 0
|
modsEnum = 0
|
||||||
break
|
break
|
||||||
elif i == "NF":
|
elif i == "NF":
|
||||||
modsEnum += mods.NoFail
|
modsEnum += mods.NOFAIL
|
||||||
elif i == "EZ":
|
elif i == "EZ":
|
||||||
modsEnum += mods.Easy
|
modsEnum += mods.EASY
|
||||||
elif i == "HD":
|
elif i == "HD":
|
||||||
modsEnum += mods.Hidden
|
modsEnum += mods.HIDDEN
|
||||||
elif i == "HR":
|
elif i == "HR":
|
||||||
modsEnum += mods.HardRock
|
modsEnum += mods.HARDROCK
|
||||||
elif i == "DT":
|
elif i == "DT":
|
||||||
modsEnum += mods.DoubleTime
|
modsEnum += mods.DOUBLETIME
|
||||||
elif i == "HT":
|
elif i == "HT":
|
||||||
modsEnum += mods.HalfTime
|
modsEnum += mods.HALFTIME
|
||||||
elif i == "NC":
|
elif i == "NC":
|
||||||
modsEnum += mods.Nightcore
|
modsEnum += mods.NIGHTCORE
|
||||||
elif i == "FL":
|
elif i == "FL":
|
||||||
modsEnum += mods.Flashlight
|
modsEnum += mods.FLASHLIGHT
|
||||||
elif i == "SO":
|
elif i == "SO":
|
||||||
modsEnum += mods.SpunOut
|
modsEnum += mods.SPUNOUT
|
||||||
|
|
||||||
# Set mods
|
# Set mods
|
||||||
token.tillerino[1] = modsEnum
|
token.tillerino[1] = modsEnum
|
||||||
|
@ -582,22 +584,22 @@ def tillerinoLast(fro, chan, message):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
diffString = "difficulty_{}".format(gameModes.getGameModeForDB(data["play_mode"]))
|
diffString = "difficulty_{}".format(gameModes.getGameModeForDB(data["play_mode"]))
|
||||||
rank = generalFunctions.getRank(data["play_mode"], data["mods"], data["accuracy"],
|
rank = generalUtils.getRank(data["play_mode"], data["mods"], data["accuracy"],
|
||||||
data["300_count"], data["100_count"], data["50_count"], data["misses_count"])
|
data["300_count"], data["100_count"], data["50_count"], data["misses_count"])
|
||||||
|
|
||||||
ifPlayer = "{0} | ".format(fro) if chan != "FokaBot" else ""
|
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"])
|
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"])
|
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 = ifPlayer
|
||||||
msg += beatmapLink
|
msg += beatmapLink
|
||||||
if data["play_mode"] != gameModes.std:
|
if data["play_mode"] != gameModes.STD:
|
||||||
msg += " <{0}>".format(gameModes.getGameModeForPrinting(data["play_mode"]))
|
msg += " <{0}>".format(gameModes.getGameModeForPrinting(data["play_mode"]))
|
||||||
|
|
||||||
if data["mods"]:
|
if data["mods"]:
|
||||||
msg += ' +' + generalFunctions.readableMods(data["mods"])
|
msg += ' +' + generalUtils.readableMods(data["mods"])
|
||||||
|
|
||||||
if not hasPP:
|
if not hasPP:
|
||||||
msg += " | {0:,}".format(data["score"])
|
msg += " | {0:,}".format(data["score"])
|
||||||
|
@ -657,9 +659,9 @@ def pp(fro, chan, message):
|
||||||
return False
|
return False
|
||||||
if gameMode is None:
|
if gameMode is None:
|
||||||
gameMode = token.gameMode
|
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."
|
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)
|
return "You have {:,} pp".format(pp)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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"
|
|
|
@ -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
|
|
|
@ -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
|
|
|
@ -1,11 +1,11 @@
|
||||||
""" Contains functions used to write specific server packets to byte streams """
|
""" 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 constants import dataTypes
|
||||||
from helpers import userHelper
|
|
||||||
from objects import glob
|
|
||||||
from constants import userRanks
|
|
||||||
from constants import packetIDs
|
from constants import packetIDs
|
||||||
from constants import privileges
|
from constants import userRanks
|
||||||
|
from helpers import packetHelper
|
||||||
|
from objects import glob
|
||||||
|
|
||||||
""" Login errors packets """
|
""" Login errors packets """
|
||||||
def loginFailed():
|
def loginFailed():
|
||||||
|
@ -56,7 +56,7 @@ def userSupporterGMT(supporter, GMT):
|
||||||
return packetHelper.buildPacket(packetIDs.server_supporterGMT, [[result, dataTypes.UINT32]])
|
return packetHelper.buildPacket(packetIDs.server_supporterGMT, [[result, dataTypes.UINT32]])
|
||||||
|
|
||||||
def friendList(userID):
|
def friendList(userID):
|
||||||
friends = userHelper.getFriendList(userID)
|
friends = userUtils.getFriendList(userID)
|
||||||
return packetHelper.buildPacket(packetIDs.server_friendsList, [[friends, dataTypes.INT_LIST]])
|
return packetHelper.buildPacket(packetIDs.server_friendsList, [[friends, dataTypes.INT_LIST]])
|
||||||
|
|
||||||
def onlineUsers():
|
def onlineUsers():
|
||||||
|
@ -95,9 +95,9 @@ def userPanel(userID, force = False):
|
||||||
# Only admins and normal users are currently supported
|
# Only admins and normal users are currently supported
|
||||||
if username == "FokaBot":
|
if username == "FokaBot":
|
||||||
userRank = userRanks.MOD
|
userRank = userRanks.MOD
|
||||||
elif userHelper.isInPrivilegeGroup(userID, "community manager"):
|
elif userUtils.isInPrivilegeGroup(userID, "community manager"):
|
||||||
userRank = userRanks.MOD
|
userRank = userRanks.MOD
|
||||||
elif userHelper.isInPrivilegeGroup(userID, "developer"):
|
elif userUtils.isInPrivilegeGroup(userID, "developer"):
|
||||||
userRank = userRanks.ADMIN
|
userRank = userRanks.ADMIN
|
||||||
elif (userToken.privileges & privileges.USER_DONOR) > 0:
|
elif (userToken.privileges & privileges.USER_DONOR) > 0:
|
||||||
userRank = userRanks.SUPPORTER
|
userRank = userRanks.SUPPORTER
|
||||||
|
@ -150,7 +150,7 @@ def sendMessage(fro, to, message):
|
||||||
[fro, dataTypes.STRING],
|
[fro, dataTypes.STRING],
|
||||||
[message, dataTypes.STRING],
|
[message, dataTypes.STRING],
|
||||||
[to, dataTypes.STRING],
|
[to, dataTypes.STRING],
|
||||||
[userHelper.getID(fro), dataTypes.SINT32]
|
[userUtils.getID(fro), dataTypes.SINT32]
|
||||||
])
|
])
|
||||||
|
|
||||||
def channelJoinSuccess(userID, chan):
|
def channelJoinSuccess(userID, chan):
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
from objects import glob
|
from common.log import logUtils as log
|
||||||
from constants import serverPackets
|
|
||||||
from constants import exceptions
|
from constants import exceptions
|
||||||
from helpers import logHelper as log
|
from constants import serverPackets
|
||||||
|
from objects import glob
|
||||||
|
|
||||||
|
|
||||||
def handle(userToken, _):
|
def handle(userToken, _):
|
||||||
# get usertoken data
|
# get usertoken data
|
||||||
|
|
|
@ -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 clientPackets
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from helpers import userHelper
|
from objects import glob
|
||||||
from helpers import logHelper as log
|
|
||||||
from constants import actions
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Get usertoken data
|
# Get usertoken data
|
||||||
|
@ -11,13 +12,13 @@ def handle(userToken, packetData):
|
||||||
username = userToken.username
|
username = userToken.username
|
||||||
|
|
||||||
# Make sure we are not banned
|
# Make sure we are not banned
|
||||||
if userHelper.isBanned(userID):
|
if userUtils.isBanned(userID):
|
||||||
userToken.enqueue(serverPackets.loginBanned())
|
userToken.enqueue(serverPackets.loginBanned())
|
||||||
return
|
return
|
||||||
|
|
||||||
# Send restricted message if needed
|
# Send restricted message if needed
|
||||||
if not userToken.restricted:
|
if not userToken.restricted:
|
||||||
if userHelper.isRestricted(userID):
|
if userUtils.isRestricted(userID):
|
||||||
userToken.setRestricted()
|
userToken.setRestricted()
|
||||||
|
|
||||||
# Change action packet
|
# 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
|
# 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
|
# Always update game mode, or we'll cache stats from the wrong game mode if we've changed it
|
||||||
userToken.gameMode = packetData["gameMode"]
|
userToken.gameMode = packetData["gameMode"]
|
||||||
userToken.updateCachedStats()
|
userToken.updateCachedStats()
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
from objects import glob
|
from common.constants import mods
|
||||||
from constants import clientPackets
|
from constants import clientPackets
|
||||||
from constants import matchModModes
|
from constants import matchModModes
|
||||||
from constants import mods
|
from objects import glob
|
||||||
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Get token data
|
# Get token data
|
||||||
|
@ -22,13 +23,13 @@ def handle(userToken, packetData):
|
||||||
# Host can set global DT/HT
|
# Host can set global DT/HT
|
||||||
if userID == match.hostUserID:
|
if userID == match.hostUserID:
|
||||||
# If host has selected DT/HT and Freemod is enabled, set DT/HT as match mod
|
# If host has selected DT/HT and Freemod is enabled, set DT/HT as match mod
|
||||||
if (packetData["mods"] & mods.DoubleTime) > 0:
|
if (packetData["mods"] & mods.DOUBLETIME) > 0:
|
||||||
match.changeMatchMods(mods.DoubleTime)
|
match.changeMatchMods(mods.DOUBLETIME)
|
||||||
# Nightcore
|
# Nightcore
|
||||||
if (packetData["mods"] & mods.Nightcore) > 0:
|
if (packetData["mods"] & mods.NIGHTCORE) > 0:
|
||||||
match.changeMatchMods(match.mods+mods.Nightcore)
|
match.changeMatchMods(match.mods + mods.NIGHTCORE)
|
||||||
elif (packetData["mods"] & mods.HalfTime) > 0:
|
elif (packetData["mods"] & mods.HALFTIME) > 0:
|
||||||
match.changeMatchMods(mods.HalfTime)
|
match.changeMatchMods(mods.HALFTIME)
|
||||||
else:
|
else:
|
||||||
# No DT/HT, set global mods to 0 (we are in freemod mode)
|
# No DT/HT, set global mods to 0 (we are in freemod mode)
|
||||||
match.changeMatchMods(0)
|
match.changeMatchMods(0)
|
||||||
|
|
|
@ -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 clientPackets
|
||||||
from constants import matchModModes
|
from constants import matchModModes
|
||||||
import random
|
|
||||||
from constants import matchTeamTypes
|
from constants import matchTeamTypes
|
||||||
from constants import matchTeams
|
from constants import matchTeams
|
||||||
from constants import slotStatuses
|
from constants import slotStatuses
|
||||||
from helpers import logHelper as log
|
from objects import glob
|
||||||
from helpers import generalFunctions
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Read new settings
|
# Read new settings
|
||||||
|
@ -59,7 +61,7 @@ def handle(userToken, packetData):
|
||||||
# Update match settings
|
# Update match settings
|
||||||
match.inProgress = packetData["inProgress"]
|
match.inProgress = packetData["inProgress"]
|
||||||
if packetData["matchPassword"] != "":
|
if packetData["matchPassword"] != "":
|
||||||
match.matchPassword = generalFunctions.stringMd5(packetData["matchPassword"])
|
match.matchPassword = generalUtils.stringMd5(packetData["matchPassword"])
|
||||||
else:
|
else:
|
||||||
match.matchPassword = ""
|
match.matchPassword = ""
|
||||||
match.beatmapName = packetData["beatmapName"]
|
match.beatmapName = packetData["beatmapName"]
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
from constants import serverPackets
|
from common.log import logUtils as log
|
||||||
from constants import clientPackets
|
from constants import clientPackets
|
||||||
from objects import glob
|
|
||||||
from events import joinMatchEvent
|
|
||||||
from constants import exceptions
|
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):
|
def handle(userToken, packetData):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -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 constants import clientPackets
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Friend add packet
|
# Friend add packet
|
||||||
packetData = clientPackets.addRemoveFriend(packetData)
|
packetData = clientPackets.addRemoveFriend(packetData)
|
||||||
userHelper.addFriend(userToken.userID, packetData["friendID"])
|
userUtils.addFriend(userToken.userID, packetData["friendID"])
|
||||||
|
|
||||||
# Console output
|
# Console output
|
||||||
log.info("{} have added {} to their friends".format(userToken.username, str(packetData["friendID"])))
|
log.info("{} have added {} to their friends".format(userToken.username, str(packetData["friendID"])))
|
||||||
|
|
|
@ -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 constants import clientPackets
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Friend remove packet
|
# Friend remove packet
|
||||||
packetData = clientPackets.addRemoveFriend(packetData)
|
packetData = clientPackets.addRemoveFriend(packetData)
|
||||||
userHelper.removeFriend(userToken.userID, packetData["friendID"])
|
userUtils.removeFriend(userToken.userID, packetData["friendID"])
|
||||||
|
|
||||||
# Console output
|
# Console output
|
||||||
log.info("{} have removed {} from their friends".format(userToken.username, str(packetData["friendID"])))
|
log.info("{} have removed {} from their friends".format(userToken.username, str(packetData["friendID"])))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
from common.log import logUtils as log
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
def handle(userToken, _):
|
def handle(userToken, _):
|
||||||
# Get userToken data
|
# Get userToken data
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
from common import generalUtils
|
||||||
|
from common.log import logUtils as log
|
||||||
from constants import clientPackets
|
from constants import clientPackets
|
||||||
from constants import serverPackets
|
|
||||||
from objects import glob
|
|
||||||
from constants import exceptions
|
from constants import exceptions
|
||||||
from helpers import logHelper as log
|
from constants import serverPackets
|
||||||
from helpers import chatHelper as chat
|
from helpers import chatHelper as chat
|
||||||
from helpers import generalFunctions
|
from objects import glob
|
||||||
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# read packet data
|
# read packet data
|
||||||
|
@ -34,7 +35,7 @@ def joinMatch(userToken, matchID, password, isPasswordHashed = False):
|
||||||
|
|
||||||
# Hash password if needed
|
# Hash password if needed
|
||||||
if isPasswordHashed == False and password != "":
|
if isPasswordHashed == False and password != "":
|
||||||
password = generalFunctions.stringMd5(password)
|
password = generalUtils.stringMd5(password)
|
||||||
|
|
||||||
# Check password
|
# Check password
|
||||||
# TODO: Admins can enter every match
|
# TODO: Admins can enter every match
|
||||||
|
|
|
@ -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 sys
|
||||||
import traceback
|
|
||||||
from helpers import logHelper as log
|
|
||||||
from helpers import chatHelper as chat
|
|
||||||
from constants import privileges
|
|
||||||
import time
|
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):
|
def handle(tornadoRequest):
|
||||||
# Data to return
|
# Data to return
|
||||||
|
@ -51,24 +53,24 @@ def handle(tornadoRequest):
|
||||||
|
|
||||||
# Try to get the ID from username
|
# Try to get the ID from username
|
||||||
username = str(loginData[0])
|
username = str(loginData[0])
|
||||||
userID = userHelper.getID(username)
|
userID = userUtils.getID(username)
|
||||||
|
|
||||||
if not userID:
|
if not userID:
|
||||||
# Invalid username
|
# Invalid username
|
||||||
raise exceptions.loginFailedException()
|
raise exceptions.loginFailedException()
|
||||||
if not userHelper.checkLogin(userID, loginData[1]):
|
if not userUtils.checkLogin(userID, loginData[1]):
|
||||||
# Invalid password
|
# Invalid password
|
||||||
raise exceptions.loginFailedException()
|
raise exceptions.loginFailedException()
|
||||||
|
|
||||||
# Make sure we are not banned or locked
|
# Make sure we are not banned or locked
|
||||||
priv = userHelper.getPrivileges(userID)
|
priv = userUtils.getPrivileges(userID)
|
||||||
if userHelper.isBanned(userID) == True and priv & privileges.USER_PENDING_VERIFICATION == 0:
|
if userUtils.isBanned(userID) == True and priv & privileges.USER_PENDING_VERIFICATION == 0:
|
||||||
raise exceptions.loginBannedException()
|
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()
|
raise exceptions.loginLockedException()
|
||||||
|
|
||||||
# 2FA check
|
# 2FA check
|
||||||
if userHelper.check2FA(userID, requestIP):
|
if userUtils.check2FA(userID, requestIP):
|
||||||
log.warning("Need 2FA check for user {}".format(loginData[0]))
|
log.warning("Need 2FA check for user {}".format(loginData[0]))
|
||||||
raise exceptions.need2FAException()
|
raise exceptions.need2FAException()
|
||||||
|
|
||||||
|
@ -76,8 +78,8 @@ def handle(tornadoRequest):
|
||||||
|
|
||||||
# Verify this user (if pending activation)
|
# Verify this user (if pending activation)
|
||||||
firstLogin = False
|
firstLogin = False
|
||||||
if priv & privileges.USER_PENDING_VERIFICATION > 0 or userHelper.hasVerifiedHardware(userID) == False:
|
if priv & privileges.USER_PENDING_VERIFICATION > 0 or userUtils.hasVerifiedHardware(userID) == False:
|
||||||
if userHelper.verifyUser(userID, clientData):
|
if userUtils.verifyUser(userID, clientData):
|
||||||
# Valid account
|
# Valid account
|
||||||
log.info("Account {} verified successfully!".format(userID))
|
log.info("Account {} verified successfully!".format(userID))
|
||||||
glob.verifiedCache[str(userID)] = 1
|
glob.verifiedCache[str(userID)] = 1
|
||||||
|
@ -90,7 +92,7 @@ def handle(tornadoRequest):
|
||||||
|
|
||||||
|
|
||||||
# Save HWID in db for multiaccount detection
|
# 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
|
# This is false only if HWID is empty
|
||||||
# if HWID is banned, we get restricted so there's no
|
# if HWID is banned, we get restricted so there's no
|
||||||
|
@ -99,7 +101,7 @@ def handle(tornadoRequest):
|
||||||
raise exceptions.haxException()
|
raise exceptions.haxException()
|
||||||
|
|
||||||
# Log user IP
|
# Log user IP
|
||||||
userHelper.logIP(userID, requestIP)
|
userUtils.logIP(userID, requestIP)
|
||||||
|
|
||||||
# Delete old tokens for that user and generate a new one
|
# Delete old tokens for that user and generate a new one
|
||||||
glob.tokens.deleteOldTokens(userID)
|
glob.tokens.deleteOldTokens(userID)
|
||||||
|
@ -111,7 +113,7 @@ def handle(tornadoRequest):
|
||||||
|
|
||||||
# Send message if donor expires soon
|
# Send message if donor expires soon
|
||||||
if responseToken.privileges & privileges.USER_DONOR > 0:
|
if responseToken.privileges & privileges.USER_DONOR > 0:
|
||||||
expireDate = userHelper.getDonorExpire(responseToken.userID)
|
expireDate = userUtils.getDonorExpire(responseToken.userID)
|
||||||
if expireDate-int(time.time()) <= 86400*3:
|
if expireDate-int(time.time()) <= 86400*3:
|
||||||
expireDays = round((expireDate-int(time.time()))/86400)
|
expireDays = round((expireDate-int(time.time()))/86400)
|
||||||
expireIn = "{} days".format(expireDays) if expireDays > 1 else "less than 24 hours"
|
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
|
# Set silence end UNIX time in token
|
||||||
responseToken.silenceEndTime = userHelper.getSilenceEnd(userID)
|
responseToken.silenceEndTime = userUtils.getSilenceEnd(userID)
|
||||||
|
|
||||||
# Get only silence remaining seconds
|
# Get only silence remaining seconds
|
||||||
silenceSeconds = responseToken.getSilenceSecondsLeft()
|
silenceSeconds = responseToken.getSilenceSecondsLeft()
|
||||||
|
@ -193,15 +195,15 @@ def handle(tornadoRequest):
|
||||||
log.warning("Location skipped")
|
log.warning("Location skipped")
|
||||||
location = [0,0]
|
location = [0,0]
|
||||||
countryLetters = "XX"
|
countryLetters = "XX"
|
||||||
country = countryHelper.getCountryID(userHelper.getCountry(userID))
|
country = countryHelper.getCountryID(userUtils.getCountry(userID))
|
||||||
|
|
||||||
# Set location and country
|
# Set location and country
|
||||||
responseToken.setLocation(location)
|
responseToken.setLocation(location)
|
||||||
responseToken.setCountry(country)
|
responseToken.setCountry(country)
|
||||||
|
|
||||||
# Set country in db if user has no country (first bancho login)
|
# Set country in db if user has no country (first bancho login)
|
||||||
if userHelper.getCountry(userID) == "XX":
|
if userUtils.getCountry(userID) == "XX":
|
||||||
userHelper.setCountry(userID, countryLetters)
|
userUtils.setCountry(userID, countryLetters)
|
||||||
|
|
||||||
# Send to everyone our userpanel if we are not restricted
|
# Send to everyone our userpanel if we are not restricted
|
||||||
if not responseToken.restricted:
|
if not responseToken.restricted:
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from objects import glob
|
|
||||||
from constants import serverPackets
|
|
||||||
import time
|
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 helpers import chatHelper as chat
|
||||||
|
from objects import glob
|
||||||
|
|
||||||
|
|
||||||
def handle(userToken, _=None):
|
def handle(userToken, _=None):
|
||||||
# get usertoken data
|
# get usertoken data
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from objects import glob
|
from common.log import logUtils as log
|
||||||
from helpers import logHelper as log
|
|
||||||
from helpers import chatHelper as chat
|
from helpers import chatHelper as chat
|
||||||
|
from objects import glob
|
||||||
|
|
||||||
|
|
||||||
def handle(userToken, _):
|
def handle(userToken, _):
|
||||||
# Get usertoken data
|
# Get usertoken data
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Update cache and send new stats
|
# Update cache and send new stats
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
from common.log import logUtils as log
|
||||||
from constants import clientPackets
|
from constants import clientPackets
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# get token data
|
# get token data
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
from common.log import logUtils as log
|
||||||
|
from common.ripple import userUtils
|
||||||
from constants import clientPackets
|
from constants import clientPackets
|
||||||
from constants import serverPackets
|
|
||||||
from constants import exceptions
|
from constants import exceptions
|
||||||
from objects import glob
|
from constants import serverPackets
|
||||||
from helpers import userHelper
|
|
||||||
from helpers import logHelper as log
|
|
||||||
from helpers import chatHelper as chat
|
from helpers import chatHelper as chat
|
||||||
|
from objects import glob
|
||||||
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
try:
|
try:
|
||||||
|
@ -50,7 +51,7 @@ def handle(userToken, packetData):
|
||||||
c.enqueue(serverPackets.fellowSpectatorJoined(userID))
|
c.enqueue(serverPackets.fellowSpectatorJoined(userID))
|
||||||
|
|
||||||
# Console output
|
# 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:
|
except exceptions.tokenNotFoundException:
|
||||||
# Stop spectating if token not found
|
# Stop spectating if token not found
|
||||||
log.warning("Spectator start: token not found")
|
log.warning("Spectator start: token not found")
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
from common.log import logUtils as log
|
||||||
from constants import clientPackets
|
from constants import clientPackets
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Read userIDs list
|
# Read userIDs list
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
|
from common.log import logUtils as log
|
||||||
from constants import clientPackets
|
from constants import clientPackets
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Read userIDs list
|
# Read userIDs list
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
from helpers import requestHelper
|
|
||||||
from constants import exceptions
|
|
||||||
import json
|
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):
|
def asyncGet(self):
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data = {"message": "unknown error"}
|
||||||
try:
|
try:
|
||||||
# Check arguments
|
# 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()
|
raise exceptions.invalidArgumentsException()
|
||||||
|
|
||||||
# Check ci key
|
# Check ci key
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
from helpers import requestHelper
|
|
||||||
from constants import exceptions
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from common.web import requestsManager
|
||||||
|
from constants import exceptions
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
|
||||||
class handler(requestHelper.asyncRequestHandler):
|
|
||||||
|
class handler(requestsManager.asyncRequestHandler):
|
||||||
def asyncGet(self):
|
def asyncGet(self):
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data = {"message": "unknown error"}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from helpers import requestHelper
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from common.web import requestsManager
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
|
||||||
class handler(requestHelper.asyncRequestHandler):
|
|
||||||
|
class handler(requestsManager.asyncRequestHandler):
|
||||||
def asyncGet(self):
|
def asyncGet(self):
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data = {"message": "unknown error"}
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from helpers import requestHelper
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
from common.web import requestsManager
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
|
||||||
class handler(requestHelper.asyncRequestHandler):
|
|
||||||
|
class handler(requestsManager.asyncRequestHandler):
|
||||||
def asyncGet(self):
|
def asyncGet(self):
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data = {"message": "unknown error"}
|
||||||
|
|
|
@ -1,16 +1,17 @@
|
||||||
from helpers import requestHelper
|
|
||||||
from helpers import logHelper as log
|
|
||||||
import json
|
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):
|
def asyncGet(self):
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data = {"message": "unknown error"}
|
||||||
try:
|
try:
|
||||||
# Check arguments
|
# Check arguments
|
||||||
if not requestHelper.checkArguments(self.request.arguments, ["u"]):
|
if not requestsManager.checkArguments(self.request.arguments, ["u"]):
|
||||||
raise exceptions.invalidArgumentsException()
|
raise exceptions.invalidArgumentsException()
|
||||||
|
|
||||||
# Get userID and its verified cache thing
|
# Get userID and its verified cache thing
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
from helpers import requestHelper
|
|
||||||
from constants import exceptions
|
|
||||||
import json
|
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):
|
def asyncGet(self):
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data = {"message": "unknown error"}
|
||||||
try:
|
try:
|
||||||
# Check arguments
|
# Check arguments
|
||||||
if not requestHelper.checkArguments(self.request.arguments, ["k"]):
|
if not requestsManager.checkArguments(self.request.arguments, ["k"]):
|
||||||
raise exceptions.invalidArgumentsException()
|
raise exceptions.invalidArgumentsException()
|
||||||
|
|
||||||
# Check ci key
|
# Check ci key
|
||||||
|
|
|
@ -1,60 +1,61 @@
|
||||||
import datetime
|
import datetime
|
||||||
import gzip
|
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 sys
|
||||||
import traceback
|
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.web.asynchronous
|
||||||
@tornado.gen.engine
|
@tornado.gen.engine
|
||||||
def asyncPost(self):
|
def asyncPost(self):
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
from objects import glob
|
from common.log import logUtils as log
|
||||||
from helpers import logHelper as log
|
from common.ripple import userUtils
|
||||||
from constants import exceptions
|
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 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):
|
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)
|
# File and discord logs (public chat only)
|
||||||
if to.startswith("#"):
|
if to.startswith("#"):
|
||||||
log.chat("{fro} @ {to}: {message}".format(fro=username, to=to, message=str(message.encode("utf-8"))))
|
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
|
return 0
|
||||||
except exceptions.userSilencedException:
|
except exceptions.userSilencedException:
|
||||||
token.enqueue(serverPackets.silenceEndTime(token.getSilenceSecondsLeft()))
|
token.enqueue(serverPackets.silenceEndTime(token.getSilenceSecondsLeft()))
|
||||||
|
@ -314,7 +314,7 @@ def fixUsernameForIRC(username):
|
||||||
return username.replace(" ", "_")
|
return username.replace(" ", "_")
|
||||||
|
|
||||||
def IRCConnect(username):
|
def IRCConnect(username):
|
||||||
userID = userHelper.getID(username)
|
userID = userUtils.getID(username)
|
||||||
if not userID:
|
if not userID:
|
||||||
log.warning("{} doesn't exist".format(username))
|
log.warning("{} doesn't exist".format(username))
|
||||||
return
|
return
|
||||||
|
@ -332,7 +332,7 @@ def IRCDisconnect(username):
|
||||||
log.info("{} disconnected from IRC".format(username))
|
log.info("{} disconnected from IRC".format(username))
|
||||||
|
|
||||||
def IRCJoinChannel(username, channel):
|
def IRCJoinChannel(username, channel):
|
||||||
userID = userHelper.getID(username)
|
userID = userUtils.getID(username)
|
||||||
if not userID:
|
if not userID:
|
||||||
log.warning("{} doesn't exist".format(username))
|
log.warning("{} doesn't exist".format(username))
|
||||||
return
|
return
|
||||||
|
@ -342,7 +342,7 @@ def IRCJoinChannel(username, channel):
|
||||||
return joinChannel(userID, channel)
|
return joinChannel(userID, channel)
|
||||||
|
|
||||||
def IRCPartChannel(username, channel):
|
def IRCPartChannel(username, channel):
|
||||||
userID = userHelper.getID(username)
|
userID = userUtils.getID(username)
|
||||||
if not userID:
|
if not userID:
|
||||||
log.warning("{} doesn't exist".format(username))
|
log.warning("{} doesn't exist".format(username))
|
||||||
return
|
return
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
from constants import bcolors
|
from common.constants import bcolors
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
|
||||||
def printServerStartHeader(asciiArt):
|
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("> Welcome to pep.py osu!bancho server v{}".format(glob.VERSION), bcolors.GREEN)
|
||||||
printColored("> Made by the Ripple team", bcolors.GREEN)
|
printColored("> Made by the Ripple team", bcolors.GREEN)
|
||||||
printColored("> {}https://git.zxq.co/ripple/pep.py".format(bcolors.UNDERLINE), 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):
|
def printNoNl(string):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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)
|
|
|
@ -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())
|
|
|
@ -1,8 +1,9 @@
|
||||||
import urllib.request
|
|
||||||
import json
|
import json
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
from common.log import logUtils as log
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
def getCountry(ip):
|
def getCountry(ip):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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)
|
|
|
@ -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'))
|
|
|
@ -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)))
|
|
|
@ -1,15 +1,18 @@
|
||||||
from objects import glob
|
import math
|
||||||
from constants import serverPackets
|
|
||||||
from helpers import consoleHelper
|
|
||||||
import psutil
|
|
||||||
import os
|
import os
|
||||||
|
import signal
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
import signal
|
|
||||||
from helpers import logHelper as log
|
|
||||||
from constants import bcolors
|
|
||||||
import time
|
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():
|
def dispose():
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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
|
|
|
@ -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.
|
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.
|
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
|
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
|
import raven
|
||||||
|
|
||||||
|
from common.log import logUtils as log
|
||||||
|
from helpers import chatHelper as chat
|
||||||
|
from objects import glob
|
||||||
|
|
||||||
|
|
||||||
class Client:
|
class Client:
|
||||||
"""
|
"""
|
||||||
IRC Client object
|
IRC Client object
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# TODO: Rewrite this shit
|
# TODO: Rewrite this shit
|
||||||
|
from common import generalUtils
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from helpers import generalFunctions
|
|
||||||
|
|
||||||
class banchoConfig:
|
class banchoConfig:
|
||||||
"""
|
"""
|
||||||
|
@ -26,8 +27,8 @@ class banchoConfig:
|
||||||
"""
|
"""
|
||||||
(re)load bancho_settings from DB and set values in config array
|
(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["banchoMaintenance"] = generalUtils.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["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["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"]
|
self.config["loginNotification"] = glob.db.fetch("SELECT value_string FROM bancho_settings WHERE name = 'login_notification'")["value_string"]
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from objects import glob
|
from common.log import logUtils as log
|
||||||
from objects import channel
|
from objects import channel
|
||||||
from helpers import logHelper as log
|
from objects import glob
|
||||||
|
|
||||||
|
|
||||||
class channelList:
|
class channelList:
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -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()
|
|
|
@ -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()
|
|
|
@ -1,11 +1,12 @@
|
||||||
"""FokaBot related functions"""
|
"""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
|
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
|
# Tillerino np regex, compiled only once to increase performance
|
||||||
npRegex = re.compile("^https?:\\/\\/osu\\.ppy\\.sh\\/b\\/(\\d*)")
|
npRegex = re.compile("^https?:\\/\\/osu\\.ppy\\.sh\\/b\\/(\\d*)")
|
||||||
|
@ -34,13 +35,13 @@ def fokabotResponse(fro, chan, message):
|
||||||
for i in fokabotCommands.commands:
|
for i in fokabotCommands.commands:
|
||||||
# Loop though all commands
|
# Loop though all commands
|
||||||
#if i["trigger"] in message:
|
#if i["trigger"] in message:
|
||||||
if generalFunctions.strContains(message, i["trigger"]):
|
if generalUtils.strContains(message, i["trigger"]):
|
||||||
# message has triggered a command
|
# message has triggered a command
|
||||||
|
|
||||||
# Make sure the user has right permissions
|
# Make sure the user has right permissions
|
||||||
if i["privileges"] is not None:
|
if i["privileges"] is not None:
|
||||||
# Rank = x
|
# Rank = x
|
||||||
if userHelper.getPrivileges(userHelper.getID(fro)) & i["privileges"] == 0:
|
if userUtils.getPrivileges(userUtils.getID(fro)) & i["privileges"] == 0:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Check argument number
|
# Check argument number
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
"""Global objects and variables"""
|
"""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 channelList
|
||||||
from objects import matchList
|
from objects import matchList
|
||||||
from objects import fileLocks
|
|
||||||
from objects import fileBuffer
|
|
||||||
from objects import streamList
|
from objects import streamList
|
||||||
import time
|
from objects import tokenList
|
||||||
|
from common.web import schiavo
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open("version") as f:
|
with open("version") as f:
|
||||||
|
@ -16,6 +18,7 @@ try:
|
||||||
except:
|
except:
|
||||||
VERSION = "¯\_(xd)_/¯"
|
VERSION = "¯\_(xd)_/¯"
|
||||||
|
|
||||||
|
DATADOG_PREFIX = "peppy"
|
||||||
application = None
|
application = None
|
||||||
db = None
|
db = None
|
||||||
conf = None
|
conf = None
|
||||||
|
@ -26,6 +29,8 @@ matches = matchList.matchList()
|
||||||
restarting = False
|
restarting = False
|
||||||
fLocks = fileLocks.fileLocks()
|
fLocks = fileLocks.fileLocks()
|
||||||
fileBuffers = fileBuffer.buffersList()
|
fileBuffers = fileBuffer.buffersList()
|
||||||
|
schiavo = schiavo.schiavo()
|
||||||
|
dog = datadogClient.datadogClient()
|
||||||
verifiedCache = {}
|
verifiedCache = {}
|
||||||
cloudflare = False
|
cloudflare = False
|
||||||
chatFilters = None
|
chatFilters = None
|
||||||
|
@ -36,7 +41,6 @@ busyThreads = 0
|
||||||
debug = False
|
debug = False
|
||||||
outputRequestTime = False
|
outputRequestTime = False
|
||||||
outputPackets = False
|
outputPackets = False
|
||||||
discord = False
|
|
||||||
gzip = False
|
gzip = False
|
||||||
localize = False
|
localize = False
|
||||||
sentry = False
|
sentry = False
|
||||||
|
|
|
@ -1,17 +1,19 @@
|
||||||
# TODO: Enqueue all
|
# 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 matchScoringTypes
|
||||||
from constants import matchTeamTypes
|
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 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 chatHelper as chat
|
||||||
from helpers import generalFunctions
|
from objects import glob
|
||||||
import copy
|
|
||||||
|
|
||||||
class slot:
|
class slot:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
|
@ -35,7 +37,7 @@ class match:
|
||||||
beatmapMD5 = ""
|
beatmapMD5 = ""
|
||||||
slots = []
|
slots = []
|
||||||
hostUserID = 0
|
hostUserID = 0
|
||||||
gameMode = gameModes.std
|
gameMode = gameModes.STD
|
||||||
matchScoringType = matchScoringTypes.score
|
matchScoringType = matchScoringTypes.score
|
||||||
matchTeamType = matchTeamTypes.headToHead
|
matchTeamType = matchTeamTypes.headToHead
|
||||||
matchModMode = matchModModes.normal
|
matchModMode = matchModModes.normal
|
||||||
|
@ -59,7 +61,7 @@ class match:
|
||||||
self.mods = 0
|
self.mods = 0
|
||||||
self.matchName = matchName
|
self.matchName = matchName
|
||||||
if matchPassword != "":
|
if matchPassword != "":
|
||||||
self.matchPassword = generalFunctions.stringMd5(matchPassword)
|
self.matchPassword = generalUtils.stringMd5(matchPassword)
|
||||||
else:
|
else:
|
||||||
self.matchPassword = ""
|
self.matchPassword = ""
|
||||||
self.beatmapID = beatmapID
|
self.beatmapID = beatmapID
|
||||||
|
@ -487,7 +489,7 @@ class match:
|
||||||
newPassword -- new password string
|
newPassword -- new password string
|
||||||
"""
|
"""
|
||||||
if newPassword != "":
|
if newPassword != "":
|
||||||
self.matchPassword = generalFunctions.stringMd5(newPassword)
|
self.matchPassword = generalUtils.stringMd5(newPassword)
|
||||||
else:
|
else:
|
||||||
self.matchPassword = ""
|
self.matchPassword = ""
|
||||||
|
|
||||||
|
|
|
@ -1,14 +1,15 @@
|
||||||
from constants import actions
|
import threading
|
||||||
from constants import gameModes
|
import time
|
||||||
from helpers import userHelper
|
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 constants import serverPackets
|
||||||
from events import logoutEvent
|
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 helpers import chatHelper as chat
|
||||||
|
from objects import glob
|
||||||
|
|
||||||
|
|
||||||
class token:
|
class token:
|
||||||
|
|
||||||
|
@ -25,11 +26,11 @@ class token:
|
||||||
"""
|
"""
|
||||||
# Set stuff
|
# Set stuff
|
||||||
self.userID = userID
|
self.userID = userID
|
||||||
self.username = userHelper.getUsername(self.userID)
|
self.username = userUtils.getUsername(self.userID)
|
||||||
self.privileges = userHelper.getPrivileges(self.userID)
|
self.privileges = userUtils.getPrivileges(self.userID)
|
||||||
self.admin = userHelper.isInPrivilegeGroup(self.userID, "developer") or userHelper.isInPrivilegeGroup(self.userID, "community manager")
|
self.admin = userUtils.isInPrivilegeGroup(self.userID, "developer") or userUtils.isInPrivilegeGroup(self.userID, "community manager")
|
||||||
self.irc = irc
|
self.irc = irc
|
||||||
self.restricted = userHelper.isRestricted(self.userID)
|
self.restricted = userUtils.isRestricted(self.userID)
|
||||||
self.loginTime = int(time.time())
|
self.loginTime = int(time.time())
|
||||||
self.pingTime = self.loginTime
|
self.pingTime = self.loginTime
|
||||||
self.timeOffset = timeOffset
|
self.timeOffset = timeOffset
|
||||||
|
@ -58,7 +59,7 @@ class token:
|
||||||
self.actionText = ""
|
self.actionText = ""
|
||||||
self.actionMd5 = ""
|
self.actionMd5 = ""
|
||||||
self.actionMods = 0
|
self.actionMods = 0
|
||||||
self.gameMode = gameModes.std
|
self.gameMode = gameModes.STD
|
||||||
self.beatmapID = 0
|
self.beatmapID = 0
|
||||||
self.rankedScore = 0
|
self.rankedScore = 0
|
||||||
self.accuracy = 0.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 we have a valid ip, save bancho session in DB so we can cache LETS logins
|
||||||
if ip != "":
|
if ip != "":
|
||||||
userHelper.saveBanchoSession(self.userID, self.ip)
|
userUtils.saveBanchoSession(self.userID, self.ip)
|
||||||
|
|
||||||
# Join main stream
|
# Join main stream
|
||||||
self.joinStream("main")
|
self.joinStream("main")
|
||||||
|
@ -275,7 +276,7 @@ class token:
|
||||||
"""
|
"""
|
||||||
# Silence in db and token
|
# Silence in db and token
|
||||||
self.silenceEndTime = int(time.time())+seconds
|
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
|
# Send silence packet to target
|
||||||
self.enqueue(serverPackets.silenceEndTime(seconds))
|
self.enqueue(serverPackets.silenceEndTime(seconds))
|
||||||
|
@ -316,7 +317,7 @@ class token:
|
||||||
|
|
||||||
def updateCachedStats(self):
|
def updateCachedStats(self):
|
||||||
"""Update all cached stats for this token"""
|
"""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))
|
log.debug(str(stats))
|
||||||
if stats is None:
|
if stats is None:
|
||||||
log.warning("Stats query returned None")
|
log.warning("Stats query returned None")
|
||||||
|
@ -336,7 +337,7 @@ class token:
|
||||||
If false, get the cached one. Optional. Default: False
|
If false, get the cached one. Optional. Default: False
|
||||||
"""
|
"""
|
||||||
if force:
|
if force:
|
||||||
self.restricted = userHelper.isRestricted(self.userID)
|
self.restricted = userUtils.isRestricted(self.userID)
|
||||||
if self.restricted:
|
if self.restricted:
|
||||||
self.setRestricted()
|
self.setRestricted()
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
from objects import osuToken
|
|
||||||
from objects import glob
|
|
||||||
import time
|
|
||||||
import threading
|
import threading
|
||||||
|
import time
|
||||||
|
|
||||||
|
from common.ripple import userUtils
|
||||||
from events import logoutEvent
|
from events import logoutEvent
|
||||||
from helpers import userHelper
|
from objects import glob
|
||||||
|
from objects import osuToken
|
||||||
|
|
||||||
|
|
||||||
class tokenList:
|
class tokenList:
|
||||||
"""
|
"""
|
||||||
|
@ -39,7 +41,7 @@ class tokenList:
|
||||||
if token in self.tokens:
|
if token in self.tokens:
|
||||||
# Delete session from DB
|
# Delete session from DB
|
||||||
if self.tokens[token].ip != "":
|
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
|
# Pop token from list
|
||||||
self.tokens.pop(token)
|
self.tokens.pop(token)
|
||||||
|
|
64
pep.py
64
pep.py
|
@ -2,39 +2,36 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import threading
|
import threading
|
||||||
|
from multiprocessing.pool import ThreadPool
|
||||||
|
|
||||||
import tornado.gen
|
import tornado.gen
|
||||||
import tornado.httpserver
|
import tornado.httpserver
|
||||||
import tornado.ioloop
|
import tornado.ioloop
|
||||||
import tornado.web
|
import tornado.web
|
||||||
from multiprocessing.pool import ThreadPool
|
|
||||||
|
|
||||||
# Raven
|
|
||||||
from raven.contrib.tornado import AsyncSentryClient
|
from raven.contrib.tornado import AsyncSentryClient
|
||||||
|
|
||||||
# pep.py files
|
from common import generalUtils
|
||||||
from constants import bcolors
|
from common.constants import bcolors
|
||||||
from helpers import configHelper
|
from common.db import dbConnector
|
||||||
from objects import glob
|
from common.log import logUtils as log
|
||||||
from objects import fokabot
|
from common.ripple import userUtils
|
||||||
from objects import banchoConfig
|
from common.web import schiavo
|
||||||
from objects import chatFilters
|
from handlers import apiFokabotMessageHandler
|
||||||
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 handlers import apiIsOnlineHandler
|
from handlers import apiIsOnlineHandler
|
||||||
from handlers import apiOnlineUsersHandler
|
from handlers import apiOnlineUsersHandler
|
||||||
from handlers import apiServerStatusHandler
|
from handlers import apiServerStatusHandler
|
||||||
from handlers import ciTriggerHandler
|
|
||||||
from handlers import apiVerifiedStatusHandler
|
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 irc import ircserver
|
||||||
|
from objects import banchoConfig
|
||||||
|
from objects import chatFilters
|
||||||
|
from objects import fokabot
|
||||||
|
from objects import glob
|
||||||
|
|
||||||
|
|
||||||
def make_app():
|
def make_app():
|
||||||
return tornado.web.Application([
|
return tornado.web.Application([
|
||||||
|
@ -83,7 +80,7 @@ if __name__ == "__main__":
|
||||||
# Connect to db
|
# Connect to db
|
||||||
try:
|
try:
|
||||||
consoleHelper.printNoNl("> Connecting to MySQL database...")
|
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.printNoNl(" ")
|
||||||
consoleHelper.printDone()
|
consoleHelper.printDone()
|
||||||
except:
|
except:
|
||||||
|
@ -152,29 +149,30 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
# Cache user ids
|
# Cache user ids
|
||||||
consoleHelper.printNoNl("> Caching user IDs... ")
|
consoleHelper.printNoNl("> Caching user IDs... ")
|
||||||
userHelper.cacheUserIDs()
|
userUtils.cacheUserIDs()
|
||||||
consoleHelper.printDone()
|
consoleHelper.printDone()
|
||||||
|
|
||||||
# Localize warning
|
# Localize warning
|
||||||
glob.localize = generalFunctions.stringToBool(glob.conf.config["localize"]["enable"])
|
glob.localize = generalUtils.stringToBool(glob.conf.config["localize"]["enable"])
|
||||||
if not glob.localize:
|
if not glob.localize:
|
||||||
consoleHelper.printColored("[!] Warning! Users localization is disabled!", bcolors.YELLOW)
|
consoleHelper.printColored("[!] Warning! Users localization is disabled!", bcolors.YELLOW)
|
||||||
|
|
||||||
# Discord
|
# Discord
|
||||||
glob.discord = generalFunctions.stringToBool(glob.conf.config["discord"]["enable"])
|
if generalUtils.stringToBool(glob.conf.config["discord"]["enable"]):
|
||||||
if not glob.discord:
|
glob.schiavo = schiavo.schiavo(glob.conf.config["discord"]["boturl"])
|
||||||
|
else:
|
||||||
consoleHelper.printColored("[!] Warning! Discord logging is disabled!", bcolors.YELLOW)
|
consoleHelper.printColored("[!] Warning! Discord logging is disabled!", bcolors.YELLOW)
|
||||||
|
|
||||||
# Gzip
|
# 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"])
|
glob.gziplevel = int(glob.conf.config["server"]["gziplevel"])
|
||||||
if not glob.gzip:
|
if not glob.gzip:
|
||||||
consoleHelper.printColored("[!] Warning! Gzip compression is disabled!", bcolors.YELLOW)
|
consoleHelper.printColored("[!] Warning! Gzip compression is disabled!", bcolors.YELLOW)
|
||||||
|
|
||||||
# Debug mode
|
# Debug mode
|
||||||
glob.debug = generalFunctions.stringToBool(glob.conf.config["debug"]["enable"])
|
glob.debug = generalUtils.stringToBool(glob.conf.config["debug"]["enable"])
|
||||||
glob.outputPackets = generalFunctions.stringToBool(glob.conf.config["debug"]["packets"])
|
glob.outputPackets = generalUtils.stringToBool(glob.conf.config["debug"]["packets"])
|
||||||
glob.outputRequestTime = generalFunctions.stringToBool(glob.conf.config["debug"]["time"])
|
glob.outputRequestTime = generalUtils.stringToBool(glob.conf.config["debug"]["time"])
|
||||||
if glob.debug:
|
if glob.debug:
|
||||||
consoleHelper.printColored("[!] Warning! Server running in debug mode!", bcolors.YELLOW)
|
consoleHelper.printColored("[!] Warning! Server running in debug mode!", bcolors.YELLOW)
|
||||||
|
|
||||||
|
@ -183,7 +181,7 @@ if __name__ == "__main__":
|
||||||
|
|
||||||
# Set up sentry
|
# Set up sentry
|
||||||
try:
|
try:
|
||||||
glob.sentry = generalFunctions.stringToBool(glob.conf.config["sentry"]["enable"])
|
glob.sentry = generalUtils.stringToBool(glob.conf.config["sentry"]["enable"])
|
||||||
if glob.sentry:
|
if glob.sentry:
|
||||||
glob.application.sentry_client = AsyncSentryClient(glob.conf.config["sentry"]["banchodns"], release=glob.VERSION)
|
glob.application.sentry_client = AsyncSentryClient(glob.conf.config["sentry"]["banchodns"], release=glob.VERSION)
|
||||||
else:
|
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)
|
consoleHelper.printColored("[!] Error while starting sentry client! Please check your config.ini and run the server again", bcolors.RED)
|
||||||
|
|
||||||
# Cloudflare memes
|
# 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
|
# 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:
|
if glob.irc:
|
||||||
# IRC port
|
# IRC port
|
||||||
try:
|
try:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user