IRC Support for username with spaces
BATs with Donor have bright yellow username in chat General performance improvements Code cleaning Multiplayer improvements and fixes Fixed some spectator bugs
This commit is contained in:
@@ -147,9 +147,6 @@ def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = Fal
|
||||
log.warning("User not connected to IRC/Bancho")
|
||||
return 442 # idk
|
||||
|
||||
|
||||
|
||||
|
||||
def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||
"""
|
||||
Send a message to osu!bancho and IRC server
|
||||
@@ -299,8 +296,13 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||
return 401
|
||||
|
||||
|
||||
|
||||
""" IRC-Bancho Connect/Disconnect/Join/Part interfaces"""
|
||||
def fixUsernameForBancho(username):
|
||||
return username.replace("_", " ")
|
||||
|
||||
def fixUsernameForIRC(username):
|
||||
return username.replace(" ", "_")
|
||||
|
||||
def IRCConnect(username):
|
||||
userID = userHelper.getID(username)
|
||||
if userID == False:
|
||||
|
@@ -1,18 +1,7 @@
|
||||
import os
|
||||
import configparser
|
||||
|
||||
class config:
|
||||
"""
|
||||
config.ini object
|
||||
|
||||
config -- list with ini data
|
||||
default -- if true, we have generated a default config.ini
|
||||
"""
|
||||
|
||||
config = configparser.ConfigParser()
|
||||
fileName = "" # config filename
|
||||
default = True
|
||||
|
||||
class config():
|
||||
# Check if config.ini exists and load/generate it
|
||||
def __init__(self, file):
|
||||
"""
|
||||
@@ -20,7 +9,8 @@ class config:
|
||||
|
||||
file -- filename
|
||||
"""
|
||||
|
||||
self.config = configparser.ConfigParser()
|
||||
self.default = True
|
||||
self.fileName = file
|
||||
if os.path.isfile(self.fileName):
|
||||
# config.ini found, load it
|
||||
@@ -39,7 +29,6 @@ class config:
|
||||
|
||||
return -- True if valid, False if not
|
||||
"""
|
||||
|
||||
try:
|
||||
# Try to get all the required keys
|
||||
self.config.get("db","host")
|
||||
@@ -75,11 +64,10 @@ class config:
|
||||
except:
|
||||
return False
|
||||
|
||||
|
||||
# Generate a default config.ini
|
||||
def generateDefaultConfig(self):
|
||||
"""Open and set default keys for that config file"""
|
||||
|
||||
"""
|
||||
Open and set default keys for that config file
|
||||
"""
|
||||
# Open config.ini in write mode
|
||||
f = open(self.fileName, "w")
|
||||
|
||||
|
@@ -1,13 +1,12 @@
|
||||
"""Some console related functions"""
|
||||
|
||||
from constants import bcolors
|
||||
from objects import glob
|
||||
|
||||
def printServerStartHeader(asciiArt):
|
||||
"""Print server start header with optional ascii art
|
||||
|
||||
asciiArt -- if True, will print ascii art too"""
|
||||
"""
|
||||
Print server start header with optional ascii art
|
||||
|
||||
asciiArt -- if True, will print ascii art too
|
||||
"""
|
||||
if asciiArt == True:
|
||||
print("{} _ __".format(bcolors.GREEN))
|
||||
print(" (_) / /")
|
||||
@@ -28,20 +27,17 @@ def printServerStartHeader(asciiArt):
|
||||
|
||||
printColored("> Welcome to pep.py osu!bancho server v{}".format(glob.VERSION), bcolors.GREEN)
|
||||
printColored("> Made by the Ripple team", bcolors.GREEN)
|
||||
printColored("> {}https://github.com/osuripple/ripple".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)
|
||||
|
||||
|
||||
def printNoNl(string):
|
||||
"""
|
||||
Print string without new line at the end
|
||||
|
||||
string -- string to print
|
||||
"""
|
||||
|
||||
print(string, end="")
|
||||
|
||||
|
||||
def printColored(string, color):
|
||||
"""
|
||||
Print colored string
|
||||
@@ -49,23 +45,22 @@ def printColored(string, color):
|
||||
string -- string to print
|
||||
color -- see bcolors.py
|
||||
"""
|
||||
|
||||
print("{}{}{}".format(color, string, bcolors.ENDC))
|
||||
|
||||
|
||||
def printError():
|
||||
"""Print error text FOR LOADING"""
|
||||
|
||||
"""
|
||||
Print error text FOR LOADING
|
||||
"""
|
||||
printColored("Error", bcolors.RED)
|
||||
|
||||
|
||||
def printDone():
|
||||
"""Print error text FOR LOADING"""
|
||||
|
||||
"""
|
||||
Print error text FOR LOADING
|
||||
"""
|
||||
printColored("Done", bcolors.GREEN)
|
||||
|
||||
|
||||
def printWarning():
|
||||
"""Print error text FOR LOADING"""
|
||||
|
||||
"""
|
||||
Print error text FOR LOADING
|
||||
"""
|
||||
printColored("Warning", bcolors.YELLOW)
|
||||
|
@@ -253,7 +253,6 @@ countryCodes = {
|
||||
"AI": 7
|
||||
}
|
||||
|
||||
|
||||
def getCountryID(code):
|
||||
"""
|
||||
Get country ID for osu client
|
||||
|
@@ -2,13 +2,13 @@ import MySQLdb
|
||||
import threading
|
||||
from helpers import logHelper as log
|
||||
|
||||
class mysqlWorker:
|
||||
class mysqlWorker():
|
||||
"""
|
||||
Instance of a pettirosso meme
|
||||
Instance of a mysql worker
|
||||
"""
|
||||
def __init__(self, wid, host, username, password, database):
|
||||
"""
|
||||
Create a pettirosso meme (mysql worker)
|
||||
Create a mysql worker
|
||||
|
||||
wid -- worker id
|
||||
host -- hostname
|
||||
@@ -22,11 +22,10 @@ class mysqlWorker:
|
||||
self.ready = True
|
||||
self.lock = threading.Lock()
|
||||
|
||||
class db:
|
||||
class db():
|
||||
"""
|
||||
A MySQL db connection with multiple workers
|
||||
"""
|
||||
|
||||
def __init__(self, host, username, password, database, workers):
|
||||
"""
|
||||
Create MySQL workers aka pettirossi meme
|
||||
@@ -37,9 +36,6 @@ class db:
|
||||
database -- MySQL database name
|
||||
workers -- Number of workers to spawn
|
||||
"""
|
||||
#self.lock = threading.Lock()
|
||||
#self.connection = MySQLdb.connect(host, username, password, database)
|
||||
|
||||
self.workers = []
|
||||
self.lastWorker = 0
|
||||
self.workersNumber = workers
|
||||
@@ -57,7 +53,6 @@ class db:
|
||||
self.lastWorker = 0
|
||||
else:
|
||||
self.lastWorker += 1
|
||||
#print("Using worker {}".format(self.lastWorker))
|
||||
return self.workers[self.lastWorker]
|
||||
|
||||
def execute(self, query, params = ()):
|
||||
|
@@ -1,9 +1,6 @@
|
||||
import requests
|
||||
from objects import glob
|
||||
from helpers import generalFunctions
|
||||
from urllib.parse import urlencode
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
|
||||
def sendDiscordMessage(channel, message, alertDev = False, prefix = "**pep.py**"):
|
||||
"""
|
||||
@@ -24,7 +21,6 @@ def sendDiscordMessage(channel, message, alertDev = False, prefix = "**pep.py**"
|
||||
except:
|
||||
continue
|
||||
|
||||
|
||||
def sendConfidential(message, alertDev = False):
|
||||
"""
|
||||
Send a message to #bunker
|
||||
@@ -33,7 +29,6 @@ def sendConfidential(message, alertDev = False):
|
||||
"""
|
||||
sendDiscordMessage("bunk", message, alertDev)
|
||||
|
||||
|
||||
def sendStaff(message):
|
||||
"""
|
||||
Send a message to #staff
|
||||
@@ -42,7 +37,6 @@ def sendStaff(message):
|
||||
"""
|
||||
sendDiscordMessage("staff", message)
|
||||
|
||||
|
||||
def sendGeneral(message):
|
||||
"""
|
||||
Send a message to #general
|
||||
@@ -51,7 +45,6 @@ def sendGeneral(message):
|
||||
"""
|
||||
sendDiscordMessage("general", message)
|
||||
|
||||
|
||||
def sendChatlog(message):
|
||||
"""
|
||||
Send a message to #chatlog
|
||||
|
@@ -1,6 +1,17 @@
|
||||
"""Some functions that don't fit in any other file"""
|
||||
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):
|
||||
"""
|
||||
@@ -9,10 +20,8 @@ def stringToBool(s):
|
||||
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
|
||||
@@ -20,7 +29,6 @@ def hexString(s):
|
||||
s -- string
|
||||
return -- string with hex value
|
||||
"""
|
||||
|
||||
return ":".join("{:02x}".format(ord(str(c))) for c in s)
|
||||
|
||||
def readableMods(__mods):
|
||||
|
@@ -11,7 +11,6 @@ def getCountry(ip):
|
||||
ip -- IP Address
|
||||
return -- Country code (2 letters)
|
||||
"""
|
||||
|
||||
try:
|
||||
# Try to get country from Pikolo Aul's Go-Sanic ip API
|
||||
result = json.loads(urllib.request.urlopen("{}/{}".format(glob.conf.config["localize"]["ipapiurl"], ip), timeout=3).read().decode())["country"]
|
||||
@@ -20,7 +19,6 @@ def getCountry(ip):
|
||||
log.error("Error in get country")
|
||||
return "XX"
|
||||
|
||||
|
||||
def getLocation(ip):
|
||||
"""
|
||||
Get latitude and longitude from IP address
|
||||
@@ -28,7 +26,6 @@ def getLocation(ip):
|
||||
ip -- IP address
|
||||
return -- [latitude, longitude]
|
||||
"""
|
||||
|
||||
try:
|
||||
# Try to get position from Pikolo Aul's Go-Sanic ip API
|
||||
result = json.loads(urllib.request.urlopen("{}/{}".format(glob.conf.config["localize"]["ipapiurl"], ip), timeout=3).read().decode())["loc"].split(",")
|
||||
|
@@ -8,7 +8,6 @@ def uleb128Encode(num):
|
||||
num -- int to encode
|
||||
return -- bytearray with encoded number
|
||||
"""
|
||||
|
||||
arr = bytearray()
|
||||
length = 0
|
||||
|
||||
@@ -24,7 +23,6 @@ def uleb128Encode(num):
|
||||
|
||||
return arr
|
||||
|
||||
|
||||
def uleb128Decode(num):
|
||||
"""
|
||||
Decode uleb128 -> int
|
||||
@@ -32,9 +30,7 @@ def uleb128Decode(num):
|
||||
num -- encoded uleb128
|
||||
return -- list. [total, length]
|
||||
"""
|
||||
|
||||
shift = 0
|
||||
|
||||
arr = [0,0] #total, length
|
||||
|
||||
while True:
|
||||
@@ -47,42 +43,40 @@ def uleb128Decode(num):
|
||||
|
||||
return arr
|
||||
|
||||
|
||||
def unpackData(__data, __dataType):
|
||||
def unpackData(data, dataType):
|
||||
"""
|
||||
Unpacks data according to dataType
|
||||
|
||||
__data -- bytes array to unpack
|
||||
__dataType -- data type. See dataTypes.py
|
||||
data -- bytes array to unpack
|
||||
dataType -- data type. See dataTypes.py
|
||||
|
||||
return -- unpacked bytes
|
||||
"""
|
||||
|
||||
# Get right pack Type
|
||||
if __dataType == dataTypes.uInt16:
|
||||
if dataType == dataTypes.uInt16:
|
||||
unpackType = "<H"
|
||||
elif __dataType == dataTypes.sInt16:
|
||||
elif dataType == dataTypes.sInt16:
|
||||
unpackType = "<h"
|
||||
elif __dataType == dataTypes.uInt32:
|
||||
elif dataType == dataTypes.uInt32:
|
||||
unpackType = "<L"
|
||||
elif __dataType == dataTypes.sInt32:
|
||||
elif dataType == dataTypes.sInt32:
|
||||
unpackType = "<l"
|
||||
elif __dataType == dataTypes.uInt64:
|
||||
elif dataType == dataTypes.uInt64:
|
||||
unpackType = "<Q"
|
||||
elif __dataType == dataTypes.sInt64:
|
||||
elif dataType == dataTypes.sInt64:
|
||||
unpackType = "<q"
|
||||
elif __dataType == dataTypes.string:
|
||||
elif dataType == dataTypes.string:
|
||||
unpackType = "<s"
|
||||
elif __dataType == dataTypes.ffloat:
|
||||
elif dataType == dataTypes.ffloat:
|
||||
unpackType = "<f"
|
||||
else:
|
||||
unpackType = "<B"
|
||||
|
||||
# Unpack
|
||||
return struct.unpack(unpackType, bytes(__data))[0]
|
||||
return struct.unpack(unpackType, bytes(data))[0]
|
||||
|
||||
|
||||
def packData(__data, __dataType):
|
||||
def packData(__data, dataType):
|
||||
"""
|
||||
Packs data according to dataType
|
||||
|
||||
@@ -96,11 +90,11 @@ def packData(__data, __dataType):
|
||||
pack = True # if True, use pack. False only with strings
|
||||
|
||||
# Get right pack Type
|
||||
if __dataType == dataTypes.bbytes:
|
||||
if dataType == dataTypes.bbytes:
|
||||
# Bytes, do not use pack, do manually
|
||||
pack = False
|
||||
data = __data
|
||||
elif __dataType == dataTypes.intList:
|
||||
elif dataType == dataTypes.intList:
|
||||
# Pack manually
|
||||
pack = False
|
||||
# Add length
|
||||
@@ -108,7 +102,7 @@ def packData(__data, __dataType):
|
||||
# Add all elements
|
||||
for i in __data:
|
||||
data += packData(i, dataTypes.sInt32)
|
||||
elif __dataType == dataTypes.string:
|
||||
elif dataType == dataTypes.string:
|
||||
# String, do not use pack, do manually
|
||||
pack = False
|
||||
if len(__data) == 0:
|
||||
@@ -119,21 +113,21 @@ def packData(__data, __dataType):
|
||||
data += b"\x0B"
|
||||
data += uleb128Encode(len(__data))
|
||||
data += str.encode(__data, "latin_1", "ignore")
|
||||
elif __dataType == dataTypes.uInt16:
|
||||
elif dataType == dataTypes.uInt16:
|
||||
packType = "<H"
|
||||
elif __dataType == dataTypes.sInt16:
|
||||
elif dataType == dataTypes.sInt16:
|
||||
packType = "<h"
|
||||
elif __dataType == dataTypes.uInt32:
|
||||
elif dataType == dataTypes.uInt32:
|
||||
packType = "<L"
|
||||
elif __dataType == dataTypes.sInt32:
|
||||
elif dataType == dataTypes.sInt32:
|
||||
packType = "<l"
|
||||
elif __dataType == dataTypes.uInt64:
|
||||
elif dataType == dataTypes.uInt64:
|
||||
packType = "<Q"
|
||||
elif __dataType == dataTypes.sInt64:
|
||||
elif dataType == dataTypes.sInt64:
|
||||
packType = "<q"
|
||||
elif __dataType == dataTypes.string:
|
||||
elif dataType == dataTypes.string:
|
||||
packType = "<s"
|
||||
elif __dataType == dataTypes.ffloat:
|
||||
elif dataType == dataTypes.ffloat:
|
||||
packType = "<f"
|
||||
else:
|
||||
packType = "<B"
|
||||
@@ -144,7 +138,6 @@ def packData(__data, __dataType):
|
||||
|
||||
return data
|
||||
|
||||
# TODO: Wat dangerous
|
||||
def buildPacket(__packet, __packetData = []):
|
||||
"""
|
||||
Build a packet
|
||||
@@ -154,7 +147,6 @@ def buildPacket(__packet, __packetData = []):
|
||||
|
||||
return -- packet bytes
|
||||
"""
|
||||
|
||||
# Set some variables
|
||||
packetData = bytes()
|
||||
packetLength = 0
|
||||
@@ -174,7 +166,6 @@ def buildPacket(__packet, __packetData = []):
|
||||
packetBytes += packetData # packet data
|
||||
return packetBytes
|
||||
|
||||
|
||||
def readPacketID(stream):
|
||||
"""
|
||||
Read packetID from stream (0-1 bytes)
|
||||
@@ -182,10 +173,8 @@ def readPacketID(stream):
|
||||
stream -- data stream
|
||||
return -- packet ID (int)
|
||||
"""
|
||||
|
||||
return unpackData(stream[0:2], dataTypes.uInt16)
|
||||
|
||||
|
||||
def readPacketLength(stream):
|
||||
"""
|
||||
Read packet length from stream (3-4-5-6 bytes)
|
||||
@@ -193,7 +182,6 @@ def readPacketLength(stream):
|
||||
stream -- data stream
|
||||
return -- packet length (int)
|
||||
"""
|
||||
|
||||
return unpackData(stream[3:7], dataTypes.uInt32)
|
||||
|
||||
|
||||
@@ -208,7 +196,6 @@ def readPacketData(stream, structure = [], hasFirstBytes = True):
|
||||
Optional. Default: True
|
||||
return -- dictionary. key: name, value: read data
|
||||
"""
|
||||
|
||||
# Read packet ID (first 2 bytes)
|
||||
data = {}
|
||||
|
||||
|
@@ -11,7 +11,6 @@ def checkOldPassword(password, salt, rightPassword):
|
||||
rightPassword -- right password
|
||||
return -- bool
|
||||
"""
|
||||
|
||||
return (rightPassword == cryptHelper.crypt(password, "$2y$"+str(base64.b64decode(salt))))
|
||||
|
||||
def checkNewPassword(password, dbPassword):
|
||||
|
@@ -3,8 +3,6 @@ import tornado.web
|
||||
import tornado.gen
|
||||
from tornado.ioloop import IOLoop
|
||||
from objects import glob
|
||||
from raven.contrib.tornado import SentryMixin
|
||||
from raven.contrib.tornado import AsyncSentryClient
|
||||
import gevent
|
||||
|
||||
class asyncRequestHandler(tornado.web.RequestHandler):
|
||||
@@ -50,7 +48,6 @@ class asyncRequestHandler(tornado.web.RequestHandler):
|
||||
return realIP
|
||||
return self.request.remote_ip
|
||||
|
||||
|
||||
def runBackground(data, callback):
|
||||
"""
|
||||
Run a function in the background.
|
||||
@@ -59,7 +56,6 @@ def runBackground(data, callback):
|
||||
func, args, kwargs = data
|
||||
def _callback(result):
|
||||
IOLoop.instance().add_callback(lambda: callback(result))
|
||||
#glob.pool.apply_async(func, args, kwargs, _callback)
|
||||
g = gevent.Greenlet(func, *args, **kwargs)
|
||||
g.link(_callback)
|
||||
g.start()
|
||||
|
@@ -15,10 +15,8 @@ def runningUnderUnix():
|
||||
|
||||
return --- True if running under UNIX, otherwise False
|
||||
"""
|
||||
|
||||
return True if os.name == "posix" else False
|
||||
|
||||
|
||||
def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
|
||||
"""
|
||||
Schedule a server shutdown/restart
|
||||
@@ -27,7 +25,6 @@ def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
|
||||
restart -- if True, server will restart. if False, server will shudown
|
||||
message -- if set, send that message to every client to warn about the shutdown/restart
|
||||
"""
|
||||
|
||||
# Console output
|
||||
log.info("Pep.py will {} in {} seconds!".format("restart" if restart else "shutdown", sendRestartTime+delay))
|
||||
log.info("Sending server restart packets in {} seconds...".format(sendRestartTime))
|
||||
@@ -49,27 +46,23 @@ def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
|
||||
# Schedule actual server shutdown/restart some seconds after server restart packet, so everyone gets it
|
||||
threading.Timer(sendRestartTime+delay, action).start()
|
||||
|
||||
|
||||
def restartServer():
|
||||
"""Restart pep.py script"""
|
||||
log.info("Restarting pep.py...")
|
||||
os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||
|
||||
|
||||
def shutdownServer():
|
||||
"""Shutdown pep.py"""
|
||||
log.info("Shutting down pep.py...")
|
||||
sig = signal.SIGKILL if runningUnderUnix() else signal.CTRL_C_EVENT
|
||||
os.kill(os.getpid(), sig)
|
||||
|
||||
|
||||
def getSystemInfo():
|
||||
"""
|
||||
Get a dictionary with some system/server info
|
||||
|
||||
return -- ["unix", "connectedUsers", "webServer", "cpuUsage", "totalMemory", "usedMemory", "loadAverage"]
|
||||
"""
|
||||
|
||||
data = {}
|
||||
|
||||
# Get if server is running under unix/nt
|
||||
|
@@ -14,9 +14,8 @@ def getID(username):
|
||||
username -- user
|
||||
return -- user id or False
|
||||
"""
|
||||
|
||||
# Get user ID from db
|
||||
userID = glob.db.fetch("SELECT id FROM users WHERE username = %s", [username])
|
||||
userID = glob.db.fetch("SELECT id FROM users WHERE username = %s LIMIT 1", [username])
|
||||
|
||||
# Make sure the query returned something
|
||||
if userID == None:
|
||||
@@ -25,7 +24,6 @@ def getID(username):
|
||||
# Return user ID
|
||||
return userID["id"]
|
||||
|
||||
|
||||
def checkLogin(userID, password):
|
||||
"""
|
||||
Check userID's login with specified password
|
||||
@@ -35,9 +33,8 @@ def checkLogin(userID, password):
|
||||
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", [userID])
|
||||
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 == None:
|
||||
@@ -51,8 +48,7 @@ def checkLogin(userID, password):
|
||||
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", [newpass, userID])
|
||||
|
||||
glob.db.execute("UPDATE users SET password_md5=%s, salt='', password_version='2' WHERE id = %s LIMIT 1", [newpass, userID])
|
||||
|
||||
def exists(userID):
|
||||
"""
|
||||
@@ -61,8 +57,7 @@ def exists(userID):
|
||||
userID -- user ID to check
|
||||
return -- bool
|
||||
"""
|
||||
|
||||
result = glob.db.fetch("SELECT id FROM users WHERE id = %s", [userID])
|
||||
result = glob.db.fetch("SELECT id FROM users WHERE id = %s LIMIT 1", [userID])
|
||||
if result == None:
|
||||
return False
|
||||
else:
|
||||
@@ -76,8 +71,7 @@ def getSilenceEnd(userID):
|
||||
userID -- userID
|
||||
return -- UNIX time
|
||||
"""
|
||||
|
||||
return glob.db.fetch("SELECT silence_end FROM users WHERE id = %s", [userID])["silence_end"]
|
||||
return glob.db.fetch("SELECT silence_end FROM users WHERE id = %s LIMIT 1", [userID])["silence_end"]
|
||||
|
||||
|
||||
def silence(userID, seconds, silenceReason, author = 999):
|
||||
@@ -91,7 +85,7 @@ def silence(userID, seconds, silenceReason, author = 999):
|
||||
"""
|
||||
# db qurey
|
||||
silenceEndTime = int(time.time())+seconds
|
||||
glob.db.execute("UPDATE users SET silence_end = %s, silence_reason = %s WHERE id = %s", [silenceEndTime, silenceReason, userID])
|
||||
glob.db.execute("UPDATE users SET silence_end = %s, silence_reason = %s WHERE id = %s LIMIT 1", [silenceEndTime, silenceReason, userID])
|
||||
|
||||
# Loh
|
||||
targetUsername = getUsername(userID)
|
||||
@@ -109,9 +103,8 @@ def getRankedScore(userID, gameMode):
|
||||
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", [userID])["ranked_score_"+modeForDB]
|
||||
return glob.db.fetch("SELECT ranked_score_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["ranked_score_"+modeForDB]
|
||||
|
||||
|
||||
def getTotalScore(userID, gameMode):
|
||||
@@ -122,10 +115,8 @@ def getTotalScore(userID, gameMode):
|
||||
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", [userID])["total_score_"+modeForDB]
|
||||
|
||||
return glob.db.fetch("SELECT total_score_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["total_score_"+modeForDB]
|
||||
|
||||
def getAccuracy(userID, gameMode):
|
||||
"""
|
||||
@@ -135,10 +126,8 @@ def getAccuracy(userID, gameMode):
|
||||
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", [userID])["avg_accuracy_"+modeForDB]
|
||||
|
||||
return glob.db.fetch("SELECT avg_accuracy_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["avg_accuracy_"+modeForDB]
|
||||
|
||||
def getGameRank(userID, gameMode):
|
||||
"""
|
||||
@@ -150,13 +139,12 @@ def getGameRank(userID, gameMode):
|
||||
"""
|
||||
|
||||
modeForDB = gameModes.getGameModeForDB(gameMode)
|
||||
result = glob.db.fetch("SELECT position FROM leaderboard_"+modeForDB+" WHERE user = %s", [userID])
|
||||
result = glob.db.fetch("SELECT position FROM leaderboard_"+modeForDB+" WHERE user = %s LIMIT 1", [userID])
|
||||
if result == None:
|
||||
return 0
|
||||
else:
|
||||
return result["position"]
|
||||
|
||||
|
||||
def getPlaycount(userID, gameMode):
|
||||
"""
|
||||
Get userID's playcount relative to gameMode
|
||||
@@ -167,8 +155,7 @@ def getPlaycount(userID, gameMode):
|
||||
"""
|
||||
|
||||
modeForDB = gameModes.getGameModeForDB(gameMode)
|
||||
return glob.db.fetch("SELECT playcount_"+modeForDB+" FROM users_stats WHERE id = %s", [userID])["playcount_"+modeForDB]
|
||||
|
||||
return glob.db.fetch("SELECT playcount_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["playcount_"+modeForDB]
|
||||
|
||||
def getUsername(userID):
|
||||
"""
|
||||
@@ -178,8 +165,7 @@ def getUsername(userID):
|
||||
return -- username
|
||||
"""
|
||||
|
||||
return glob.db.fetch("SELECT username FROM users WHERE id = %s", [userID])["username"]
|
||||
|
||||
return glob.db.fetch("SELECT username FROM users WHERE id = %s LIMIT 1", [userID])["username"]
|
||||
|
||||
def getFriendList(userID):
|
||||
"""
|
||||
@@ -202,7 +188,6 @@ def getFriendList(userID):
|
||||
# Return friend IDs
|
||||
return friends
|
||||
|
||||
|
||||
def addFriend(userID, friendID):
|
||||
"""
|
||||
Add friendID to userID's friend list
|
||||
@@ -216,7 +201,7 @@ def addFriend(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", [userID, friendID]) != None:
|
||||
if glob.db.fetch("SELECT id FROM users_relationships WHERE user1 = %s AND user2 = %s LIMIT 1", [userID, friendID]) != None:
|
||||
return
|
||||
|
||||
# Set new value
|
||||
@@ -230,7 +215,6 @@ def removeFriend(userID, friendID):
|
||||
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])
|
||||
@@ -245,8 +229,7 @@ def getCountry(userID):
|
||||
userID -- user
|
||||
return -- country code (two letters)
|
||||
"""
|
||||
|
||||
return glob.db.fetch("SELECT country FROM users_stats WHERE id = %s", [userID])["country"]
|
||||
return glob.db.fetch("SELECT country FROM users_stats WHERE id = %s LIMIT 1", [userID])["country"]
|
||||
|
||||
def getPP(userID, gameMode):
|
||||
"""
|
||||
@@ -257,7 +240,7 @@ def getPP(userID, gameMode):
|
||||
"""
|
||||
|
||||
modeForDB = gameModes.getGameModeForDB(gameMode)
|
||||
return glob.db.fetch("SELECT pp_{} FROM users_stats WHERE id = %s".format(modeForDB), [userID])["pp_{}".format(modeForDB)]
|
||||
return glob.db.fetch("SELECT pp_{} FROM users_stats WHERE id = %s LIMIT 1".format(modeForDB), [userID])["pp_{}".format(modeForDB)]
|
||||
|
||||
def setCountry(userID, country):
|
||||
"""
|
||||
@@ -266,7 +249,7 @@ def setCountry(userID, country):
|
||||
userID -- userID
|
||||
country -- country letters
|
||||
"""
|
||||
glob.db.execute("UPDATE users_stats SET country = %s WHERE id = %s", [country, userID])
|
||||
glob.db.execute("UPDATE users_stats SET country = %s WHERE id = %s LIMIT 1", [country, userID])
|
||||
|
||||
def getShowCountry(userID):
|
||||
"""
|
||||
@@ -275,7 +258,7 @@ def getShowCountry(userID):
|
||||
userID -- userID
|
||||
return -- True if country is shown, False if it's hidden
|
||||
"""
|
||||
country = glob.db.fetch("SELECT show_country FROM users_stats WHERE id = %s", [userID])
|
||||
country = glob.db.fetch("SELECT show_country FROM users_stats WHERE id = %s LIMIT 1", [userID])
|
||||
if country == None:
|
||||
return False
|
||||
return generalFunctions.stringToBool(country)
|
||||
@@ -292,25 +275,42 @@ 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
|
||||
"""
|
||||
log.debug("Saving bancho session ({}::{}) in db".format(userID, ip))
|
||||
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"""
|
||||
log.debug("Deleting bancho session ({}::{}) from db".format(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):
|
||||
"""Returns True if 2FA is enable for this account"""
|
||||
"""
|
||||
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):
|
||||
"""Returns True if this IP is untrusted"""
|
||||
"""
|
||||
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 is2FAEnabled(userID) == False:
|
||||
return False
|
||||
|
||||
@@ -353,7 +353,7 @@ def isAllowed(userID):
|
||||
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", [userID])
|
||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
|
||||
if result != None:
|
||||
return (result["privileges"] & privileges.USER_NORMAL) and (result["privileges"] & privileges.USER_PUBLIC)
|
||||
else:
|
||||
@@ -366,7 +366,7 @@ def isRestricted(userID):
|
||||
userID -- id of the user
|
||||
return -- True if not restricted, otherwise false.
|
||||
"""
|
||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
|
||||
if result != None:
|
||||
return (result["privileges"] & privileges.USER_NORMAL) and not (result["privileges"] & privileges.USER_PUBLIC)
|
||||
else:
|
||||
@@ -379,7 +379,7 @@ def isBanned(userID):
|
||||
userID -- id of the user
|
||||
return -- True if not banned, otherwise false.
|
||||
"""
|
||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
|
||||
if result != None:
|
||||
return not (result["privileges"] & 3 > 0)
|
||||
else:
|
||||
@@ -392,7 +392,7 @@ def 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", [ ~(privileges.USER_NORMAL | privileges.USER_PUBLIC | privileges.USER_PENDING_VERIFICATION) , banDateTime, userID])
|
||||
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):
|
||||
"""
|
||||
@@ -400,7 +400,7 @@ def unban(userID):
|
||||
|
||||
userID -- id of user
|
||||
"""
|
||||
glob.db.execute("UPDATE users SET privileges = privileges | %s, ban_datetime = 0 WHERE id = %s", [ (privileges.USER_NORMAL | privileges.USER_PUBLIC) , userID])
|
||||
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):
|
||||
"""
|
||||
@@ -409,7 +409,7 @@ def restrict(userID):
|
||||
userID -- id of user
|
||||
"""
|
||||
banDateTime = int(time.time())
|
||||
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s", [~privileges.USER_PUBLIC, banDateTime, userID])
|
||||
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):
|
||||
"""
|
||||
@@ -427,7 +427,7 @@ def getPrivileges(userID):
|
||||
userID -- id of user
|
||||
return -- privileges number
|
||||
"""
|
||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
|
||||
if result != None:
|
||||
return result["privileges"]
|
||||
else:
|
||||
@@ -440,10 +440,10 @@ def setPrivileges(userID, priv):
|
||||
userID -- id of user
|
||||
priv -- privileges number
|
||||
"""
|
||||
glob.db.execute("UPDATE users SET privileges = %s WHERE id = %s", [priv, userID])
|
||||
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", [groupName])
|
||||
groupPrivileges = glob.db.fetch("SELECT privileges FROM privileges_groups WHERE name = %s LIMIT 1", [groupName])
|
||||
if groupPrivileges == None:
|
||||
return False
|
||||
groupPrivileges = groupPrivileges["privileges"]
|
||||
@@ -465,7 +465,7 @@ def appendNotes(userID, notes, addNl = True):
|
||||
"""
|
||||
if addNl == True:
|
||||
notes = "\n"+notes
|
||||
glob.db.execute("UPDATE users SET notes=CONCAT(COALESCE(notes, ''),%s) WHERE id = %s", [notes, userID])
|
||||
glob.db.execute("UPDATE users SET notes=CONCAT(COALESCE(notes, ''),%s) WHERE id = %s LIMIT 1", [notes, userID])
|
||||
|
||||
|
||||
def logHardware(userID, hashes, activation = False):
|
||||
|
Reference in New Issue
Block a user