.BANCHO. Changed config.ini structure, better logs, add logs to output file

This commit is contained in:
Nyo 2016-06-04 12:44:54 +02:00
parent f6be15fa59
commit bd8c810f45
31 changed files with 223 additions and 201 deletions

View File

@ -10,10 +10,8 @@ import requests
import json
from constants import mods
from helpers import generalFunctions
from helpers import consoleHelper
from helpers import discordBotHelper
from constants import bcolors
from helpers import logHelper as log
"""
Commands callbacks
@ -492,7 +490,7 @@ def tillerinoLast(fro, chan, message):
return False
return "{0:.2f}pp ({1} on {2})".format(data["pp"], fro, data["sn"])
except Exception as a:
print(a)
log.error(a)
return False
def mm00(fro, chan, message):

View File

@ -1,8 +1,7 @@
from objects import glob
from constants import serverPackets
from helpers import consoleHelper
from constants import bcolors
from constants import exceptions
from helpers import logHelper as log
def handle(userToken, packetData):
# get usertoken data
@ -17,5 +16,5 @@ def handle(userToken, packetData):
targetToken.enqueue(serverPackets.noSongSpectator(userID))
except exceptions.tokenNotFoundException:
# Stop spectating if token not found
consoleHelper.printColored("[!] Spectator can't spectate: token not found", bcolors.RED)
log.warning("Spectator can't spectate: token not found")
userToken.stopSpectating()

View File

@ -1,8 +1,8 @@
from objects import glob
from constants import clientPackets
from constants import serverPackets
from constants import actions
from helpers import userHelper
from helpers import logHelper as log
def handle(userToken, packetData):
# Get usertoken data
@ -29,4 +29,4 @@ def handle(userToken, packetData):
glob.tokens.enqueueAll(serverPackets.userStats(userID))
# Console output
print("> {} changed action: {} [{}][{}]".format(username, str(userToken.actionID), userToken.actionText, userToken.actionMd5))
log.info("{} changed action: {} [{}][{}]".format(username, str(userToken.actionID), userToken.actionText, userToken.actionMd5))

View File

@ -7,6 +7,7 @@ import random
from constants import matchTeamTypes
from constants import matchTeams
from constants import slotStatuses
from helpers import logHelper as log
def handle(userToken, packetData):
# Read new settings
@ -105,5 +106,5 @@ def handle(userToken, packetData):
match.sendUpdate()
# Console output
consoleHelper.printColored("> MPROOM{}: Updated room settings".format(match.matchID), bcolors.BLUE)
log.info("MPROOM{}: Updated room settings".format(match.matchID))
#consoleHelper.printColored("> MPROOM{}: DEBUG: Host is {}".format(match.matchID, match.hostUserID), bcolors.PINK)

View File

@ -8,6 +8,7 @@ from constants import bcolors
from constants import serverPackets
from objects import glob
from constants import exceptions
from helpers import logHelper as log
def handle(userToken, packetData):
# Channel join packet
@ -49,8 +50,8 @@ def joinChannel(userToken, channelName):
userToken.enqueue(serverPackets.channelJoinSuccess(userID, channelName))
# Console output
consoleHelper.printColored("> {} joined channel {}".format(username, channelName), bcolors.GREEN)
log.info("{} joined channel {}".format(username, channelName))
except exceptions.channelNoPermissionsException:
consoleHelper.printColored("[!] {} attempted to join channel {}, but they have no read permissions".format(username, channelName), bcolors.RED)
log.warning("{} attempted to join channel {}, but they have no read permissions".format(username, channelName))
except exceptions.channelUnknownException:
consoleHelper.printColored("[!] {} attempted to join an unknown channel ({})".format(username, channelName), bcolors.RED)
log.warning("{} attempted to join an unknown channel ({})".format(username, channelName))

View File

@ -7,6 +7,7 @@ from constants import bcolors
from objects import glob
from constants import clientPackets
from constants import serverPackets
from helpers import logHelper as log
def handle(userToken, packetData):
# Channel part packet
@ -33,4 +34,4 @@ def partChannel(userToken, channelName, kick = False):
userToken.enqueue(serverPackets.channelKicked(channelName))
# Console output
consoleHelper.printColored("> {} parted channel {}".format(username, channelName), bcolors.YELLOW)
log.info("{} parted channel {}".format(username, channelName))

View File

@ -1,10 +1,9 @@
from constants import serverPackets
from constants import clientPackets
from objects import glob
from helpers import consoleHelper
from constants import bcolors
from events import joinMatchEvent
from constants import exceptions
from helpers import logHelper as log
def handle(userToken, packetData):
try:
@ -39,6 +38,6 @@ def handle(userToken, packetData):
token.enqueue(serverPackets.createMatch(matchID))
# Console output
consoleHelper.printColored("> MPROOM{}: Room created!".format(matchID), bcolors.BLUE)
log.info("MPROOM{}: Room created!".format(matchID))
except exceptions.matchCreateError:
consoleHelper.printColored("[!] Error while creating match!", bcolors.RED)
log.error("Error while creating match!")

View File

@ -1,5 +1,6 @@
from helpers import userHelper
from constants import clientPackets
from helpers import logHelper as log
def handle(userToken, packetData):
# Friend add packet
@ -7,4 +8,4 @@ def handle(userToken, packetData):
userHelper.addFriend(userToken.userID, packetData["friendID"])
# Console output
print("> {} have added {} to their friends".format(userToken.username, str(packetData["friendID"])))
log.info("{} have added {} to their friends".format(userToken.username, str(packetData["friendID"])))

View File

@ -1,5 +1,6 @@
from helpers import userHelper
from constants import clientPackets
from helpers import logHelper as log
def handle(userToken, packetData):
# Friend remove packet
@ -7,4 +8,4 @@ def handle(userToken, packetData):
userHelper.removeFriend(userToken.userID, packetData["friendID"])
# Console output
print("> {} have removed {} from their friends".format(userToken.username, str(packetData["friendID"])))
log.info("{} have removed {} from their friends".format(userToken.username, str(packetData["friendID"])))

View File

@ -1,7 +1,6 @@
from constants import serverPackets
from objects import glob
from helpers import consoleHelper
from constants import bcolors
from helpers import logHelper as log
def handle(userToken, _):
# Get userToken data
@ -16,4 +15,4 @@ def handle(userToken, _):
userToken.enqueue(serverPackets.createMatch(key))
# Console output
consoleHelper.printColored("> {} has joined multiplayer lobby".format(username), bcolors.BLUE)
log.info("{} has joined multiplayer lobby".format(username))

View File

@ -1,9 +1,8 @@
from constants import clientPackets
from constants import serverPackets
from objects import glob
from helpers import consoleHelper
from constants import bcolors
from constants import exceptions
from helpers import logHelper as log
def handle(userToken, packetData):
# read packet data
@ -12,7 +11,6 @@ def handle(userToken, packetData):
# Get match from ID
joinMatch(userToken, packetData["matchID"], packetData["password"])
def joinMatch(userToken, matchID, password):
try:
# TODO: leave other matches
@ -20,7 +18,6 @@ def joinMatch(userToken, matchID, password):
# get usertoken data
userID = userToken.userID
username = userToken.username
# Make sure the match exists
if matchID not in glob.matches.matches:
@ -51,10 +48,10 @@ def joinMatch(userToken, matchID, password):
#userToken.enqueue(serverPackets.sendMessage("FokaBot", "#multiplayer", "Hi {}, and welcome to Ripple's multiplayer mode! This feature is still WIP and might have some issues. If you find any bugs, please report them (by clicking here)[https://ripple.moe/index.php?p=22].".format(username)))
except exceptions.matchNotFoundException:
userToken.enqueue(serverPackets.matchJoinFail())
consoleHelper.printColored("[!] {} has tried to join a mp room, but it doesn't exist".format(userToken.username), bcolors.RED)
log.warning("{} has tried to join a mp room, but it doesn't exist".format(userToken.username))
except exceptions.matchWrongPasswordException:
userToken.enqueue(serverPackets.matchJoinFail())
consoleHelper.printColored("[!] {} has tried to join a mp room, but he typed the wrong password".format(userToken.username), bcolors.RED)
log.warning("{} has tried to join a mp room, but he typed the wrong password".format(userToken.username))
except exceptions.matchJoinErrorException:
userToken.enqueue(serverPackets.matchJoinFail())
consoleHelper.printColored("[!] {} has tried to join a mp room, but an error has occured".format(userToken.username), bcolors.RED)
log.warning("{} has tried to join a mp room, but an error has occured".format(userToken.username))

View File

@ -13,24 +13,19 @@ import sys
import traceback
from helpers import requestHelper
from helpers import discordBotHelper
from helpers import logHelper as log
def handle(tornadoRequest):
# Data to return
responseTokenString = "ayy"
responseData = bytes()
# Get IP from flask request
# Get IP from tornado request
requestIP = tornadoRequest.getRequestIP()
# Console output
print("> Accepting connection from {}...".format(requestIP))
# 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
loginData = str(tornadoRequest.request.body)[2:-3].split("\\n")
# Process login
print("> Processing login request for {}...".format(loginData[0]))
try:
# If true, print error to console
err = False
@ -128,14 +123,14 @@ def handle(tornadoRequest):
responseToken.enqueue(serverPackets.onlineUsers())
# Get location and country from ip.zxq.co or database
if generalFunctions.stringToBool(glob.conf.config["server"]["localizeusers"]):
if glob.localize == True:
# Get location and country from IP
location = locationHelper.getLocation(requestIP)
countryLetters = locationHelper.getCountry(requestIP)
country = countryHelper.getCountryID(countryLetters)
else:
# Set location to 0,0 and get country from db
print("[!] Location skipped")
log.warning("Location skipped")
location = [0,0]
countryLetters = "XX"
country = countryHelper.getCountryID(userHelper.getCountry(userID))
@ -155,9 +150,6 @@ def handle(tornadoRequest):
# Set reponse data to right value and reset our queue
responseData = responseToken.queue
responseToken.resetQueue()
# Print logged in message
consoleHelper.printColored("> {} logged in ({})".format(loginData[0], responseToken.token), bcolors.GREEN)
except exceptions.loginFailedException:
# Login failed error packet
# (we don't use enqueue because we don't have a token since login has failed)
@ -175,17 +167,10 @@ def handle(tornadoRequest):
# Bancho is restarting
responseData += serverPackets.notification("Bancho is restarting. Try again in a few minutes.")
responseData += serverPackets.loginError()
except:
# Unknown exception
msg = "UNKNOWN ERROR IN LOGIN!!!\n{}\n{}".format(sys.exc_info(), traceback.format_exc())
consoleHelper.printColored("[!] {}".format(msg), bcolors.RED)
finally:
# Print login failed message to console if needed
if err == True:
consoleHelper.printColored("> {}'s login failed".format(loginData[0]), bcolors.YELLOW)
# Discord message
discordBotHelper.sendConfidential("Bancho login request from {} for user {} ({})".format(requestIP, loginData[0], "failed" if err == True else "success"))
# Console and discord log
msg = "Bancho login request from {} for user {} ({})".format(requestIP, loginData[0], "failed" if err == True else "success")
log.info(msg, True)
# Return token string and data
return (responseTokenString, responseData)

View File

@ -3,6 +3,7 @@ from helpers import consoleHelper
from constants import bcolors
from constants import serverPackets
import time
from helpers import logHelper as log
def handle(userToken, _):
# get usertoken data
@ -36,4 +37,4 @@ def handle(userToken, _):
glob.tokens.deleteToken(requestToken)
# Console output
consoleHelper.printColored("> {} have been disconnected.".format(username), bcolors.YELLOW)
log.info("{} have been disconnected.".format(username))

View File

@ -1,6 +1,7 @@
from objects import glob
from constants import slotStatuses
from constants import serverPackets
from helpers import logHelper as log
def handle(userToken, packetData):
# Get usertoken data
@ -22,10 +23,6 @@ def handle(userToken, packetData):
# Change slot id in packetData
slotID = match.getUserSlotID(userID)
'''opd = packetData[4]
packetData = bytearray(packetData)
packetData[4] = slotID
print("User: {}, slot {}, oldPackData: {}, packData {}".format(userID, slotID, opd, packetData[4]))'''
# Enqueue frames to who's playing
for i in range(0,16):

View File

@ -1,7 +1,6 @@
from objects import glob
from events import channelPartEvent
from helpers import consoleHelper
from constants import bcolors
from helpers import logHelper as log
def handle(userToken, _):
# Get usertoken data
@ -15,4 +14,4 @@ def handle(userToken, _):
channelPartEvent.partChannel(userToken, "#lobby", True)
# Console output
consoleHelper.printColored("> {} has left multiplayer lobby".format(username), bcolors.BLUE)
log.info("{} has left multiplayer lobby".format(username))

View File

@ -7,6 +7,7 @@ from objects import fokabot
from constants import exceptions
from constants import messageTemplates
from helpers import generalFunctions
from helpers import logHelper as log
def handle(userToken, packetData):
"""
@ -28,7 +29,7 @@ def handle(userToken, packetData):
fokaMessage = fokabot.fokabotResponse(username, packetData["to"], packetData["message"])
if fokaMessage != False:
userToken.enqueue(serverPackets.sendMessage("FokaBot", username, fokaMessage))
consoleHelper.printColored("> FokaBot>{}: {}".format(packetData["to"], str(fokaMessage.encode("UTF-8"))), bcolors.PINK)
log.pm("FokaBot -> {}: {}".format(packetData["to"], str(fokaMessage.encode("UTF-8"))))
else:
# Send packet message to target if it exists
token = glob.tokens.getTokenFromUsername(packetData["to"])
@ -46,12 +47,12 @@ def handle(userToken, packetData):
if token.awayMessage != "":
userToken.enqueue(serverPackets.sendMessage(packetData["to"], username, "This user is away: {}".format(token.awayMessage)))
# Console output
consoleHelper.printColored("> {}>{}: {}".format(username, packetData["to"], packetData["message"]), bcolors.PINK)
# Console and file output
log.pm("{} -> {}: {}".format(username, packetData["to"], packetData["message"]))
# Log to file
with open(".data/chatlog_private.txt", "a") as f:
f.write("[{date}] {fro} -> {to}: {message}\n".format(date=generalFunctions.getTimestamp(), fro=username, to=packetData["to"], message=str(packetData["message"].encode("utf-8"))[2:-1]))
# Log to chatlog_private
#with open(".data/chatlog_private.txt", "a") as f:
# f.write("[{date}] {fro} -> {to}: {message}\n".format(date=generalFunctions.getTimestamp(), fro=username, to=packetData["to"], message=str(packetData["message"].encode("utf-8"))[2:-1]))
except exceptions.tokenNotFoundException:
# Token not found, user disconnected
consoleHelper.printColored("[!] {} tried to send a message to {}, but their token couldn't be found".format(username, packetData["to"]), bcolors.RED)
log.warning("{} tried to send a message to {}, but their token couldn't be found".format(username, packetData["to"]))

