# Path: constants/exceptions.py
# class loginFailedException(Exception):
# class loginBannedException(Exception):
# class tokenNotFoundException(Exception):
# class channelNoPermissionsException(Exception):
# class channelUnknownException(Exception):
# class channelModeratedException(Exception):
# class noAdminException(Exception):
# class commandSyntaxException(Exception):
# class banchoConfigErrorException(Exception):
# class banchoMaintenanceException(Exception):
# class moderatedPMException(Exception):
# class userNotFoundException(Exception):
# class alreadyConnectedException(Exception):
# class stopSpectating(Exception):
# class matchWrongPasswordException(Exception):
# class matchNotFoundException(Exception):
# class matchJoinErrorException(Exception):
# class matchCreateError(Exception):
# class banchoRestartingException(Exception):
# class apiException(Exception):
# class invalidArgumentsException(Exception):
# class messageTooLongWarnException(Exception):
# class messageTooLongException(Exception):
# class userSilencedException(Exception):
# class need2FAException(Exception):
# class userRestrictedException(Exception):
# class haxException(Exception):
# class forceUpdateException(Exception):
# class loginLockedException(Exception):
# class unknownStreamException(Exception):
# class userTournamentException(Exception):
# class userAlreadyInChannelException(Exception):
# class userNotInChannelException(Exception):
# class missingReportInfoException(Exception):
# class invalidUserException(Exception):
# class wrongChannelException(Exception):
# class periodicLoopException(Exception):
# 
# Path: constants/slotStatuses.py
# FREE = 1
# LOCKED = 2
# NOT_READY = 4
# READY = 8
# NO_MAP = 16
# PLAYING = 32
# OCCUPIED = 124
# PLAYING_QUIT = 128
# 
# Path: constants/matchModModes.py
# NORMAL = 0
# FREE_MOD = 1
# 
# Path: constants/matchTeams.py
# NO_TEAM = 0
# BLUE = 1
# RED = 2
# 
# Path: constants/matchTeamTypes.py
# HEAD_TO_HEAD = 0
# TAG_COOP = 1
# TEAM_VS = 2
# TAG_TEAM_VS = 3
# 
# Path: constants/matchScoringTypes.py
# SCORE = 0
# ACCURACY = 1
# COMBO = 2
# SCORE_V2 = 3
# 
# Path: constants/serverPackets.py
# def loginFailed():
# def forceUpdate():
# def loginBanned():
# def loginLocked():
# def loginError():
# def needSupporter():
# def needVerification():
# def userID(uid):
# def silenceEndTime(seconds):
# def protocolVersion(version = 19):
# def mainMenuIcon(icon):
# def userSupporterGMT(supporter, GMT, tournamentStaff):
# def friendList(userID):
# def onlineUsers():
# def userLogout(userID):
# def userPanel(userID, force = False):
# def userStats(userID, force = False):
# def sendMessage(fro, to, message):
# def channelJoinSuccess(userID, chan):
# def channelInfo(chan):
# def channelInfoEnd():
# def channelKicked(chan):
# def userSilenced(userID):
# def addSpectator(userID):
# def removeSpectator(userID):
# def spectatorFrames(data):
# def noSongSpectator(userID):
# def fellowSpectatorJoined(userID):
# def fellowSpectatorLeft(userID):
# def createMatch(matchID):
# def updateMatch(matchID, censored = False):
# def matchStart(matchID):
# def disposeMatch(matchID):
# def matchJoinSuccess(matchID):
# def matchJoinFail():
# def changeMatchPassword(newPassword):
# def allPlayersLoaded():
# def playerSkipped(userID):
# def allPlayersSkipped():
# def matchFrames(slotID, data):
# def matchComplete():
# def playerFailed(slotID):
# def matchTransferHost():
# def matchAbort():
# def switchServer(address):
# def notification(message):
# def banchoRestart(msUntilReconnection):
# def rtx(message):
# 
# Path: helpers/systemHelper.py
# def dispose():
# def runningUnderUnix():
# def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
# def restartServer():
# def shutdownServer():
# def getSystemInfo():
# 
# Path: objects/fokabot.py
# def connect():
# def disconnect():
# def fokabotResponse(fro, chan, message):
# 
# Path: objects/glob.py
# 		VERSION = f.read().strip()
# 	VERSION = "Unknown"
# DATADOG_PREFIX = "peppy"
# 
# Path: helpers/chatHelper.py
# def joinChannel(userID = 0, channel = "", token = None, toIRC = True, force=False):
# def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = False, force=False):
# def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
# def fixUsernameForBancho(username):
# def fixUsernameForIRC(username):
# def IRCConnect(username):
# def IRCDisconnect(username):
# def IRCJoinChannel(username, channel):
# def IRCPartChannel(username, channel):
# def IRCAway(username, message):


