.BANCHO. Switched from tornado to bottle + gevent, code cleaning
This commit is contained in:
parent
0e74e5c1ce
commit
7910291b77
|
@ -1,8 +1,6 @@
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from constants import clientPackets
|
from constants import clientPackets
|
||||||
from constants import matchModModes
|
from constants import matchModModes
|
||||||
from helpers import consoleHelper
|
|
||||||
from constants import bcolors
|
|
||||||
import random
|
import random
|
||||||
from constants import matchTeamTypes
|
from constants import matchTeamTypes
|
||||||
from constants import matchTeams
|
from constants import matchTeams
|
||||||
|
|
|
@ -1,12 +1,9 @@
|
||||||
from constants import clientPackets
|
from constants import clientPackets
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from helpers import consoleHelper
|
|
||||||
from constants import bcolors
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Get usertoken data
|
# Get usertoken data
|
||||||
userID = userToken.userID
|
userID = userToken.userID
|
||||||
username = userToken.username
|
|
||||||
|
|
||||||
# Read packet data
|
# Read packet data
|
||||||
packetData = clientPackets.changeSlot(packetData)
|
packetData = clientPackets.changeSlot(packetData)
|
||||||
|
|
|
@ -1,6 +1,3 @@
|
||||||
"""
|
|
||||||
Event called when someone parts a channel
|
|
||||||
"""
|
|
||||||
from constants import clientPackets
|
from constants import clientPackets
|
||||||
from helpers import chatHelper as chat
|
from helpers import chatHelper as chat
|
||||||
|
|
||||||
|
|
|
@ -2,27 +2,22 @@ from helpers import userHelper
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from constants import exceptions
|
from constants import exceptions
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from helpers import consoleHelper
|
|
||||||
from constants import bcolors
|
|
||||||
from helpers import locationHelper
|
from helpers import locationHelper
|
||||||
from helpers import countryHelper
|
from helpers import countryHelper
|
||||||
import time
|
|
||||||
from helpers import generalFunctions
|
|
||||||
import sys
|
import sys
|
||||||
import traceback
|
import traceback
|
||||||
from helpers import requestHelper
|
|
||||||
from helpers import discordBotHelper
|
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
from helpers import chatHelper as chat
|
from helpers import chatHelper as chat
|
||||||
from constants import privileges
|
from constants import privileges
|
||||||
|
from helpers import requestHelper
|
||||||
|
|
||||||
def handle(tornadoRequest):
|
def handle(bottleRequest):
|
||||||
# Data to return
|
# Data to return
|
||||||
responseTokenString = "ayy"
|
responseTokenString = "ayy"
|
||||||
responseData = bytes()
|
responseData = bytes()
|
||||||
|
|
||||||
# Get IP from tornado request
|
# Get IP from tornado request
|
||||||
requestIP = tornadoRequest.getRequestIP()
|
requestIP = requestHelper.getRequestIP(bottleRequest)
|
||||||
|
|
||||||
# Avoid exceptions
|
# Avoid exceptions
|
||||||
clientData = ["unknown", "unknown", "unknown", "unknown", "unknown"]
|
clientData = ["unknown", "unknown", "unknown", "unknown", "unknown"]
|
||||||
|
@ -30,7 +25,8 @@ def handle(tornadoRequest):
|
||||||
|
|
||||||
# Split POST body so we can get username/password/hardware data
|
# Split POST body so we can get username/password/hardware data
|
||||||
# 2:-3 thing is because requestData has some escape stuff that we don't need
|
# 2:-3 thing is because requestData has some escape stuff that we don't need
|
||||||
loginData = str(tornadoRequest.request.body)[2:-3].split("\\n")
|
postBody = bottleRequest.body.read()
|
||||||
|
loginData = str(postBody)[2:-3].split("\\n")
|
||||||
try:
|
try:
|
||||||
# If true, print error to console
|
# If true, print error to console
|
||||||
err = False
|
err = False
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from helpers import consoleHelper
|
|
||||||
from constants import bcolors
|
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
import time
|
import time
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from constants import slotStatuses
|
from constants import slotStatuses
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Get usertoken data
|
# Get usertoken data
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from events import channelPartEvent
|
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
from helpers import chatHelper as chat
|
from helpers import chatHelper as chat
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from helpers import chatHelper as chat
|
|
||||||
|
|
||||||
def handle(userToken, _):
|
def handle(userToken, _):
|
||||||
# get data from usertoken
|
# get data from usertoken
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
from constants import clientPackets
|
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from helpers import userHelper
|
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
|
|
37
handlers/apiFokabotMessageHandler.py
Normal file
37
handlers/apiFokabotMessageHandler.py
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
from constants import exceptions
|
||||||
|
import json
|
||||||
|
from objects import glob
|
||||||
|
from helpers import chatHelper
|
||||||
|
import bottle
|
||||||
|
|
||||||
|
@bottle.route("/api/v1/fokabotMessage")
|
||||||
|
def GETApiFokabotMessage():
|
||||||
|
statusCode = 400
|
||||||
|
data = {"message": "unknown error"}
|
||||||
|
try:
|
||||||
|
# Check arguments
|
||||||
|
if "k" not in bottle.request.query or "to" not in bottle.request.query or "msg" not in bottle.request.query:
|
||||||
|
raise exceptions.invalidArgumentsException()
|
||||||
|
|
||||||
|
# Check ci key
|
||||||
|
key = bottle.request.query["k"]
|
||||||
|
if key is None or key != glob.conf.config["server"]["cikey"]:
|
||||||
|
raise exceptions.invalidArgumentsException()
|
||||||
|
|
||||||
|
# Send chat message
|
||||||
|
chatHelper.sendMessage("FokaBot", bottle.request.query["to"], bottle.request.query["msg"])
|
||||||
|
|
||||||
|
# Status code and message
|
||||||
|
statusCode = 200
|
||||||
|
data["message"] = "ok"
|
||||||
|
except exceptions.invalidArgumentsException:
|
||||||
|
statusCode = 400
|
||||||
|
data["message"] = "invalid parameters"
|
||||||
|
finally:
|
||||||
|
# Add status code to data
|
||||||
|
data["status"] = statusCode
|
||||||
|
|
||||||
|
# Send response
|
||||||
|
bottle.response.status = statusCode
|
||||||
|
bottle.response.add_header("Content-Type", "application/json")
|
||||||
|
yield json.dumps(data)
|
|
@ -1,36 +1,32 @@
|
||||||
from helpers import requestHelper
|
|
||||||
from constants import exceptions
|
from constants import exceptions
|
||||||
import json
|
import json
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
import bottle
|
||||||
|
|
||||||
class handler(requestHelper.asyncRequestHandler):
|
@bottle.route("/api/v1/isOnline")
|
||||||
def asyncGet(self):
|
def GETApiIsOnline():
|
||||||
|
statusCode = 400
|
||||||
|
data = {"message": "unknown error"}
|
||||||
|
try:
|
||||||
|
# Check arguments
|
||||||
|
if "u" not in bottle.request.query:
|
||||||
|
raise exceptions.invalidArgumentsException()
|
||||||
|
|
||||||
|
# Get online staus
|
||||||
|
username = bottle.request.query["u"]
|
||||||
|
data["result"] = True if glob.tokens.getTokenFromUsername(username) != None else False
|
||||||
|
|
||||||
|
# Status code and message
|
||||||
|
statusCode = 200
|
||||||
|
data["message"] = "ok"
|
||||||
|
except exceptions.invalidArgumentsException:
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data["message"] = "missing required arguments"
|
||||||
try:
|
finally:
|
||||||
# Check arguments
|
# Add status code to data
|
||||||
if requestHelper.checkArguments(self.request.arguments, ["u"]) == False:
|
data["status"] = statusCode
|
||||||
raise exceptions.invalidArgumentsException()
|
|
||||||
|
|
||||||
# Get online staus
|
# Send response
|
||||||
username = self.get_argument("u")
|
bottle.response.status = statusCode
|
||||||
if username == None:
|
bottle.response.add_header("Content-Type", "application/json")
|
||||||
data["result"] = False
|
yield json.dumps(data)
|
||||||
else:
|
|
||||||
data["result"] = True if glob.tokens.getTokenFromUsername(username) != None else False
|
|
||||||
|
|
||||||
# Status code and message
|
|
||||||
statusCode = 200
|
|
||||||
data["message"] = "ok"
|
|
||||||
except exceptions.invalidArgumentsException:
|
|
||||||
statusCode = 400
|
|
||||||
data["message"] = "missing required arguments"
|
|
||||||
finally:
|
|
||||||
# Add status code to data
|
|
||||||
data["status"] = statusCode
|
|
||||||
|
|
||||||
# Send response
|
|
||||||
#self.clear()
|
|
||||||
self.write(json.dumps(data))
|
|
||||||
self.set_status(statusCode)
|
|
||||||
#self.finish(json.dumps(data))
|
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
from helpers import requestHelper
|
|
||||||
import json
|
import json
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
import bottle
|
||||||
|
|
||||||
class handler(requestHelper.asyncRequestHandler):
|
@bottle.route("/api/v1/onlineUsers")
|
||||||
def asyncGet(self):
|
def GETApiOnlineUsers():
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data = {"message": "unknown error"}
|
||||||
try:
|
try:
|
||||||
# Get online users count
|
# Get online users count
|
||||||
data["result"] = len(glob.tokens.tokens)
|
data["result"] = len(glob.tokens.tokens)
|
||||||
|
|
||||||
# Status code and message
|
# Status code and message
|
||||||
statusCode = 200
|
statusCode = 200
|
||||||
data["message"] = "ok"
|
data["message"] = "ok"
|
||||||
finally:
|
finally:
|
||||||
# Add status code to data
|
# Add status code to data
|
||||||
data["status"] = statusCode
|
data["status"] = statusCode
|
||||||
|
|
||||||
# Send response
|
# Send response
|
||||||
#self.clear()
|
bottle.response.status = statusCode
|
||||||
self.write(json.dumps(data))
|
bottle.response.add_header("Content-Type", "application/json")
|
||||||
self.set_status(statusCode)
|
yield json.dumps(data)
|
||||||
#self.finish(json.dumps(data))
|
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
from helpers import requestHelper
|
|
||||||
import json
|
import json
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
import bottle
|
||||||
|
|
||||||
class handler(requestHelper.asyncRequestHandler):
|
@bottle.route("/api/v1/serverStatus")
|
||||||
def asyncGet(self):
|
def GETApiServerStatus():
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data = {"message": "unknown error"}
|
||||||
try:
|
try:
|
||||||
# Get online users count
|
# Get online users count
|
||||||
data["result"] = -1 if glob.restarting == True else 1
|
data["result"] = -1 if glob.restarting == True else 1
|
||||||
|
|
||||||
# Status code and message
|
# Status code and message
|
||||||
statusCode = 200
|
statusCode = 200
|
||||||
data["message"] = "ok"
|
data["message"] = "ok"
|
||||||
finally:
|
finally:
|
||||||
# Add status code to data
|
# Add status code to data
|
||||||
data["status"] = statusCode
|
data["status"] = statusCode
|
||||||
|
|
||||||
# Send response
|
# Send response
|
||||||
#self.clear()
|
bottle.response.status = statusCode
|
||||||
self.write(json.dumps(data))
|
bottle.response.add_header("Content-Type", "application/json")
|
||||||
self.set_status(statusCode)
|
yield json.dumps(data)
|
||||||
#self.finish(json.dumps(data))
|
|
||||||
|
|
|
@ -1,46 +1,48 @@
|
||||||
from helpers import requestHelper
|
|
||||||
from helpers import logHelper as log
|
|
||||||
import json
|
import json
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from constants import exceptions
|
from constants import exceptions
|
||||||
|
import bottle
|
||||||
|
|
||||||
class handler(requestHelper.asyncRequestHandler):
|
@bottle.route("/api/v1/verifiedStatus")
|
||||||
def asyncGet(self):
|
def GETApiVerifiedStatus():
|
||||||
|
statusCode = 400
|
||||||
|
data = {"message": "unknown error"}
|
||||||
|
try:
|
||||||
|
# Check arguments
|
||||||
|
if "u" not in bottle.request.query:
|
||||||
|
raise exceptions.invalidArgumentsException()
|
||||||
|
|
||||||
|
# Get userID and its verified cache thing
|
||||||
|
# -1: Not in cache
|
||||||
|
# 0: Not verified (multiacc)
|
||||||
|
# 1: Verified
|
||||||
|
userID = bottle.request.query["u"]
|
||||||
|
callback = None
|
||||||
|
if "callback" in bottle.request.query:
|
||||||
|
callback = bottle.request.query["callback"]
|
||||||
|
data["result"] = -1 if userID not in glob.verifiedCache else glob.verifiedCache[userID]
|
||||||
|
|
||||||
|
# Status code and message
|
||||||
|
statusCode = 200
|
||||||
|
data["message"] = "ok"
|
||||||
|
except exceptions.invalidArgumentsException:
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data["message"] = "missing required arguments"
|
||||||
try:
|
finally:
|
||||||
# Check arguments
|
# Add status code to data
|
||||||
if requestHelper.checkArguments(self.request.arguments, ["u"]) == False:
|
data["status"] = statusCode
|
||||||
raise exceptions.invalidArgumentsException()
|
|
||||||
|
|
||||||
# Get userID and its verified cache thing
|
# Send response
|
||||||
# -1: Not in cache
|
bottle.response.add_header("Access-Control-Allow-Origin", "*")
|
||||||
# 0: Not verified (multiacc)
|
bottle.response.add_header("Content-Type", "application/json")
|
||||||
# 1: Verified
|
|
||||||
userID = self.get_argument("u")
|
|
||||||
data["result"] = -1 if userID not in glob.verifiedCache else glob.verifiedCache[userID]
|
|
||||||
|
|
||||||
# Status code and message
|
# jquery meme
|
||||||
statusCode = 200
|
output = ""
|
||||||
data["message"] = "ok"
|
if callback != None:
|
||||||
except exceptions.invalidArgumentsException:
|
output += callback+"("
|
||||||
statusCode = 400
|
output += json.dumps(data)
|
||||||
data["message"] = "missing required arguments"
|
if callback != None:
|
||||||
finally:
|
output += ")"
|
||||||
# Add status code to data
|
|
||||||
data["status"] = statusCode
|
|
||||||
|
|
||||||
# Send response
|
bottle.response.status = statusCode
|
||||||
self.add_header("Access-Control-Allow-Origin", "*")
|
yield output
|
||||||
self.add_header("Content-Type", "application/json")
|
|
||||||
|
|
||||||
# jquery meme
|
|
||||||
output = ""
|
|
||||||
if "callback" in self.request.arguments:
|
|
||||||
output += self.get_argument("callback")+"("
|
|
||||||
output += json.dumps(data)
|
|
||||||
if "callback" in self.request.arguments:
|
|
||||||
output += ")"
|
|
||||||
|
|
||||||
self.write(output)
|
|
||||||
self.set_status(statusCode)
|
|
||||||
|
|
|
@ -1,39 +1,38 @@
|
||||||
from helpers import requestHelper
|
|
||||||
from constants import exceptions
|
from constants import exceptions
|
||||||
import json
|
import json
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from helpers import systemHelper
|
from helpers import systemHelper
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
|
import bottle
|
||||||
|
|
||||||
class handler(requestHelper.asyncRequestHandler):
|
@bottle.route("/api/v1/ciTrigger")
|
||||||
def asyncGet(self):
|
def GETCiTrigger():
|
||||||
statusCode = 400
|
statusCode = 400
|
||||||
data = {"message": "unknown error"}
|
data = {"message": "unknown error"}
|
||||||
try:
|
try:
|
||||||
# Check arguments
|
# Check arguments
|
||||||
if requestHelper.checkArguments(self.request.arguments, ["k"]) == False:
|
if "k" not in bottle.request.query:
|
||||||
raise exceptions.invalidArgumentsException()
|
raise exceptions.invalidArgumentsException()
|
||||||
|
|
||||||
# Check ci key
|
# Check ci key
|
||||||
key = self.get_argument("k")
|
key = bottle.request.query["k"]
|
||||||
if key is None or key != glob.conf.config["server"]["cikey"]:
|
if key != glob.conf.config["server"]["cikey"]:
|
||||||
raise exceptions.invalidArgumentsException()
|
raise exceptions.invalidArgumentsException()
|
||||||
|
|
||||||
log.info("Ci event triggered!!")
|
log.info("Ci event triggered!!")
|
||||||
systemHelper.scheduleShutdown(5, False, "A new Bancho update is available and the server will be restarted in 5 seconds. Thank you for your patience.")
|
systemHelper.scheduleShutdown(5, False, "A new Bancho update is available and the server will be restarted in 5 seconds. Thank you for your patience.")
|
||||||
|
|
||||||
# Status code and message
|
# Status code and message
|
||||||
statusCode = 200
|
statusCode = 200
|
||||||
data["message"] = "ok"
|
data["message"] = "ok"
|
||||||
except exceptions.invalidArgumentsException:
|
except exceptions.invalidArgumentsException:
|
||||||
statusCode = 400
|
statusCode = 403
|
||||||
data["message"] = "invalid ci key"
|
data["message"] = "invalid ci key"
|
||||||
finally:
|
finally:
|
||||||
# Add status code to data
|
# Add status code to data
|
||||||
data["status"] = statusCode
|
data["status"] = statusCode
|
||||||
|
|
||||||
# Send response
|
# Send response
|
||||||
#self.clear()
|
bottle.response.status = statusCode
|
||||||
self.write(json.dumps(data))
|
bottle.response.add_header("Content-Type", "application/json")
|
||||||
self.set_status(statusCode)
|
yield json.dumps(data)
|
||||||
#self.finish(json.dumps(data))
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
from helpers import requestHelper
|
|
||||||
from constants import exceptions
|
|
||||||
import json
|
|
||||||
from objects import glob
|
|
||||||
from helpers import chatHelper
|
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
class handler(requestHelper.asyncRequestHandler):
|
|
||||||
def asyncGet(self):
|
|
||||||
statusCode = 400
|
|
||||||
data = {"message": "unknown error"}
|
|
||||||
try:
|
|
||||||
# Check arguments
|
|
||||||
if requestHelper.checkArguments(self.request.arguments, ["k", "to", "msg"]) == False:
|
|
||||||
raise exceptions.invalidArgumentsException()
|
|
||||||
|
|
||||||
# Check ci key
|
|
||||||
key = self.get_argument("k")
|
|
||||||
if key is None or key != glob.conf.config["server"]["cikey"]:
|
|
||||||
raise exceptions.invalidArgumentsException()
|
|
||||||
|
|
||||||
log.info("API REQUEST FOR FOKABOT MESSAGE AAAAAAA")
|
|
||||||
chatHelper.sendMessage("FokaBot", self.get_argument("to"), self.get_argument("msg"))
|
|
||||||
|
|
||||||
# Status code and message
|
|
||||||
statusCode = 200
|
|
||||||
data["message"] = "ok"
|
|
||||||
except exceptions.invalidArgumentsException:
|
|
||||||
statusCode = 400
|
|
||||||
data["message"] = "invalid parameters"
|
|
||||||
finally:
|
|
||||||
# Add status code to data
|
|
||||||
data["status"] = statusCode
|
|
||||||
|
|
||||||
# Send response
|
|
||||||
#self.clear()
|
|
||||||
self.write(json.dumps(data))
|
|
||||||
self.set_status(statusCode)
|
|
||||||
#self.finish(json.dumps(data))
|
|
|
@ -1,10 +1,11 @@
|
||||||
|
import bottle
|
||||||
import datetime
|
import datetime
|
||||||
import gzip
|
import gzip
|
||||||
from helpers import requestHelper
|
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
from helpers import packetHelper
|
||||||
|
from helpers import logHelper as log
|
||||||
from constants import exceptions
|
from constants import exceptions
|
||||||
from constants import packetIDs
|
from constants import packetIDs
|
||||||
from helpers import packetHelper
|
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from events import sendPublicMessageEvent
|
from events import sendPublicMessageEvent
|
||||||
from events import sendPrivateMessageEvent
|
from events import sendPrivateMessageEvent
|
||||||
|
@ -46,219 +47,198 @@ from events import userStatsRequestEvent
|
||||||
from events import requestStatusUpdateEvent
|
from events import requestStatusUpdateEvent
|
||||||
from events import userPanelRequestEvent
|
from events import userPanelRequestEvent
|
||||||
|
|
||||||
# Exception tracking
|
@bottle.route("/", method="POST")
|
||||||
import tornado.web
|
def POSTMain():
|
||||||
import tornado.gen
|
# Track time if needed
|
||||||
import sys
|
if glob.outputRequestTime == True:
|
||||||
import traceback
|
# Start time
|
||||||
from raven.contrib.tornado import SentryMixin
|
st = datetime.datetime.now()
|
||||||
from helpers import logHelper as log
|
|
||||||
|
|
||||||
class handler(SentryMixin, requestHelper.asyncRequestHandler):
|
# Client's token string and request data
|
||||||
@tornado.web.asynchronous
|
requestTokenString = bottle.request.headers.get("osu-token")
|
||||||
@tornado.gen.engine
|
requestData = bottle.request.body.read()
|
||||||
def asyncPost(self):
|
|
||||||
|
# Server's token string and request data
|
||||||
|
responseTokenString = "ayy"
|
||||||
|
responseData = bytes()
|
||||||
|
|
||||||
|
if requestTokenString == None:
|
||||||
|
# No token, first request. Handle login.
|
||||||
|
responseTokenString, responseData = loginEvent.handle(bottle.request)
|
||||||
|
else:
|
||||||
|
userToken = None # default value
|
||||||
try:
|
try:
|
||||||
# Track time if needed
|
# This is not the first packet, send response based on client's request
|
||||||
if glob.outputRequestTime == True:
|
# Packet start position, used to read stacked packets
|
||||||
# Start time
|
pos = 0
|
||||||
st = datetime.datetime.now()
|
|
||||||
|
|
||||||
# Client's token string and request data
|
# Make sure the token exists
|
||||||
requestTokenString = self.request.headers.get("osu-token")
|
if requestTokenString not in glob.tokens.tokens:
|
||||||
requestData = self.request.body
|
raise exceptions.tokenNotFoundException()
|
||||||
|
|
||||||
# Server's token string and request data
|
# Token exists, get its object and lock it
|
||||||
responseTokenString = "ayy"
|
userToken = glob.tokens.tokens[requestTokenString]
|
||||||
responseData = bytes()
|
userToken.lock.acquire()
|
||||||
|
|
||||||
if requestTokenString == None:
|
# Keep reading packets until everything has been read
|
||||||
# No token, first request. Handle login.
|
while pos < len(requestData):
|
||||||
responseTokenString, responseData = loginEvent.handle(self)
|
# Get packet from stack starting from new packet
|
||||||
else:
|
leftData = requestData[pos:]
|
||||||
userToken = None # default value
|
|
||||||
try:
|
|
||||||
# This is not the first packet, send response based on client's request
|
|
||||||
# Packet start position, used to read stacked packets
|
|
||||||
pos = 0
|
|
||||||
|
|
||||||
# Make sure the token exists
|
# Get packet ID, data length and data
|
||||||
if requestTokenString not in glob.tokens.tokens:
|
packetID = packetHelper.readPacketID(leftData)
|
||||||
raise exceptions.tokenNotFoundException()
|
dataLength = packetHelper.readPacketLength(leftData)
|
||||||
|
packetData = requestData[pos:(pos+dataLength+7)]
|
||||||
|
|
||||||
# Token exists, get its object and lock it
|
# Console output if needed
|
||||||
userToken = glob.tokens.tokens[requestTokenString]
|
if glob.outputPackets == True and packetID != 4:
|
||||||
userToken.lock.acquire()
|
log.debug("Incoming packet ({})({}):\n\nPacket code: {}\nPacket length: {}\nSingle packet data: {}\n".format(requestTokenString, userToken.username, str(packetID), str(dataLength), str(packetData)))
|
||||||
|
|
||||||
# Keep reading packets until everything has been read
|
# Event handler
|
||||||
while pos < len(requestData):
|
def handleEvent(ev):
|
||||||
# Get packet from stack starting from new packet
|
def wrapper():
|
||||||
leftData = requestData[pos:]
|
ev.handle(userToken, packetData)
|
||||||
|
return wrapper
|
||||||
|
|
||||||
# Get packet ID, data length and data
|
eventHandler = {
|
||||||
packetID = packetHelper.readPacketID(leftData)
|
# TODO: Rename packets and events
|
||||||
dataLength = packetHelper.readPacketLength(leftData)
|
# TODO: Host check for multi
|
||||||
packetData = requestData[pos:(pos+dataLength+7)]
|
packetIDs.client_changeAction: handleEvent(changeActionEvent),
|
||||||
|
packetIDs.client_logout: handleEvent(logoutEvent),
|
||||||
|
packetIDs.client_friendAdd: handleEvent(friendAddEvent),
|
||||||
|
packetIDs.client_friendRemove: handleEvent(friendRemoveEvent),
|
||||||
|
packetIDs.client_userStatsRequest: handleEvent(userStatsRequestEvent),
|
||||||
|
packetIDs.client_requestStatusUpdate: handleEvent(requestStatusUpdateEvent),
|
||||||
|
packetIDs.client_userPanelRequest: handleEvent(userPanelRequestEvent),
|
||||||
|
|
||||||
|
packetIDs.client_channelJoin: handleEvent(channelJoinEvent),
|
||||||
|
packetIDs.client_channelPart: handleEvent(channelPartEvent),
|
||||||
|
packetIDs.client_sendPublicMessage: handleEvent(sendPublicMessageEvent),
|
||||||
|
packetIDs.client_sendPrivateMessage: handleEvent(sendPrivateMessageEvent),
|
||||||
|
packetIDs.client_setAwayMessage: handleEvent(setAwayMessageEvent),
|
||||||
|
|
||||||
# Console output if needed
|
packetIDs.client_startSpectating: handleEvent(startSpectatingEvent),
|
||||||
if glob.outputPackets == True and packetID != 4:
|
packetIDs.client_stopSpectating: handleEvent(stopSpectatingEvent),
|
||||||
log.debug("Incoming packet ({})({}):\n\nPacket code: {}\nPacket length: {}\nSingle packet data: {}\n".format(requestTokenString, userToken.username, str(packetID), str(dataLength), str(packetData)))
|
packetIDs.client_cantSpectate: handleEvent(cantSpectateEvent),
|
||||||
|
packetIDs.client_spectateFrames: handleEvent(spectateFramesEvent),
|
||||||
|
|
||||||
# Event handler
|
packetIDs.client_joinLobby: handleEvent(joinLobbyEvent),
|
||||||
def handleEvent(ev):
|
packetIDs.client_partLobby: handleEvent(partLobbyEvent),
|
||||||
def wrapper():
|
packetIDs.client_createMatch: handleEvent(createMatchEvent),
|
||||||
ev.handle(userToken, packetData)
|
packetIDs.client_joinMatch: handleEvent(joinMatchEvent),
|
||||||
return wrapper
|
packetIDs.client_partMatch: handleEvent(partMatchEvent),
|
||||||
|
packetIDs.client_matchChangeSlot: handleEvent(changeSlotEvent),
|
||||||
|
packetIDs.client_matchChangeSettings: handleEvent(changeMatchSettingsEvent),
|
||||||
|
packetIDs.client_matchChangePassword: handleEvent(changeMatchPasswordEvent),
|
||||||
|
packetIDs.client_matchChangeMods: handleEvent(changeMatchModsEvent),
|
||||||
|
packetIDs.client_matchReady: handleEvent(matchReadyEvent),
|
||||||
|
packetIDs.client_matchNotReady: handleEvent(matchReadyEvent),
|
||||||
|
packetIDs.client_matchLock: handleEvent(matchLockEvent),
|
||||||
|
packetIDs.client_matchStart: handleEvent(matchStartEvent),
|
||||||
|
packetIDs.client_matchLoadComplete: handleEvent(matchPlayerLoadEvent),
|
||||||
|
packetIDs.client_matchSkipRequest: handleEvent(matchSkipEvent),
|
||||||
|
packetIDs.client_matchScoreUpdate: handleEvent(matchFramesEvent),
|
||||||
|
packetIDs.client_matchComplete: handleEvent(matchCompleteEvent),
|
||||||
|
packetIDs.client_matchNoBeatmap: handleEvent(matchNoBeatmapEvent),
|
||||||
|
packetIDs.client_matchHasBeatmap: handleEvent(matchHasBeatmapEvent),
|
||||||
|
packetIDs.client_matchTransferHost: handleEvent(matchTransferHostEvent),
|
||||||
|
packetIDs.client_matchFailed: handleEvent(matchFailedEvent),
|
||||||
|
packetIDs.client_matchChangeTeam: handleEvent(matchChangeTeamEvent),
|
||||||
|
packetIDs.client_invite: handleEvent(matchInviteEvent),
|
||||||
|
}
|
||||||
|
|
||||||
eventHandler = {
|
# Packets processed if in restricted mode.
|
||||||
# TODO: Rename packets and events
|
# All other packets will be ignored if the user is in restricted mode
|
||||||
# TODO: Host check for multi
|
packetsRestricted = [
|
||||||
packetIDs.client_changeAction: handleEvent(changeActionEvent),
|
packetIDs.client_logout,
|
||||||
packetIDs.client_logout: handleEvent(logoutEvent),
|
packetIDs.client_userStatsRequest,
|
||||||
packetIDs.client_friendAdd: handleEvent(friendAddEvent),
|
packetIDs.client_requestStatusUpdate,
|
||||||
packetIDs.client_friendRemove: handleEvent(friendRemoveEvent),
|
packetIDs.client_userPanelRequest,
|
||||||
packetIDs.client_userStatsRequest: handleEvent(userStatsRequestEvent),
|
packetIDs.client_changeAction,
|
||||||
packetIDs.client_requestStatusUpdate: handleEvent(requestStatusUpdateEvent),
|
packetIDs.client_channelJoin,
|
||||||
packetIDs.client_userPanelRequest: handleEvent(userPanelRequestEvent),
|
packetIDs.client_channelPart,
|
||||||
|
]
|
||||||
packetIDs.client_channelJoin: handleEvent(channelJoinEvent),
|
|
||||||
packetIDs.client_channelPart: handleEvent(channelPartEvent),
|
|
||||||
packetIDs.client_sendPublicMessage: handleEvent(sendPublicMessageEvent),
|
|
||||||
packetIDs.client_sendPrivateMessage: handleEvent(sendPrivateMessageEvent),
|
|
||||||
packetIDs.client_setAwayMessage: handleEvent(setAwayMessageEvent),
|
|
||||||
|
|
||||||
packetIDs.client_startSpectating: handleEvent(startSpectatingEvent),
|
# Process/ignore packet
|
||||||
packetIDs.client_stopSpectating: handleEvent(stopSpectatingEvent),
|
if packetID != 4:
|
||||||
packetIDs.client_cantSpectate: handleEvent(cantSpectateEvent),
|
if packetID in eventHandler:
|
||||||
packetIDs.client_spectateFrames: handleEvent(spectateFramesEvent),
|
if userToken.restricted == False or (userToken.restricted == True and packetID in packetsRestricted):
|
||||||
|
eventHandler[packetID]()
|
||||||
|
else:
|
||||||
|
log.warning("Ignored packet id from {} ({}) (user is restricted)".format(requestTokenString, packetID))
|
||||||
|
else:
|
||||||
|
log.warning("Unknown packet id from {} ({})".format(requestTokenString, packetID))
|
||||||
|
|
||||||
packetIDs.client_joinLobby: handleEvent(joinLobbyEvent),
|
# Update pos so we can read the next stacked packet
|
||||||
packetIDs.client_partLobby: handleEvent(partLobbyEvent),
|
# +7 because we add packet ID bytes, unused byte and data length bytes
|
||||||
packetIDs.client_createMatch: handleEvent(createMatchEvent),
|
pos += dataLength+7
|
||||||
packetIDs.client_joinMatch: handleEvent(joinMatchEvent),
|
|
||||||
packetIDs.client_partMatch: handleEvent(partMatchEvent),
|
|
||||||
packetIDs.client_matchChangeSlot: handleEvent(changeSlotEvent),
|
|
||||||
packetIDs.client_matchChangeSettings: handleEvent(changeMatchSettingsEvent),
|
|
||||||
packetIDs.client_matchChangePassword: handleEvent(changeMatchPasswordEvent),
|
|
||||||
packetIDs.client_matchChangeMods: handleEvent(changeMatchModsEvent),
|
|
||||||
packetIDs.client_matchReady: handleEvent(matchReadyEvent),
|
|
||||||
packetIDs.client_matchNotReady: handleEvent(matchReadyEvent),
|
|
||||||
packetIDs.client_matchLock: handleEvent(matchLockEvent),
|
|
||||||
packetIDs.client_matchStart: handleEvent(matchStartEvent),
|
|
||||||
packetIDs.client_matchLoadComplete: handleEvent(matchPlayerLoadEvent),
|
|
||||||
packetIDs.client_matchSkipRequest: handleEvent(matchSkipEvent),
|
|
||||||
packetIDs.client_matchScoreUpdate: handleEvent(matchFramesEvent),
|
|
||||||
packetIDs.client_matchComplete: handleEvent(matchCompleteEvent),
|
|
||||||
packetIDs.client_matchNoBeatmap: handleEvent(matchNoBeatmapEvent),
|
|
||||||
packetIDs.client_matchHasBeatmap: handleEvent(matchHasBeatmapEvent),
|
|
||||||
packetIDs.client_matchTransferHost: handleEvent(matchTransferHostEvent),
|
|
||||||
packetIDs.client_matchFailed: handleEvent(matchFailedEvent),
|
|
||||||
packetIDs.client_matchChangeTeam: handleEvent(matchChangeTeamEvent),
|
|
||||||
packetIDs.client_invite: handleEvent(matchInviteEvent),
|
|
||||||
}
|
|
||||||
|
|
||||||
# Packets processed if in restricted mode.
|
# Token queue built, send it
|
||||||
# All other packets will be ignored if the user is in restricted mode
|
responseTokenString = userToken.token
|
||||||
packetsRestricted = [
|
responseData = userToken.queue
|
||||||
packetIDs.client_logout,
|
userToken.resetQueue()
|
||||||
packetIDs.client_userStatsRequest,
|
|
||||||
packetIDs.client_requestStatusUpdate,
|
|
||||||
packetIDs.client_userPanelRequest,
|
|
||||||
packetIDs.client_changeAction,
|
|
||||||
packetIDs.client_channelJoin,
|
|
||||||
packetIDs.client_channelPart,
|
|
||||||
]
|
|
||||||
|
|
||||||
# Process/ignore packet
|
# Update ping time for timeout
|
||||||
if packetID != 4:
|
userToken.updatePingTime()
|
||||||
if packetID in eventHandler:
|
except exceptions.tokenNotFoundException:
|
||||||
if userToken.restricted == False or (userToken.restricted == True and packetID in packetsRestricted):
|
# Token not found. Disconnect that user
|
||||||
eventHandler[packetID]()
|
responseData = serverPackets.loginError()
|
||||||
else:
|
responseData += serverPackets.notification("Whoops! Something went wrong, please login again.")
|
||||||
log.warning("Ignored packet id from {} ({}) (user is restricted)".format(requestTokenString, packetID))
|
log.warning("Received packet from unknown token ({}).".format(requestTokenString))
|
||||||
else:
|
log.info("{} has been disconnected (invalid token)".format(requestTokenString))
|
||||||
log.warning("Unknown packet id from {} ({})".format(requestTokenString, packetID))
|
finally:
|
||||||
|
# Unlock token
|
||||||
|
if userToken != None:
|
||||||
|
userToken.lock.release()
|
||||||
|
|
||||||
# Update pos so we can read the next stacked packet
|
if glob.outputRequestTime == True:
|
||||||
# +7 because we add packet ID bytes, unused byte and data length bytes
|
# End time
|
||||||
pos += dataLength+7
|
et = datetime.datetime.now()
|
||||||
|
|
||||||
# Token queue built, send it
|
# Total time:
|
||||||
responseTokenString = userToken.token
|
tt = float((et.microsecond-st.microsecond)/1000)
|
||||||
responseData = userToken.queue
|
log.debug("Request time: {}ms".format(tt))
|
||||||
userToken.resetQueue()
|
|
||||||
|
|
||||||
# Update ping time for timeout
|
# Send server's response to client
|
||||||
userToken.updatePingTime()
|
# We don't use token object because we might not have a token (failed login)
|
||||||
except exceptions.tokenNotFoundException:
|
if glob.gzip == True:
|
||||||
# Token not found. Disconnect that user
|
# First, write the gzipped response
|
||||||
responseData = serverPackets.loginError()
|
responseData = gzip.compress(responseData, int(glob.conf.config["server"]["gziplevel"]))
|
||||||
responseData += serverPackets.notification("Whoops! Something went wrong, please login again.")
|
|
||||||
log.warning("Received packet from unknown token ({}).".format(requestTokenString))
|
|
||||||
log.info("{} has been disconnected (invalid token)".format(requestTokenString))
|
|
||||||
finally:
|
|
||||||
# Unlock token
|
|
||||||
if userToken != None:
|
|
||||||
userToken.lock.release()
|
|
||||||
|
|
||||||
if glob.outputRequestTime == True:
|
# Then, add gzip headers
|
||||||
# End time
|
bottle.response.add_header("Vary", "Accept-Encoding")
|
||||||
et = datetime.datetime.now()
|
bottle.response.add_header("Content-Encoding", "gzip")
|
||||||
|
else:
|
||||||
|
# First, write the response
|
||||||
|
responseData = responseData
|
||||||
|
|
||||||
# Total time:
|
# Add all the headers AFTER the response has been written
|
||||||
tt = float((et.microsecond-st.microsecond)/1000)
|
bottle.response.status = 200
|
||||||
log.debug("Request time: {}ms".format(tt))
|
bottle.response.add_header("cho-token", responseTokenString)
|
||||||
|
bottle.response.add_header("cho-protocol", "19")
|
||||||
|
bottle.response.add_header("Content-Type", "text/html; charset=UTF-8")
|
||||||
|
yield responseData
|
||||||
|
|
||||||
# Send server's response to client
|
@bottle.route("/", method="GET")
|
||||||
# We don't use token object because we might not have a token (failed login)
|
def GETMain():
|
||||||
if glob.gzip == True:
|
html = "<html><head><title>MA MAURO ESISTE?</title><style type='text/css'>body{width:30%}</style></head><body><pre>"
|
||||||
# First, write the gzipped response
|
html += " _ __<br>"
|
||||||
self.write(gzip.compress(responseData, int(glob.conf.config["server"]["gziplevel"])))
|
html += " (_) / /<br>"
|
||||||
|
html += " ______ __ ____ ____ / /____<br>"
|
||||||
# Then, add gzip headers
|
html += " / ___/ / _ \\/ _ \\/ / _ \\<br>"
|
||||||
self.add_header("Vary", "Accept-Encoding")
|
html += " / / / / /_) / /_) / / ____/<br>"
|
||||||
self.add_header("Content-Encoding", "gzip")
|
html += "/__/ /__/ .___/ .___/__/ \\_____/<br>"
|
||||||
else:
|
html += " / / / /<br>"
|
||||||
# First, write the response
|
html += " /__/ /__/<br>"
|
||||||
self.write(responseData)
|
html += "<b>PYTHON > ALL VERSION</b><br><br>"
|
||||||
|
html += "<marquee style='white-space:pre;'><br>"
|
||||||
# Add all the headers AFTER the response has been written
|
html += " .. o .<br>"
|
||||||
self.set_status(200)
|
html += " o.o o . o<br>"
|
||||||
self.add_header("cho-token", responseTokenString)
|
html += " oo...<br>"
|
||||||
self.add_header("cho-protocol", "19")
|
html += " __[]__<br>"
|
||||||
#self.add_header("Keep-Alive", "timeout=5, max=100")
|
html += " phwr--> _\\:D/_/o_o_o_|__ <span style=\"font-family: 'Comic Sans MS'; font-size: 8pt;\">u wot m8</span><br>"
|
||||||
#self.add_header("Connection", "keep-alive")
|
html += " \\\"\"\"\"\"\"\"\"\"\"\"\"\"\"/<br>"
|
||||||
self.add_header("Content-Type", "text/html; charset=UTF-8")
|
html += " \\ . .. .. . /<br>"
|
||||||
except:
|
html += "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>"
|
||||||
log.error("Unknown error!\n```\n{}\n{}```".format(sys.exc_info(), traceback.format_exc()))
|
html += "</marquee><br><strike>reverse engineering a protocol impossible to reverse engineer since always</strike><br>we are actually reverse engineering bancho successfully. for the third time.<br><br><i>© Ripple team, 2016</i></pre></body></html>"
|
||||||
if glob.sentry:
|
yield html
|
||||||
yield tornado.gen.Task(self.captureException, exc_info=True)
|
|
||||||
#finally:
|
|
||||||
# self.finish()
|
|
||||||
|
|
||||||
@tornado.web.asynchronous
|
|
||||||
@tornado.gen.engine
|
|
||||||
def asyncGet(self):
|
|
||||||
html = "<html><head><title>MA MAURO ESISTE?</title><style type='text/css'>body{width:30%}</style></head><body><pre>"
|
|
||||||
html += " _ __<br>"
|
|
||||||
html += " (_) / /<br>"
|
|
||||||
html += " ______ __ ____ ____ / /____<br>"
|
|
||||||
html += " / ___/ / _ \\/ _ \\/ / _ \\<br>"
|
|
||||||
html += " / / / / /_) / /_) / / ____/<br>"
|
|
||||||
html += "/__/ /__/ .___/ .___/__/ \\_____/<br>"
|
|
||||||
html += " / / / /<br>"
|
|
||||||
html += " /__/ /__/<br>"
|
|
||||||
html += "<b>PYTHON > ALL VERSION</b><br><br>"
|
|
||||||
html += "<marquee style='white-space:pre;'><br>"
|
|
||||||
html += " .. o .<br>"
|
|
||||||
html += " o.o o . o<br>"
|
|
||||||
html += " oo...<br>"
|
|
||||||
html += " __[]__<br>"
|
|
||||||
html += " phwr--> _\\:D/_/o_o_o_|__ <span style=\"font-family: 'Comic Sans MS'; font-size: 8pt;\">u wot m8</span><br>"
|
|
||||||
html += " \\\"\"\"\"\"\"\"\"\"\"\"\"\"\"/<br>"
|
|
||||||
html += " \\ . .. .. . /<br>"
|
|
||||||
html += "^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^<br>"
|
|
||||||
html += "</marquee><br><strike>reverse engineering a protocol impossible to reverse engineer since always</strike><br>we are actually reverse engineering bancho successfully. for the third time.<br><br><i>© Ripple team, 2016</i></pre></body></html>"
|
|
||||||
self.write(html)
|
|
||||||
#yield tornado.gen.Task(self.captureMessage, "test")
|
|
||||||
#self.finish()
|
|
||||||
|
|
|
@ -14,14 +14,14 @@ class config:
|
||||||
default = True
|
default = True
|
||||||
|
|
||||||
# Check if config.ini exists and load/generate it
|
# Check if config.ini exists and load/generate it
|
||||||
def __init__(self, __file):
|
def __init__(self, file):
|
||||||
"""
|
"""
|
||||||
Initialize a config object
|
Initialize a config object
|
||||||
|
|
||||||
__file -- filename
|
file -- filename
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.fileName = __file
|
self.fileName = file
|
||||||
if os.path.isfile(self.fileName):
|
if os.path.isfile(self.fileName):
|
||||||
# config.ini found, load it
|
# config.ini found, load it
|
||||||
self.config.read(self.fileName)
|
self.config.read(self.fileName)
|
||||||
|
@ -49,7 +49,6 @@ class config:
|
||||||
self.config.get("db","workers")
|
self.config.get("db","workers")
|
||||||
|
|
||||||
self.config.get("server","port")
|
self.config.get("server","port")
|
||||||
self.config.get("server","threads")
|
|
||||||
self.config.get("server","gzip")
|
self.config.get("server","gzip")
|
||||||
self.config.get("server","gziplevel")
|
self.config.get("server","gziplevel")
|
||||||
self.config.get("server","cikey")
|
self.config.get("server","cikey")
|
||||||
|
@ -94,7 +93,6 @@ class config:
|
||||||
|
|
||||||
self.config.add_section("server")
|
self.config.add_section("server")
|
||||||
self.config.set("server", "port", "5001")
|
self.config.set("server", "port", "5001")
|
||||||
self.config.set("server", "threads", "16")
|
|
||||||
self.config.set("server", "gzip", "1")
|
self.config.set("server", "gzip", "1")
|
||||||
self.config.set("server", "gziplevel", "6")
|
self.config.set("server", "gziplevel", "6")
|
||||||
self.config.set("server", "cikey", "changeme")
|
self.config.set("server", "cikey", "changeme")
|
||||||
|
|
|
@ -1,138 +0,0 @@
|
||||||
import pymysql
|
|
||||||
from constants import bcolors
|
|
||||||
from helpers import consoleHelper
|
|
||||||
import threading
|
|
||||||
from objects import glob
|
|
||||||
|
|
||||||
class db:
|
|
||||||
"""A MySQL database connection"""
|
|
||||||
|
|
||||||
connection = None
|
|
||||||
disconnected = False
|
|
||||||
pingTime = 600
|
|
||||||
|
|
||||||
def __init__(self, __host, __username, __password, __database, __pingTime = 600):
|
|
||||||
"""
|
|
||||||
Connect to MySQL database
|
|
||||||
|
|
||||||
__host -- MySQL host name
|
|
||||||
__username -- MySQL username
|
|
||||||
__password -- MySQL password
|
|
||||||
__database -- MySQL database name
|
|
||||||
__pingTime -- MySQL database ping time (default: 600)
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.connection = pymysql.connect(host=__host, user=__username, password=__password, db=__database, cursorclass=pymysql.cursors.DictCursor, autocommit=True)
|
|
||||||
self.pingTime = __pingTime
|
|
||||||
self.pingLoop()
|
|
||||||
|
|
||||||
|
|
||||||
def bindParams(self, __query, __params):
|
|
||||||
"""
|
|
||||||
Replace every ? with the respective **escaped** parameter in array
|
|
||||||
|
|
||||||
__query -- query with ?s
|
|
||||||
__params -- array with params
|
|
||||||
|
|
||||||
return -- new query
|
|
||||||
"""
|
|
||||||
|
|
||||||
for i in __params:
|
|
||||||
escaped = self.connection.escape(i)
|
|
||||||
__query = __query.replace("?", str(escaped), 1)
|
|
||||||
|
|
||||||
return __query
|
|
||||||
|
|
||||||
|
|
||||||
def execute(self, __query, __params = None):
|
|
||||||
"""
|
|
||||||
Execute a SQL query
|
|
||||||
|
|
||||||
__query -- query, can contain ?s
|
|
||||||
__params -- array with params. Optional
|
|
||||||
"""
|
|
||||||
|
|
||||||
log.debug(query)
|
|
||||||
with self.connection.cursor() as cursor:
|
|
||||||
try:
|
|
||||||
# Bind params if needed
|
|
||||||
if __params != None:
|
|
||||||
__query = self.bindParams(__query, __params)
|
|
||||||
|
|
||||||
# Execute the query
|
|
||||||
cursor.execute(__query)
|
|
||||||
finally:
|
|
||||||
# Close this connection
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
|
|
||||||
def fetch(self, __query, __params = None, __all = False):
|
|
||||||
"""
|
|
||||||
Fetch the first (or all) element(s) of SQL query result
|
|
||||||
|
|
||||||
__query -- query, can contain ?s
|
|
||||||
__params -- array with params. Optional
|
|
||||||
__all -- if true, will fetch all values. Same as fetchAll
|
|
||||||
|
|
||||||
return -- dictionary with result data or False if failed
|
|
||||||
"""
|
|
||||||
|
|
||||||
log.debug(query)
|
|
||||||
with self.connection.cursor() as cursor:
|
|
||||||
try:
|
|
||||||
# Bind params if needed
|
|
||||||
if __params != None:
|
|
||||||
__query = self.bindParams(__query, __params)
|
|
||||||
|
|
||||||
# Execute the query with binded params
|
|
||||||
cursor.execute(__query)
|
|
||||||
|
|
||||||
# Get first result and return it
|
|
||||||
if __all == False:
|
|
||||||
return cursor.fetchone()
|
|
||||||
else:
|
|
||||||
return cursor.fetchall()
|
|
||||||
finally:
|
|
||||||
# Close this connection
|
|
||||||
cursor.close()
|
|
||||||
|
|
||||||
|
|
||||||
def fetchAll(self, __query, __params = None):
|
|
||||||
"""
|
|
||||||
Fetch the all elements of SQL query result
|
|
||||||
|
|
||||||
__query -- query, can contain ?s
|
|
||||||
__params -- array with params. Optional
|
|
||||||
|
|
||||||
return -- dictionary with result data
|
|
||||||
"""
|
|
||||||
|
|
||||||
return self.fetch(__query, __params, True)
|
|
||||||
|
|
||||||
def pingLoop(self):
|
|
||||||
"""
|
|
||||||
Pings MySQL server. We need to ping/execute a query at least once every 8 hours
|
|
||||||
or the connection will die.
|
|
||||||
If called once, will recall after 30 minutes and so on, forever
|
|
||||||
CALL THIS FUNCTION ONLY ONCE!
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Default loop time
|
|
||||||
time = self.pingTime
|
|
||||||
|
|
||||||
# Make sure the connection is alive
|
|
||||||
try:
|
|
||||||
# Try to ping and reconnect if not connected
|
|
||||||
self.connection.ping()
|
|
||||||
if self.disconnected == True:
|
|
||||||
# If we were disconnected, set disconnected to false and print message
|
|
||||||
self.disconnected = False
|
|
||||||
log.error("> Reconnected to MySQL server!", bcolors.GREEN)
|
|
||||||
except:
|
|
||||||
# Can't ping MySQL server. Show error and call loop in 5 seconds
|
|
||||||
log.error("[!] CRITICAL!! MySQL connection died! Make sure your MySQL server is running! Checking again in 5 seconds...", bcolors.RED)
|
|
||||||
self.disconnected = True
|
|
||||||
time = 5
|
|
||||||
|
|
||||||
# Schedule a new check (endless loop)
|
|
||||||
threading.Timer(time, self.pingLoop).start()
|
|
|
@ -72,42 +72,42 @@ def logMessage(message, alertType = "INFO", messageColor = bcolors.ENDC, discord
|
||||||
|
|
||||||
def warning(message, discord = None, alertDev = False):
|
def warning(message, discord = None, alertDev = False):
|
||||||
"""
|
"""
|
||||||
Log a warning to stdout, warnings.log (always) and discord (optional)
|
Log a warning to stdout (always) and discord (optional)
|
||||||
|
|
||||||
message -- warning message
|
message -- warning message
|
||||||
discord -- if not None, send message to that discord channel through schiavo. Optional. Default = None
|
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.
|
alertDev -- if True, send al hl to devs on discord. Optional. Default = False.
|
||||||
"""
|
"""
|
||||||
logMessage(message, "WARNING", bcolors.YELLOW, discord, alertDev, "warnings.txt")
|
logMessage(message, "WARNING", bcolors.YELLOW, discord, alertDev)
|
||||||
|
|
||||||
def error(message, discord = None, alertDev = True):
|
def error(message, discord = None, alertDev = True):
|
||||||
"""
|
"""
|
||||||
Log an error to stdout, errors.log (always) and discord (optional)
|
Log an error to stdout (always) and discord (optional)
|
||||||
|
|
||||||
message -- error message
|
message -- error message
|
||||||
discord -- if not None, send message to that discord channel through schiavo. Optional. Default = None
|
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.
|
alertDev -- if True, send al hl to devs on discord. Optional. Default = False.
|
||||||
"""
|
"""
|
||||||
logMessage(message, "ERROR", bcolors.RED, discord, alertDev, "errors.txt")
|
logMessage(message, "ERROR", bcolors.RED, discord, alertDev)
|
||||||
|
|
||||||
def info(message, discord = None, alertDev = False):
|
def info(message, discord = None, alertDev = False):
|
||||||
"""
|
"""
|
||||||
Log an error to stdout (and info.log)
|
Log an info message to stdout
|
||||||
|
|
||||||
message -- info message
|
message -- info message
|
||||||
discord -- if not None, send message to that discord channel through schiavo. Optional. Default = None
|
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.
|
alertDev -- if True, send al hl to devs on discord. Optional. Default = False.
|
||||||
"""
|
"""
|
||||||
logMessage(message, "INFO", bcolors.ENDC, discord, alertDev, "info.txt")
|
logMessage(message, "INFO", bcolors.ENDC, discord, alertDev)
|
||||||
|
|
||||||
def debug(message):
|
def debug(message):
|
||||||
"""
|
"""
|
||||||
Log a debug message to stdout and debug.log if server is running in debug mode
|
Log a debug message to stdout if server is running in debug mode
|
||||||
|
|
||||||
message -- debug message
|
message -- debug message
|
||||||
"""
|
"""
|
||||||
if glob.debug == True:
|
if glob.debug == True:
|
||||||
logMessage(message, "DEBUG", bcolors.PINK, of="debug.txt")
|
logMessage(message, "DEBUG", bcolors.PINK)
|
||||||
|
|
||||||
def chat(message):
|
def chat(message):
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -1,86 +1,7 @@
|
||||||
import tornado
|
|
||||||
import tornado.web
|
|
||||||
import tornado.gen
|
|
||||||
from tornado.ioloop import IOLoop
|
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from raven.contrib.tornado import SentryMixin
|
|
||||||
from raven.contrib.tornado import AsyncSentryClient
|
|
||||||
|
|
||||||
class asyncRequestHandler(tornado.web.RequestHandler):
|
def getRequestIP(bottleRequest):
|
||||||
"""
|
realIP = bottleRequest.headers.get("X-Forwarded-For") if glob.cloudflare == True else bottleRequest.headers.get("X-Real-IP")
|
||||||
Tornado asynchronous request handler
|
if realIP != None:
|
||||||
create a class that extends this one (requestHelper.asyncRequestHandler)
|
return realIP
|
||||||
use asyncGet() and asyncPost() instad of get() and post().
|
return bottleRequest.environ.get("REMOTE_ADDR")
|
||||||
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 != 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):
|
|
||||||
IOLoop.instance().add_callback(lambda: callback(result))
|
|
||||||
glob.pool.apply_async(func, args, kwargs, _callback)
|
|
||||||
|
|
||||||
|
|
||||||
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)))
|
|
|
@ -8,14 +8,14 @@ class banchoConfig:
|
||||||
|
|
||||||
config = {"banchoMaintenance": False, "freeDirect": True, "menuIcon": "", "loginNotification": ""}
|
config = {"banchoMaintenance": False, "freeDirect": True, "menuIcon": "", "loginNotification": ""}
|
||||||
|
|
||||||
def __init__(self, __loadFromDB = True):
|
def __init__(self, loadFromDB = True):
|
||||||
"""
|
"""
|
||||||
Initialize a banchoConfig object (and load bancho_settings from db)
|
Initialize a banchoConfig object (and load bancho_settings from db)
|
||||||
|
|
||||||
[__loadFromDB -- if True, load values from db. If False, don't load values. Default: True]
|
[loadFromDB -- if True, load values from db. If False, don't load values. Default: True]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if __loadFromDB:
|
if loadFromDB:
|
||||||
try:
|
try:
|
||||||
self.loadSettings()
|
self.loadSettings()
|
||||||
except:
|
except:
|
||||||
|
@ -31,12 +31,12 @@ class banchoConfig:
|
||||||
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"]
|
||||||
|
|
||||||
def setMaintenance(self, __maintenance):
|
def setMaintenance(self, maintenance):
|
||||||
"""
|
"""
|
||||||
Turn on/off bancho maintenance mode. Write new value to db too
|
Turn on/off bancho maintenance mode. Write new value to db too
|
||||||
|
|
||||||
__maintenance -- if True, turn on maintenance mode. If false, turn it off
|
maintenance -- if True, turn on maintenance mode. If false, turn it off
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.config["banchoMaintenance"] = __maintenance
|
self.config["banchoMaintenance"] = maintenance
|
||||||
glob.db.execute("UPDATE bancho_settings SET value_int = %s WHERE name = 'bancho_maintenance'", [int(__maintenance)])
|
glob.db.execute("UPDATE bancho_settings SET value_int = %s WHERE name = 'bancho_maintenance'", [int(maintenance)])
|
||||||
|
|
|
@ -5,22 +5,22 @@ class channel:
|
||||||
A chat channel
|
A chat channel
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, __name, __description, __publicRead, __publicWrite, temp, hidden):
|
def __init__(self, name, description, publicRead, publicWrite, temp, hidden):
|
||||||
"""
|
"""
|
||||||
Create a new chat channel object
|
Create a new chat channel object
|
||||||
|
|
||||||
__name -- channel name
|
name -- channel name
|
||||||
__description -- channel description
|
description -- channel description
|
||||||
__publicRead -- bool, if true channel can be read by everyone, if false it can be read only by mods/admins
|
publicRead -- bool, if true channel can be read by everyone, if false it can be read only by mods/admins
|
||||||
__publicWrite -- bool, same as public read but relative to write permissions
|
publicWrite -- bool, same as public read but relative to write permissions
|
||||||
temp -- if True, channel will be deleted when there's no one in the channel
|
temp -- if True, channel will be deleted when there's no one in the channel
|
||||||
hidden -- if True, channel won't be shown in channels list
|
hidden -- if True, channel won't be shown in channels list
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.name = __name
|
self.name = name
|
||||||
self.description = __description
|
self.description = description
|
||||||
self.publicRead = __publicRead
|
self.publicRead = publicRead
|
||||||
self.publicWrite = __publicWrite
|
self.publicWrite = publicWrite
|
||||||
self.moderated = False
|
self.moderated = False
|
||||||
self.temp = temp
|
self.temp = temp
|
||||||
self.connectedUsers = [999] # Fokabot is always connected to every channels (otherwise it doesn't show up in IRC users list)
|
self.connectedUsers = [999] # Fokabot is always connected to every channels (otherwise it doesn't show up in IRC users list)
|
||||||
|
@ -34,26 +34,26 @@ class channel:
|
||||||
self.clientName = "#multiplayer"
|
self.clientName = "#multiplayer"
|
||||||
|
|
||||||
|
|
||||||
def userJoin(self, __userID):
|
def userJoin(self, userID):
|
||||||
"""
|
"""
|
||||||
Add a user to connected users
|
Add a user to connected users
|
||||||
|
|
||||||
__userID -- user ID that joined the channel
|
userID -- user ID that joined the channel
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if __userID not in self.connectedUsers:
|
if userID not in self.connectedUsers:
|
||||||
self.connectedUsers.append(__userID)
|
self.connectedUsers.append(userID)
|
||||||
|
|
||||||
|
|
||||||
def userPart(self, __userID):
|
def userPart(self, userID):
|
||||||
"""
|
"""
|
||||||
Remove a user from connected users
|
Remove a user from connected users
|
||||||
|
|
||||||
__userID -- user ID that left the channel
|
userID -- user ID that left the channel
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if __userID in self.connectedUsers:
|
if userID in self.connectedUsers:
|
||||||
self.connectedUsers.remove(__userID)
|
self.connectedUsers.remove(userID)
|
||||||
|
|
||||||
# Remove temp channels if empty or there's only fokabot connected
|
# Remove temp channels if empty or there's only fokabot connected
|
||||||
l = len(self.connectedUsers)
|
l = len(self.connectedUsers)
|
||||||
|
|
|
@ -56,6 +56,7 @@ class channelList:
|
||||||
self.channels[name] = channel.channel(name, "Chat", True, True, True, True)
|
self.channels[name] = channel.channel(name, "Chat", True, True, True, True)
|
||||||
log.info("Created temp channel {}".format(name))
|
log.info("Created temp channel {}".format(name))
|
||||||
|
|
||||||
|
|
||||||
def removeChannel(self, name):
|
def removeChannel(self, name):
|
||||||
"""
|
"""
|
||||||
Removes a channel from channels list
|
Removes a channel from channels list
|
||||||
|
|
|
@ -12,23 +12,17 @@ npRegex = re.compile("^https?:\\/\\/osu\\.ppy\\.sh\\/b\\/(\\d*)")
|
||||||
|
|
||||||
def connect():
|
def connect():
|
||||||
"""Add FokaBot to connected users and send userpanel/stats packet to everyone"""
|
"""Add FokaBot to connected users and send userpanel/stats packet to everyone"""
|
||||||
|
|
||||||
token = glob.tokens.addToken(999)
|
token = glob.tokens.addToken(999)
|
||||||
token.actionID = actions.idle
|
token.actionID = actions.idle
|
||||||
glob.tokens.enqueueAll(serverPackets.userPanel(999))
|
glob.tokens.enqueueAll(serverPackets.userPanel(999))
|
||||||
####glob.tokens.enqueueAll(serverPackets.userStats(999))
|
glob.tokens.enqueueAll(serverPackets.userStats(999))
|
||||||
|
|
||||||
# NOTE: Debug thing to set all users as connected
|
|
||||||
#users = glob.db.fetchAll("SELECT id FROM users")
|
|
||||||
#for i in users:
|
|
||||||
# t = glob.tokens.addToken(i["id"])
|
|
||||||
# t.actionID = actions.idle
|
|
||||||
|
|
||||||
def disconnect():
|
def disconnect():
|
||||||
"""Remove FokaBot from connected users"""
|
"""Remove FokaBot from connected users"""
|
||||||
|
|
||||||
glob.tokens.deleteToken(glob.tokens.getTokenFromUserID(999))
|
glob.tokens.deleteToken(glob.tokens.getTokenFromUserID(999))
|
||||||
|
|
||||||
|
|
||||||
def fokabotResponse(fro, chan, message):
|
def fokabotResponse(fro, chan, message):
|
||||||
"""
|
"""
|
||||||
Check if a message has triggered fokabot (and return its response)
|
Check if a message has triggered fokabot (and return its response)
|
||||||
|
@ -39,7 +33,6 @@ def fokabotResponse(fro, chan, message):
|
||||||
|
|
||||||
return -- fokabot's response string or False
|
return -- fokabot's response string or False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
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:
|
||||||
|
|
|
@ -20,7 +20,6 @@ tokens = tokenList.tokenList()
|
||||||
channels = channelList.channelList()
|
channels = channelList.channelList()
|
||||||
matches = matchList.matchList()
|
matches = matchList.matchList()
|
||||||
restarting = False
|
restarting = False
|
||||||
pool = None
|
|
||||||
fLocks = fileLocks.fileLocks()
|
fLocks = fileLocks.fileLocks()
|
||||||
verifiedCache = {}
|
verifiedCache = {}
|
||||||
cloudflare = False
|
cloudflare = False
|
||||||
|
|
|
@ -1,24 +0,0 @@
|
||||||
'''
|
|
||||||
import threading
|
|
||||||
|
|
||||||
class task:
|
|
||||||
def __init__(self, function, args = (), kwargs = {}):
|
|
||||||
self.function = function
|
|
||||||
self.args = args
|
|
||||||
self.kwargs = kwargs
|
|
||||||
|
|
||||||
class logThread:
|
|
||||||
def __init__(self):
|
|
||||||
self.thread = threading.Thread()
|
|
||||||
self.queue = []
|
|
||||||
|
|
||||||
def enqueue(self, function, args = (), kwargs = {}):
|
|
||||||
self.queue.append(task(function, args, kwargs))
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
for i in self.queue:
|
|
||||||
self.thread = threading.Thread(i.function, i.args, i.kwargs)
|
|
||||||
self.thread.run()
|
|
||||||
self.thread.join()
|
|
||||||
self.queue = []
|
|
||||||
'''
|
|
|
@ -29,29 +29,29 @@ class match:
|
||||||
matchModMode = matchModModes.normal
|
matchModMode = matchModModes.normal
|
||||||
seed = 0
|
seed = 0
|
||||||
|
|
||||||
def __init__(self, __matchID, __matchName, __matchPassword, __beatmapID, __beatmapName, __beatmapMD5, __gameMode, __hostUserID):
|
def __init__(self, matchID, matchName, matchPassword, beatmapID, beatmapName, beatmapMD5, gameMode, hostUserID):
|
||||||
"""
|
"""
|
||||||
Create a new match object
|
Create a new match object
|
||||||
|
|
||||||
__matchID -- match progressive identifier
|
matchID -- match progressive identifier
|
||||||
__matchName -- match name, string
|
matchName -- match name, string
|
||||||
__matchPassword -- match md5 password. Leave empty for no password
|
matchPassword -- match md5 password. Leave empty for no password
|
||||||
__beatmapID -- beatmap ID
|
beatmapID -- beatmap ID
|
||||||
__beatmapName -- beatmap name, string
|
beatmapName -- beatmap name, string
|
||||||
__beatmapMD5 -- beatmap md5 hash, string
|
beatmapMD5 -- beatmap md5 hash, string
|
||||||
__gameMode -- game mode ID. See gameModes.py
|
gameMode -- game mode ID. See gameModes.py
|
||||||
__hostUserID -- user id of the host
|
hostUserID -- user id of the host
|
||||||
"""
|
"""
|
||||||
self.matchID = __matchID
|
self.matchID = matchID
|
||||||
self.inProgress = False
|
self.inProgress = False
|
||||||
self.mods = 0
|
self.mods = 0
|
||||||
self.matchName = __matchName
|
self.matchName = matchName
|
||||||
self.matchPassword = __matchPassword
|
self.matchPassword = matchPassword
|
||||||
self.beatmapID = __beatmapID
|
self.beatmapID = beatmapID
|
||||||
self.beatmapName = __beatmapName
|
self.beatmapName = beatmapName
|
||||||
self.beatmapMD5 = __beatmapMD5
|
self.beatmapMD5 = beatmapMD5
|
||||||
self.hostUserID = __hostUserID
|
self.hostUserID = hostUserID
|
||||||
self.gameMode = __gameMode
|
self.gameMode = gameMode
|
||||||
self.matchScoringTypes = matchScoringTypes.score # default values
|
self.matchScoringTypes = matchScoringTypes.score # default values
|
||||||
self.matchTeamType = matchTeamTypes.headToHead # default value
|
self.matchTeamType = matchTeamTypes.headToHead # default value
|
||||||
self.matchModMode = matchModModes.normal # default value
|
self.matchModMode = matchModModes.normal # default value
|
||||||
|
@ -618,8 +618,6 @@ class match:
|
||||||
self.setSlot(slotID, None, newTeam)
|
self.setSlot(slotID, None, newTeam)
|
||||||
self.sendUpdate()
|
self.sendUpdate()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def sendUpdate(self):
|
def sendUpdate(self):
|
||||||
# Send to users in room
|
# Send to users in room
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
|
|
|
@ -13,50 +13,50 @@ class matchList:
|
||||||
self.usersInLobby = []
|
self.usersInLobby = []
|
||||||
self.lastID = 1
|
self.lastID = 1
|
||||||
|
|
||||||
def createMatch(self, __matchName, __matchPassword, __beatmapID, __beatmapName, __beatmapMD5, __gameMode, __hostUserID):
|
def createMatch(self, matchName, matchPassword, beatmapID, beatmapName, beatmapMD5, gameMode, hostUserID):
|
||||||
"""
|
"""
|
||||||
Add a new match to matches list
|
Add a new match to matches list
|
||||||
|
|
||||||
__matchName -- match name, string
|
matchName -- match name, string
|
||||||
__matchPassword -- match md5 password. Leave empty for no password
|
matchPassword -- match md5 password. Leave empty for no password
|
||||||
__beatmapID -- beatmap ID
|
beatmapID -- beatmap ID
|
||||||
__beatmapName -- beatmap name, string
|
beatmapName -- beatmap name, string
|
||||||
__beatmapMD5 -- beatmap md5 hash, string
|
beatmapMD5 -- beatmap md5 hash, string
|
||||||
__gameMode -- game mode ID. See gameModes.py
|
gameMode -- game mode ID. See gameModes.py
|
||||||
__hostUserID -- user id of who created the match
|
hostUserID -- user id of who created the match
|
||||||
return -- match ID
|
return -- match ID
|
||||||
"""
|
"""
|
||||||
# Add a new match to matches list
|
# Add a new match to matches list
|
||||||
matchID = self.lastID
|
matchID = self.lastID
|
||||||
self.lastID+=1
|
self.lastID+=1
|
||||||
self.matches[matchID] = match.match(matchID, __matchName, __matchPassword, __beatmapID, __beatmapName, __beatmapMD5, __gameMode, __hostUserID)
|
self.matches[matchID] = match.match(matchID, matchName, matchPassword, beatmapID, beatmapName, beatmapMD5, gameMode, hostUserID)
|
||||||
return matchID
|
return matchID
|
||||||
|
|
||||||
|
|
||||||
def lobbyUserJoin(self, __userID):
|
def lobbyUserJoin(self, userID):
|
||||||
"""
|
"""
|
||||||
Add userID to users in lobby
|
Add userID to users in lobby
|
||||||
|
|
||||||
__userID -- user who joined mp lobby
|
userID -- user who joined mp lobby
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Make sure the user is not already in mp lobby
|
# Make sure the user is not already in mp lobby
|
||||||
if __userID not in self.usersInLobby:
|
if userID not in self.usersInLobby:
|
||||||
# We don't need to join #lobby, client will automatically send a packet for it
|
# We don't need to join #lobby, client will automatically send a packet for it
|
||||||
self.usersInLobby.append(__userID)
|
self.usersInLobby.append(userID)
|
||||||
|
|
||||||
|
|
||||||
def lobbyUserPart(self, __userID):
|
def lobbyUserPart(self, userID):
|
||||||
"""
|
"""
|
||||||
Remove userID from users in lobby
|
Remove userID from users in lobby
|
||||||
|
|
||||||
__userID -- user who left mp lobby
|
userID -- user who left mp lobby
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Make sure the user is in mp lobby
|
# Make sure the user is in mp lobby
|
||||||
if __userID in self.usersInLobby:
|
if userID in self.usersInLobby:
|
||||||
# Part lobby and #lobby channel
|
# Part lobby and #lobby channel
|
||||||
self.usersInLobby.remove(__userID)
|
self.usersInLobby.remove(userID)
|
||||||
|
|
||||||
|
|
||||||
def disposeMatch(self, __matchID):
|
def disposeMatch(self, __matchID):
|
||||||
|
|
|
@ -35,11 +35,11 @@ class token:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, __userID, token = None, ip = "", irc = False, timeOffset = 0):
|
def __init__(self, userID, token = None, ip = "", irc = False, timeOffset = 0):
|
||||||
"""
|
"""
|
||||||
Create a token object and set userID and token
|
Create a token object and set userID and token
|
||||||
|
|
||||||
__userID -- user associated to this token
|
userID -- user associated to this token
|
||||||
token -- if passed, set token to that value
|
token -- if passed, set token to that value
|
||||||
if not passed, token will be generated
|
if not passed, token will be generated
|
||||||
ip -- client ip. optional.
|
ip -- client ip. optional.
|
||||||
|
@ -47,7 +47,7 @@ class token:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Set stuff
|
# Set stuff
|
||||||
self.userID = __userID
|
self.userID = userID
|
||||||
self.username = userHelper.getUsername(self.userID)
|
self.username = userHelper.getUsername(self.userID)
|
||||||
self.privileges = userHelper.getPrivileges(self.userID)
|
self.privileges = userHelper.getPrivileges(self.userID)
|
||||||
self.admin = userHelper.isInPrivilegeGroup(self.userID, "developer") or userHelper.isInPrivilegeGroup(self.userID, "community manager")
|
self.admin = userHelper.isInPrivilegeGroup(self.userID, "developer") or userHelper.isInPrivilegeGroup(self.userID, "community manager")
|
||||||
|
@ -102,12 +102,6 @@ class token:
|
||||||
if ip != "":
|
if ip != "":
|
||||||
userHelper.saveBanchoSession(self.userID, self.ip)
|
userHelper.saveBanchoSession(self.userID, self.ip)
|
||||||
|
|
||||||
# If we are restricted, send message from FokaBot to user
|
|
||||||
# NOTE: Sent later
|
|
||||||
#if self.restricted == True:
|
|
||||||
# self.setRestricted()
|
|
||||||
|
|
||||||
|
|
||||||
def enqueue(self, __bytes):
|
def enqueue(self, __bytes):
|
||||||
"""
|
"""
|
||||||
Add bytes (packets) to queue
|
Add bytes (packets) to queue
|
||||||
|
@ -164,11 +158,11 @@ class token:
|
||||||
return self.location[1]
|
return self.location[1]
|
||||||
|
|
||||||
|
|
||||||
def startSpectating(self, __userID):
|
def startSpectating(self, userID):
|
||||||
"""Set the spectating user to __userID
|
"""Set the spectating user to userID
|
||||||
|
|
||||||
__userID -- target userID"""
|
userID -- target userID"""
|
||||||
self.spectating = __userID
|
self.spectating = userID
|
||||||
|
|
||||||
|
|
||||||
def stopSpectating(self):
|
def stopSpectating(self):
|
||||||
|
@ -176,24 +170,24 @@ class token:
|
||||||
self.spectating = 0
|
self.spectating = 0
|
||||||
|
|
||||||
|
|
||||||
def addSpectator(self, __userID):
|
def addSpectator(self, userID):
|
||||||
"""Add __userID to our spectators
|
"""Add userID to our spectators
|
||||||
|
|
||||||
userID -- new spectator userID"""
|
userID -- new spectator userID"""
|
||||||
|
|
||||||
# Add userID to spectators if not already in
|
# Add userID to spectators if not already in
|
||||||
if __userID not in self.spectators:
|
if userID not in self.spectators:
|
||||||
self.spectators.append(__userID)
|
self.spectators.append(userID)
|
||||||
|
|
||||||
|
|
||||||
def removeSpectator(self, __userID):
|
def removeSpectator(self, userID):
|
||||||
"""Remove __userID from our spectators
|
"""Remove userID from our spectators
|
||||||
|
|
||||||
userID -- old spectator userID"""
|
userID -- old spectator userID"""
|
||||||
|
|
||||||
# Remove spectator
|
# Remove spectator
|
||||||
if __userID in self.spectators:
|
if userID in self.spectators:
|
||||||
self.spectators.remove(__userID)
|
self.spectators.remove(userID)
|
||||||
|
|
||||||
|
|
||||||
def setCountry(self, __countryID):
|
def setCountry(self, __countryID):
|
||||||
|
|
65
pep.py
65
pep.py
|
@ -1,17 +1,12 @@
|
||||||
"""Hello, pep.py here, ex-owner of ripple and prime minister of Ripwot."""
|
"""Hello, pep.py here, ex-owner of ripple and prime minister of Ripwot."""
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
from multiprocessing.pool import ThreadPool
|
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
# Tornado
|
# Bottle
|
||||||
import tornado.ioloop
|
import bottle
|
||||||
import tornado.web
|
from gevent import monkey as brit_monkey
|
||||||
import tornado.httpserver
|
brit_monkey.patch_all()
|
||||||
import tornado.gen
|
|
||||||
|
|
||||||
# Raven
|
|
||||||
from raven.contrib.tornado import AsyncSentryClient
|
|
||||||
|
|
||||||
# pep.py files
|
# pep.py files
|
||||||
from constants import bcolors
|
from constants import bcolors
|
||||||
|
@ -25,27 +20,13 @@ from helpers import databaseHelperNew
|
||||||
from helpers import generalFunctions
|
from helpers import generalFunctions
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
|
|
||||||
from handlers import mainHandler
|
# Raven
|
||||||
from handlers import apiIsOnlineHandler
|
from raven import Client
|
||||||
from handlers import apiOnlineUsersHandler
|
from raven.contrib.bottle import Sentry
|
||||||
from handlers import apiServerStatusHandler
|
|
||||||
from handlers import ciTriggerHandler
|
|
||||||
from handlers import apiVerifiedStatusHandler
|
|
||||||
from handlers import fokabotMessageHandler
|
|
||||||
|
|
||||||
|
# IRC
|
||||||
from irc import ircserver
|
from irc import ircserver
|
||||||
|
|
||||||
def make_app():
|
|
||||||
return tornado.web.Application([
|
|
||||||
(r"/", mainHandler.handler),
|
|
||||||
(r"/api/v1/isOnline", apiIsOnlineHandler.handler),
|
|
||||||
(r"/api/v1/onlineUsers", apiOnlineUsersHandler.handler),
|
|
||||||
(r"/api/v1/serverStatus", apiServerStatusHandler.handler),
|
|
||||||
(r"/api/v1/ciTrigger", ciTriggerHandler.handler),
|
|
||||||
(r"/api/v1/verifiedStatus", apiVerifiedStatusHandler.handler),
|
|
||||||
(r"/api/v1/fokabotMessage", fokabotMessageHandler.handler)
|
|
||||||
])
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Server start
|
# Server start
|
||||||
consoleHelper.printServerStartHeader(True)
|
consoleHelper.printServerStartHeader(True)
|
||||||
|
@ -98,15 +79,6 @@ if __name__ == "__main__":
|
||||||
glob.tokens.deleteBanchoSessions()
|
glob.tokens.deleteBanchoSessions()
|
||||||
consoleHelper.printDone()
|
consoleHelper.printDone()
|
||||||
|
|
||||||
# Create threads pool
|
|
||||||
try:
|
|
||||||
consoleHelper.printNoNl("> Creating threads pool... ")
|
|
||||||
glob.pool = ThreadPool(int(glob.conf.config["server"]["threads"]))
|
|
||||||
consoleHelper.printDone()
|
|
||||||
except:
|
|
||||||
consoleHelper.printError()
|
|
||||||
consoleHelper.printColored("[!] Error while creating threads pool. Please check your config.ini and run the server again", bcolors.RED)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
consoleHelper.printNoNl("> Loading chat filters... ")
|
consoleHelper.printNoNl("> Loading chat filters... ")
|
||||||
glob.chatFilters = chatFilters.chatFilters()
|
glob.chatFilters = chatFilters.chatFilters()
|
||||||
|
@ -168,13 +140,21 @@ if __name__ == "__main__":
|
||||||
consoleHelper.printColored("[!] Warning! Server running in debug mode!", bcolors.YELLOW)
|
consoleHelper.printColored("[!] Warning! Server running in debug mode!", bcolors.YELLOW)
|
||||||
|
|
||||||
# Make app
|
# Make app
|
||||||
application = make_app()
|
app = bottle.app()
|
||||||
|
app.catchall = False
|
||||||
|
from handlers import mainHandler
|
||||||
|
from handlers import apiIsOnlineHandler
|
||||||
|
from handlers import apiServerStatusHandler
|
||||||
|
from handlers import ciTriggerHandler
|
||||||
|
from handlers import apiVerifiedStatusHandler
|
||||||
|
from handlers import apiFokabotMessageHandler
|
||||||
|
|
||||||
# Set up sentry
|
# Set up sentry
|
||||||
try:
|
try:
|
||||||
glob.sentry = generalFunctions.stringToBool(glob.conf.config["sentry"]["enable"])
|
glob.sentry = generalFunctions.stringToBool(glob.conf.config["sentry"]["enable"])
|
||||||
if glob.sentry == True:
|
if glob.sentry == True:
|
||||||
application.sentry_client = AsyncSentryClient(glob.conf.config["sentry"]["banchodns"], release=glob.VERSION)
|
client = Client(glob.conf.config["sentry"]["banchodns"], release=glob.VERSION)
|
||||||
|
app = Sentry(app, client)
|
||||||
else:
|
else:
|
||||||
consoleHelper.printColored("[!] Warning! Sentry logging is disabled!", bcolors.YELLOW)
|
consoleHelper.printColored("[!] Warning! Sentry logging is disabled!", bcolors.YELLOW)
|
||||||
except:
|
except:
|
||||||
|
@ -204,9 +184,8 @@ if __name__ == "__main__":
|
||||||
consoleHelper.printColored("[!] Invalid server port! Please check your config.ini and run the server again", bcolors.RED)
|
consoleHelper.printColored("[!] Invalid server port! Please check your config.ini and run the server again", bcolors.RED)
|
||||||
|
|
||||||
# Server start message and console output
|
# Server start message and console output
|
||||||
log.logMessage("Server started!", discord=True, of="info.txt", stdout=False)
|
log.logMessage("Server started!", discord=True, stdout=False)
|
||||||
consoleHelper.printColored("> Tornado listening for HTTP(s) clients on 127.0.0.1:{}...".format(serverPort), bcolors.GREEN)
|
consoleHelper.printColored("> Bottle listening for HTTP(s) clients on 127.0.0.1:{}...".format(serverPort), bcolors.GREEN)
|
||||||
|
|
||||||
# Start tornado
|
# Start bottle
|
||||||
application.listen(serverPort)
|
bottle.run(app=app, host="0.0.0.0", port=serverPort, server="gevent", quiet=True)
|
||||||
tornado.ioloop.IOLoop.instance().start()
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user