View File

@ -2,10 +2,9 @@ from constants import exceptions
from constants import clientPackets
from objects import glob
from objects import fokabot
from helpers import consoleHelper
from constants import bcolors
from constants import serverPackets
from helpers import discordBotHelper
from helpers import logHelper as log
def handle(userToken, packetData):
"""
@ -97,16 +96,16 @@ def handle(userToken, packetData):
if fokaMessage != False:
who.append(userID)
glob.tokens.multipleEnqueue(serverPackets.sendMessage("FokaBot", packetData["to"], fokaMessage), who, False)
consoleHelper.printColored("> FokaBot@{}: {}".format(packetData["to"], str(fokaMessage.encode("UTF-8"))), bcolors.PINK)
log.chat("FokaBot @ {}: {}".format(packetData["to"], str(fokaMessage.encode("UTF-8"))))
# Console output
consoleHelper.printColored("> {}@{}: {}".format(username, packetData["to"], str(packetData["message"].encode("utf-8"))), bcolors.PINK)
# Console and file log
log.chat("{fro} @ {to}: {message}".format(fro=username, to=packetData["to"], message=str(packetData["message"].encode("utf-8"))))
# Discord/file log
discordBotHelper.sendChatlog("**{fro}{type}{to}:** {message}".format(fro=username, type="@" if packetData["to"].startswith("#") else ">", to=packetData["to"], message=str(packetData["message"].encode("utf-8"))[2:-1]))
# Discord log
discordBotHelper.sendChatlog("**{fro} @ {to}:** {message}".format(fro=username, to=packetData["to"], message=str(packetData["message"].encode("utf-8"))[2:-1]))
except exceptions.channelModeratedException:
consoleHelper.printColored("[!] {} tried to send a message to a channel that is in moderated mode ({})".format(username, packetData["to"]), bcolors.RED)
log.warning("{} tried to send a message to a channel that is in moderated mode ({})".format(username, packetData["to"]))
except exceptions.channelUnknownException:
consoleHelper.printColored("[!] {} tried to send a message to an unknown channel ({})".format(username, packetData["to"]), bcolors.RED)
log.warning("{} tried to send a message to an unknown channel ({})".format(username, packetData["to"]))
except exceptions.channelNoPermissionsException:
consoleHelper.printColored("[!] {} tried to send a message to channel {}, but they have no write permissions".format(username, packetData["to"]), bcolors.RED)
log.warning("{} tried to send a message to channel {}, but they have no write permissions".format(username, packetData["to"]))

View File

@ -1,5 +1,6 @@
from constants import clientPackets
from constants import serverPackets
from helpers import logHelper as log
def handle(userToken, packetData):
# get token data
@ -17,4 +18,4 @@ def handle(userToken, packetData):
else:
fokaMessage = "Your away message is now: {}".format(packetData["awayMessage"])
userToken.enqueue(serverPackets.sendMessage("FokaBot", username, fokaMessage))
print("{} has changed their away message to: {}".format(username, packetData["awayMessage"]))
log.info("{} has changed their away message to: {}".format(username, packetData["awayMessage"]))

View File

@ -1,6 +1,4 @@
from objects import glob
from helpers import consoleHelper
from constants import bcolors
from constants import serverPackets
from constants import exceptions
@ -9,7 +7,6 @@ def handle(userToken, packetData):
userID = userToken.userID
# Send spectator frames to every spectator
consoleHelper.printColored("> {}'s spectators: {}".format(str(userID), str(userToken.spectators)), bcolors.BLUE)
for i in userToken.spectators:
# Send to every user but host
if i != userID:

View File

@ -1,10 +1,9 @@
from helpers import consoleHelper
from constants import bcolors
from constants import clientPackets
from constants import serverPackets
from constants import exceptions
from objects import glob
from helpers import userHelper
from helpers import logHelper as log
def handle(userToken, packetData):
try:
@ -43,9 +42,8 @@ def handle(userToken, packetData):
targetToken.enqueue(serverPackets.channelJoinSuccess(userID, "#spectator"))
# Console output
consoleHelper.printColored("> {} are spectating {}".format(username, userHelper.getUsername(packetData["userID"])), bcolors.PINK)
consoleHelper.printColored("> {}'s spectators: {}".format(str(packetData["userID"]), str(targetToken.spectators)), bcolors.BLUE)
log.info("{} are spectating {}".format(username, userHelper.getUsername(packetData["userID"])))
except exceptions.tokenNotFoundException:
# Stop spectating if token not found
consoleHelper.printColored("[!] Spectator start: token not found", bcolors.RED)
log.warning("Spectator start: token not found")
userToken.stopSpectating()

View File

@ -1,8 +1,7 @@
from helpers import consoleHelper
from constants import bcolors
from objects import glob
from constants import serverPackets
from constants import exceptions
from helpers import logHelper as log
def handle(userToken, _):
try:
@ -22,10 +21,9 @@ def handle(userToken, _):
# Console output
# TODO: Move messages in stop spectating
consoleHelper.printColored("> {} are no longer spectating whoever they were spectating".format(username), bcolors.PINK)
consoleHelper.printColored("> {}'s spectators: {}".format(str(target), str(targetToken.spectators)), bcolors.BLUE)
log.info("{} are no longer spectating whoever they were spectating".format(username))
except exceptions.tokenNotFoundException:
consoleHelper.printColored("[!] Spectator stop: token not found", bcolors.RED)
log.warning("Spectator stop: token not found")
finally:
# Set our spectating user to 0
userToken.stopSpectating()

View File

@ -2,9 +2,8 @@ from helpers import requestHelper
from constants import exceptions
import json
from objects import glob
from helpers import consoleHelper
from constants import bcolors
from helpers import systemHelper
from helpers import logHelper as log
class handler(requestHelper.asyncRequestHandler):
def asyncGet(self):
@ -17,10 +16,10 @@ class handler(requestHelper.asyncRequestHandler):
# Check ci key
key = self.get_argument("k")
if key is None or key != glob.conf.config["ci"]["key"]:
if key is None or key != glob.conf.config["server"]["cikey"]:
raise exceptions.invalidArgumentsException()
consoleHelper.printColored("[!] Ci event triggered!!", bcolors.PINK)
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.")
# Status code and message

View File

@ -44,15 +44,15 @@ from events import matchTransferHostEvent
from events import matchFailedEvent
from events import matchInviteEvent
from events import matchChangeTeamEvent
from helpers import discordBotHelper
import sys
import traceback
from helpers import logHelper as log
class handler(requestHelper.asyncRequestHandler):
def asyncPost(self):
try:
# Track time if needed
if glob.requestTime == True:
if glob.outputRequestTime == True:
# Start time
st = datetime.datetime.now()
@ -81,7 +81,6 @@ class handler(requestHelper.asyncRequestHandler):
# Token exists, get its object and lock it
userToken = glob.tokens.tokens[requestTokenString]
userToken.lock.acquire()
#consoleHelper.printColored("[{}] locked".format(userToken.token), bcolors.YELLOW)
# Keep reading packets until everything has been read
while pos < len(requestData):
@ -94,9 +93,8 @@ class handler(requestHelper.asyncRequestHandler):
packetData = requestData[pos:(pos+dataLength+7)]
# Console output if needed
if glob.conf.config["server"]["outputpackets"] == True and packetID != 4:
consoleHelper.printColored("Incoming packet ({})({}):".format(requestTokenString, userToken.username), bcolors.GREEN)
consoleHelper.printColored("Packet code: {}\nPacket length: {}\nSingle packet data: {}\n".format(str(packetID), str(dataLength), str(packetData)), bcolors.YELLOW)
if glob.outputPackets == True and packetID != 4:
log.debug("Incoming packet ({})({}):\n\nPacket code: {}\nPacket length: {}\nSingle packet data: {}\n".format(requestTokenString, userToken.username, str(packetID), str(dataLength), str(packetData)))
# Event handler
def handleEvent(ev):
@ -149,7 +147,7 @@ class handler(requestHelper.asyncRequestHandler):
if packetID in eventHandler:
eventHandler[packetID]()
else:
consoleHelper.printColored("[!] Unknown packet id from {} ({})".format(requestTokenString, packetID), bcolors.RED)
log.warning("Unknown packet id from {} ({})".format(requestTokenString, packetID))
# Update pos so we can read the next stacked packet
# +7 because we add packet ID bytes, unused byte and data length bytes
@ -166,21 +164,20 @@ class handler(requestHelper.asyncRequestHandler):
# Token not found. Disconnect that user
responseData = serverPackets.loginError()
responseData += serverPackets.notification("Whoops! Something went wrong, please login again.")
consoleHelper.printColored("[!] Received packet from unknown token ({}).".format(requestTokenString), bcolors.RED)
consoleHelper.printColored("> {} have been disconnected (invalid token)".format(requestTokenString), bcolors.YELLOW)
log.warning("Received packet from unknown token ({}).".format(requestTokenString))
log.info("{} have been disconnected (invalid token)".format(requestTokenString))
finally:
# Unlock token
if userToken != None:
#consoleHelper.printColored("[{}] unlocked".format(userToken.token), bcolors.GREEN)
userToken.lock.release()
if glob.requestTime == True:
if glob.outputRequestTime == True:
# End time
et = datetime.datetime.now()
# Total time:
tt = float((et.microsecond-st.microsecond)/1000)
consoleHelper.printColored("Request time: {}ms".format(tt), bcolors.PINK)
log.debug("Request time: {}ms".format(tt))
# Send server's response to client
# We don't use token object because we might not have a token (failed login)
@ -190,13 +187,16 @@ class handler(requestHelper.asyncRequestHandler):
self.add_header("Keep-Alive", "timeout=5, max=100")
self.add_header("Connection", "keep-alive")
self.add_header("Content-Type", "text/html; charset=UTF-8")
self.add_header("Vary", "Accept-Encoding")
self.add_header("Content-Encoding", "gzip")
self.write(gzip.compress(responseData, 6))
if glob.gzip == True:
self.add_header("Vary", "Accept-Encoding")
self.add_header("Content-Encoding", "gzip")
self.write(gzip.compress(responseData, int(glob.conf.config["server"]["gziplevel"])))
else:
self.write(responseData)
except:
msg = "Unhandled exception in mainHandler:\n```\n{}\n{}\n```".format(sys.exc_info(), traceback.format_exc())
consoleHelper.printColored("[!] {}".format(msg), bcolors.RED)
discordBotHelper.sendConfidential(msg, True)
log.error("{}".format(msg), True)
finally:
try:
if not self._finished:

View File

@ -48,19 +48,20 @@ class config:
self.config.get("db","database")
self.config.get("db","workers")
self.config.get("server","threads")
self.config.get("server","port")
self.config.get("server","localizeusers")
self.config.get("server","outputpackets")
self.config.get("server","outputrequesttime")
self.config.get("server","timeouttime")
self.config.get("server","timeoutlooptime")
self.config.get("server","threads")
self.config.get("server","gzip")
self.config.get("server","gziplevel")
self.config.get("server","localize")
self.config.get("server","cikey")
self.config.get("debug","enable")
self.config.get("debug","packets")
self.config.get("debug","time")
self.config.get("discord","enable")
self.config.get("discord","boturl")
self.config.get("discord","devgroup")
self.config.get("ci","key")
return True
except:
return False
@ -82,19 +83,20 @@ class config:
self.config.set("db", "workers", "4")
self.config.add_section("server")
self.config.set("server", "threads", "16")
self.config.set("server", "port", "5001")
self.config.set("server", "localizeusers", "1")
self.config.set("server", "outputpackets", "0")
self.config.set("server", "outputrequesttime", "0")
self.config.set("server", "timeoutlooptime", "100")
self.config.set("server", "timeouttime", "100")
self.config.set("server", "threads", "16")
self.config.set("server", "gzip", "1")
self.config.set("server", "gziplevel", "6")
self.config.set("server", "localize", "1")
self.config.set("server", "cikey", "changeme")
self.config.add_section("ci")
self.config.set("ci", "key", "changeme")
self.config.add_section("debug")
self.config.set("debug", "enable", "0")
self.config.set("debug", "packets", "0")
self.config.set("debug", "time", "0")
self.config.add_section("discord")
self.config.set("discord", "enable", "False")
self.config.set("discord", "enable", "0")
self.config.set("discord", "boturl", "")
self.config.set("discord", "devgroup", "")

View File

@ -127,10 +127,10 @@ class db:
if self.disconnected == True:
# If we were disconnected, set disconnected to false and print message
self.disconnected = False
consoleHelper.printColored("> Reconnected to MySQL server!", bcolors.GREEN)
log.error("> Reconnected to MySQL server!", bcolors.GREEN)
except:
# Can't ping MySQL server. Show error and call loop in 5 seconds
consoleHelper.printColored("[!] CRITICAL!! MySQL connection died! Make sure your MySQL server is running! Checking again in 5 seconds...", bcolors.RED)
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

View File

@ -1,8 +1,7 @@
import urllib.request
import json
from helpers import consoleHelper
from constants import bcolors
from helpers import logHelper as log
# API URL
URL = "http://ip.zxq.co/"
@ -16,15 +15,12 @@ def getCountry(ip):
return -- Country code (2 letters)
"""
# Default value, sent if API is memeing
country = "XX"
try:
# Try to get country from Pikolo Aul's Go-Sanic ip API
result = json.loads(urllib.request.urlopen("{}/{}".format(URL, ip), timeout=3).read().decode())["country"]
return result.upper()
except:
consoleHelper.printColored("[!] Error in get country", bcolors.RED)
log.error("Error in get country")
return "XX"
@ -36,13 +32,10 @@ def getLocation(ip):
return -- [latitude, longitude]
"""
# Default value, sent if API is memeing
data = [0,0]
try:
# Try to get position from Pikolo Aul's Go-Sanic ip API
result = json.loads(urllib.request.urlopen("{}/{}".format(URL, ip), timeout=3).read().decode())["loc"].split(",")
return [float(result[0]), float(result[1])]
except:
consoleHelper.printColored("[!] Error in get position", bcolors.RED)
log.error("Error in get position")
return [0,0]

View File

@ -1,8 +1,11 @@
from constants import bcolors
from helpers import discordBotHelper
from helpers import generalFunctions
from helpers.systemHelper import runningUnderUnix
from objects import glob
def logMessage(message, alertType = INFO, messageColor = bcolors.ENDC, discord = False, alertDev = False, of = None):
ENDL = "\n" if runningUnderUnix() else "\r\n"
def logMessage(message, alertType = "INFO", messageColor = bcolors.ENDC, discord = False, alertDev = False, of = None, stdout = True):
"""
Logs a message to stdout/discord/file
@ -12,15 +15,17 @@ def logMessage(message, alertType = INFO, messageColor = bcolors.ENDC, discord =
discord -- if True, the message will be logged on #bunker channel on discord. Default: False
alertDev -- if True, devs will receive an hl on discord. Default: False
of -- if not None but a string, log the message to that file (inside .data folder). Eg: "warnings.txt" Default: None (don't log to file)
stdout -- if True, print the message to stdout. Default: True
"""
# Get type color from alertType
if alertType == "INFO":
typeColor = bcolors.GREEN
elif alertType == "WARNING":
typeColor = bcolors.YELLOW
elif typeColor == "ERROR":
elif alertType == "ERROR":
typeColor = bcolors.RED
elif alertType == "CHAT":
typeColor = bcolors.BLUE
else:
typeColor = bcolors.ENDC
@ -37,8 +42,9 @@ def logMessage(message, alertType = INFO, messageColor = bcolors.ENDC, discord =
messageColor=messageColor,
endc=bcolors.ENDC)
# Always log to console
print(finalMessageConsole)
# Log to console
if stdout == True:
print(finalMessageConsole)
# Log to discord if needed
if discord == True:
@ -48,7 +54,7 @@ def logMessage(message, alertType = INFO, messageColor = bcolors.ENDC, discord =
if of != None:
# TODO: Lock
with open(".data/{}".format(of), "a") as f:
f.write(finalMessage)
f.write(finalMessage+ENDL)
def warning(message, discord = False, alertDev = False):
"""
@ -69,3 +75,38 @@ def error(message, discord = False, alertDev = True):
alertDev -- if True, send al hl to devs on discord. Optional. Default = False.
"""
logMessage(message, "ERROR", bcolors.RED, discord, alertDev, "errors.txt")
def info(message, discord = False, alertDev = False):
"""
Log an error to stdout (and info.log)
message -- info message
discord -- if True, send error to #bunker. 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")
def debug(message):
"""
Log a debug message to stdout and debug.log if server is running in debug mode
message -- debug message
"""
if glob.debug == True:
logMessage(message, "DEBUG", bcolors.PINK, of="debug.txt")
def chat(message):
"""
Log public messages to stdout and chatlog_public.txt
message -- chat message
"""
logMessage(message, "CHAT", bcolors.BLUE, of="chatlog_public.txt")
def pm(message):
"""
Log private messages to stdout and chatlog_private.txt
message -- chat message
"""
logMessage(message, "CHAT", bcolors.BLUE, of="chatlog_private.txt")

View File

@ -3,11 +3,9 @@ from constants import serverPackets
import psutil
import os
import sys
from helpers import consoleHelper
from constants import bcolors
import threading
import signal
from helpers import logHelper as log
def runningUnderUnix():
"""
@ -29,8 +27,8 @@ def scheduleShutdown(sendRestartTime, restart, message = ""):
"""
# Console output
consoleHelper.printColored("[!] Pep.py will {} in {} seconds!".format("restart" if restart else "shutdown", sendRestartTime+20), bcolors.PINK)
consoleHelper.printColored("[!] Sending server restart packets in {} seconds...".format(sendRestartTime), bcolors.PINK)
log.info("Pep.py will {} in {} seconds!".format("restart" if restart else "shutdown", sendRestartTime+20))
log.info("Sending server restart packets in {} seconds...".format(sendRestartTime))
# Send notification if set
if message != "":
@ -52,13 +50,13 @@ def scheduleShutdown(sendRestartTime, restart, message = ""):
def restartServer():
"""Restart pep.py script"""
print("> Restarting pep.py...")
log.info("Restarting pep.py...")
os.execv(sys.executable, [sys.executable] + sys.argv)
def shutdownServer():
"""Shutdown pep.py"""
print("> Shutting down pep.py...")
log.info("> Shutting down pep.py...")
sig = signal.SIGKILL if runningUnderUnix() else signal.CTRL_C_EVENT
os.kill(os.getpid(), sig)

View File

@ -14,5 +14,11 @@ channels = channelList.channelList()
matches = matchList.matchList()
restarting = False
pool = None
requestTime = False
debug = False
outputRequestTime = False
outputPackets = False
discord = False
gzip = False
localize = False

View File

@ -10,6 +10,7 @@ from constants import bcolors
from constants import serverPackets
from constants import dataTypes
from constants import matchTeams
from helpers import logHelper as log
class match:
"""Multiplayer match object"""
@ -128,7 +129,7 @@ class match:
if token != None:
token.enqueue(serverPackets.matchTransferHost())
consoleHelper.printColored("> MPROOM{}: {} is now the host".format(self.matchID, newHost), bcolors.BLUE)
log.info("MPROOM{}: {} is now the host".format(self.matchID, newHost))
def setSlot(self, slotID, slotStatus = None, slotTeam = None, slotUserID = None, slotMods = None, slotLoaded = None, slotSkip = None, slotComplete = None):
"""
@ -177,7 +178,7 @@ class match:
# Set new slot data and send update
self.setSlot(slotID, None, None, None, mods)
self.sendUpdate()
consoleHelper.printColored("> MPROOM{}: Slot{} mods changed to {}".format(self.matchID, slotID, mods), bcolors.BLUE)
log.info("MPROOM{}: Slot{} mods changed to {}".format(self.matchID, slotID, mods))
def toggleSlotReady(self, slotID):
@ -195,7 +196,7 @@ class match:
newStatus = slotStatuses.ready
self.setSlot(slotID, newStatus, None, None, None)
self.sendUpdate()
consoleHelper.printColored("> MPROOM{}: Slot{} changed ready status to {}".format(self.matchID, slotID, self.slots[slotID]["status"]), bcolors.BLUE)
log.info("MPROOM{}: Slot{} changed ready status to {}".format(self.matchID, slotID, self.slots[slotID]["status"]))
def toggleSlotLock(self, slotID):
"""
@ -224,7 +225,7 @@ class match:
# Send updates to everyone else
self.sendUpdate()
consoleHelper.printColored("> MPROOM{}: Slot{} {}".format(self.matchID, slotID, "locked" if newStatus == slotStatuses.locked else "unlocked"), bcolors.BLUE)
log.info("MPROOM{}: Slot{} {}".format(self.matchID, slotID, "locked" if newStatus == slotStatuses.locked else "unlocked"))
def playerLoaded(self, userID):
"""
@ -238,7 +239,7 @@ class match:
# Set loaded to True
self.slots[slotID]["loaded"] = True
consoleHelper.printColored("> MPROOM{}: User {} loaded".format(self.matchID, userID), bcolors.BLUE)
log.info("MPROOM{}: User {} loaded".format(self.matchID, userID))
# Check all loaded
total = 0
@ -261,7 +262,7 @@ class match:
if token != None:
token.enqueue(serverPackets.allPlayersLoaded())
consoleHelper.printColored("> MPROOM{}: All players loaded! Corrispondere iniziare in 3...".format(self.matchID), bcolors.BLUE)
log.info("MPROOM{}: All players loaded! Match starting...".format(self.matchID))
def playerSkip(self, userID):
@ -276,7 +277,7 @@ class match:
# Set skip to True
self.slots[slotID]["skip"] = True
consoleHelper.printColored("> MPROOM{}: User {} skipped".format(self.matchID, userID), bcolors.BLUE)
log.info("MPROOM{}: User {} skipped".format(self.matchID, userID))
# Send skip packet to every playing useR
for i in range(0,16):
@ -284,7 +285,6 @@ class match:
if self.slots[i]["status"] == slotStatuses.playing and uid > -1:
token = glob.tokens.getTokenFromUserID(uid)
if token != None:
print("Enqueueueue {}".format(uid))
token.enqueue(serverPackets.playerSkipped(uid))
# Check all skipped
@ -307,7 +307,7 @@ class match:
if token != None:
token.enqueue(serverPackets.allPlayersSkipped())
consoleHelper.printColored("> MPROOM{}: All players skipped!".format(self.matchID), bcolors.BLUE)
log.info("MPROOM{}: All players have skipped!".format(self.matchID))
def playerCompleted(self, userID):
"""
@ -321,7 +321,7 @@ class match:
self.setSlot(slotID, None, None, None, None, None, None, True)
# Console output
consoleHelper.printColored("> MPROOM{}: User {} has completed".format(self.matchID, userID), bcolors.BLUE)
log.info("MPROOM{}: User {} has completed his play".format(self.matchID, userID))
# Check all completed
total = 0
@ -360,7 +360,7 @@ class match:
token.enqueue(serverPackets.matchComplete())
# Console output
consoleHelper.printColored("> MPROOM{}: Match completed".format(self.matchID), bcolors.BLUE)
log.info("MPROOM{}: Match completed".format(self.matchID))
@ -395,7 +395,7 @@ class match:
self.sendUpdate()
# Console output
consoleHelper.printColored("> MPROOM{}: {} joined the room".format(self.matchID, userID), bcolors.BLUE)
log.info("MPROOM{}: {} joined the room".format(self.matchID, userID))
return True
@ -420,7 +420,7 @@ class match:
if self.countUsers() == 0:
# Dispose match
glob.matches.disposeMatch(self.matchID)
consoleHelper.printColored("> MPROOM{}: Room disposed".format(self.matchID), bcolors.BLUE)
log.info("MPROOM{}: Room disposed".format(self.matchID))
return
# Check if host left
@ -436,7 +436,7 @@ class match:
self.sendUpdate()
# Console output
consoleHelper.printColored("> MPROOM{}: {} left the room".format(self.matchID, userID), bcolors.BLUE)
log.info("MPROOM{}: {} left the room".format(self.matchID, userID))
def userChangeSlot(self, userID, newSlotID):
@ -469,7 +469,7 @@ class match:
self.sendUpdate()
# Console output
consoleHelper.printColored("> MPROOM{}: {} moved to slot {}".format(self.matchID, userID, newSlotID), bcolors.BLUE)
log.info("MPROOM{}: {} moved to slot {}".format(self.matchID, userID, newSlotID))
def changePassword(self, newPassword):
"""
@ -490,7 +490,7 @@ class match:
self.sendUpdate()
# Console output
consoleHelper.printColored("> MPROOM{}: Password changed to {}".format(self.matchID, self.matchPassword), bcolors.BLUE)
log.info("MPROOM{}: Password changed to {}".format(self.matchID, self.matchPassword))
def changeMatchMods(self, mods):
@ -502,7 +502,7 @@ class match:
# Set new mods and send update
self.mods = mods
self.sendUpdate()
consoleHelper.printColored("> MPROOM{}: Mods changed to {}".format(self.matchID, self.mods), bcolors.BLUE)
log.info("MPROOM{}: Mods changed to {}".format(self.matchID, self.mods))
def userHasBeatmap(self, userID, has = True):
"""
@ -560,7 +560,7 @@ class match:
token.enqueue(serverPackets.playerFailed(slotID))
# Console output
consoleHelper.printColored("> MPROOM{}: {} has failed!".format(self.matchID, userID), bcolors.BLUE)
log.info("MPROOM{}: {} has failed!".format(self.matchID, userID))
def invite(self, fro, to):
@ -649,8 +649,8 @@ class match:
if firstTeam == -1:
firstTeam = self.slots[i]["team"]
elif firstTeam != self.slots[i]["teams"]:
consoleHelper.printColored("> MPROOM{}: Teams are valid".format(self.matchID), bcolors.BLUE)
log.info("MPROOM{}: Teams are valid".format(self.matchID))
return True
consoleHelper.printColored("> MPROOM{}: Invalid teams!".format(self.matchID), bcolors.RED)
log.warning("MPROOM{}: Invalid teams!".format(self.matchID))
return False

62
pep.py
View File

@ -12,13 +12,13 @@ import tornado.gen
# pep.py files
from constants import bcolors
from helpers import configHelper
from helpers import discordBotHelper
from objects import glob
from objects import fokabot
from objects import banchoConfig
from helpers import consoleHelper
from helpers import databaseHelperNew
from helpers import generalFunctions
from helpers import logHelper as log
from handlers import mainHandler
from handlers import apiIsOnlineHandler
@ -71,15 +71,6 @@ if __name__ == "__main__":
consoleHelper.printColored("[!] Error while connection to database. Please check your config.ini and run the server again", bcolors.RED)
raise
# 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)
# Load bancho_settings
try:
consoleHelper.printNoNl("> Loading bancho settings from DB... ")
@ -90,6 +81,15 @@ if __name__ == "__main__":
consoleHelper.printColored("[!] Error while loading bancho_settings. Please make sure the table in DB has all the required rows", bcolors.RED)
raise
# 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)
# Create data folder if needed
consoleHelper.printNoNl("> Checking folders... ")
paths = [".data"]
@ -109,31 +109,41 @@ if __name__ == "__main__":
consoleHelper.printDone()
# Initialize user timeout check loop
try:
consoleHelper.printNoNl("> Initializing user timeout check loop... ")
glob.tokens.usersTimeoutCheckLoop(int(glob.conf.config["server"]["timeouttime"]), int(glob.conf.config["server"]["timeoutlooptime"]))
consoleHelper.printDone()
except:
consoleHelper.printError()
consoleHelper.printColored("[!] Error while initializing user timeout check loop", bcolors.RED)
consoleHelper.printColored("[!] Make sure that 'timeouttime' and 'timeoutlooptime' in config.ini are numbers", bcolors.RED)
raise
consoleHelper.printNoNl("> Initializing user timeout check loop... ")
glob.tokens.usersTimeoutCheckLoop()
consoleHelper.printDone()
# Localize warning
if generalFunctions.stringToBool(glob.conf.config["server"]["localizeusers"]) == False:
consoleHelper.printColored("[!] Warning! users localization is disabled!", bcolors.YELLOW)
glob.localize = generalFunctions.stringToBool(glob.conf.config["server"]["localize"])
if glob.localize == False:
consoleHelper.printColored("[!] Warning! Users localization is disabled!", bcolors.YELLOW)
# Discord
glob.discord = generalFunctions.stringToBool(glob.conf.config["discord"]["enable"])
if glob.discord == False:
consoleHelper.printColored("[!] Discord logging is disabled!", bcolors.YELLOW)
consoleHelper.printColored("[!] Warning! Discord logging is disabled!", bcolors.YELLOW)
# Get server parameters from config.ini
serverPort = int(glob.conf.config["server"]["port"])
glob.requestTime = generalFunctions.stringToBool(glob.conf.config["server"]["outputrequesttime"])
# Gzip
glob.gzip = generalFunctions.stringToBool(glob.conf.config["server"]["gzip"])
glob.gziplevel = int(glob.conf.config["server"]["gziplevel"])
if glob.gzip == False:
consoleHelper.printColored("[!] Warning! Gzip compression is disabled!", bcolors.YELLOW)
# Debug mode
glob.debug = generalFunctions.stringToBool(glob.conf.config["debug"]["enable"])
glob.outputPackets = generalFunctions.stringToBool(glob.conf.config["debug"]["packets"])
glob.outputRequestTime = generalFunctions.stringToBool(glob.conf.config["debug"]["time"])
if glob.debug == True:
consoleHelper.printColored("[!] Warning! Server running in debug mode!", bcolors.YELLOW)
# Server port
try:
serverPort = int(glob.conf.config["server"]["port"])
except:
consoleHelper.printColored("[!] Invalid server port! Please check your config.ini and run the server again", bcolors.RED)
# Server start message and console output
discordBotHelper.sendConfidential("Server started!")
log.logMessage("Server started!", discord=True, of="info.txt", stdout=False)
consoleHelper.printColored("> Tornado listening for clients on 127.0.0.1:{}...".format(serverPort), bcolors.GREEN)
# Start tornado