class handler(requestsManager.asyncRequestHandler):
	def asyncGet(self): class handler(requestsManager.asyncRequestHandler):
	def asyncGet(self): class handler(requestsManager.asyncRequestHandler):
	def asyncGet(self): class handler(requestsManager.asyncRequestHandler):
	def asyncGet(self): class handler(requestsManager.asyncRequestHandler):
	def asyncGet(self): class handler(requestsManager.asyncRequestHandler):
	def asyncGet(self): class handler(requestsManager.asyncRequestHandler):
	def asyncGet(self): class config:
	def __init__(self, file):
	def reload(self):
	def checkConfig(self, parsedConfig=None):
	def generateDefaultConfig(self): def printServerStartHeader(asciiArt=True):
def printNoNl(string):
def printColored(string, color):
def printError():
def printDone():
def printWarning(): def dispose():
def runningUnderUnix():
def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
def restartServer():
def shutdownServer():
def getSystemInfo(): class Client:
class Server:
	def __init__(self, server, sock):
	def messageChannel(self, channel, command, message, includeSelf=False):
	def message(self, msg):
	def writeBufferSize(self):
	def reply(self, msg):
	def replyCode(self, code, message, nickname="", channel=""):
	def reply403(self, channel):
	def reply461(self, command):
	def disconnect(self, quitmsg = "Client quit", callLogout = True):
	def readSocket(self):
	def parseBuffer(self):
	def writeSocket(self):
	def checkAlive(self):
	def sendLusers(self):
	def sendMotd(self):
	def dummyHandler(self, command, arguments):
	def passHandler(self, command, arguments):
	def registerHandler(self, command, arguments):
	def quitHandler(self, _, arguments):
	def joinHandler(self, _, arguments):
	def partHandler(self, _, arguments):
	def noticePrivmsgHandler(self, command, arguments):
	def motdHandler(self, command, arguments):
	def lusersHandler(self, command, arguments):
	def pingHandler(self, _, arguments):
	def pongHandler(self, command, arguments):
	def awayHandler(self, _, arguments):
	def mainHandler(self, command, arguments):
	def __init__(self, port):
	def forceDisconnection(self, username, isBanchoUsername=True):
	def banchoJoinChannel(self, username, channel):
	def banchoPartChannel(self, username, channel):
	def banchoMessage(self, fro, to, message):
	def removeClient(self, client, _):
	def start(self):