import json
import random
import re
import threading
import requests
import time
from common import generalUtils
from common.constants import mods
from common.log import logUtils as log
from common.ripple import userUtils
from constants import exceptions, slotStatuses, matchModModes, matchTeams, matchTeamTypes, matchScoringTypes
from common.constants import gameModes
from common.constants import privileges
from constants import serverPackets
from helpers import systemHelper
from objects import fokabot
from objects import glob
from helpers import chatHelper as chat
from common.web import cheesegull




def bloodcatMessage(beatmapID):
	beatmap = glob.db.fetch("SELECT song_name, beatmapset_id FROM beatmaps WHERE beatmap_id = %s LIMIT 1", [beatmapID])
	if beatmap is None:
		return "Sorry, I'm not able to provide a download link for this map :("
	return "Download [https://bloodcat.com/osu/s/{} {}] from Bloodcat".format(
		beatmap["beatmapset_id"],
		beatmap["song_name"],
	)

"""
Commands callbacks

Must have fro, chan and messages as arguments
:param fro: username of who triggered the command
:param chan: channel"(or username, if PM) where the message was sent
:param message: list containing arguments passed from the message
				[0] = first argument
				[1] = second argument
				. . .

return the message or **False** if there's no response by the bot
TODO: Change False to None, because False doesn't make any sense
"""
def instantRestart(fro, chan, message):