def main(port=6667): class banchoConfig:
	"""
	Class that loads settings from bancho_settings db table
	"""

	config = {"banchoMaintenance": False, "freeDirect": True, "menuIcon": "", "loginNotification": ""}

	def __init__(self, loadFromDB = True):
		"""
		Initialize a banchoConfig object (and load bancho_settings from db)

		loadFromDB -- if True, load values from db. If False, don't load values. Optional.
		"""
		if loadFromDB:
			try:
				self.loadSettings()
			except:
				raise


	def loadSettings(self):
		"""
		(re)load bancho_settings from DB and set values in config array
		"""
		self.config["banchoMaintenance"] = generalUtils.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'bancho_maintenance'")["value_int"])
		self.config["freeDirect"] = generalUtils.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'free_direct'")["value_int"])
		mainMenuIcon = glob.db.fetch("SELECT file_id, url FROM main_menu_icons WHERE is_current = 1 LIMIT 1")
		if mainMenuIcon is None:
			self.config["menuIcon"] = ""
		else:
			imageURL = "https://i.ppy.sh/{}.png".format(mainMenuIcon["file_id"])
			self.config["menuIcon"] = "{}|{}".format(imageURL, mainMenuIcon["url"])
		self.config["loginNotification"] = glob.db.fetch("SELECT value_string FROM bancho_settings WHERE name = 'login_notification'")["value_string"]


	def setMaintenance(self, maintenance):
		"""
		Turn on/off bancho maintenance mode. Write new value to db too

		maintenance -- if True, turn on maintenance mode. If false, turn it off
		"""
		self.config["banchoMaintenance"] = maintenance
		glob.db.execute("UPDATE bancho_settings SET value_int = %s WHERE name = 'bancho_maintenance'", [int(maintenance)])

	def reload(self):
		# Reload settings from bancho_settings
		glob.banchoConf.loadSettings()

		# Reload channels too
		glob.channels.loadChannels()

		# And chat filters
		glob.chatFilters.loadFilters()

		# Send new channels and new bottom icon to everyone
		glob.streams.broadcast("main", serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"]))
		glob.streams.broadcast("main", serverPackets.channelInfoEnd())
		for key, value in glob.channels.channels.items():
			if value.publicRead and not value.hidden:
				glob.streams.broadcast("main", serverPackets.channelInfo(key)) class chatFilters:
	def __init__(self, fileName="filters.txt"):
		"""
		Initialize chat filters

		:param fileName: name of the file containing filters. Default: filters.txt
		"""
		self.filters = {}
		self.loadFilters(fileName)

	def loadFilters(self, fileName="filters.txt"):
		"""
		Load filters from a file

		:param fileName: name of the file containing filters. Default: filters.txt
		:return:
		"""
		# Reset chat filters
		self.filters = {}

		# Open filters file
		with open(fileName, "r") as f:
			# Read all lines
			data = f.readlines()

			# Process each line
			for line in data:
				# Get old/new word and save it in dictionary
				lineSplit = line.split("=")
				self.filters[lineSplit[0].lower()] = lineSplit[1].replace("\n", "")

	def filterMessage(self, message):
		"""
		Replace forbidden words with filtered ones

		:param message: normal message
		:return: filtered message
		"""
		return message
		"""
		# Split words by spaces
		messageTemp = message.split(" ")

		# Check each word
		for word in messageTemp:
			lowerWord = word.lower()

			# If the word is filtered, replace it
			if lowerWord in self.filters:
				message = message.replace(word, self.filters[lowerWord])

		# Return filtered message
		return message
		""" def connect():
def disconnect():
def fokabotResponse(fro, chan, message): 		VERSION = f.read().strip()
	VERSION = "Unknown"
DATADOG_PREFIX = "peppy" def handleUsernameChange(userID, newUsername, targetToken=None):
	def __init__(self):
	def handle(self, data):
class handler(generalPubSubHandler.generalPubSubHandler): class handler(generalPubSubHandler.generalPubSubHandler):
	def __init__(self):
	def handle(self, data): class handler(generalPubSubHandler.generalPubSubHandler):
	def __init__(self):
	def handle(self, data): class handler(generalPubSubHandler.generalPubSubHandler):
	def __init__(self):
	def handle(self, userID): class handler(generalPubSubHandler.generalPubSubHandler):
	def __init__(self):
	def handle(self, data): class handler(generalPubSubHandler.generalPubSubHandler):
	def __init__(self):
	def handle(self, userID): class handler(generalPubSubHandler.generalPubSubHandler):
	def __init__(self):
	def handle(self, userID):
import os
import sys
import threading
import tornado.gen
import tornado.httpserver
import tornado.ioloop
import tornado.web
import redis
from multiprocessing.pool import ThreadPool
from raven.contrib.tornado import AsyncSentryClient
from common import generalUtils, agpl
from common.constants import bcolors
from common.db import dbConnector
from common.ddog import datadogClient
from common.log import logUtils as log
from common.redis import pubSub
from common.web import schiavo
from handlers import apiFokabotMessageHandler
from handlers import apiIsOnlineHandler
from handlers import apiOnlineUsersHandler
from handlers import apiServerStatusHandler
from handlers import apiVerifiedStatusHandler
from handlers import ciTriggerHandler
from handlers import mainHandler
from handlers import heavyHandler
from helpers import configHelper
from helpers import consoleHelper
from helpers import systemHelper as system
from irc import ircserver
from objects import banchoConfig
from objects import chatFilters
from objects import fokabot
from objects import glob
from pubSubHandlers import changeUsernameHandler, setMainMenuIconHandler
from pubSubHandlers import disconnectHandler
from pubSubHandlers import banHandler
from pubSubHandlers import notificationHandler
from pubSubHandlers import updateSilenceHandler
from pubSubHandlers import updateStatsHandler
		if not glob.conf.checkConfig():
			consoleHelper.printError()
			consoleHelper.printColored("[!] Invalid config.ini. Please configure it properly", bcolors.RED)
			consoleHelper.printColored("[!] Delete your config.ini to generate a default one", bcolors.RED)
			sys.exit()
		else:
			consoleHelper.printDone()

		# Create data folder if needed
		consoleHelper.printNoNl("> Checking folders... ")
		paths = [".data"]
		for i in paths:
			if not os.path.exists(i):
				os.makedirs(i, 0o770)
		consoleHelper.printDone()

		# Connect to db
		try:
			consoleHelper.printNoNl("> Connecting to MySQL database... ")
			glob.db = dbConnector.db(glob.conf.config["db"]["host"], glob.conf.config["db"]["username"], glob.conf.config["db"]["password"], glob.conf.config["db"]["database"], int(glob.conf.config["db"]["workers"]))
			consoleHelper.printNoNl(" ")
			consoleHelper.printDone()
		except:
			# Exception while connecting to db
			consoleHelper.printError()
			consoleHelper.printColored("[!] Error while connection to database. Please check your config.ini and run the server again", bcolors.RED)
			raise

		# Connect to redis
		try:
			consoleHelper.printNoNl("> Connecting to redis... ")
			glob.redis = redis.Redis(glob.conf.config["redis"]["host"], glob.conf.config["redis"]["port"], glob.conf.config["redis"]["database"], glob.conf.config["redis"]["password"])
			glob.redis.ping()
			consoleHelper.printNoNl(" ")
			consoleHelper.printDone()
		except:
			# Exception while connecting to db
			consoleHelper.printError()
			consoleHelper.printColored("[!] Error while connection to redis. Please check your config.ini and run the server again", bcolors.RED)
			raise

		# Empty redis cache
		try:
			# TODO: Make function or some redis meme
			glob.redis.set("ripple:online_users", 0)
			glob.redis.eval("return redis.call('del', unpack(redis.call('keys', ARGV[1])))", 0, "peppy:*")
		except redis.exceptions.ResponseError:
			# Script returns error if there are no keys starting with peppy:*
			pass

		# Save peppy version in redis
		glob.redis.set("peppy:version", glob.VERSION)

		# Load bancho_settings
		try:
			consoleHelper.printNoNl("> Loading bancho settings from DB... ")
			glob.banchoConf = banchoConfig.banchoConfig()
			consoleHelper.printDone()
		except:
			consoleHelper.printError()
			consoleHelper.printColored("[!] Error while loading bancho_settings. Please make sure the table in DB has all the required rows", bcolors.RED)
			raise

		# Delete old bancho sessions
		consoleHelper.printNoNl("> Deleting cached bancho sessions from DB... ")
		glob.tokens.deleteBanchoSessions()
		consoleHelper.printDone()

		# Create threads pool
		try:
			consoleHelper.printNoNl("> Creating threads pool... ")
			glob.pool = ThreadPool(int(glob.conf.config["server"]["threads"]))
			consoleHelper.printDone()
		except ValueError:
			consoleHelper.printError()
			consoleHelper.printColored("[!] Error while creating threads pool. Please check your config.ini and run the server again", bcolors.RED)

		try:
			consoleHelper.printNoNl("> Loading chat filters... ")
			glob.chatFilters = chatFilters.chatFilters()
			consoleHelper.printDone()
		except:
			consoleHelper.printError()
			consoleHelper.printColored("[!] Error while loading chat filters. Make sure there is a filters.txt file present", bcolors.RED)
			raise

		# Start fokabot
		consoleHelper.printNoNl("> Connecting FokaBot... ")
		fokabot.connect()
		consoleHelper.printDone()

		# Initialize chat channels
		print("> Initializing chat channels... ")
		glob.channels.loadChannels()
		consoleHelper.printDone()

		# Initialize stremas
		consoleHelper.printNoNl("> Creating packets streams... ")
		glob.streams.add("main")
		glob.streams.add("lobby")
		consoleHelper.printDone()

		# Initialize user timeout check loop
		consoleHelper.printNoNl("> Initializing user timeout check loop... ")
		glob.tokens.usersTimeoutCheckLoop()
		consoleHelper.printDone()

		# Initialize spam protection reset loop
		consoleHelper.printNoNl("> Initializing spam protection reset loop... ")
		glob.tokens.spamProtectionResetLoop()
		consoleHelper.printDone()

		# Initialize multiplayer cleanup loop
		consoleHelper.printNoNl("> Initializing multiplayer cleanup loop... ")
		glob.matches.cleanupLoop()
		consoleHelper.printDone()

		# Localize warning
		glob.localize = generalUtils.stringToBool(glob.conf.config["localize"]["enable"])
		if not glob.localize:

			consoleHelper.printColored("[!] Warning! Users localization is disabled!", bcolors.YELLOW)