# Path: constants/exceptions.py
# class loginFailedException(Exception):
# class loginBannedException(Exception):
# class tokenNotFoundException(Exception):
# class channelNoPermissionsException(Exception):
# class channelUnknownException(Exception):
# class channelModeratedException(Exception):
# class noAdminException(Exception):
# class commandSyntaxException(Exception):
# class banchoConfigErrorException(Exception):
# class banchoMaintenanceException(Exception):
# class moderatedPMException(Exception):
# class userNotFoundException(Exception):
# class alreadyConnectedException(Exception):
# class stopSpectating(Exception):
# class matchWrongPasswordException(Exception):
# class matchNotFoundException(Exception):
# class matchJoinErrorException(Exception):
# class matchCreateError(Exception):
# class banchoRestartingException(Exception):
# class apiException(Exception):
# class invalidArgumentsException(Exception):
# class messageTooLongWarnException(Exception):
# class messageTooLongException(Exception):
# class userSilencedException(Exception):
# class need2FAException(Exception):
# class userRestrictedException(Exception):
# class haxException(Exception):
# class forceUpdateException(Exception):
# class loginLockedException(Exception):
# class unknownStreamException(Exception):
# class userTournamentException(Exception):
# class userAlreadyInChannelException(Exception):
# class userNotInChannelException(Exception):
# class missingReportInfoException(Exception):
# class invalidUserException(Exception):
# class wrongChannelException(Exception):
# class periodicLoopException(Exception):
# 
# Path: constants/slotStatuses.py
# FREE = 1
# LOCKED = 2
# NOT_READY = 4
# READY = 8
# NO_MAP = 16
# PLAYING = 32
# OCCUPIED = 124
# PLAYING_QUIT = 128
# 
# Path: constants/matchModModes.py
# NORMAL = 0
# FREE_MOD = 1
# 
# Path: constants/matchTeams.py
# NO_TEAM = 0
# BLUE = 1
# RED = 2
# 
# Path: constants/matchTeamTypes.py
# HEAD_TO_HEAD = 0
# TAG_COOP = 1
# TEAM_VS = 2
# TAG_TEAM_VS = 3
# 
# Path: constants/matchScoringTypes.py
# SCORE = 0
# ACCURACY = 1
# COMBO = 2
# SCORE_V2 = 3
# 
# Path: constants/serverPackets.py
# def loginFailed():
# def forceUpdate():
# def loginBanned():
# def loginLocked():
# def loginError():
# def needSupporter():
# def needVerification():
# def userID(uid):
# def silenceEndTime(seconds):
# def protocolVersion(version = 19):
# def mainMenuIcon(icon):
# def userSupporterGMT(supporter, GMT, tournamentStaff):
# def friendList(userID):
# def onlineUsers():
# def userLogout(userID):
# def userPanel(userID, force = False):
# def userStats(userID, force = False):
# def sendMessage(fro, to, message):
# def channelJoinSuccess(userID, chan):
# def channelInfo(chan):
# def channelInfoEnd():
# def channelKicked(chan):
# def userSilenced(userID):
# def addSpectator(userID):
# def removeSpectator(userID):
# def spectatorFrames(data):
# def noSongSpectator(userID):
# def fellowSpectatorJoined(userID):
# def fellowSpectatorLeft(userID):
# def createMatch(matchID):
# def updateMatch(matchID, censored = False):
# def matchStart(matchID):
# def disposeMatch(matchID):
# def matchJoinSuccess(matchID):
# def matchJoinFail():
# def changeMatchPassword(newPassword):
# def allPlayersLoaded():
# def playerSkipped(userID):
# def allPlayersSkipped():
# def matchFrames(slotID, data):
# def matchComplete():
# def playerFailed(slotID):
# def matchTransferHost():
# def matchAbort():
# def switchServer(address):
# def notification(message):
# def banchoRestart(msUntilReconnection):
# def rtx(message):
# 
# Path: helpers/systemHelper.py
# def dispose():
# def runningUnderUnix():
# def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
# def restartServer():
# def shutdownServer():
# def getSystemInfo():
# 
# Path: objects/fokabot.py
# def connect():
# def disconnect():
# def fokabotResponse(fro, chan, message):
# 
# Path: objects/glob.py
# 		VERSION = f.read().strip()
# 	VERSION = "Unknown"
# DATADOG_PREFIX = "peppy"
# 
# Path: helpers/chatHelper.py
# def joinChannel(userID = 0, channel = "", token = None, toIRC = True, force=False):
# def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = False, force=False):
# def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
# def fixUsernameForBancho(username):
# def fixUsernameForIRC(username):
# def IRCConnect(username):
# def IRCDisconnect(username):
# def IRCJoinChannel(username, channel):
# def IRCPartChannel(username, channel):
# def IRCAway(username, message):


# Path: constants/fokabotCommands.py
import json
import random
import re
import threading
import requests
import time
from common import generalUtils
from common.constants import mods
from common.log import logUtils as log
from common.ripple import userUtils
from constants import exceptions, slotStatuses, matchModModes, matchTeams, matchTeamTypes, matchScoringTypes
from common.constants import gameModes
from common.constants import privileges
from constants import serverPackets
from helpers import systemHelper
from objects import fokabot
from objects import glob
from helpers import chatHelper as chat
from common.web import cheesegull





def bloodcatMessage(beatmapID):
	beatmap = glob.db.fetch("SELECT song_name, beatmapset_id FROM beatmaps WHERE beatmap_id = %s LIMIT 1", [beatmapID])
	if beatmap is None:
		return "Sorry, I'm not able to provide a download link for this map :("
	return "Download [https://bloodcat.com/osu/s/{} {}] from Bloodcat".format(
		beatmap["beatmapset_id"],
		beatmap["song_name"],
	)

"""
Commands callbacks

Must have fro, chan and messages as arguments
:param fro: username of who triggered the command
:param chan: channel"(or username, if PM) where the message was sent
:param message: list containing arguments passed from the message
				[0] = first argument
				[1] = second argument
				. . .

return the message or **False** if there's no response by the bot
TODO: Change False to None, because False doesn't make any sense
"""
def instantRestart(fro, chan, message):

	glob.streams.broadcast("main", serverPackets.notification("We are restarting Bancho. Be right back!"))