IRC Support for username with spaces
BATs with Donor have bright yellow username in chat General performance improvements Code cleaning Multiplayer improvements and fixes Fixed some spectator bugs
This commit is contained in:
parent
e16e4d7493
commit
653303831b
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -2,3 +2,4 @@
|
||||||
config.ini
|
config.ini
|
||||||
filters.txt
|
filters.txt
|
||||||
.data
|
.data
|
||||||
|
.idea
|
|
@ -57,13 +57,12 @@ def addRemoveFriend(stream):
|
||||||
return packetHelper.readPacketData(stream, [["friendID", dataTypes.sInt32]])
|
return packetHelper.readPacketData(stream, [["friendID", dataTypes.sInt32]])
|
||||||
|
|
||||||
|
|
||||||
|
""" Spectator packets """
|
||||||
""" SPECTATOR PACKETS """
|
|
||||||
def startSpectating(stream):
|
def startSpectating(stream):
|
||||||
return packetHelper.readPacketData(stream,[["userID", dataTypes.sInt32]])
|
return packetHelper.readPacketData(stream,[["userID", dataTypes.sInt32]])
|
||||||
|
|
||||||
|
|
||||||
""" MULTIPLAYER PACKETS """
|
""" Multiplayer packets """
|
||||||
def matchSettings(stream):
|
def matchSettings(stream):
|
||||||
# Data to return, will be merged later
|
# Data to return, will be merged later
|
||||||
data = []
|
data = []
|
||||||
|
@ -115,9 +114,6 @@ def matchSettings(stream):
|
||||||
# Read last part
|
# Read last part
|
||||||
data.append(packetHelper.readPacketData(stream[start:], struct, False))
|
data.append(packetHelper.readPacketData(stream[start:], struct, False))
|
||||||
|
|
||||||
# Mods if freemod (not used)
|
|
||||||
#if data[1]["freeMods"] == 1:
|
|
||||||
|
|
||||||
result = {}
|
result = {}
|
||||||
for i in data:
|
for i in data:
|
||||||
result.update(i)
|
result.update(i)
|
||||||
|
|
|
@ -25,8 +25,8 @@ message -- list containing arguments passed from the message
|
||||||
. . .
|
. . .
|
||||||
|
|
||||||
return the message or **False** if there's no response by the bot
|
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):
|
def instantRestart(fro, chan, message):
|
||||||
glob.tokens.enqueueAll(serverPackets.notification("We are restarting Bancho. Be right back!"))
|
glob.tokens.enqueueAll(serverPackets.notification("We are restarting Bancho. Be right back!"))
|
||||||
systemHelper.scheduleShutdown(0, True, delay=1)
|
systemHelper.scheduleShutdown(0, True, delay=1)
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
"""Contains readable gamemodes with their codes"""
|
|
||||||
std = 0
|
std = 0
|
||||||
taiko = 1
|
taiko = 1
|
||||||
ctb = 2
|
ctb = 2
|
||||||
|
@ -9,10 +8,8 @@ def getGameModeForDB(gameMode):
|
||||||
Convert a gamemode number to string for database table/column
|
Convert a gamemode number to string for database table/column
|
||||||
|
|
||||||
gameMode -- gameMode int or variable (ex: gameMode.std)
|
gameMode -- gameMode int or variable (ex: gameMode.std)
|
||||||
|
|
||||||
return -- game mode readable string for db
|
return -- game mode readable string for db
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if gameMode == std:
|
if gameMode == std:
|
||||||
return "std"
|
return "std"
|
||||||
elif gameMode == taiko:
|
elif gameMode == taiko:
|
||||||
|
@ -27,10 +24,8 @@ def getGameModeForPrinting(gameMode):
|
||||||
Convert a gamemode number to string for showing to a user (e.g. !last)
|
Convert a gamemode number to string for showing to a user (e.g. !last)
|
||||||
|
|
||||||
gameMode -- gameMode int or variable (ex: gameMode.std)
|
gameMode -- gameMode int or variable (ex: gameMode.std)
|
||||||
|
|
||||||
return -- game mode readable string for a human
|
return -- game mode readable string for a human
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if gameMode == std:
|
if gameMode == std:
|
||||||
return "osu!"
|
return "osu!"
|
||||||
elif gameMode == taiko:
|
elif gameMode == taiko:
|
||||||
|
|
|
@ -5,9 +5,9 @@ from helpers import userHelper
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from constants import userRanks
|
from constants import userRanks
|
||||||
from constants import packetIDs
|
from constants import packetIDs
|
||||||
|
from constants import privileges
|
||||||
|
|
||||||
""" Login errors packets
|
""" Login errors packets """
|
||||||
(userID packets derivates) """
|
|
||||||
def loginFailed():
|
def loginFailed():
|
||||||
return packetHelper.buildPacket(packetIDs.server_userID, [[-1, dataTypes.sInt32]])
|
return packetHelper.buildPacket(packetIDs.server_userID, [[-1, dataTypes.sInt32]])
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ def loginBanned():
|
||||||
packets = packetHelper.buildPacket(packetIDs.server_userID, [[-1, dataTypes.sInt32]])
|
packets = packetHelper.buildPacket(packetIDs.server_userID, [[-1, dataTypes.sInt32]])
|
||||||
packets += notification("You are banned. You can ask to get unbanned after 1 month since your ban by contacting support@ripple.moe")
|
packets += notification("You are banned. You can ask to get unbanned after 1 month since your ban by contacting support@ripple.moe")
|
||||||
return packets
|
return packets
|
||||||
#return packetHelper.buildPacket(packetIDs.server_userID, [[-3, dataTypes.sInt32]])
|
|
||||||
|
|
||||||
def loginError():
|
def loginError():
|
||||||
return packetHelper.buildPacket(packetIDs.server_userID, [[-5, dataTypes.sInt32]])
|
return packetHelper.buildPacket(packetIDs.server_userID, [[-5, dataTypes.sInt32]])
|
||||||
|
@ -29,6 +28,7 @@ def needSupporter():
|
||||||
def needVerification():
|
def needVerification():
|
||||||
return packetHelper.buildPacket(packetIDs.server_userID, [[-8, dataTypes.sInt32]])
|
return packetHelper.buildPacket(packetIDs.server_userID, [[-8, dataTypes.sInt32]])
|
||||||
|
|
||||||
|
|
||||||
""" Login packets """
|
""" Login packets """
|
||||||
def userID(uid):
|
def userID(uid):
|
||||||
return packetHelper.buildPacket(packetIDs.server_userID, [[uid, dataTypes.sInt32]])
|
return packetHelper.buildPacket(packetIDs.server_userID, [[uid, dataTypes.sInt32]])
|
||||||
|
@ -51,19 +51,8 @@ def userSupporterGMT(supporter, GMT):
|
||||||
return packetHelper.buildPacket(packetIDs.server_supporterGMT, [[result, dataTypes.uInt32]])
|
return packetHelper.buildPacket(packetIDs.server_supporterGMT, [[result, dataTypes.uInt32]])
|
||||||
|
|
||||||
def friendList(userID):
|
def friendList(userID):
|
||||||
friendsData = []
|
|
||||||
|
|
||||||
# Get friend IDs from db
|
|
||||||
friends = userHelper.getFriendList(userID)
|
friends = userHelper.getFriendList(userID)
|
||||||
|
return packetHelper.buildPacket(packetIDs.server_friendsList, [[friends, dataTypes.intList]])
|
||||||
# Friends number
|
|
||||||
friendsData.append([len(friends), dataTypes.uInt16])
|
|
||||||
|
|
||||||
# Add all friend user IDs to friendsData
|
|
||||||
for i in friends:
|
|
||||||
friendsData.append([i, dataTypes.sInt32])
|
|
||||||
|
|
||||||
return packetHelper.buildPacket(packetIDs.server_friendsList, friendsData)
|
|
||||||
|
|
||||||
def onlineUsers():
|
def onlineUsers():
|
||||||
userIDs = []
|
userIDs = []
|
||||||
|
@ -91,7 +80,7 @@ def userPanel(userID, force = False):
|
||||||
|
|
||||||
# Get user data
|
# Get user data
|
||||||
username = userToken.username
|
username = userToken.username
|
||||||
timezone = 24+userToken.timeOffset # TODO: Timezone
|
timezone = 24+userToken.timeOffset
|
||||||
country = userToken.country
|
country = userToken.country
|
||||||
gameRank = userToken.gameRank
|
gameRank = userToken.gameRank
|
||||||
latitude = userToken.getLatitude()
|
latitude = userToken.getLatitude()
|
||||||
|
@ -105,7 +94,7 @@ def userPanel(userID, force = False):
|
||||||
userRank = userRanks.MOD
|
userRank = userRanks.MOD
|
||||||
elif userHelper.isInPrivilegeGroup(userID, "developer") == True:
|
elif userHelper.isInPrivilegeGroup(userID, "developer") == True:
|
||||||
userRank = userRanks.ADMIN
|
userRank = userRanks.ADMIN
|
||||||
elif userHelper.isInPrivilegeGroup(userID, "donor") == True:
|
elif (userToken.privileges & privileges.USER_DONOR) > 0:
|
||||||
userRank = userRanks.SUPPORTER
|
userRank = userRanks.SUPPORTER
|
||||||
else:
|
else:
|
||||||
userRank = userRanks.NORMAL
|
userRank = userRanks.NORMAL
|
||||||
|
@ -126,10 +115,12 @@ def userPanel(userID, force = False):
|
||||||
def userStats(userID, force = False):
|
def userStats(userID, force = False):
|
||||||
# Get userID's token from tokens list
|
# Get userID's token from tokens list
|
||||||
userToken = glob.tokens.getTokenFromUserID(userID)
|
userToken = glob.tokens.getTokenFromUserID(userID)
|
||||||
|
|
||||||
if userToken == None:
|
if userToken == None:
|
||||||
return bytes()
|
return bytes()
|
||||||
if (userToken.restricted == True or userToken.irc == True) and force == False:
|
if (userToken.restricted == True or userToken.irc == True) and force == False:
|
||||||
return bytes()
|
return bytes()
|
||||||
|
|
||||||
return packetHelper.buildPacket(packetIDs.server_userStats,
|
return packetHelper.buildPacket(packetIDs.server_userStats,
|
||||||
[
|
[
|
||||||
[userID, dataTypes.uInt32],
|
[userID, dataTypes.uInt32],
|
||||||
|
@ -150,14 +141,23 @@ def userStats(userID, force = False):
|
||||||
|
|
||||||
""" Chat packets """
|
""" Chat packets """
|
||||||
def sendMessage(fro, to, message):
|
def sendMessage(fro, to, message):
|
||||||
return packetHelper.buildPacket(packetIDs.server_sendMessage, [[fro, dataTypes.string], [message, dataTypes.string], [to, dataTypes.string], [userHelper.getID(fro), dataTypes.sInt32]])
|
return packetHelper.buildPacket(packetIDs.server_sendMessage, [
|
||||||
|
[fro, dataTypes.string],
|
||||||
|
[message, dataTypes.string],
|
||||||
|
[to, dataTypes.string],
|
||||||
|
[userHelper.getID(fro), dataTypes.sInt32]
|
||||||
|
])
|
||||||
|
|
||||||
def channelJoinSuccess(userID, chan):
|
def channelJoinSuccess(userID, chan):
|
||||||
return packetHelper.buildPacket(packetIDs.server_channelJoinSuccess, [[chan, dataTypes.string]])
|
return packetHelper.buildPacket(packetIDs.server_channelJoinSuccess, [[chan, dataTypes.string]])
|
||||||
|
|
||||||
def channelInfo(chan):
|
def channelInfo(chan):
|
||||||
channel = glob.channels.channels[chan]
|
channel = glob.channels.channels[chan]
|
||||||
return packetHelper.buildPacket(packetIDs.server_channelInfo, [[chan, dataTypes.string], [channel.description, dataTypes.string], [channel.getConnectedUsersCount(), dataTypes.uInt16]])
|
return packetHelper.buildPacket(packetIDs.server_channelInfo, [
|
||||||
|
[chan, dataTypes.string],
|
||||||
|
[channel.description, dataTypes.string],
|
||||||
|
[channel.getConnectedUsersCount(), dataTypes.uInt16]
|
||||||
|
])
|
||||||
|
|
||||||
def channelInfoEnd():
|
def channelInfoEnd():
|
||||||
return packetHelper.buildPacket(packetIDs.server_channelInfoEnd, [[0, dataTypes.uInt32]])
|
return packetHelper.buildPacket(packetIDs.server_channelInfoEnd, [[0, dataTypes.uInt32]])
|
||||||
|
@ -199,7 +199,6 @@ def createMatch(matchID):
|
||||||
match = glob.matches.matches[matchID]
|
match = glob.matches.matches[matchID]
|
||||||
return packetHelper.buildPacket(packetIDs.server_newMatch, match.getMatchData())
|
return packetHelper.buildPacket(packetIDs.server_newMatch, match.getMatchData())
|
||||||
|
|
||||||
|
|
||||||
def updateMatch(matchID):
|
def updateMatch(matchID):
|
||||||
# Make sure the match exists
|
# Make sure the match exists
|
||||||
if matchID not in glob.matches.matches:
|
if matchID not in glob.matches.matches:
|
||||||
|
@ -209,7 +208,6 @@ def updateMatch(matchID):
|
||||||
match = glob.matches.matches[matchID]
|
match = glob.matches.matches[matchID]
|
||||||
return packetHelper.buildPacket(packetIDs.server_updateMatch, match.getMatchData())
|
return packetHelper.buildPacket(packetIDs.server_updateMatch, match.getMatchData())
|
||||||
|
|
||||||
|
|
||||||
def matchStart(matchID):
|
def matchStart(matchID):
|
||||||
# Make sure the match exists
|
# Make sure the match exists
|
||||||
if matchID not in glob.matches.matches:
|
if matchID not in glob.matches.matches:
|
||||||
|
@ -219,9 +217,8 @@ def matchStart(matchID):
|
||||||
match = glob.matches.matches[matchID]
|
match = glob.matches.matches[matchID]
|
||||||
return packetHelper.buildPacket(packetIDs.server_matchStart, match.getMatchData())
|
return packetHelper.buildPacket(packetIDs.server_matchStart, match.getMatchData())
|
||||||
|
|
||||||
|
|
||||||
def disposeMatch(matchID):
|
def disposeMatch(matchID):
|
||||||
return packetHelper.buildPacket(packetIDs.server_disposeMatch, [[matchID, dataTypes.uInt16]])
|
return packetHelper.buildPacket(packetIDs.server_disposeMatch, [[matchID, dataTypes.uInt32]])
|
||||||
|
|
||||||
def matchJoinSuccess(matchID):
|
def matchJoinSuccess(matchID):
|
||||||
# Make sure the match exists
|
# Make sure the match exists
|
||||||
|
@ -260,9 +257,10 @@ def playerFailed(slotID):
|
||||||
def matchTransferHost():
|
def matchTransferHost():
|
||||||
return packetHelper.buildPacket(packetIDs.server_matchTransferHost)
|
return packetHelper.buildPacket(packetIDs.server_matchTransferHost)
|
||||||
|
|
||||||
|
|
||||||
""" Other packets """
|
""" Other packets """
|
||||||
def notification(message):
|
def notification(message):
|
||||||
return packetHelper.buildPacket(packetIDs.server_notification, [[message, dataTypes.string]])
|
return packetHelper.buildPacket(packetIDs.server_notification, [[message, dataTypes.string]])
|
||||||
|
|
||||||
def banchoRestart(msUntilReconnection):
|
def banchoRestart(msUntilReconnection):
|
||||||
return packetHelper.buildPacket(packetIDs.server_restart, [[msUntilReconnection, dataTypes.uInt32]])
|
return packetHelper.buildPacket(packetIDs.server_restart, [[msUntilReconnection, dataTypes.uInt32]])
|
|
@ -4,7 +4,6 @@ from constants import serverPackets
|
||||||
from helpers import userHelper
|
from helpers import userHelper
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
from constants import actions
|
from constants import actions
|
||||||
from helpers import chatHelper as chat
|
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Get usertoken data
|
# Get usertoken data
|
||||||
|
@ -24,9 +23,16 @@ def handle(userToken, packetData):
|
||||||
# Change action packet
|
# Change action packet
|
||||||
packetData = clientPackets.userActionChange(packetData)
|
packetData = clientPackets.userActionChange(packetData)
|
||||||
|
|
||||||
|
# If we are not in spectate status but we're spectating someone, stop spectating
|
||||||
|
#if userToken.spectating != 0 and userToken.actionID != actions.watching and userToken.actionID != actions.idle and userToken.actionID != actions.afk:
|
||||||
|
# userToken.stopSpectating()
|
||||||
|
|
||||||
|
# If we are not in multiplayer but we are in a match, part match
|
||||||
|
#if userToken.matchID != -1 and userToken.actionID != actions.multiplaying and userToken.actionID != actions.multiplayer and userToken.actionID != actions.afk:
|
||||||
|
# userToken.partMatch()
|
||||||
|
|
||||||
# Update cached stats if our pp changedm if we've just submitted a score or we've changed gameMode
|
# Update cached stats if our pp changedm if we've just submitted a score or we've changed gameMode
|
||||||
if (userToken.actionID == actions.playing or userToken.actionID == actions.multiplaying) or (userToken.pp != userHelper.getPP(userID, userToken.gameMode)) or (userToken.gameMode != packetData["gameMode"]):
|
if (userToken.actionID == actions.playing or userToken.actionID == actions.multiplaying) or (userToken.pp != userHelper.getPP(userID, userToken.gameMode)) or (userToken.gameMode != packetData["gameMode"]):
|
||||||
log.debug("!!!! UPDATING CACHED STATS !!!!")
|
|
||||||
# Always update game mode, or we'll cache stats from the wrong game mode if we've changed it
|
# Always update game mode, or we'll cache stats from the wrong game mode if we've changed it
|
||||||
userToken.gameMode = packetData["gameMode"]
|
userToken.gameMode = packetData["gameMode"]
|
||||||
userToken.updateCachedStats()
|
userToken.updateCachedStats()
|
||||||
|
@ -55,12 +61,5 @@ def handle(userToken, packetData):
|
||||||
token.enqueue(serverPackets.userPanel(userID, force))
|
token.enqueue(serverPackets.userPanel(userID, force))
|
||||||
token.enqueue(serverPackets.userStats(userID, force))
|
token.enqueue(serverPackets.userStats(userID, force))
|
||||||
|
|
||||||
# Send osu!direct alert if needed
|
|
||||||
# NOTE: Remove this when osu!direct will be fixed
|
|
||||||
if userToken.actionID == actions.osuDirect and userToken.osuDirectAlert == False:
|
|
||||||
userToken.osuDirectAlert = True
|
|
||||||
chat.sendMessage("FokaBot", userToken.username, "Sup! osu!direct works, but you'll need to update the switcher to have the Download button working. If you didn't update the switcher yet, please do!")
|
|
||||||
|
|
||||||
|
|
||||||
# Console output
|
# Console output
|
||||||
log.info("{} changed action: {} [{}][{}]".format(username, str(userToken.actionID), userToken.actionText, userToken.actionMd5))
|
log.info("{} changed action: {} [{}][{}]".format(username, str(userToken.actionID), userToken.actionText, userToken.actionMd5))
|
||||||
|
|
|
@ -16,6 +16,10 @@ def handle(userToken, packetData):
|
||||||
return
|
return
|
||||||
match = glob.matches.matches[matchID]
|
match = glob.matches.matches[matchID]
|
||||||
|
|
||||||
|
# Host check
|
||||||
|
if userID != match.hostUserID:
|
||||||
|
return
|
||||||
|
|
||||||
# Set slot or match mods according to modType
|
# Set slot or match mods according to modType
|
||||||
if match.matchModMode == matchModModes.freeMod:
|
if match.matchModMode == matchModModes.freeMod:
|
||||||
# Freemod
|
# Freemod
|
||||||
|
@ -25,7 +29,7 @@ def handle(userToken, packetData):
|
||||||
# If host has selected DT/HT and Freemod is enabled, set DT/HT as match mod
|
# If host has selected DT/HT and Freemod is enabled, set DT/HT as match mod
|
||||||
if (packetData["mods"] & mods.DoubleTime) > 0:
|
if (packetData["mods"] & mods.DoubleTime) > 0:
|
||||||
match.changeMatchMods(mods.DoubleTime)
|
match.changeMatchMods(mods.DoubleTime)
|
||||||
# Nighcore
|
# Nightcore
|
||||||
if (packetData["mods"] & mods.Nightcore) > 0:
|
if (packetData["mods"] & mods.Nightcore) > 0:
|
||||||
match.changeMatchMods(match.mods+mods.Nightcore)
|
match.changeMatchMods(match.mods+mods.Nightcore)
|
||||||
elif (packetData["mods"] & mods.HalfTime) > 0:
|
elif (packetData["mods"] & mods.HalfTime) > 0:
|
||||||
|
|
|
@ -13,5 +13,9 @@ def handle(userToken, packetData):
|
||||||
# Get our match
|
# Get our match
|
||||||
match = glob.matches.matches[matchID]
|
match = glob.matches.matches[matchID]
|
||||||
|
|
||||||
|
# Host check
|
||||||
|
if userToken.userID != match.hostUserID:
|
||||||
|
return
|
||||||
|
|
||||||
# Update match password
|
# Update match password
|
||||||
match.changePassword(packetData["matchPassword"])
|
match.changePassword(packetData["matchPassword"])
|
||||||
|
|
|
@ -6,6 +6,7 @@ from constants import matchTeamTypes
|
||||||
from constants import matchTeams
|
from constants import matchTeams
|
||||||
from constants import slotStatuses
|
from constants import slotStatuses
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
|
from helpers import generalFunctions
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# Read new settings
|
# Read new settings
|
||||||
|
@ -13,7 +14,7 @@ def handle(userToken, packetData):
|
||||||
|
|
||||||
# Get match ID
|
# Get match ID
|
||||||
matchID = userToken.matchID
|
matchID = userToken.matchID
|
||||||
|
|
||||||
# Make sure the match exists
|
# Make sure the match exists
|
||||||
if matchID not in glob.matches.matches:
|
if matchID not in glob.matches.matches:
|
||||||
return
|
return
|
||||||
|
@ -21,6 +22,10 @@ def handle(userToken, packetData):
|
||||||
# Get match object
|
# Get match object
|
||||||
match = glob.matches.matches[matchID]
|
match = glob.matches.matches[matchID]
|
||||||
|
|
||||||
|
# Host check
|
||||||
|
if userToken.userID != match.hostUserID:
|
||||||
|
return
|
||||||
|
|
||||||
# Some dank memes easter egg
|
# Some dank memes easter egg
|
||||||
memeTitles = [
|
memeTitles = [
|
||||||
"RWC 2020",
|
"RWC 2020",
|
||||||
|
@ -53,7 +58,10 @@ def handle(userToken, packetData):
|
||||||
|
|
||||||
# Update match settings
|
# Update match settings
|
||||||
match.inProgress = packetData["inProgress"]
|
match.inProgress = packetData["inProgress"]
|
||||||
match.matchPassword = packetData["matchPassword"]
|
if packetData["matchPassword"] != "":
|
||||||
|
match.matchPassword = generalFunctions.stringMd5(packetData["matchPassword"])
|
||||||
|
else:
|
||||||
|
match.matchPassword = ""
|
||||||
match.beatmapName = packetData["beatmapName"]
|
match.beatmapName = packetData["beatmapName"]
|
||||||
match.beatmapID = packetData["beatmapID"]
|
match.beatmapID = packetData["beatmapID"]
|
||||||
match.hostUserID = packetData["hostUserID"]
|
match.hostUserID = packetData["hostUserID"]
|
||||||
|
@ -71,14 +79,14 @@ def handle(userToken, packetData):
|
||||||
# Reset ready if needed
|
# Reset ready if needed
|
||||||
if oldMods != match.mods or oldBeatmapMD5 != match.beatmapMD5:
|
if oldMods != match.mods or oldBeatmapMD5 != match.beatmapMD5:
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if match.slots[i]["status"] == slotStatuses.ready:
|
if match.slots[i].status == slotStatuses.ready:
|
||||||
match.slots[i]["status"] = slotStatuses.notReady
|
match.slots[i].status = slotStatuses.notReady
|
||||||
|
|
||||||
# Reset mods if needed
|
# Reset mods if needed
|
||||||
if match.matchModMode == matchModModes.normal:
|
if match.matchModMode == matchModModes.normal:
|
||||||
# Reset slot mods if not freeMods
|
# Reset slot mods if not freeMods
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
match.slots[i]["mods"] = 0
|
match.slots[i].mods = 0
|
||||||
else:
|
else:
|
||||||
# Reset match mods if freemod
|
# Reset match mods if freemod
|
||||||
match.mods = 0
|
match.mods = 0
|
||||||
|
@ -88,13 +96,13 @@ def handle(userToken, packetData):
|
||||||
# Set teams
|
# Set teams
|
||||||
c=0
|
c=0
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if match.slots[i]["team"] == matchTeams.noTeam:
|
if match.slots[i].team == matchTeams.noTeam:
|
||||||
match.slots[i]["team"] = matchTeams.red if c % 2 == 0 else matchTeams.blue
|
match.slots[i].team = matchTeams.red if c % 2 == 0 else matchTeams.blue
|
||||||
c+=1
|
c+=1
|
||||||
else:
|
else:
|
||||||
# Reset teams
|
# Reset teams
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
match.slots[i]["team"] = matchTeams.noTeam
|
match.slots[i].team = matchTeams.noTeam
|
||||||
|
|
||||||
# Force no freemods if tag coop
|
# Force no freemods if tag coop
|
||||||
if match.matchTeamType == matchTeamTypes.tagCoop or match.matchTeamType == matchTeamTypes.tagTeamVs:
|
if match.matchTeamType == matchTeamTypes.tagCoop or match.matchTeamType == matchTeamTypes.tagTeamVs:
|
||||||
|
@ -105,4 +113,3 @@ def handle(userToken, packetData):
|
||||||
|
|
||||||
# Console output
|
# Console output
|
||||||
log.info("MPROOM{}: Updated room settings".format(match.matchID))
|
log.info("MPROOM{}: Updated room settings".format(match.matchID))
|
||||||
#consoleHelper.printColored("> MPROOM{}: DEBUG: Host is {}".format(match.matchID, match.hostUserID), bcolors.PINK)
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ from objects import glob
|
||||||
from constants import exceptions
|
from constants import exceptions
|
||||||
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 helpers import generalFunctions
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
# read packet data
|
# read packet data
|
||||||
|
@ -12,12 +13,15 @@ def handle(userToken, packetData):
|
||||||
# Get match from ID
|
# Get match from ID
|
||||||
joinMatch(userToken, packetData["matchID"], packetData["password"])
|
joinMatch(userToken, packetData["matchID"], packetData["password"])
|
||||||
|
|
||||||
def joinMatch(userToken, matchID, password):
|
def joinMatch(userToken, matchID, password, isPasswordHashed = False):
|
||||||
try:
|
try:
|
||||||
# TODO: leave other matches
|
# Stop spectating
|
||||||
# TODO: Stop spectating
|
userToken.stopSpectating()
|
||||||
|
|
||||||
# get usertoken data
|
# Leave other matches
|
||||||
|
userToken.partMatch()
|
||||||
|
|
||||||
|
# Get usertoken data
|
||||||
userID = userToken.userID
|
userID = userToken.userID
|
||||||
|
|
||||||
# Make sure the match exists
|
# Make sure the match exists
|
||||||
|
@ -27,6 +31,10 @@ def joinMatch(userToken, matchID, password):
|
||||||
# Match exists, get object
|
# Match exists, get object
|
||||||
match = glob.matches.matches[matchID]
|
match = glob.matches.matches[matchID]
|
||||||
|
|
||||||
|
# Hash password if needed
|
||||||
|
if isPasswordHashed == False and password != "":
|
||||||
|
password = generalFunctions.stringMd5(password)
|
||||||
|
|
||||||
# Check password
|
# Check password
|
||||||
# TODO: Admins can enter every match
|
# TODO: Admins can enter every match
|
||||||
if match.matchPassword != "":
|
if match.matchPassword != "":
|
||||||
|
|
|
@ -2,16 +2,10 @@ 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
|
||||||
|
|
|
@ -15,21 +15,16 @@ def handle(userToken, _=None):
|
||||||
# the server, so we accept logout packets sent at least 5 seconds after login
|
# the server, so we accept logout packets sent at least 5 seconds after login
|
||||||
# if the user logs out before 5 seconds, he will be disconnected later with timeout check
|
# if the user logs out before 5 seconds, he will be disconnected later with timeout check
|
||||||
if int(time.time()-userToken.loginTime) >= 5 or userToken.irc == True:
|
if int(time.time()-userToken.loginTime) >= 5 or userToken.irc == True:
|
||||||
# Stop spectating if needed
|
# Stop spectating
|
||||||
# TODO: Call stopSpectatingEvent!!!!!!!!!
|
userToken.stopSpectating()
|
||||||
if userToken.spectating != 0:
|
|
||||||
# The user was spectating someone
|
|
||||||
spectatorHostToken = glob.tokens.getTokenFromUserID(userToken.spectating)
|
|
||||||
if spectatorHostToken != None:
|
|
||||||
# The host is still online, send removeSpectator to him
|
|
||||||
spectatorHostToken.enqueue(serverPackets.removeSpectator(userID))
|
|
||||||
|
|
||||||
|
# Part matches
|
||||||
|
userToken.partMatch()
|
||||||
|
|
||||||
# Part all joined channels
|
# Part all joined channels
|
||||||
for i in userToken.joinedChannels:
|
for i in userToken.joinedChannels:
|
||||||
chat.partChannel(token=userToken, channel=i)
|
chat.partChannel(token=userToken, channel=i)
|
||||||
|
|
||||||
# TODO: Lobby left if joined
|
|
||||||
|
|
||||||
# Enqueue our disconnection to everyone else
|
# Enqueue our disconnection to everyone else
|
||||||
glob.tokens.enqueueAll(serverPackets.userLogout(userID))
|
glob.tokens.enqueueAll(serverPackets.userLogout(userID))
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ def handle(userToken, packetData):
|
||||||
|
|
||||||
# Enqueue frames to who's playing
|
# Enqueue frames to who's playing
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if match.slots[i]["userID"] > -1 and match.slots[i]["status"] == slotStatuses.playing:
|
if match.slots[i].userID > -1 and match.slots[i].status == slotStatuses.playing:
|
||||||
token = glob.tokens.getTokenFromUserID(match.slots[i]["userID"])
|
token = glob.tokens.getTokenFromUserID(match.slots[i].userID)
|
||||||
if token != None:
|
if token != None:
|
||||||
token.enqueue(serverPackets.matchFrames(slotID, packetData))
|
token.enqueue(serverPackets.matchFrames(slotID, packetData))
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
from events import matchBeatmapEvent
|
from events import matchBeatmapEvent
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
matchBeatmapEvent.handle(userToken, packetData, True)
|
matchBeatmapEvent.handle(userToken, packetData, True)
|
||||||
|
|
|
@ -14,6 +14,10 @@ def handle(userToken, packetData):
|
||||||
return
|
return
|
||||||
match = glob.matches.matches[matchID]
|
match = glob.matches.matches[matchID]
|
||||||
|
|
||||||
|
# Host check
|
||||||
|
if userID != match.hostUserID:
|
||||||
|
return
|
||||||
|
|
||||||
# Make sure we aren't locking our slot
|
# Make sure we aren't locking our slot
|
||||||
ourSlot = match.getUserSlotID(userID)
|
ourSlot = match.getUserSlotID(userID)
|
||||||
if packetData["slotID"] == ourSlot:
|
if packetData["slotID"] == ourSlot:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
from events import matchBeatmapEvent
|
from events import matchBeatmapEvent
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
matchBeatmapEvent.handle(userToken, packetData, False)
|
matchBeatmapEvent.handle(userToken, packetData, False)
|
||||||
|
|
|
@ -3,7 +3,6 @@ from constants import slotStatuses
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
|
|
||||||
def handle(userToken, _):
|
def handle(userToken, _):
|
||||||
# TODO: Host check
|
|
||||||
|
|
||||||
# Get match ID and match object
|
# Get match ID and match object
|
||||||
matchID = userToken.matchID
|
matchID = userToken.matchID
|
||||||
|
@ -19,10 +18,12 @@ def handle(userToken, _):
|
||||||
# The match exists, get object
|
# The match exists, get object
|
||||||
match = glob.matches.matches[matchID]
|
match = glob.matches.matches[matchID]
|
||||||
|
|
||||||
force = False # TODO: Force thing
|
# Host check
|
||||||
|
if userToken.userID != match.hostUserID:
|
||||||
|
return
|
||||||
|
|
||||||
# Make sure we have enough players
|
# Make sure we have enough players
|
||||||
if (match.countUsers() < 2 or not match.checkTeams()) and not force:
|
if (match.countUsers() < 2 or match.checkTeams() == False):
|
||||||
return
|
return
|
||||||
|
|
||||||
# Change inProgress value
|
# Change inProgress value
|
||||||
|
@ -30,16 +31,16 @@ def handle(userToken, _):
|
||||||
|
|
||||||
# Set playing to ready players and set load, skip and complete to False
|
# Set playing to ready players and set load, skip and complete to False
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if (match.slots[i]["status"] & slotStatuses.ready) > 0:
|
if (match.slots[i].status & slotStatuses.ready) > 0:
|
||||||
match.slots[i]["status"] = slotStatuses.playing
|
match.slots[i].status = slotStatuses.playing
|
||||||
match.slots[i]["loaded"] = False
|
match.slots[i].loaded = False
|
||||||
match.slots[i]["skip"] = False
|
match.slots[i].skip = False
|
||||||
match.slots[i]["complete"] = False
|
match.slots[i].complete = False
|
||||||
|
|
||||||
# Send match start packet
|
# Send match start packet
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if (match.slots[i]["status"] & slotStatuses.playing) > 0 and match.slots[i]["userID"] != -1:
|
if (match.slots[i].status & slotStatuses.playing) > 0 and match.slots[i].userID != -1:
|
||||||
token = glob.tokens.getTokenFromUserID(match.slots[i]["userID"])
|
token = glob.tokens.getTokenFromUserID(match.slots[i].userID)
|
||||||
if token != None:
|
if token != None:
|
||||||
token.enqueue(serverPackets.matchStart(matchID))
|
token.enqueue(serverPackets.matchStart(matchID))
|
||||||
|
|
||||||
|
|
|
@ -19,5 +19,9 @@ def handle(userToken, packetData):
|
||||||
# Match exists, get object
|
# Match exists, get object
|
||||||
match = glob.matches.matches[matchID]
|
match = glob.matches.matches[matchID]
|
||||||
|
|
||||||
|
# Host check
|
||||||
|
if userToken.userID != match.hostUserID:
|
||||||
|
return
|
||||||
|
|
||||||
# Transfer host
|
# Transfer host
|
||||||
match.transferHost(packetData["slotID"])
|
match.transferHost(packetData["slotID"])
|
||||||
|
|
|
@ -1,28 +1,2 @@
|
||||||
from objects import glob
|
def handle(userToken, _=None):
|
||||||
|
userToken.partMatch()
|
||||||
def handle(userToken, _):
|
|
||||||
# get data from usertoken
|
|
||||||
userID = userToken.userID
|
|
||||||
|
|
||||||
# Get match ID and match object
|
|
||||||
matchID = userToken.matchID
|
|
||||||
|
|
||||||
# Make sure we are in a match
|
|
||||||
if matchID == -1:
|
|
||||||
return
|
|
||||||
|
|
||||||
# Make sure the match exists
|
|
||||||
if matchID not in glob.matches.matches:
|
|
||||||
return
|
|
||||||
|
|
||||||
# The match exists, get object
|
|
||||||
match = glob.matches.matches[matchID]
|
|
||||||
|
|
||||||
# Set slot to free
|
|
||||||
match.userLeft(userID)
|
|
||||||
|
|
||||||
# Part #multiplayer channel
|
|
||||||
#chat.partChannel(token=userToken, channel="#multi_{}".format(matchID), kick=True)
|
|
||||||
|
|
||||||
# Set usertoken match to -1
|
|
||||||
userToken.partMatch()
|
|
|
@ -2,8 +2,6 @@ from constants import serverPackets
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
|
|
||||||
def handle(userToken, packetData):
|
def handle(userToken, packetData):
|
||||||
log.debug("Requested status update")
|
|
||||||
|
|
||||||
# Update cache and send new stats
|
# Update cache and send new stats
|
||||||
userToken.updateCachedStats()
|
userToken.updateCachedStats()
|
||||||
userToken.enqueue(serverPackets.userStats(userToken.userID))
|
userToken.enqueue(serverPackets.userStats(userToken.userID))
|
||||||
|
|
|
@ -1,37 +1,2 @@
|
||||||
from objects import glob
|
def handle(userToken, _=None):
|
||||||
from constants import serverPackets
|
userToken.stopSpectating()
|
||||||
from constants import exceptions
|
|
||||||
from helpers import logHelper as log
|
|
||||||
from helpers import chatHelper as chat
|
|
||||||
|
|
||||||
def handle(userToken, _):
|
|
||||||
try:
|
|
||||||
# get user token data
|
|
||||||
userID = userToken.userID
|
|
||||||
username = userToken.username
|
|
||||||
|
|
||||||
# Remove our userID from host's spectators
|
|
||||||
target = userToken.spectating
|
|
||||||
targetToken = glob.tokens.getTokenFromUserID(target)
|
|
||||||
if targetToken == None:
|
|
||||||
raise exceptions.tokenNotFoundException
|
|
||||||
targetToken.removeSpectator(userID)
|
|
||||||
|
|
||||||
# Part #spectator channel
|
|
||||||
chat.partChannel(token=userToken, channel="#spect_{}".format(target))
|
|
||||||
|
|
||||||
# Send the spectator left packet to host
|
|
||||||
targetToken.enqueue(serverPackets.removeSpectator(userID))
|
|
||||||
for c in targetToken.spectators:
|
|
||||||
spec = glob.tokens.getTokenFromUserID(c)
|
|
||||||
spec.enqueue(serverPackets.fellowSpectatorLeft(userID))
|
|
||||||
|
|
||||||
#targetToken.enqueue(serverPackets.fellowSpectatorLeft(userID))
|
|
||||||
|
|
||||||
# Console output
|
|
||||||
log.info("{} are no longer spectating {}".format(username, target))
|
|
||||||
except exceptions.tokenNotFoundException:
|
|
||||||
log.warning("Spectator stop: token not found")
|
|
||||||
finally:
|
|
||||||
# Set our spectating user to 0
|
|
||||||
userToken.stopSpectating()
|
|
||||||
|
|
|
@ -33,7 +33,5 @@ class handler(requestHelper.asyncRequestHandler):
|
||||||
data["status"] = statusCode
|
data["status"] = statusCode
|
||||||
|
|
||||||
# Send response
|
# Send response
|
||||||
#self.clear()
|
|
||||||
self.write(json.dumps(data))
|
self.write(json.dumps(data))
|
||||||
self.set_status(statusCode)
|
self.set_status(statusCode)
|
||||||
#self.finish(json.dumps(data))
|
|
||||||
|
|
|
@ -226,8 +226,8 @@ class handler(SentryMixin, requestHelper.asyncRequestHandler):
|
||||||
self.set_status(200)
|
self.set_status(200)
|
||||||
self.add_header("cho-token", responseTokenString)
|
self.add_header("cho-token", responseTokenString)
|
||||||
self.add_header("cho-protocol", "19")
|
self.add_header("cho-protocol", "19")
|
||||||
#self.add_header("Keep-Alive", "timeout=5, max=100")
|
self.add_header("Connection", "keep-alive")
|
||||||
#self.add_header("Connection", "keep-alive")
|
self.add_header("Keep-Alive", "timeout=5, max=100")
|
||||||
self.add_header("Content-Type", "text/html; charset=UTF-8")
|
self.add_header("Content-Type", "text/html; charset=UTF-8")
|
||||||
except:
|
except:
|
||||||
log.error("Unknown error!\n```\n{}\n{}```".format(sys.exc_info(), traceback.format_exc()))
|
log.error("Unknown error!\n```\n{}\n{}```".format(sys.exc_info(), traceback.format_exc()))
|
||||||
|
@ -259,6 +259,4 @@ class handler(SentryMixin, requestHelper.asyncRequestHandler):
|
||||||
html += " \\ . .. .. . /<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>"
|
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)
|
self.write(html)
|
||||||
#yield tornado.gen.Task(self.captureMessage, "test")
|
|
||||||
#self.finish()
|
|
|
@ -1,52 +0,0 @@
|
||||||
"""
|
|
||||||
WIP feature that will come in the future.
|
|
||||||
Don't import
|
|
||||||
"""
|
|
||||||
import flask
|
|
||||||
from objects import glob
|
|
||||||
from constants import exceptions
|
|
||||||
|
|
||||||
@app.route("/api/online-users-count")
|
|
||||||
def APIonlineUsersCount():
|
|
||||||
return flask.jsonify({"count" : len(glob.tokens.tokens)-1})
|
|
||||||
|
|
||||||
@app.route("/api/user-info")
|
|
||||||
def APIonlineUsers():
|
|
||||||
resp = {}
|
|
||||||
|
|
||||||
try:
|
|
||||||
u = flask.request.args.get('u')
|
|
||||||
|
|
||||||
# Username/userID
|
|
||||||
if u.isdigit():
|
|
||||||
u = int(u)
|
|
||||||
else:
|
|
||||||
u = userHelper.getID(u)
|
|
||||||
if u == None:
|
|
||||||
raise exceptions.userNotFoundException
|
|
||||||
|
|
||||||
# Make sure this user is online
|
|
||||||
userToken = glob.tokens.getTokenFromUserID(u)
|
|
||||||
if userToken == None:
|
|
||||||
raise exceptions.tokenNotFoundException
|
|
||||||
|
|
||||||
# Build response dictionary
|
|
||||||
resp["response"] = "1"
|
|
||||||
resp[userToken.username] = {
|
|
||||||
"userID" : userToken.userID,
|
|
||||||
"actionID" : userToken.actionID,
|
|
||||||
"actionText" : userToken.actionText,
|
|
||||||
"actionMd5" : userToken.actionMd5,
|
|
||||||
"actionMods": userToken.actionMods,
|
|
||||||
"gameMode": userToken.gameMode,
|
|
||||||
"country": countryHelper.getCountryLetters(userToken.country),
|
|
||||||
"position": userToken.location,
|
|
||||||
"spectating": userToken.spectating,
|
|
||||||
"spectators": userToken.spectators
|
|
||||||
}
|
|
||||||
except exceptions.userNotFoundException:
|
|
||||||
resp["response"] = "-1"
|
|
||||||
except exceptions.tokenNotFoundException:
|
|
||||||
resp["response"] = "-2"
|
|
||||||
finally:
|
|
||||||
return flask.jsonify(resp)
|
|
|
@ -147,9 +147,6 @@ def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = Fal
|
||||||
log.warning("User not connected to IRC/Bancho")
|
log.warning("User not connected to IRC/Bancho")
|
||||||
return 442 # idk
|
return 442 # idk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||||
"""
|
"""
|
||||||
Send a message to osu!bancho and IRC server
|
Send a message to osu!bancho and IRC server
|
||||||
|
@ -299,8 +296,13 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||||
return 401
|
return 401
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
""" IRC-Bancho Connect/Disconnect/Join/Part interfaces"""
|
""" IRC-Bancho Connect/Disconnect/Join/Part interfaces"""
|
||||||
|
def fixUsernameForBancho(username):
|
||||||
|
return username.replace("_", " ")
|
||||||
|
|
||||||
|
def fixUsernameForIRC(username):
|
||||||
|
return username.replace(" ", "_")
|
||||||
|
|
||||||
def IRCConnect(username):
|
def IRCConnect(username):
|
||||||
userID = userHelper.getID(username)
|
userID = userHelper.getID(username)
|
||||||
if userID == False:
|
if userID == False:
|
||||||
|
|
|
@ -1,18 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
class config:
|
class config():
|
||||||
"""
|
|
||||||
config.ini object
|
|
||||||
|
|
||||||
config -- list with ini data
|
|
||||||
default -- if true, we have generated a default config.ini
|
|
||||||
"""
|
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
|
||||||
fileName = "" # config filename
|
|
||||||
default = True
|
|
||||||
|
|
||||||
# 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):
|
||||||
"""
|
"""
|
||||||
|
@ -20,7 +9,8 @@ class config:
|
||||||
|
|
||||||
file -- filename
|
file -- filename
|
||||||
"""
|
"""
|
||||||
|
self.config = configparser.ConfigParser()
|
||||||
|
self.default = True
|
||||||
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
|
||||||
|
@ -39,7 +29,6 @@ class config:
|
||||||
|
|
||||||
return -- True if valid, False if not
|
return -- True if valid, False if not
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Try to get all the required keys
|
# Try to get all the required keys
|
||||||
self.config.get("db","host")
|
self.config.get("db","host")
|
||||||
|
@ -75,11 +64,10 @@ class config:
|
||||||
except:
|
except:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
# Generate a default config.ini
|
|
||||||
def generateDefaultConfig(self):
|
def generateDefaultConfig(self):
|
||||||
"""Open and set default keys for that config file"""
|
"""
|
||||||
|
Open and set default keys for that config file
|
||||||
|
"""
|
||||||
# Open config.ini in write mode
|
# Open config.ini in write mode
|
||||||
f = open(self.fileName, "w")
|
f = open(self.fileName, "w")
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
"""Some console related functions"""
|
|
||||||
|
|
||||||
from constants import bcolors
|
from constants import bcolors
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
|
||||||
def printServerStartHeader(asciiArt):
|
def printServerStartHeader(asciiArt):
|
||||||
"""Print server start header with optional ascii art
|
"""
|
||||||
|
Print server start header with optional ascii art
|
||||||
asciiArt -- if True, will print ascii art too"""
|
|
||||||
|
|
||||||
|
asciiArt -- if True, will print ascii art too
|
||||||
|
"""
|
||||||
if asciiArt == True:
|
if asciiArt == True:
|
||||||
print("{} _ __".format(bcolors.GREEN))
|
print("{} _ __".format(bcolors.GREEN))
|
||||||
print(" (_) / /")
|
print(" (_) / /")
|
||||||
|
@ -28,20 +27,17 @@ def printServerStartHeader(asciiArt):
|
||||||
|
|
||||||
printColored("> Welcome to pep.py osu!bancho server v{}".format(glob.VERSION), bcolors.GREEN)
|
printColored("> Welcome to pep.py osu!bancho server v{}".format(glob.VERSION), bcolors.GREEN)
|
||||||
printColored("> Made by the Ripple team", bcolors.GREEN)
|
printColored("> Made by the Ripple team", bcolors.GREEN)
|
||||||
printColored("> {}https://github.com/osuripple/ripple".format(bcolors.UNDERLINE), bcolors.GREEN)
|
printColored("> {}https://git.zxq.co/ripple/pep.py".format(bcolors.UNDERLINE), bcolors.GREEN)
|
||||||
printColored("> Press CTRL+C to exit\n",bcolors.GREEN)
|
printColored("> Press CTRL+C to exit\n",bcolors.GREEN)
|
||||||
|
|
||||||
|
|
||||||
def printNoNl(string):
|
def printNoNl(string):
|
||||||
"""
|
"""
|
||||||
Print string without new line at the end
|
Print string without new line at the end
|
||||||
|
|
||||||
string -- string to print
|
string -- string to print
|
||||||
"""
|
"""
|
||||||
|
|
||||||
print(string, end="")
|
print(string, end="")
|
||||||
|
|
||||||
|
|
||||||
def printColored(string, color):
|
def printColored(string, color):
|
||||||
"""
|
"""
|
||||||
Print colored string
|
Print colored string
|
||||||
|
@ -49,23 +45,22 @@ def printColored(string, color):
|
||||||
string -- string to print
|
string -- string to print
|
||||||
color -- see bcolors.py
|
color -- see bcolors.py
|
||||||
"""
|
"""
|
||||||
|
|
||||||
print("{}{}{}".format(color, string, bcolors.ENDC))
|
print("{}{}{}".format(color, string, bcolors.ENDC))
|
||||||
|
|
||||||
|
|
||||||
def printError():
|
def printError():
|
||||||
"""Print error text FOR LOADING"""
|
"""
|
||||||
|
Print error text FOR LOADING
|
||||||
|
"""
|
||||||
printColored("Error", bcolors.RED)
|
printColored("Error", bcolors.RED)
|
||||||
|
|
||||||
|
|
||||||
def printDone():
|
def printDone():
|
||||||
"""Print error text FOR LOADING"""
|
"""
|
||||||
|
Print error text FOR LOADING
|
||||||
|
"""
|
||||||
printColored("Done", bcolors.GREEN)
|
printColored("Done", bcolors.GREEN)
|
||||||
|
|
||||||
|
|
||||||
def printWarning():
|
def printWarning():
|
||||||
"""Print error text FOR LOADING"""
|
"""
|
||||||
|
Print error text FOR LOADING
|
||||||
|
"""
|
||||||
printColored("Warning", bcolors.YELLOW)
|
printColored("Warning", bcolors.YELLOW)
|
||||||
|
|
|
@ -253,7 +253,6 @@ countryCodes = {
|
||||||
"AI": 7
|
"AI": 7
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def getCountryID(code):
|
def getCountryID(code):
|
||||||
"""
|
"""
|
||||||
Get country ID for osu client
|
Get country ID for osu client
|
||||||
|
|
|
@ -2,13 +2,13 @@ import MySQLdb
|
||||||
import threading
|
import threading
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
|
|
||||||
class mysqlWorker:
|
class mysqlWorker():
|
||||||
"""
|
"""
|
||||||
Instance of a pettirosso meme
|
Instance of a mysql worker
|
||||||
"""
|
"""
|
||||||
def __init__(self, wid, host, username, password, database):
|
def __init__(self, wid, host, username, password, database):
|
||||||
"""
|
"""
|
||||||
Create a pettirosso meme (mysql worker)
|
Create a mysql worker
|
||||||
|
|
||||||
wid -- worker id
|
wid -- worker id
|
||||||
host -- hostname
|
host -- hostname
|
||||||
|
@ -22,11 +22,10 @@ class mysqlWorker:
|
||||||
self.ready = True
|
self.ready = True
|
||||||
self.lock = threading.Lock()
|
self.lock = threading.Lock()
|
||||||
|
|
||||||
class db:
|
class db():
|
||||||
"""
|
"""
|
||||||
A MySQL db connection with multiple workers
|
A MySQL db connection with multiple workers
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, host, username, password, database, workers):
|
def __init__(self, host, username, password, database, workers):
|
||||||
"""
|
"""
|
||||||
Create MySQL workers aka pettirossi meme
|
Create MySQL workers aka pettirossi meme
|
||||||
|
@ -37,9 +36,6 @@ class db:
|
||||||
database -- MySQL database name
|
database -- MySQL database name
|
||||||
workers -- Number of workers to spawn
|
workers -- Number of workers to spawn
|
||||||
"""
|
"""
|
||||||
#self.lock = threading.Lock()
|
|
||||||
#self.connection = MySQLdb.connect(host, username, password, database)
|
|
||||||
|
|
||||||
self.workers = []
|
self.workers = []
|
||||||
self.lastWorker = 0
|
self.lastWorker = 0
|
||||||
self.workersNumber = workers
|
self.workersNumber = workers
|
||||||
|
@ -57,7 +53,6 @@ class db:
|
||||||
self.lastWorker = 0
|
self.lastWorker = 0
|
||||||
else:
|
else:
|
||||||
self.lastWorker += 1
|
self.lastWorker += 1
|
||||||
#print("Using worker {}".format(self.lastWorker))
|
|
||||||
return self.workers[self.lastWorker]
|
return self.workers[self.lastWorker]
|
||||||
|
|
||||||
def execute(self, query, params = ()):
|
def execute(self, query, params = ()):
|
||||||
|
|
|
@ -1,9 +1,6 @@
|
||||||
import requests
|
import requests
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from helpers import generalFunctions
|
|
||||||
from urllib.parse import urlencode
|
from urllib.parse import urlencode
|
||||||
from helpers import consoleHelper
|
|
||||||
from constants import bcolors
|
|
||||||
|
|
||||||
def sendDiscordMessage(channel, message, alertDev = False, prefix = "**pep.py**"):
|
def sendDiscordMessage(channel, message, alertDev = False, prefix = "**pep.py**"):
|
||||||
"""
|
"""
|
||||||
|
@ -24,7 +21,6 @@ def sendDiscordMessage(channel, message, alertDev = False, prefix = "**pep.py**"
|
||||||
except:
|
except:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
|
||||||
def sendConfidential(message, alertDev = False):
|
def sendConfidential(message, alertDev = False):
|
||||||
"""
|
"""
|
||||||
Send a message to #bunker
|
Send a message to #bunker
|
||||||
|
@ -33,7 +29,6 @@ def sendConfidential(message, alertDev = False):
|
||||||
"""
|
"""
|
||||||
sendDiscordMessage("bunk", message, alertDev)
|
sendDiscordMessage("bunk", message, alertDev)
|
||||||
|
|
||||||
|
|
||||||
def sendStaff(message):
|
def sendStaff(message):
|
||||||
"""
|
"""
|
||||||
Send a message to #staff
|
Send a message to #staff
|
||||||
|
@ -42,7 +37,6 @@ def sendStaff(message):
|
||||||
"""
|
"""
|
||||||
sendDiscordMessage("staff", message)
|
sendDiscordMessage("staff", message)
|
||||||
|
|
||||||
|
|
||||||
def sendGeneral(message):
|
def sendGeneral(message):
|
||||||
"""
|
"""
|
||||||
Send a message to #general
|
Send a message to #general
|
||||||
|
@ -51,7 +45,6 @@ def sendGeneral(message):
|
||||||
"""
|
"""
|
||||||
sendDiscordMessage("general", message)
|
sendDiscordMessage("general", message)
|
||||||
|
|
||||||
|
|
||||||
def sendChatlog(message):
|
def sendChatlog(message):
|
||||||
"""
|
"""
|
||||||
Send a message to #chatlog
|
Send a message to #chatlog
|
||||||
|
|
|
@ -1,6 +1,17 @@
|
||||||
"""Some functions that don't fit in any other file"""
|
|
||||||
from constants import mods
|
from constants import mods
|
||||||
from time import gmtime, strftime
|
from time import gmtime, strftime
|
||||||
|
import hashlib
|
||||||
|
|
||||||
|
def stringMd5(string):
|
||||||
|
"""
|
||||||
|
Return string's md5
|
||||||
|
|
||||||
|
string -- string to hash
|
||||||
|
return -- string's md5 hash
|
||||||
|
"""
|
||||||
|
d = hashlib.md5()
|
||||||
|
d.update(string.encode("utf-8"))
|
||||||
|
return d.hexdigest()
|
||||||
|
|
||||||
def stringToBool(s):
|
def stringToBool(s):
|
||||||
"""
|
"""
|
||||||
|
@ -9,10 +20,8 @@ def stringToBool(s):
|
||||||
s -- string/int value
|
s -- string/int value
|
||||||
return -- True/False
|
return -- True/False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return (s == "True" or s== "true" or s == "1" or s == 1)
|
return (s == "True" or s== "true" or s == "1" or s == 1)
|
||||||
|
|
||||||
|
|
||||||
def hexString(s):
|
def hexString(s):
|
||||||
"""
|
"""
|
||||||
Output s' bytes in HEX
|
Output s' bytes in HEX
|
||||||
|
@ -20,7 +29,6 @@ def hexString(s):
|
||||||
s -- string
|
s -- string
|
||||||
return -- string with hex value
|
return -- string with hex value
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return ":".join("{:02x}".format(ord(str(c))) for c in s)
|
return ":".join("{:02x}".format(ord(str(c))) for c in s)
|
||||||
|
|
||||||
def readableMods(__mods):
|
def readableMods(__mods):
|
||||||
|
|
|
@ -11,7 +11,6 @@ def getCountry(ip):
|
||||||
ip -- IP Address
|
ip -- IP Address
|
||||||
return -- Country code (2 letters)
|
return -- Country code (2 letters)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Try to get country from Pikolo Aul's Go-Sanic ip API
|
# Try to get country from Pikolo Aul's Go-Sanic ip API
|
||||||
result = json.loads(urllib.request.urlopen("{}/{}".format(glob.conf.config["localize"]["ipapiurl"], ip), timeout=3).read().decode())["country"]
|
result = json.loads(urllib.request.urlopen("{}/{}".format(glob.conf.config["localize"]["ipapiurl"], ip), timeout=3).read().decode())["country"]
|
||||||
|
@ -20,7 +19,6 @@ def getCountry(ip):
|
||||||
log.error("Error in get country")
|
log.error("Error in get country")
|
||||||
return "XX"
|
return "XX"
|
||||||
|
|
||||||
|
|
||||||
def getLocation(ip):
|
def getLocation(ip):
|
||||||
"""
|
"""
|
||||||
Get latitude and longitude from IP address
|
Get latitude and longitude from IP address
|
||||||
|
@ -28,7 +26,6 @@ def getLocation(ip):
|
||||||
ip -- IP address
|
ip -- IP address
|
||||||
return -- [latitude, longitude]
|
return -- [latitude, longitude]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Try to get position from Pikolo Aul's Go-Sanic ip API
|
# Try to get position from Pikolo Aul's Go-Sanic ip API
|
||||||
result = json.loads(urllib.request.urlopen("{}/{}".format(glob.conf.config["localize"]["ipapiurl"], ip), timeout=3).read().decode())["loc"].split(",")
|
result = json.loads(urllib.request.urlopen("{}/{}".format(glob.conf.config["localize"]["ipapiurl"], ip), timeout=3).read().decode())["loc"].split(",")
|
||||||
|
|
|
@ -8,7 +8,6 @@ def uleb128Encode(num):
|
||||||
num -- int to encode
|
num -- int to encode
|
||||||
return -- bytearray with encoded number
|
return -- bytearray with encoded number
|
||||||
"""
|
"""
|
||||||
|
|
||||||
arr = bytearray()
|
arr = bytearray()
|
||||||
length = 0
|
length = 0
|
||||||
|
|
||||||
|
@ -24,7 +23,6 @@ def uleb128Encode(num):
|
||||||
|
|
||||||
return arr
|
return arr
|
||||||
|
|
||||||
|
|
||||||
def uleb128Decode(num):
|
def uleb128Decode(num):
|
||||||
"""
|
"""
|
||||||
Decode uleb128 -> int
|
Decode uleb128 -> int
|
||||||
|
@ -32,9 +30,7 @@ def uleb128Decode(num):
|
||||||
num -- encoded uleb128
|
num -- encoded uleb128
|
||||||
return -- list. [total, length]
|
return -- list. [total, length]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
shift = 0
|
shift = 0
|
||||||
|
|
||||||
arr = [0,0] #total, length
|
arr = [0,0] #total, length
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
@ -47,42 +43,40 @@ def uleb128Decode(num):
|
||||||
|
|
||||||
return arr
|
return arr
|
||||||
|
|
||||||
|
def unpackData(data, dataType):
|
||||||
def unpackData(__data, __dataType):
|
|
||||||
"""
|
"""
|
||||||
Unpacks data according to dataType
|
Unpacks data according to dataType
|
||||||
|
|
||||||
__data -- bytes array to unpack
|
data -- bytes array to unpack
|
||||||
__dataType -- data type. See dataTypes.py
|
dataType -- data type. See dataTypes.py
|
||||||
|
|
||||||
return -- unpacked bytes
|
return -- unpacked bytes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Get right pack Type
|
# Get right pack Type
|
||||||
if __dataType == dataTypes.uInt16:
|
if dataType == dataTypes.uInt16:
|
||||||
unpackType = "<H"
|
unpackType = "<H"
|
||||||
elif __dataType == dataTypes.sInt16:
|
elif dataType == dataTypes.sInt16:
|
||||||
unpackType = "<h"
|
unpackType = "<h"
|
||||||
elif __dataType == dataTypes.uInt32:
|
elif dataType == dataTypes.uInt32:
|
||||||
unpackType = "<L"
|
unpackType = "<L"
|
||||||
elif __dataType == dataTypes.sInt32:
|
elif dataType == dataTypes.sInt32:
|
||||||
unpackType = "<l"
|
unpackType = "<l"
|
||||||
elif __dataType == dataTypes.uInt64:
|
elif dataType == dataTypes.uInt64:
|
||||||
unpackType = "<Q"
|
unpackType = "<Q"
|
||||||
elif __dataType == dataTypes.sInt64:
|
elif dataType == dataTypes.sInt64:
|
||||||
unpackType = "<q"
|
unpackType = "<q"
|
||||||
elif __dataType == dataTypes.string:
|
elif dataType == dataTypes.string:
|
||||||
unpackType = "<s"
|
unpackType = "<s"
|
||||||
elif __dataType == dataTypes.ffloat:
|
elif dataType == dataTypes.ffloat:
|
||||||
unpackType = "<f"
|
unpackType = "<f"
|
||||||
else:
|
else:
|
||||||
unpackType = "<B"
|
unpackType = "<B"
|
||||||
|
|
||||||
# Unpack
|
# Unpack
|
||||||
return struct.unpack(unpackType, bytes(__data))[0]
|
return struct.unpack(unpackType, bytes(data))[0]
|
||||||
|
|
||||||
|
def packData(__data, dataType):
|
||||||
def packData(__data, __dataType):
|
|
||||||
"""
|
"""
|
||||||
Packs data according to dataType
|
Packs data according to dataType
|
||||||
|
|
||||||
|
@ -96,11 +90,11 @@ def packData(__data, __dataType):
|
||||||
pack = True # if True, use pack. False only with strings
|
pack = True # if True, use pack. False only with strings
|
||||||
|
|
||||||
# Get right pack Type
|
# Get right pack Type
|
||||||
if __dataType == dataTypes.bbytes:
|
if dataType == dataTypes.bbytes:
|
||||||
# Bytes, do not use pack, do manually
|
# Bytes, do not use pack, do manually
|
||||||
pack = False
|
pack = False
|
||||||
data = __data
|
data = __data
|
||||||
elif __dataType == dataTypes.intList:
|
elif dataType == dataTypes.intList:
|
||||||
# Pack manually
|
# Pack manually
|
||||||
pack = False
|
pack = False
|
||||||
# Add length
|
# Add length
|
||||||
|
@ -108,7 +102,7 @@ def packData(__data, __dataType):
|
||||||
# Add all elements
|
# Add all elements
|
||||||
for i in __data:
|
for i in __data:
|
||||||
data += packData(i, dataTypes.sInt32)
|
data += packData(i, dataTypes.sInt32)
|
||||||
elif __dataType == dataTypes.string:
|
elif dataType == dataTypes.string:
|
||||||
# String, do not use pack, do manually
|
# String, do not use pack, do manually
|
||||||
pack = False
|
pack = False
|
||||||
if len(__data) == 0:
|
if len(__data) == 0:
|
||||||
|
@ -119,21 +113,21 @@ def packData(__data, __dataType):
|
||||||
data += b"\x0B"
|
data += b"\x0B"
|
||||||
data += uleb128Encode(len(__data))
|
data += uleb128Encode(len(__data))
|
||||||
data += str.encode(__data, "latin_1", "ignore")
|
data += str.encode(__data, "latin_1", "ignore")
|
||||||
elif __dataType == dataTypes.uInt16:
|
elif dataType == dataTypes.uInt16:
|
||||||
packType = "<H"
|
packType = "<H"
|
||||||
elif __dataType == dataTypes.sInt16:
|
elif dataType == dataTypes.sInt16:
|
||||||
packType = "<h"
|
packType = "<h"
|
||||||
elif __dataType == dataTypes.uInt32:
|
elif dataType == dataTypes.uInt32:
|
||||||
packType = "<L"
|
packType = "<L"
|
||||||
elif __dataType == dataTypes.sInt32:
|
elif dataType == dataTypes.sInt32:
|
||||||
packType = "<l"
|
packType = "<l"
|
||||||
elif __dataType == dataTypes.uInt64:
|
elif dataType == dataTypes.uInt64:
|
||||||
packType = "<Q"
|
packType = "<Q"
|
||||||
elif __dataType == dataTypes.sInt64:
|
elif dataType == dataTypes.sInt64:
|
||||||
packType = "<q"
|
packType = "<q"
|
||||||
elif __dataType == dataTypes.string:
|
elif dataType == dataTypes.string:
|
||||||
packType = "<s"
|
packType = "<s"
|
||||||
elif __dataType == dataTypes.ffloat:
|
elif dataType == dataTypes.ffloat:
|
||||||
packType = "<f"
|
packType = "<f"
|
||||||
else:
|
else:
|
||||||
packType = "<B"
|
packType = "<B"
|
||||||
|
@ -144,7 +138,6 @@ def packData(__data, __dataType):
|
||||||
|
|
||||||
return data
|
return data
|
||||||
|
|
||||||
# TODO: Wat dangerous
|
|
||||||
def buildPacket(__packet, __packetData = []):
|
def buildPacket(__packet, __packetData = []):
|
||||||
"""
|
"""
|
||||||
Build a packet
|
Build a packet
|
||||||
|
@ -154,7 +147,6 @@ def buildPacket(__packet, __packetData = []):
|
||||||
|
|
||||||
return -- packet bytes
|
return -- packet bytes
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Set some variables
|
# Set some variables
|
||||||
packetData = bytes()
|
packetData = bytes()
|
||||||
packetLength = 0
|
packetLength = 0
|
||||||
|
@ -174,7 +166,6 @@ def buildPacket(__packet, __packetData = []):
|
||||||
packetBytes += packetData # packet data
|
packetBytes += packetData # packet data
|
||||||
return packetBytes
|
return packetBytes
|
||||||
|
|
||||||
|
|
||||||
def readPacketID(stream):
|
def readPacketID(stream):
|
||||||
"""
|
"""
|
||||||
Read packetID from stream (0-1 bytes)
|
Read packetID from stream (0-1 bytes)
|
||||||
|
@ -182,10 +173,8 @@ def readPacketID(stream):
|
||||||
stream -- data stream
|
stream -- data stream
|
||||||
return -- packet ID (int)
|
return -- packet ID (int)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return unpackData(stream[0:2], dataTypes.uInt16)
|
return unpackData(stream[0:2], dataTypes.uInt16)
|
||||||
|
|
||||||
|
|
||||||
def readPacketLength(stream):
|
def readPacketLength(stream):
|
||||||
"""
|
"""
|
||||||
Read packet length from stream (3-4-5-6 bytes)
|
Read packet length from stream (3-4-5-6 bytes)
|
||||||
|
@ -193,7 +182,6 @@ def readPacketLength(stream):
|
||||||
stream -- data stream
|
stream -- data stream
|
||||||
return -- packet length (int)
|
return -- packet length (int)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return unpackData(stream[3:7], dataTypes.uInt32)
|
return unpackData(stream[3:7], dataTypes.uInt32)
|
||||||
|
|
||||||
|
|
||||||
|
@ -208,7 +196,6 @@ def readPacketData(stream, structure = [], hasFirstBytes = True):
|
||||||
Optional. Default: True
|
Optional. Default: True
|
||||||
return -- dictionary. key: name, value: read data
|
return -- dictionary. key: name, value: read data
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Read packet ID (first 2 bytes)
|
# Read packet ID (first 2 bytes)
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ def checkOldPassword(password, salt, rightPassword):
|
||||||
rightPassword -- right password
|
rightPassword -- right password
|
||||||
return -- bool
|
return -- bool
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return (rightPassword == cryptHelper.crypt(password, "$2y$"+str(base64.b64decode(salt))))
|
return (rightPassword == cryptHelper.crypt(password, "$2y$"+str(base64.b64decode(salt))))
|
||||||
|
|
||||||
def checkNewPassword(password, dbPassword):
|
def checkNewPassword(password, dbPassword):
|
||||||
|
|
|
@ -3,8 +3,6 @@ import tornado.web
|
||||||
import tornado.gen
|
import tornado.gen
|
||||||
from tornado.ioloop import IOLoop
|
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
|
|
||||||
import gevent
|
import gevent
|
||||||
|
|
||||||
class asyncRequestHandler(tornado.web.RequestHandler):
|
class asyncRequestHandler(tornado.web.RequestHandler):
|
||||||
|
@ -50,7 +48,6 @@ class asyncRequestHandler(tornado.web.RequestHandler):
|
||||||
return realIP
|
return realIP
|
||||||
return self.request.remote_ip
|
return self.request.remote_ip
|
||||||
|
|
||||||
|
|
||||||
def runBackground(data, callback):
|
def runBackground(data, callback):
|
||||||
"""
|
"""
|
||||||
Run a function in the background.
|
Run a function in the background.
|
||||||
|
@ -59,7 +56,6 @@ def runBackground(data, callback):
|
||||||
func, args, kwargs = data
|
func, args, kwargs = data
|
||||||
def _callback(result):
|
def _callback(result):
|
||||||
IOLoop.instance().add_callback(lambda: callback(result))
|
IOLoop.instance().add_callback(lambda: callback(result))
|
||||||
#glob.pool.apply_async(func, args, kwargs, _callback)
|
|
||||||
g = gevent.Greenlet(func, *args, **kwargs)
|
g = gevent.Greenlet(func, *args, **kwargs)
|
||||||
g.link(_callback)
|
g.link(_callback)
|
||||||
g.start()
|
g.start()
|
||||||
|
|
|
@ -15,10 +15,8 @@ def runningUnderUnix():
|
||||||
|
|
||||||
return --- True if running under UNIX, otherwise False
|
return --- True if running under UNIX, otherwise False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return True if os.name == "posix" else False
|
return True if os.name == "posix" else False
|
||||||
|
|
||||||
|
|
||||||
def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
|
def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
|
||||||
"""
|
"""
|
||||||
Schedule a server shutdown/restart
|
Schedule a server shutdown/restart
|
||||||
|
@ -27,7 +25,6 @@ def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
|
||||||
restart -- if True, server will restart. if False, server will shudown
|
restart -- if True, server will restart. if False, server will shudown
|
||||||
message -- if set, send that message to every client to warn about the shutdown/restart
|
message -- if set, send that message to every client to warn about the shutdown/restart
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Console output
|
# Console output
|
||||||
log.info("Pep.py will {} in {} seconds!".format("restart" if restart else "shutdown", sendRestartTime+delay))
|
log.info("Pep.py will {} in {} seconds!".format("restart" if restart else "shutdown", sendRestartTime+delay))
|
||||||
log.info("Sending server restart packets in {} seconds...".format(sendRestartTime))
|
log.info("Sending server restart packets in {} seconds...".format(sendRestartTime))
|
||||||
|
@ -49,27 +46,23 @@ def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
|
||||||
# Schedule actual server shutdown/restart some seconds after server restart packet, so everyone gets it
|
# Schedule actual server shutdown/restart some seconds after server restart packet, so everyone gets it
|
||||||
threading.Timer(sendRestartTime+delay, action).start()
|
threading.Timer(sendRestartTime+delay, action).start()
|
||||||
|
|
||||||
|
|
||||||
def restartServer():
|
def restartServer():
|
||||||
"""Restart pep.py script"""
|
"""Restart pep.py script"""
|
||||||
log.info("Restarting pep.py...")
|
log.info("Restarting pep.py...")
|
||||||
os.execv(sys.executable, [sys.executable] + sys.argv)
|
os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||||
|
|
||||||
|
|
||||||
def shutdownServer():
|
def shutdownServer():
|
||||||
"""Shutdown pep.py"""
|
"""Shutdown pep.py"""
|
||||||
log.info("Shutting down pep.py...")
|
log.info("Shutting down pep.py...")
|
||||||
sig = signal.SIGKILL if runningUnderUnix() else signal.CTRL_C_EVENT
|
sig = signal.SIGKILL if runningUnderUnix() else signal.CTRL_C_EVENT
|
||||||
os.kill(os.getpid(), sig)
|
os.kill(os.getpid(), sig)
|
||||||
|
|
||||||
|
|
||||||
def getSystemInfo():
|
def getSystemInfo():
|
||||||
"""
|
"""
|
||||||
Get a dictionary with some system/server info
|
Get a dictionary with some system/server info
|
||||||
|
|
||||||
return -- ["unix", "connectedUsers", "webServer", "cpuUsage", "totalMemory", "usedMemory", "loadAverage"]
|
return -- ["unix", "connectedUsers", "webServer", "cpuUsage", "totalMemory", "usedMemory", "loadAverage"]
|
||||||
"""
|
"""
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
# Get if server is running under unix/nt
|
# Get if server is running under unix/nt
|
||||||
|
|
|
@ -14,9 +14,8 @@ def getID(username):
|
||||||
username -- user
|
username -- user
|
||||||
return -- user id or False
|
return -- user id or False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Get user ID from db
|
# Get user ID from db
|
||||||
userID = glob.db.fetch("SELECT id FROM users WHERE username = %s", [username])
|
userID = glob.db.fetch("SELECT id FROM users WHERE username = %s LIMIT 1", [username])
|
||||||
|
|
||||||
# Make sure the query returned something
|
# Make sure the query returned something
|
||||||
if userID == None:
|
if userID == None:
|
||||||
|
@ -25,7 +24,6 @@ def getID(username):
|
||||||
# Return user ID
|
# Return user ID
|
||||||
return userID["id"]
|
return userID["id"]
|
||||||
|
|
||||||
|
|
||||||
def checkLogin(userID, password):
|
def checkLogin(userID, password):
|
||||||
"""
|
"""
|
||||||
Check userID's login with specified password
|
Check userID's login with specified password
|
||||||
|
@ -35,9 +33,8 @@ def checkLogin(userID, password):
|
||||||
password -- plain md5 password
|
password -- plain md5 password
|
||||||
return -- True or False
|
return -- True or False
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Get password data
|
# Get password data
|
||||||
passwordData = glob.db.fetch("SELECT password_md5, salt, password_version FROM users WHERE id = %s", [userID])
|
passwordData = glob.db.fetch("SELECT password_md5, salt, password_version FROM users WHERE id = %s LIMIT 1", [userID])
|
||||||
|
|
||||||
# Make sure the query returned something
|
# Make sure the query returned something
|
||||||
if passwordData == None:
|
if passwordData == None:
|
||||||
|
@ -51,8 +48,7 @@ def checkLogin(userID, password):
|
||||||
ok = passwordHelper.checkOldPassword(password, passwordData["salt"], passwordData["password_md5"])
|
ok = passwordHelper.checkOldPassword(password, passwordData["salt"], passwordData["password_md5"])
|
||||||
if not ok: return False
|
if not ok: return False
|
||||||
newpass = passwordHelper.genBcrypt(password)
|
newpass = passwordHelper.genBcrypt(password)
|
||||||
glob.db.execute("UPDATE users SET password_md5=%s, salt='', password_version='2' WHERE id = %s", [newpass, userID])
|
glob.db.execute("UPDATE users SET password_md5=%s, salt='', password_version='2' WHERE id = %s LIMIT 1", [newpass, userID])
|
||||||
|
|
||||||
|
|
||||||
def exists(userID):
|
def exists(userID):
|
||||||
"""
|
"""
|
||||||
|
@ -61,8 +57,7 @@ def exists(userID):
|
||||||
userID -- user ID to check
|
userID -- user ID to check
|
||||||
return -- bool
|
return -- bool
|
||||||
"""
|
"""
|
||||||
|
result = glob.db.fetch("SELECT id FROM users WHERE id = %s LIMIT 1", [userID])
|
||||||
result = glob.db.fetch("SELECT id FROM users WHERE id = %s", [userID])
|
|
||||||
if result == None:
|
if result == None:
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
|
@ -76,8 +71,7 @@ def getSilenceEnd(userID):
|
||||||
userID -- userID
|
userID -- userID
|
||||||
return -- UNIX time
|
return -- UNIX time
|
||||||
"""
|
"""
|
||||||
|
return glob.db.fetch("SELECT silence_end FROM users WHERE id = %s LIMIT 1", [userID])["silence_end"]
|
||||||
return glob.db.fetch("SELECT silence_end FROM users WHERE id = %s", [userID])["silence_end"]
|
|
||||||
|
|
||||||
|
|
||||||
def silence(userID, seconds, silenceReason, author = 999):
|
def silence(userID, seconds, silenceReason, author = 999):
|
||||||
|
@ -91,7 +85,7 @@ def silence(userID, seconds, silenceReason, author = 999):
|
||||||
"""
|
"""
|
||||||
# db qurey
|
# db qurey
|
||||||
silenceEndTime = int(time.time())+seconds
|
silenceEndTime = int(time.time())+seconds
|
||||||
glob.db.execute("UPDATE users SET silence_end = %s, silence_reason = %s WHERE id = %s", [silenceEndTime, silenceReason, userID])
|
glob.db.execute("UPDATE users SET silence_end = %s, silence_reason = %s WHERE id = %s LIMIT 1", [silenceEndTime, silenceReason, userID])
|
||||||
|
|
||||||
# Loh
|
# Loh
|
||||||
targetUsername = getUsername(userID)
|
targetUsername = getUsername(userID)
|
||||||
|
@ -109,9 +103,8 @@ def getRankedScore(userID, gameMode):
|
||||||
gameMode -- int value, see gameModes
|
gameMode -- int value, see gameModes
|
||||||
return -- ranked score
|
return -- ranked score
|
||||||
"""
|
"""
|
||||||
|
|
||||||
modeForDB = gameModes.getGameModeForDB(gameMode)
|
modeForDB = gameModes.getGameModeForDB(gameMode)
|
||||||
return glob.db.fetch("SELECT ranked_score_"+modeForDB+" FROM users_stats WHERE id = %s", [userID])["ranked_score_"+modeForDB]
|
return glob.db.fetch("SELECT ranked_score_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["ranked_score_"+modeForDB]
|
||||||
|
|
||||||
|
|
||||||
def getTotalScore(userID, gameMode):
|
def getTotalScore(userID, gameMode):
|
||||||
|
@ -122,10 +115,8 @@ def getTotalScore(userID, gameMode):
|
||||||
gameMode -- int value, see gameModes
|
gameMode -- int value, see gameModes
|
||||||
return -- total score
|
return -- total score
|
||||||
"""
|
"""
|
||||||
|
|
||||||
modeForDB = gameModes.getGameModeForDB(gameMode)
|
modeForDB = gameModes.getGameModeForDB(gameMode)
|
||||||
return glob.db.fetch("SELECT total_score_"+modeForDB+" FROM users_stats WHERE id = %s", [userID])["total_score_"+modeForDB]
|
return glob.db.fetch("SELECT total_score_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["total_score_"+modeForDB]
|
||||||
|
|
||||||
|
|
||||||
def getAccuracy(userID, gameMode):
|
def getAccuracy(userID, gameMode):
|
||||||
"""
|
"""
|
||||||
|
@ -135,10 +126,8 @@ def getAccuracy(userID, gameMode):
|
||||||
gameMode -- int value, see gameModes
|
gameMode -- int value, see gameModes
|
||||||
return -- accuracy
|
return -- accuracy
|
||||||
"""
|
"""
|
||||||
|
|
||||||
modeForDB = gameModes.getGameModeForDB(gameMode)
|
modeForDB = gameModes.getGameModeForDB(gameMode)
|
||||||
return glob.db.fetch("SELECT avg_accuracy_"+modeForDB+" FROM users_stats WHERE id = %s", [userID])["avg_accuracy_"+modeForDB]
|
return glob.db.fetch("SELECT avg_accuracy_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["avg_accuracy_"+modeForDB]
|
||||||
|
|
||||||
|
|
||||||
def getGameRank(userID, gameMode):
|
def getGameRank(userID, gameMode):
|
||||||
"""
|
"""
|
||||||
|
@ -150,13 +139,12 @@ def getGameRank(userID, gameMode):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
modeForDB = gameModes.getGameModeForDB(gameMode)
|
modeForDB = gameModes.getGameModeForDB(gameMode)
|
||||||
result = glob.db.fetch("SELECT position FROM leaderboard_"+modeForDB+" WHERE user = %s", [userID])
|
result = glob.db.fetch("SELECT position FROM leaderboard_"+modeForDB+" WHERE user = %s LIMIT 1", [userID])
|
||||||
if result == None:
|
if result == None:
|
||||||
return 0
|
return 0
|
||||||
else:
|
else:
|
||||||
return result["position"]
|
return result["position"]
|
||||||
|
|
||||||
|
|
||||||
def getPlaycount(userID, gameMode):
|
def getPlaycount(userID, gameMode):
|
||||||
"""
|
"""
|
||||||
Get userID's playcount relative to gameMode
|
Get userID's playcount relative to gameMode
|
||||||
|
@ -167,8 +155,7 @@ def getPlaycount(userID, gameMode):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
modeForDB = gameModes.getGameModeForDB(gameMode)
|
modeForDB = gameModes.getGameModeForDB(gameMode)
|
||||||
return glob.db.fetch("SELECT playcount_"+modeForDB+" FROM users_stats WHERE id = %s", [userID])["playcount_"+modeForDB]
|
return glob.db.fetch("SELECT playcount_"+modeForDB+" FROM users_stats WHERE id = %s LIMIT 1", [userID])["playcount_"+modeForDB]
|
||||||
|
|
||||||
|
|
||||||
def getUsername(userID):
|
def getUsername(userID):
|
||||||
"""
|
"""
|
||||||
|
@ -178,8 +165,7 @@ def getUsername(userID):
|
||||||
return -- username
|
return -- username
|
||||||
"""
|
"""
|
||||||
|
|
||||||
return glob.db.fetch("SELECT username FROM users WHERE id = %s", [userID])["username"]
|
return glob.db.fetch("SELECT username FROM users WHERE id = %s LIMIT 1", [userID])["username"]
|
||||||
|
|
||||||
|
|
||||||
def getFriendList(userID):
|
def getFriendList(userID):
|
||||||
"""
|
"""
|
||||||
|
@ -202,7 +188,6 @@ def getFriendList(userID):
|
||||||
# Return friend IDs
|
# Return friend IDs
|
||||||
return friends
|
return friends
|
||||||
|
|
||||||
|
|
||||||
def addFriend(userID, friendID):
|
def addFriend(userID, friendID):
|
||||||
"""
|
"""
|
||||||
Add friendID to userID's friend list
|
Add friendID to userID's friend list
|
||||||
|
@ -216,7 +201,7 @@ def addFriend(userID, friendID):
|
||||||
return
|
return
|
||||||
|
|
||||||
# check user isn't already a friend of ours
|
# check user isn't already a friend of ours
|
||||||
if glob.db.fetch("SELECT id FROM users_relationships WHERE user1 = %s AND user2 = %s", [userID, friendID]) != None:
|
if glob.db.fetch("SELECT id FROM users_relationships WHERE user1 = %s AND user2 = %s LIMIT 1", [userID, friendID]) != None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Set new value
|
# Set new value
|
||||||
|
@ -230,7 +215,6 @@ def removeFriend(userID, friendID):
|
||||||
userID -- user
|
userID -- user
|
||||||
friendID -- old friend
|
friendID -- old friend
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Delete user relationship. We don't need to check if the relationship was there, because who gives a shit,
|
# Delete user relationship. We don't need to check if the relationship was there, because who gives a shit,
|
||||||
# if they were not friends and they don't want to be anymore, be it. ¯\_(ツ)_/¯
|
# if they were not friends and they don't want to be anymore, be it. ¯\_(ツ)_/¯
|
||||||
glob.db.execute("DELETE FROM users_relationships WHERE user1 = %s AND user2 = %s", [userID, friendID])
|
glob.db.execute("DELETE FROM users_relationships WHERE user1 = %s AND user2 = %s", [userID, friendID])
|
||||||
|
@ -245,8 +229,7 @@ def getCountry(userID):
|
||||||
userID -- user
|
userID -- user
|
||||||
return -- country code (two letters)
|
return -- country code (two letters)
|
||||||
"""
|
"""
|
||||||
|
return glob.db.fetch("SELECT country FROM users_stats WHERE id = %s LIMIT 1", [userID])["country"]
|
||||||
return glob.db.fetch("SELECT country FROM users_stats WHERE id = %s", [userID])["country"]
|
|
||||||
|
|
||||||
def getPP(userID, gameMode):
|
def getPP(userID, gameMode):
|
||||||
"""
|
"""
|
||||||
|
@ -257,7 +240,7 @@ def getPP(userID, gameMode):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
modeForDB = gameModes.getGameModeForDB(gameMode)
|
modeForDB = gameModes.getGameModeForDB(gameMode)
|
||||||
return glob.db.fetch("SELECT pp_{} FROM users_stats WHERE id = %s".format(modeForDB), [userID])["pp_{}".format(modeForDB)]
|
return glob.db.fetch("SELECT pp_{} FROM users_stats WHERE id = %s LIMIT 1".format(modeForDB), [userID])["pp_{}".format(modeForDB)]
|
||||||
|
|
||||||
def setCountry(userID, country):
|
def setCountry(userID, country):
|
||||||
"""
|
"""
|
||||||
|
@ -266,7 +249,7 @@ def setCountry(userID, country):
|
||||||
userID -- userID
|
userID -- userID
|
||||||
country -- country letters
|
country -- country letters
|
||||||
"""
|
"""
|
||||||
glob.db.execute("UPDATE users_stats SET country = %s WHERE id = %s", [country, userID])
|
glob.db.execute("UPDATE users_stats SET country = %s WHERE id = %s LIMIT 1", [country, userID])
|
||||||
|
|
||||||
def getShowCountry(userID):
|
def getShowCountry(userID):
|
||||||
"""
|
"""
|
||||||
|
@ -275,7 +258,7 @@ def getShowCountry(userID):
|
||||||
userID -- userID
|
userID -- userID
|
||||||
return -- True if country is shown, False if it's hidden
|
return -- True if country is shown, False if it's hidden
|
||||||
"""
|
"""
|
||||||
country = glob.db.fetch("SELECT show_country FROM users_stats WHERE id = %s", [userID])
|
country = glob.db.fetch("SELECT show_country FROM users_stats WHERE id = %s LIMIT 1", [userID])
|
||||||
if country == None:
|
if country == None:
|
||||||
return False
|
return False
|
||||||
return generalFunctions.stringToBool(country)
|
return generalFunctions.stringToBool(country)
|
||||||
|
@ -292,25 +275,42 @@ def saveBanchoSession(userID, ip):
|
||||||
"""
|
"""
|
||||||
Save userid and ip of this token in bancho_sessions table.
|
Save userid and ip of this token in bancho_sessions table.
|
||||||
Used to cache logins on LETS requests
|
Used to cache logins on LETS requests
|
||||||
|
|
||||||
|
userID --
|
||||||
|
ip -- user's ip address
|
||||||
"""
|
"""
|
||||||
log.debug("Saving bancho session ({}::{}) in db".format(userID, ip))
|
|
||||||
glob.db.execute("INSERT INTO bancho_sessions (id, userid, ip) VALUES (NULL, %s, %s)", [userID, ip])
|
glob.db.execute("INSERT INTO bancho_sessions (id, userid, ip) VALUES (NULL, %s, %s)", [userID, ip])
|
||||||
|
|
||||||
def deleteBanchoSessions(userID, ip):
|
def deleteBanchoSessions(userID, ip):
|
||||||
"""Delete this bancho session from DB"""
|
"""
|
||||||
log.debug("Deleting bancho session ({}::{}) from db".format(userID, ip))
|
Delete this bancho session from DB
|
||||||
|
|
||||||
|
userID --
|
||||||
|
ip -- user's IP address
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
glob.db.execute("DELETE FROM bancho_sessions WHERE userid = %s AND ip = %s", [userID, ip])
|
glob.db.execute("DELETE FROM bancho_sessions WHERE userid = %s AND ip = %s", [userID, ip])
|
||||||
except:
|
except:
|
||||||
log.warning("Token for user: {} ip: {} doesn't exist".format(userID, ip))
|
log.warning("Token for user: {} ip: {} doesn't exist".format(userID, ip))
|
||||||
|
|
||||||
def is2FAEnabled(userID):
|
def is2FAEnabled(userID):
|
||||||
"""Returns True if 2FA is enable for this account"""
|
"""
|
||||||
|
Check if 2FA is enabled on an account
|
||||||
|
|
||||||
|
userID --
|
||||||
|
return -- True if 2FA is enabled, False if 2FA is disabled
|
||||||
|
"""
|
||||||
result = glob.db.fetch("SELECT id FROM 2fa_telegram WHERE userid = %s LIMIT 1", [userID])
|
result = glob.db.fetch("SELECT id FROM 2fa_telegram WHERE userid = %s LIMIT 1", [userID])
|
||||||
return True if result is not None else False
|
return True if result is not None else False
|
||||||
|
|
||||||
def check2FA(userID, ip):
|
def check2FA(userID, ip):
|
||||||
"""Returns True if this IP is untrusted"""
|
"""
|
||||||
|
Check if an ip is trusted
|
||||||
|
|
||||||
|
userID --
|
||||||
|
ip -- user's IP address
|
||||||
|
return -- True if the IP is untrusted, False if it's trusted
|
||||||
|
"""
|
||||||
if is2FAEnabled(userID) == False:
|
if is2FAEnabled(userID) == False:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -353,7 +353,7 @@ def isAllowed(userID):
|
||||||
userID -- id of the user
|
userID -- id of the user
|
||||||
return -- True if not banned or restricted, otherwise false.
|
return -- True if not banned or restricted, otherwise false.
|
||||||
"""
|
"""
|
||||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
|
||||||
if result != None:
|
if result != None:
|
||||||
return (result["privileges"] & privileges.USER_NORMAL) and (result["privileges"] & privileges.USER_PUBLIC)
|
return (result["privileges"] & privileges.USER_NORMAL) and (result["privileges"] & privileges.USER_PUBLIC)
|
||||||
else:
|
else:
|
||||||
|
@ -366,7 +366,7 @@ def isRestricted(userID):
|
||||||
userID -- id of the user
|
userID -- id of the user
|
||||||
return -- True if not restricted, otherwise false.
|
return -- True if not restricted, otherwise false.
|
||||||
"""
|
"""
|
||||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
|
||||||
if result != None:
|
if result != None:
|
||||||
return (result["privileges"] & privileges.USER_NORMAL) and not (result["privileges"] & privileges.USER_PUBLIC)
|
return (result["privileges"] & privileges.USER_NORMAL) and not (result["privileges"] & privileges.USER_PUBLIC)
|
||||||
else:
|
else:
|
||||||
|
@ -379,7 +379,7 @@ def isBanned(userID):
|
||||||
userID -- id of the user
|
userID -- id of the user
|
||||||
return -- True if not banned, otherwise false.
|
return -- True if not banned, otherwise false.
|
||||||
"""
|
"""
|
||||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
|
||||||
if result != None:
|
if result != None:
|
||||||
return not (result["privileges"] & 3 > 0)
|
return not (result["privileges"] & 3 > 0)
|
||||||
else:
|
else:
|
||||||
|
@ -392,7 +392,7 @@ def ban(userID):
|
||||||
userID -- id of user
|
userID -- id of user
|
||||||
"""
|
"""
|
||||||
banDateTime = int(time.time())
|
banDateTime = int(time.time())
|
||||||
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s", [ ~(privileges.USER_NORMAL | privileges.USER_PUBLIC | privileges.USER_PENDING_VERIFICATION) , banDateTime, userID])
|
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s LIMIT 1", [ ~(privileges.USER_NORMAL | privileges.USER_PUBLIC | privileges.USER_PENDING_VERIFICATION) , banDateTime, userID])
|
||||||
|
|
||||||
def unban(userID):
|
def unban(userID):
|
||||||
"""
|
"""
|
||||||
|
@ -400,7 +400,7 @@ def unban(userID):
|
||||||
|
|
||||||
userID -- id of user
|
userID -- id of user
|
||||||
"""
|
"""
|
||||||
glob.db.execute("UPDATE users SET privileges = privileges | %s, ban_datetime = 0 WHERE id = %s", [ (privileges.USER_NORMAL | privileges.USER_PUBLIC) , userID])
|
glob.db.execute("UPDATE users SET privileges = privileges | %s, ban_datetime = 0 WHERE id = %s LIMIT 1", [ (privileges.USER_NORMAL | privileges.USER_PUBLIC) , userID])
|
||||||
|
|
||||||
def restrict(userID):
|
def restrict(userID):
|
||||||
"""
|
"""
|
||||||
|
@ -409,7 +409,7 @@ def restrict(userID):
|
||||||
userID -- id of user
|
userID -- id of user
|
||||||
"""
|
"""
|
||||||
banDateTime = int(time.time())
|
banDateTime = int(time.time())
|
||||||
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s", [~privileges.USER_PUBLIC, banDateTime, userID])
|
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s LIMIT 1", [~privileges.USER_PUBLIC, banDateTime, userID])
|
||||||
|
|
||||||
def unrestrict(userID):
|
def unrestrict(userID):
|
||||||
"""
|
"""
|
||||||
|
@ -427,7 +427,7 @@ def getPrivileges(userID):
|
||||||
userID -- id of user
|
userID -- id of user
|
||||||
return -- privileges number
|
return -- privileges number
|
||||||
"""
|
"""
|
||||||
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s LIMIT 1", [userID])
|
||||||
if result != None:
|
if result != None:
|
||||||
return result["privileges"]
|
return result["privileges"]
|
||||||
else:
|
else:
|
||||||
|
@ -440,10 +440,10 @@ def setPrivileges(userID, priv):
|
||||||
userID -- id of user
|
userID -- id of user
|
||||||
priv -- privileges number
|
priv -- privileges number
|
||||||
"""
|
"""
|
||||||
glob.db.execute("UPDATE users SET privileges = %s WHERE id = %s", [priv, userID])
|
glob.db.execute("UPDATE users SET privileges = %s WHERE id = %s LIMIT 1", [priv, userID])
|
||||||
|
|
||||||
def isInPrivilegeGroup(userID, groupName):
|
def isInPrivilegeGroup(userID, groupName):
|
||||||
groupPrivileges = glob.db.fetch("SELECT privileges FROM privileges_groups WHERE name = %s", [groupName])
|
groupPrivileges = glob.db.fetch("SELECT privileges FROM privileges_groups WHERE name = %s LIMIT 1", [groupName])
|
||||||
if groupPrivileges == None:
|
if groupPrivileges == None:
|
||||||
return False
|
return False
|
||||||
groupPrivileges = groupPrivileges["privileges"]
|
groupPrivileges = groupPrivileges["privileges"]
|
||||||
|
@ -465,7 +465,7 @@ def appendNotes(userID, notes, addNl = True):
|
||||||
"""
|
"""
|
||||||
if addNl == True:
|
if addNl == True:
|
||||||
notes = "\n"+notes
|
notes = "\n"+notes
|
||||||
glob.db.execute("UPDATE users SET notes=CONCAT(COALESCE(notes, ''),%s) WHERE id = %s", [notes, userID])
|
glob.db.execute("UPDATE users SET notes=CONCAT(COALESCE(notes, ''),%s) WHERE id = %s LIMIT 1", [notes, userID])
|
||||||
|
|
||||||
|
|
||||||
def logHardware(userID, hashes, activation = False):
|
def logHardware(userID, hashes, activation = False):
|
||||||
|
|
|
@ -19,7 +19,7 @@ from objects import glob
|
||||||
from helpers import chatHelper as chat
|
from helpers import chatHelper as chat
|
||||||
import raven
|
import raven
|
||||||
|
|
||||||
class Client:
|
class Client():
|
||||||
"""
|
"""
|
||||||
IRC Client object
|
IRC Client object
|
||||||
"""
|
"""
|
||||||
|
@ -43,6 +43,7 @@ class Client:
|
||||||
self.socket = sock
|
self.socket = sock
|
||||||
(self.ip, self.port) = sock.getpeername()
|
(self.ip, self.port) = sock.getpeername()
|
||||||
self.username = ""
|
self.username = ""
|
||||||
|
self.banchoUsername = ""
|
||||||
self.supposedUsername = ""
|
self.supposedUsername = ""
|
||||||
self.joinedChannels = []
|
self.joinedChannels = []
|
||||||
|
|
||||||
|
@ -275,12 +276,12 @@ class Client:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Make sure the IRC token was correct:
|
# Make sure the IRC token was correct:
|
||||||
if nick.lower() != self.supposedUsername.lower():
|
if nick.lower() != chat.fixUsernameForIRC(self.supposedUsername.lower()):
|
||||||
self.reply("464 :Password incorrect")
|
self.reply("464 :Password incorrect")
|
||||||
return
|
return
|
||||||
|
|
||||||
# Make sure we are not connected to Bancho
|
# Make sure we are not connected to Bancho
|
||||||
token = glob.tokens.getTokenFromUsername(nick)
|
token = glob.tokens.getTokenFromUsername(chat.fixUsernameForBancho(nick))
|
||||||
if token != None:
|
if token != None:
|
||||||
self.reply("433 * {} :Nickname is already in use".format(nick))
|
self.reply("433 * {} :Nickname is already in use".format(nick))
|
||||||
return
|
return
|
||||||
|
@ -293,6 +294,7 @@ class Client:
|
||||||
|
|
||||||
# Everything seems fine, set username (nickname)
|
# Everything seems fine, set username (nickname)
|
||||||
self.username = nick
|
self.username = nick
|
||||||
|
self.banchoUsername = chat.fixUsernameForBancho(self.username)
|
||||||
elif command == "USER":
|
elif command == "USER":
|
||||||
# Ignore USER command, we use nickname only
|
# Ignore USER command, we use nickname only
|
||||||
return
|
return
|
||||||
|
@ -307,7 +309,7 @@ class Client:
|
||||||
# If we now have a valid username, connect to bancho and send IRC welcome stuff
|
# If we now have a valid username, connect to bancho and send IRC welcome stuff
|
||||||
if self.username != "":
|
if self.username != "":
|
||||||
# Bancho connection
|
# Bancho connection
|
||||||
chat.IRCConnect(self.username)
|
chat.IRCConnect(self.banchoUsername)
|
||||||
|
|
||||||
# IRC reply
|
# IRC reply
|
||||||
self.replyCode(1, "Welcome to the Internet Relay Network")
|
self.replyCode(1, "Welcome to the Internet Relay Network")
|
||||||
|
@ -329,7 +331,7 @@ class Client:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get bancho token object
|
# Get bancho token object
|
||||||
token = glob.tokens.getTokenFromUsername(self.username)
|
token = glob.tokens.getTokenFromUsername(self.banchoUsername)
|
||||||
if token == None:
|
if token == None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -354,7 +356,7 @@ class Client:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Attempt to join the channel
|
# Attempt to join the channel
|
||||||
response = chat.IRCJoinChannel(self.username, channel)
|
response = chat.IRCJoinChannel(self.banchoUsername, channel)
|
||||||
if response == 0:
|
if response == 0:
|
||||||
# Joined successfully
|
# Joined successfully
|
||||||
self.joinedChannels.append(channel)
|
self.joinedChannels.append(channel)
|
||||||
|
@ -376,7 +378,7 @@ class Client:
|
||||||
token = glob.tokens.getTokenFromUserID(user)
|
token = glob.tokens.getTokenFromUserID(user)
|
||||||
if token == None:
|
if token == None:
|
||||||
continue
|
continue
|
||||||
usernames.append(token.username)
|
usernames.append(chat.fixUsernameForIRC(token.username))
|
||||||
usernames = " ".join(usernames)
|
usernames = " ".join(usernames)
|
||||||
|
|
||||||
# Send IRC users lis
|
# Send IRC users lis
|
||||||
|
@ -394,7 +396,7 @@ class Client:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get bancho token object
|
# Get bancho token object
|
||||||
token = glob.tokens.getTokenFromUsername(self.username)
|
token = glob.tokens.getTokenFromUsername(self.banchoUsername)
|
||||||
if token == None:
|
if token == None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -409,7 +411,7 @@ class Client:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Attempt to part the channel
|
# Attempt to part the channel
|
||||||
response = chat.IRCPartChannel(self.username, channel)
|
response = chat.IRCPartChannel(self.banchoUsername, channel)
|
||||||
if response == 0:
|
if response == 0:
|
||||||
# No errors, remove channel from joinedChannels
|
# No errors, remove channel from joinedChannels
|
||||||
self.joinedChannels.remove(channel)
|
self.joinedChannels.remove(channel)
|
||||||
|
@ -433,7 +435,7 @@ class Client:
|
||||||
message = arguments[1]
|
message = arguments[1]
|
||||||
|
|
||||||
# Send the message to bancho and reply
|
# Send the message to bancho and reply
|
||||||
response = chat.sendMessage(self.username, recipient, message, toIRC=False)
|
response = chat.sendMessage(self.banchoUsername, recipient, message, toIRC=False)
|
||||||
if response == 404:
|
if response == 404:
|
||||||
self.replyCode(404, "Cannot send to channel", channel=recipient)
|
self.replyCode(404, "Cannot send to channel", channel=recipient)
|
||||||
return
|
return
|
||||||
|
@ -453,7 +455,6 @@ class Client:
|
||||||
for _, value in self.server.clients.items():
|
for _, value in self.server.clients.items():
|
||||||
if recipient in value.joinedChannels and value != self:
|
if recipient in value.joinedChannels and value != self:
|
||||||
value.message(":{} PRIVMSG {} :{}".format(self.username, recipient, message))
|
value.message(":{} PRIVMSG {} :{}".format(self.username, recipient, message))
|
||||||
#self.messageChannel(recipient, command, "{} :{}".format(recipient, message))
|
|
||||||
else:
|
else:
|
||||||
# Private message (IRC)
|
# Private message (IRC)
|
||||||
for _, value in self.server.clients.items():
|
for _, value in self.server.clients.items():
|
||||||
|
@ -513,7 +514,7 @@ class Client:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class Server:
|
class Server():
|
||||||
def __init__(self, port):
|
def __init__(self, port):
|
||||||
self.host = socket.getfqdn("127.0.0.1")[:63]
|
self.host = socket.getfqdn("127.0.0.1")[:63]
|
||||||
self.port = port
|
self.port = port
|
||||||
|
@ -529,7 +530,7 @@ class Server:
|
||||||
for _, value in self.clients.items():
|
for _, value in self.clients.items():
|
||||||
if value.username == username:
|
if value.username == username:
|
||||||
value.disconnect(callLogout=False)
|
value.disconnect(callLogout=False)
|
||||||
break# or dictionary changes size during iteration
|
break # or dictionary changes size during iteration
|
||||||
|
|
||||||
def banchoJoinChannel(self, username, channel):
|
def banchoJoinChannel(self, username, channel):
|
||||||
"""
|
"""
|
||||||
|
@ -538,6 +539,7 @@ class Server:
|
||||||
username -- username of bancho user
|
username -- username of bancho user
|
||||||
channel -- joined channel name
|
channel -- joined channel name
|
||||||
"""
|
"""
|
||||||
|
username = chat.fixUsernameForIRC(username)
|
||||||
for _, value in self.clients.items():
|
for _, value in self.clients.items():
|
||||||
if channel in value.joinedChannels:
|
if channel in value.joinedChannels:
|
||||||
value.message(":{} JOIN {}".format(username, channel))
|
value.message(":{} JOIN {}".format(username, channel))
|
||||||
|
@ -549,6 +551,7 @@ class Server:
|
||||||
username -- username of bancho user
|
username -- username of bancho user
|
||||||
channel -- joined channel name
|
channel -- joined channel name
|
||||||
"""
|
"""
|
||||||
|
username = chat.fixUsernameForIRC(username)
|
||||||
for _, value in self.clients.items():
|
for _, value in self.clients.items():
|
||||||
if channel in value.joinedChannels:
|
if channel in value.joinedChannels:
|
||||||
value.message(":{} PART {}".format(username, channel))
|
value.message(":{} PART {}".format(username, channel))
|
||||||
|
@ -561,6 +564,8 @@ class Server:
|
||||||
to -- receiver username
|
to -- receiver username
|
||||||
message -- text of the message
|
message -- text of the message
|
||||||
"""
|
"""
|
||||||
|
fro = chat.fixUsernameForIRC(fro)
|
||||||
|
to = chat.fixUsernameForIRC(to)
|
||||||
if to.startswith("#"):
|
if to.startswith("#"):
|
||||||
# Public message
|
# Public message
|
||||||
for _, value in self.clients.items():
|
for _, value in self.clients.items():
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
|
# TODO: Rewrite this shit
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from helpers import generalFunctions
|
from helpers import generalFunctions
|
||||||
|
|
||||||
class banchoConfig:
|
class banchoConfig():
|
||||||
"""
|
"""
|
||||||
Class that loads settings from bancho_settings db table
|
Class that loads settings from bancho_settings db table
|
||||||
"""
|
"""
|
||||||
|
@ -12,31 +13,30 @@ class banchoConfig:
|
||||||
"""
|
"""
|
||||||
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. Optional.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if loadFromDB:
|
if loadFromDB:
|
||||||
try:
|
try:
|
||||||
self.loadSettings()
|
self.loadSettings()
|
||||||
except:
|
except:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
|
||||||
def loadSettings(self):
|
def loadSettings(self):
|
||||||
"""
|
"""
|
||||||
(re)load bancho_settings from DB and set values in config array
|
(re)load bancho_settings from DB and set values in config array
|
||||||
"""
|
"""
|
||||||
|
|
||||||
self.config["banchoMaintenance"] = generalFunctions.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'bancho_maintenance'")["value_int"])
|
self.config["banchoMaintenance"] = generalFunctions.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'bancho_maintenance'")["value_int"])
|
||||||
self.config["freeDirect"] = generalFunctions.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'free_direct'")["value_int"])
|
self.config["freeDirect"] = generalFunctions.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'free_direct'")["value_int"])
|
||||||
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)])
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
|
||||||
class channel:
|
class channel():
|
||||||
"""
|
"""
|
||||||
A chat channel
|
A chat channel
|
||||||
"""
|
"""
|
||||||
|
@ -16,7 +16,6 @@ class channel:
|
||||||
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
|
||||||
|
@ -33,25 +32,21 @@ class channel:
|
||||||
elif self.name.startswith("#multi_"):
|
elif self.name.startswith("#multi_"):
|
||||||
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)
|
||||||
|
|
||||||
|
@ -60,7 +55,6 @@ class channel:
|
||||||
if self.temp == True and ((l == 0) or (l == 1 and 999 in self.connectedUsers)):
|
if self.temp == True and ((l == 0) or (l == 1 and 999 in self.connectedUsers)):
|
||||||
glob.channels.removeChannel(self.name)
|
glob.channels.removeChannel(self.name)
|
||||||
|
|
||||||
|
|
||||||
def getConnectedUsers(self):
|
def getConnectedUsers(self):
|
||||||
"""
|
"""
|
||||||
Get connected user IDs list
|
Get connected user IDs list
|
||||||
|
@ -69,7 +63,6 @@ class channel:
|
||||||
"""
|
"""
|
||||||
return self.connectedUsers
|
return self.connectedUsers
|
||||||
|
|
||||||
|
|
||||||
def getConnectedUsersCount(self):
|
def getConnectedUsersCount(self):
|
||||||
"""
|
"""
|
||||||
Count connected users
|
Count connected users
|
||||||
|
|
|
@ -2,16 +2,14 @@ from objects import glob
|
||||||
from objects import channel
|
from objects import channel
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
|
|
||||||
class channelList:
|
class channelList():
|
||||||
"""
|
"""
|
||||||
Channel list
|
Channel list
|
||||||
|
|
||||||
channels -- dictionary. key: channel name, value: channel object
|
channels -- dictionary. key: channel name, value: channel object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
channels = {}
|
channels = {}
|
||||||
|
|
||||||
|
|
||||||
def loadChannels(self):
|
def loadChannels(self):
|
||||||
"""
|
"""
|
||||||
Load chat channels from db and add them to channels dictionary
|
Load chat channels from db and add them to channels dictionary
|
||||||
|
@ -27,7 +25,6 @@ class channelList:
|
||||||
publicWrite = True if i["public_write"] == 1 else False
|
publicWrite = True if i["public_write"] == 1 else False
|
||||||
self.addChannel(i["name"], i["description"], publicRead, publicWrite)
|
self.addChannel(i["name"], i["description"], publicRead, publicWrite)
|
||||||
|
|
||||||
|
|
||||||
def addChannel(self, name, description, publicRead, publicWrite, temp = False, hidden = False):
|
def addChannel(self, name, description, publicRead, publicWrite, temp = False, hidden = False):
|
||||||
"""
|
"""
|
||||||
Add a channel object to channels dictionary
|
Add a channel object to channels dictionary
|
||||||
|
@ -42,7 +39,6 @@ class channelList:
|
||||||
self.channels[name] = channel.channel(name, description, publicRead, publicWrite, temp, hidden)
|
self.channels[name] = channel.channel(name, description, publicRead, publicWrite, temp, hidden)
|
||||||
log.info("Created channel {}".format(name))
|
log.info("Created channel {}".format(name))
|
||||||
|
|
||||||
|
|
||||||
def addTempChannel(self, name):
|
def addTempChannel(self, name):
|
||||||
"""
|
"""
|
||||||
Add a temporary channel (like #spectator or #multiplayer), gets deleted when there's no one in the channel
|
Add a temporary channel (like #spectator or #multiplayer), gets deleted when there's no one in the channel
|
||||||
|
@ -56,7 +52,6 @@ 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
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
class chatFilters:
|
class chatFilters():
|
||||||
def __init__(self, fileName="filters.txt"):
|
def __init__(self, fileName="filters.txt"):
|
||||||
self.filters = {}
|
self.filters = {}
|
||||||
self.loadFilters(fileName)
|
self.loadFilters(fileName)
|
||||||
|
|
|
@ -17,12 +17,10 @@ def connect():
|
||||||
glob.tokens.enqueueAll(serverPackets.userPanel(999))
|
glob.tokens.enqueueAll(serverPackets.userPanel(999))
|
||||||
glob.tokens.enqueueAll(serverPackets.userStats(999))
|
glob.tokens.enqueueAll(serverPackets.userStats(999))
|
||||||
|
|
||||||
|
|
||||||
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)
|
||||||
|
@ -57,4 +55,4 @@ def fokabotResponse(fro, chan, message):
|
||||||
return i["callback"](fro, chan, message[1:])
|
return i["callback"](fro, chan, message[1:])
|
||||||
|
|
||||||
# No commands triggered
|
# No commands triggered
|
||||||
return False
|
return False
|
158
objects/match.py
158
objects/match.py
|
@ -10,8 +10,20 @@ from constants import dataTypes
|
||||||
from constants import matchTeams
|
from constants import matchTeams
|
||||||
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 helpers import generalFunctions
|
||||||
|
import copy
|
||||||
|
|
||||||
class match:
|
class slot():
|
||||||
|
def __init__(self):
|
||||||
|
self.status = slotStatuses.free
|
||||||
|
self.team = 0
|
||||||
|
self.userID = -1
|
||||||
|
self.mods = 0
|
||||||
|
self.loaded = False
|
||||||
|
self.skip = False
|
||||||
|
self.complete = False
|
||||||
|
|
||||||
|
class match():
|
||||||
"""Multiplayer match object"""
|
"""Multiplayer match object"""
|
||||||
matchID = 0
|
matchID = 0
|
||||||
inProgress = False
|
inProgress = False
|
||||||
|
@ -21,7 +33,7 @@ class match:
|
||||||
beatmapName = ""
|
beatmapName = ""
|
||||||
beatmapID = 0
|
beatmapID = 0
|
||||||
beatmapMD5 = ""
|
beatmapMD5 = ""
|
||||||
slots = [] # list of dictionaries {"status": 0, "team": 0, "userID": -1, "mods": 0, "loaded": False, "skip": False, "complete": False}
|
slots = []
|
||||||
hostUserID = 0
|
hostUserID = 0
|
||||||
gameMode = gameModes.std
|
gameMode = gameModes.std
|
||||||
matchScoringType = matchScoringTypes.score
|
matchScoringType = matchScoringTypes.score
|
||||||
|
@ -46,7 +58,10 @@ class match:
|
||||||
self.inProgress = False
|
self.inProgress = False
|
||||||
self.mods = 0
|
self.mods = 0
|
||||||
self.matchName = matchName
|
self.matchName = matchName
|
||||||
self.matchPassword = matchPassword
|
if matchPassword != "":
|
||||||
|
self.matchPassword = generalFunctions.stringMd5(matchPassword)
|
||||||
|
else:
|
||||||
|
self.matchPassword = ""
|
||||||
self.beatmapID = beatmapID
|
self.beatmapID = beatmapID
|
||||||
self.beatmapName = beatmapName
|
self.beatmapName = beatmapName
|
||||||
self.beatmapMD5 = beatmapMD5
|
self.beatmapMD5 = beatmapMD5
|
||||||
|
@ -60,12 +75,11 @@ class match:
|
||||||
# Create all slots and reset them
|
# Create all slots and reset them
|
||||||
self.slots = []
|
self.slots = []
|
||||||
for _ in range(0,16):
|
for _ in range(0,16):
|
||||||
self.slots.append({"status": slotStatuses.free, "team": 0, "userID": -1, "mods": 0, "loaded": False, "skip": False, "complete": False})
|
self.slots.append(slot())
|
||||||
|
|
||||||
# Create #multiplayer channel
|
# Create #multiplayer channel
|
||||||
glob.channels.addTempChannel("#multi_{}".format(self.matchID))
|
glob.channels.addTempChannel("#multi_{}".format(self.matchID))
|
||||||
|
|
||||||
|
|
||||||
def getMatchData(self):
|
def getMatchData(self):
|
||||||
"""
|
"""
|
||||||
Return binary match data structure for packetHelper
|
Return binary match data structure for packetHelper
|
||||||
|
@ -85,15 +99,15 @@ class match:
|
||||||
|
|
||||||
# Slots status IDs, always 16 elements
|
# Slots status IDs, always 16 elements
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
struct.append([self.slots[i]["status"], dataTypes.byte])
|
struct.append([self.slots[i].status, dataTypes.byte])
|
||||||
|
|
||||||
# Slot teams, always 16 elements
|
# Slot teams, always 16 elements
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
struct.append([self.slots[i]["team"], dataTypes.byte])
|
struct.append([self.slots[i].team, dataTypes.byte])
|
||||||
|
|
||||||
# Slot user ID. Write only if slot is occupied
|
# Slot user ID. Write only if slot is occupied
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
uid = self.slots[i]["userID"]
|
uid = self.slots[i].userID
|
||||||
if uid > -1:
|
if uid > -1:
|
||||||
struct.append([uid, dataTypes.uInt32])
|
struct.append([uid, dataTypes.uInt32])
|
||||||
|
|
||||||
|
@ -109,15 +123,13 @@ class match:
|
||||||
# Slot mods if free mod is enabled
|
# Slot mods if free mod is enabled
|
||||||
if self.matchModMode == matchModModes.freeMod:
|
if self.matchModMode == matchModModes.freeMod:
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
struct.append([self.slots[i]["mods"], dataTypes.uInt32])
|
struct.append([self.slots[i].mods, dataTypes.uInt32])
|
||||||
|
|
||||||
# Seed idk
|
# Seed idk
|
||||||
struct.append([self.seed, dataTypes.uInt32])
|
struct.append([self.seed, dataTypes.uInt32])
|
||||||
|
|
||||||
return struct
|
return struct
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def setHost(self, newHost):
|
def setHost(self, newHost):
|
||||||
"""
|
"""
|
||||||
Set room host to newHost and send him host packet
|
Set room host to newHost and send him host packet
|
||||||
|
@ -149,26 +161,25 @@ class match:
|
||||||
If Null is passed, that value won't be edited
|
If Null is passed, that value won't be edited
|
||||||
"""
|
"""
|
||||||
if slotStatus != None:
|
if slotStatus != None:
|
||||||
self.slots[slotID]["status"] = slotStatus
|
self.slots[slotID].status = slotStatus
|
||||||
|
|
||||||
if slotTeam != None:
|
if slotTeam != None:
|
||||||
self.slots[slotID]["team"] = slotTeam
|
self.slots[slotID].team = slotTeam
|
||||||
|
|
||||||
if slotUserID != None:
|
if slotUserID != None:
|
||||||
self.slots[slotID]["userID"] = slotUserID
|
self.slots[slotID].userID = slotUserID
|
||||||
|
|
||||||
if slotMods != None:
|
if slotMods != None:
|
||||||
self.slots[slotID]["mods"] = slotMods
|
self.slots[slotID].mods = slotMods
|
||||||
|
|
||||||
if slotLoaded != None:
|
if slotLoaded != None:
|
||||||
self.slots[slotID]["loaded"] = slotLoaded
|
self.slots[slotID].loaded = slotLoaded
|
||||||
|
|
||||||
if slotSkip != None:
|
if slotSkip != None:
|
||||||
self.slots[slotID]["skip"] = slotSkip
|
self.slots[slotID].skip = slotSkip
|
||||||
|
|
||||||
if slotComplete != None:
|
if slotComplete != None:
|
||||||
self.slots[slotID]["complete"] = slotComplete
|
self.slots[slotID].complete = slotComplete
|
||||||
|
|
||||||
|
|
||||||
def setSlotMods(self, slotID, mods):
|
def setSlotMods(self, slotID, mods):
|
||||||
"""
|
"""
|
||||||
|
@ -182,7 +193,6 @@ class match:
|
||||||
self.sendUpdate()
|
self.sendUpdate()
|
||||||
log.info("MPROOM{}: Slot{} mods changed to {}".format(self.matchID, slotID, mods))
|
log.info("MPROOM{}: Slot{} mods changed to {}".format(self.matchID, slotID, mods))
|
||||||
|
|
||||||
|
|
||||||
def toggleSlotReady(self, slotID):
|
def toggleSlotReady(self, slotID):
|
||||||
"""
|
"""
|
||||||
Switch slotID ready/not ready status
|
Switch slotID ready/not ready status
|
||||||
|
@ -191,14 +201,14 @@ class match:
|
||||||
slotID -- slot number
|
slotID -- slot number
|
||||||
"""
|
"""
|
||||||
# Update ready status and setnd update
|
# Update ready status and setnd update
|
||||||
oldStatus = self.slots[slotID]["status"]
|
oldStatus = self.slots[slotID].status
|
||||||
if oldStatus == slotStatuses.ready:
|
if oldStatus == slotStatuses.ready:
|
||||||
newStatus = slotStatuses.notReady
|
newStatus = slotStatuses.notReady
|
||||||
else:
|
else:
|
||||||
newStatus = slotStatuses.ready
|
newStatus = slotStatuses.ready
|
||||||
self.setSlot(slotID, newStatus, None, None, None)
|
self.setSlot(slotID, newStatus, None, None, None)
|
||||||
self.sendUpdate()
|
self.sendUpdate()
|
||||||
log.info("MPROOM{}: Slot{} changed ready status to {}".format(self.matchID, slotID, self.slots[slotID]["status"]))
|
log.info("MPROOM{}: Slot{} changed ready status to {}".format(self.matchID, slotID, self.slots[slotID].status))
|
||||||
|
|
||||||
def toggleSlotLock(self, slotID):
|
def toggleSlotLock(self, slotID):
|
||||||
"""
|
"""
|
||||||
|
@ -208,13 +218,13 @@ class match:
|
||||||
slotID -- slot number
|
slotID -- slot number
|
||||||
"""
|
"""
|
||||||
# Get token of user in that slot (if there's someone)
|
# Get token of user in that slot (if there's someone)
|
||||||
if self.slots[slotID]["userID"] > -1:
|
if self.slots[slotID].userID > -1:
|
||||||
token = glob.tokens.getTokenFromUserID(self.slots[slotID]["userID"])
|
token = glob.tokens.getTokenFromUserID(self.slots[slotID].userID)
|
||||||
else:
|
else:
|
||||||
token = None
|
token = None
|
||||||
|
|
||||||
# Check if slot is already locked
|
# Check if slot is already locked
|
||||||
if self.slots[slotID]["status"] == slotStatuses.locked:
|
if self.slots[slotID].status == slotStatuses.locked:
|
||||||
newStatus = slotStatuses.free
|
newStatus = slotStatuses.free
|
||||||
else:
|
else:
|
||||||
newStatus = slotStatuses.locked
|
newStatus = slotStatuses.locked
|
||||||
|
@ -240,33 +250,31 @@ class match:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Set loaded to True
|
# Set loaded to True
|
||||||
self.slots[slotID]["loaded"] = True
|
self.slots[slotID].loaded = True
|
||||||
log.info("MPROOM{}: User {} loaded".format(self.matchID, userID))
|
log.info("MPROOM{}: User {} loaded".format(self.matchID, userID))
|
||||||
|
|
||||||
# Check all loaded
|
# Check all loaded
|
||||||
total = 0
|
total = 0
|
||||||
loaded = 0
|
loaded = 0
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["status"] == slotStatuses.playing:
|
if self.slots[i].status == slotStatuses.playing:
|
||||||
total+=1
|
total+=1
|
||||||
if self.slots[i]["loaded"] == True:
|
if self.slots[i].loaded == True:
|
||||||
loaded+=1
|
loaded+=1
|
||||||
|
|
||||||
if total == loaded:
|
if total == loaded:
|
||||||
self.allPlayersLoaded()
|
self.allPlayersLoaded()
|
||||||
|
|
||||||
|
|
||||||
def allPlayersLoaded(self):
|
def allPlayersLoaded(self):
|
||||||
"""Send allPlayersLoaded packet to every playing usr in match"""
|
"""Send allPlayersLoaded packet to every playing usr in match"""
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["userID"] > -1 and self.slots[i]["status"] == slotStatuses.playing:
|
if self.slots[i].userID > -1 and self.slots[i].status == slotStatuses.playing:
|
||||||
token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"])
|
token = glob.tokens.getTokenFromUserID(self.slots[i].userID)
|
||||||
if token != None:
|
if token != None:
|
||||||
token.enqueue(serverPackets.allPlayersLoaded())
|
token.enqueue(serverPackets.allPlayersLoaded())
|
||||||
|
|
||||||
log.info("MPROOM{}: All players loaded! Match starting...".format(self.matchID))
|
log.info("MPROOM{}: All players loaded! Match starting...".format(self.matchID))
|
||||||
|
|
||||||
|
|
||||||
def playerSkip(self, userID):
|
def playerSkip(self, userID):
|
||||||
"""
|
"""
|
||||||
Set a player skip status to True
|
Set a player skip status to True
|
||||||
|
@ -278,13 +286,13 @@ class match:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Set skip to True
|
# Set skip to True
|
||||||
self.slots[slotID]["skip"] = True
|
self.slots[slotID].skip = True
|
||||||
log.info("MPROOM{}: User {} skipped".format(self.matchID, userID))
|
log.info("MPROOM{}: User {} skipped".format(self.matchID, userID))
|
||||||
|
|
||||||
# Send skip packet to every playing useR
|
# Send skip packet to every playing user
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
uid = self.slots[i]["userID"]
|
uid = self.slots[i].userID
|
||||||
if self.slots[i]["status"] == slotStatuses.playing and uid > -1:
|
if (self.slots[i].status & slotStatuses.playing > 0) and uid > -1:
|
||||||
token = glob.tokens.getTokenFromUserID(uid)
|
token = glob.tokens.getTokenFromUserID(uid)
|
||||||
if token != None:
|
if token != None:
|
||||||
token.enqueue(serverPackets.playerSkipped(uid))
|
token.enqueue(serverPackets.playerSkipped(uid))
|
||||||
|
@ -293,9 +301,9 @@ class match:
|
||||||
total = 0
|
total = 0
|
||||||
skipped = 0
|
skipped = 0
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["status"] == slotStatuses.playing:
|
if self.slots[i].status == slotStatuses.playing:
|
||||||
total+=1
|
total+=1
|
||||||
if self.slots[i]["skip"] == True:
|
if self.slots[i].skip == True:
|
||||||
skipped+=1
|
skipped+=1
|
||||||
|
|
||||||
if total == skipped:
|
if total == skipped:
|
||||||
|
@ -304,8 +312,8 @@ class match:
|
||||||
def allPlayersSkipped(self):
|
def allPlayersSkipped(self):
|
||||||
"""Send allPlayersSkipped packet to every playing usr in match"""
|
"""Send allPlayersSkipped packet to every playing usr in match"""
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["userID"] > -1 and self.slots[i]["status"] == slotStatuses.playing:
|
if self.slots[i].userID > -1 and self.slots[i].status == slotStatuses.playing:
|
||||||
token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"])
|
token = glob.tokens.getTokenFromUserID(self.slots[i].userID)
|
||||||
if token != None:
|
if token != None:
|
||||||
token.enqueue(serverPackets.allPlayersSkipped())
|
token.enqueue(serverPackets.allPlayersSkipped())
|
||||||
|
|
||||||
|
@ -329,9 +337,9 @@ class match:
|
||||||
total = 0
|
total = 0
|
||||||
completed = 0
|
completed = 0
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["status"] == slotStatuses.playing:
|
if self.slots[i].status == slotStatuses.playing:
|
||||||
total+=1
|
total+=1
|
||||||
if self.slots[i]["complete"] == True:
|
if self.slots[i].complete == True:
|
||||||
completed+=1
|
completed+=1
|
||||||
|
|
||||||
if total == completed:
|
if total == completed:
|
||||||
|
@ -345,38 +353,34 @@ class match:
|
||||||
|
|
||||||
# Reset slots
|
# Reset slots
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["userID"] > -1 and self.slots[i]["status"] == slotStatuses.playing:
|
if self.slots[i].userID > -1 and self.slots[i].status == slotStatuses.playing:
|
||||||
self.slots[i]["status"] = slotStatuses.notReady
|
self.slots[i].status = slotStatuses.notReady
|
||||||
self.slots[i]["loaded"] = False
|
self.slots[i].loaded = False
|
||||||
self.slots[i]["skip"] = False
|
self.slots[i].skip = False
|
||||||
self.slots[i]["complete"] = False
|
self.slots[i].complete = False
|
||||||
|
|
||||||
# Send match update
|
# Send match update
|
||||||
self.sendUpdate()
|
self.sendUpdate()
|
||||||
|
|
||||||
# Send match complete
|
# Send match complete
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["userID"] > -1:
|
if self.slots[i].userID > -1:
|
||||||
token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"])
|
token = glob.tokens.getTokenFromUserID(self.slots[i].userID)
|
||||||
if token != None:
|
if token != None:
|
||||||
token.enqueue(serverPackets.matchComplete())
|
token.enqueue(serverPackets.matchComplete())
|
||||||
|
|
||||||
# Console output
|
# Console output
|
||||||
log.info("MPROOM{}: Match completed".format(self.matchID))
|
log.info("MPROOM{}: Match completed".format(self.matchID))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getUserSlotID(self, userID):
|
def getUserSlotID(self, userID):
|
||||||
"""
|
"""
|
||||||
Get slot ID occupied by userID
|
Get slot ID occupied by userID
|
||||||
|
|
||||||
return -- slot id if found, None if user is not in room
|
return -- slot id if found, None if user is not in room
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["userID"] == userID:
|
if self.slots[i].userID == userID:
|
||||||
return i
|
return i
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def userJoin(self, userID):
|
def userJoin(self, userID):
|
||||||
|
@ -389,7 +393,7 @@ class match:
|
||||||
|
|
||||||
# Find first free slot
|
# Find first free slot
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["status"] == slotStatuses.free:
|
if self.slots[i].status == slotStatuses.free:
|
||||||
# Occupy slot
|
# Occupy slot
|
||||||
self.setSlot(i, slotStatuses.notReady, 0, userID, 0)
|
self.setSlot(i, slotStatuses.notReady, 0, userID, 0)
|
||||||
|
|
||||||
|
@ -409,7 +413,6 @@ class match:
|
||||||
|
|
||||||
userID -- user if of the user
|
userID -- user if of the user
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Make sure the user is in room
|
# Make sure the user is in room
|
||||||
slotID = self.getUserSlotID(userID)
|
slotID = self.getUserSlotID(userID)
|
||||||
if slotID == None:
|
if slotID == None:
|
||||||
|
@ -429,7 +432,7 @@ class match:
|
||||||
if userID == self.hostUserID:
|
if userID == self.hostUserID:
|
||||||
# Give host to someone else
|
# Give host to someone else
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
uid = self.slots[i]["userID"]
|
uid = self.slots[i].userID
|
||||||
if uid > -1:
|
if uid > -1:
|
||||||
self.setHost(uid)
|
self.setHost(uid)
|
||||||
break
|
break
|
||||||
|
@ -440,7 +443,6 @@ class match:
|
||||||
# Console output
|
# Console output
|
||||||
log.info("MPROOM{}: {} left the room".format(self.matchID, userID))
|
log.info("MPROOM{}: {} left the room".format(self.matchID, userID))
|
||||||
|
|
||||||
|
|
||||||
def userChangeSlot(self, userID, newSlotID):
|
def userChangeSlot(self, userID, newSlotID):
|
||||||
"""
|
"""
|
||||||
Change userID slot to newSlotID
|
Change userID slot to newSlotID
|
||||||
|
@ -448,24 +450,23 @@ class match:
|
||||||
userID -- user that changed slot
|
userID -- user that changed slot
|
||||||
newSlotID -- slot id of new slot
|
newSlotID -- slot id of new slot
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Make sure the user is in room
|
# Make sure the user is in room
|
||||||
oldSlotID = self.getUserSlotID(userID)
|
oldSlotID = self.getUserSlotID(userID)
|
||||||
if oldSlotID == None:
|
if oldSlotID == None:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Make sure there is no one inside new slot
|
# Make sure there is no one inside new slot
|
||||||
if self.slots[newSlotID]["userID"] > -1:
|
if self.slots[newSlotID].userID > -1 and self.slots[newSlotID].status != slotStatuses.free:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Get old slot data
|
# Get old slot data
|
||||||
oldData = self.slots[oldSlotID].copy()
|
oldData = copy.deepcopy(self.slots[oldSlotID])
|
||||||
|
|
||||||
# Free old slot
|
# Free old slot
|
||||||
self.setSlot(oldSlotID, slotStatuses.free, 0, -1, 0)
|
self.setSlot(oldSlotID, slotStatuses.free, 0, -1, 0)
|
||||||
|
|
||||||
# Occupy new slot
|
# Occupy new slot
|
||||||
self.setSlot(newSlotID, oldData["status"], oldData["team"], userID, oldData["mods"])
|
self.setSlot(newSlotID, oldData.status, oldData.team, oldData.userID, oldData.mods)
|
||||||
|
|
||||||
# Send updated match data
|
# Send updated match data
|
||||||
self.sendUpdate()
|
self.sendUpdate()
|
||||||
|
@ -479,12 +480,15 @@ class match:
|
||||||
|
|
||||||
newPassword -- new password string
|
newPassword -- new password string
|
||||||
"""
|
"""
|
||||||
self.matchPassword = newPassword
|
if newPassword != "":
|
||||||
|
self.matchPassword = generalFunctions.stringMd5(newPassword)
|
||||||
|
else:
|
||||||
|
self.matchPassword = ""
|
||||||
|
|
||||||
# Send password change to every user in match
|
# Send password change to every user in match
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["userID"] > -1:
|
if self.slots[i].userID > -1:
|
||||||
token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"])
|
token = glob.tokens.getTokenFromUserID(self.slots[i].userID)
|
||||||
if token != None:
|
if token != None:
|
||||||
token.enqueue(serverPackets.changeMatchPassword(self.matchPassword))
|
token.enqueue(serverPackets.changeMatchPassword(self.matchPassword))
|
||||||
|
|
||||||
|
@ -494,7 +498,6 @@ class match:
|
||||||
# Console output
|
# Console output
|
||||||
log.info("MPROOM{}: Password changed to {}".format(self.matchID, self.matchPassword))
|
log.info("MPROOM{}: Password changed to {}".format(self.matchID, self.matchPassword))
|
||||||
|
|
||||||
|
|
||||||
def changeMatchMods(self, mods):
|
def changeMatchMods(self, mods):
|
||||||
"""
|
"""
|
||||||
Set match global mods
|
Set match global mods
|
||||||
|
@ -531,7 +534,7 @@ class match:
|
||||||
slotID -- ID of slot
|
slotID -- ID of slot
|
||||||
"""
|
"""
|
||||||
# Make sure there is someone in that slot
|
# Make sure there is someone in that slot
|
||||||
uid = self.slots[slotID]["userID"]
|
uid = self.slots[slotID].userID
|
||||||
if uid == -1:
|
if uid == -1:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -541,7 +544,6 @@ class match:
|
||||||
# Send updates
|
# Send updates
|
||||||
self.sendUpdate()
|
self.sendUpdate()
|
||||||
|
|
||||||
|
|
||||||
def playerFailed(self, userID):
|
def playerFailed(self, userID):
|
||||||
"""
|
"""
|
||||||
Send userID's failed packet to everyone in match
|
Send userID's failed packet to everyone in match
|
||||||
|
@ -555,7 +557,7 @@ class match:
|
||||||
|
|
||||||
# Send packet to everyone
|
# Send packet to everyone
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
uid = self.slots[i]["userID"]
|
uid = self.slots[i].userID
|
||||||
if uid > -1:
|
if uid > -1:
|
||||||
token = glob.tokens.getTokenFromUserID(uid)
|
token = glob.tokens.getTokenFromUserID(uid)
|
||||||
if token != None:
|
if token != None:
|
||||||
|
@ -564,7 +566,6 @@ class match:
|
||||||
# Console output
|
# Console output
|
||||||
log.info("MPROOM{}: {} has failed!".format(self.matchID, userID))
|
log.info("MPROOM{}: {} has failed!".format(self.matchID, userID))
|
||||||
|
|
||||||
|
|
||||||
def invite(self, fro, to):
|
def invite(self, fro, to):
|
||||||
"""
|
"""
|
||||||
Fro invites to in this match.
|
Fro invites to in this match.
|
||||||
|
@ -587,19 +588,16 @@ class match:
|
||||||
message = "Come join my multiplayer match: \"[osump://{}/{} {}]\"".format(self.matchID, self.matchPassword.replace(" ", "_"), self.matchName)
|
message = "Come join my multiplayer match: \"[osump://{}/{} {}]\"".format(self.matchID, self.matchPassword.replace(" ", "_"), self.matchName)
|
||||||
chat.sendMessage(token=froToken, to=toToken.username, message=message)
|
chat.sendMessage(token=froToken, to=toToken.username, message=message)
|
||||||
|
|
||||||
|
|
||||||
def countUsers(self):
|
def countUsers(self):
|
||||||
"""
|
"""
|
||||||
Return how many players are in that match
|
Return how many players are in that match
|
||||||
|
|
||||||
return -- number of users
|
return -- number of users
|
||||||
"""
|
"""
|
||||||
|
|
||||||
c = 0
|
c = 0
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["userID"] > -1:
|
if self.slots[i].userID > -1:
|
||||||
c+=1
|
c+=1
|
||||||
|
|
||||||
return c
|
return c
|
||||||
|
|
||||||
def changeTeam(self, userID):
|
def changeTeam(self, userID):
|
||||||
|
@ -614,15 +612,15 @@ class match:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Update slot and send update
|
# Update slot and send update
|
||||||
newTeam = matchTeams.blue if self.slots[slotID]["team"] == matchTeams.red else matchTeams.red
|
newTeam = matchTeams.blue if self.slots[slotID].team == matchTeams.red else matchTeams.red
|
||||||
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):
|
||||||
if self.slots[i]["userID"] > -1:
|
if self.slots[i].userID > -1:
|
||||||
token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"])
|
token = glob.tokens.getTokenFromUserID(self.slots[i].userID)
|
||||||
if token != None:
|
if token != None:
|
||||||
token.enqueue(serverPackets.updateMatch(self.matchID))
|
token.enqueue(serverPackets.updateMatch(self.matchID))
|
||||||
|
|
||||||
|
@ -645,10 +643,10 @@ class match:
|
||||||
# We have teams, check if they are valid
|
# We have teams, check if they are valid
|
||||||
firstTeam = -1
|
firstTeam = -1
|
||||||
for i in range(0,16):
|
for i in range(0,16):
|
||||||
if self.slots[i]["userID"] > -1 and (self.slots[i]["status"]&slotStatuses.noMap) == 0:
|
if self.slots[i].userID > -1 and (self.slots[i].status&slotStatuses.noMap) == 0:
|
||||||
if firstTeam == -1:
|
if firstTeam == -1:
|
||||||
firstTeam = self.slots[i]["team"]
|
firstTeam = self.slots[i].team
|
||||||
elif firstTeam != self.slots[i]["teams"]:
|
elif firstTeam != self.slots[i].team:
|
||||||
log.info("MPROOM{}: Teams are valid".format(self.matchID))
|
log.info("MPROOM{}: Teams are valid".format(self.matchID))
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ from objects import match
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
|
|
||||||
class matchList:
|
class matchList():
|
||||||
matches = {}
|
matches = {}
|
||||||
usersInLobby = []
|
usersInLobby = []
|
||||||
lastID = 1
|
lastID = 1
|
||||||
|
@ -32,49 +32,43 @@ class matchList:
|
||||||
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):
|
|
||||||
"""
|
"""
|
||||||
Destroy match object with id = __matchID
|
Destroy match object with id = matchID
|
||||||
|
|
||||||
__matchID -- ID of match to dispose
|
matchID -- ID of match to dispose
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Make sure the match exists
|
# Make sure the match exists
|
||||||
if __matchID not in self.matches:
|
if matchID not in self.matches:
|
||||||
return
|
return
|
||||||
|
|
||||||
# Remove match object
|
# Remove match object
|
||||||
self.matches.pop(__matchID)
|
self.matches.pop(matchID)
|
||||||
|
|
||||||
# Send match dispose packet to everyone in lobby
|
# Send match dispose packet to everyone in lobby
|
||||||
for i in self.usersInLobby:
|
for i in self.usersInLobby:
|
||||||
token = glob.tokens.getTokenFromUserID(i)
|
token = glob.tokens.getTokenFromUserID(i)
|
||||||
if token != None:
|
if token != None:
|
||||||
token.enqueue(serverPackets.disposeMatch(__matchID))
|
token.enqueue(serverPackets.disposeMatch(matchID))
|
||||||
|
|
|
@ -8,33 +8,9 @@ from objects import glob
|
||||||
import uuid
|
import uuid
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
from helpers import logHelper as log
|
|
||||||
from helpers import chatHelper as chat
|
from helpers import chatHelper as chat
|
||||||
|
|
||||||
class token:
|
class token():
|
||||||
"""
|
|
||||||
Osu Token object
|
|
||||||
|
|
||||||
token -- token string
|
|
||||||
userID -- userID associated to that token
|
|
||||||
username -- username relative to userID (cache)
|
|
||||||
actionID -- current user action (see actions.py)
|
|
||||||
actionText -- current user action text
|
|
||||||
actionMd5 -- md5 relative to user action
|
|
||||||
actionMods -- current acton mods
|
|
||||||
gameMode -- current user game mode
|
|
||||||
location -- [latitude,longitude]
|
|
||||||
queue -- packets queue
|
|
||||||
joinedChannels -- list. Contains joined channel names
|
|
||||||
spectating -- userID of spectating user. 0 if not spectating.
|
|
||||||
spectators -- list. Contains userIDs of spectators
|
|
||||||
country -- osu country code. Use countryHelper to convert from letter country code to osu country code
|
|
||||||
pingTime -- latest packet received UNIX time
|
|
||||||
loginTime -- login UNIX time
|
|
||||||
latestTillerino -- beatmap ID of latest song from tillerino bot
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
@ -44,8 +20,8 @@ class token:
|
||||||
if not passed, token will be generated
|
if not passed, token will be generated
|
||||||
ip -- client ip. optional.
|
ip -- client ip. optional.
|
||||||
irc -- if True, set this token as IRC client. optional.
|
irc -- if True, set this token as IRC client. optional.
|
||||||
|
timeOffset -- the time offset from UTC for this user. optional.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Set stuff
|
# Set stuff
|
||||||
self.userID = userID
|
self.userID = userID
|
||||||
self.username = userHelper.getUsername(self.userID)
|
self.username = userHelper.getUsername(self.userID)
|
||||||
|
@ -71,7 +47,6 @@ class token:
|
||||||
self.tillerino = [0,0,-1.0] # beatmap, mods, acc
|
self.tillerino = [0,0,-1.0] # beatmap, mods, acc
|
||||||
self.silenceEndTime = 0
|
self.silenceEndTime = 0
|
||||||
self.queue = bytes()
|
self.queue = bytes()
|
||||||
self.osuDirectAlert = False # NOTE: Remove this when osu!direct will be fixed
|
|
||||||
|
|
||||||
# Spam protection
|
# Spam protection
|
||||||
self.spamRate = 0
|
self.spamRate = 0
|
||||||
|
@ -102,14 +77,14 @@ class token:
|
||||||
if ip != "":
|
if ip != "":
|
||||||
userHelper.saveBanchoSession(self.userID, self.ip)
|
userHelper.saveBanchoSession(self.userID, self.ip)
|
||||||
|
|
||||||
def enqueue(self, __bytes):
|
def enqueue(self, bytes):
|
||||||
"""
|
"""
|
||||||
Add bytes (packets) to queue
|
Add bytes (packets) to queue
|
||||||
|
|
||||||
__bytes -- (packet) bytes to enqueue
|
bytes -- (packet) bytes to enqueue
|
||||||
"""
|
"""
|
||||||
if self.irc == False:
|
if self.irc == False:
|
||||||
self.queue += __bytes
|
self.queue += bytes
|
||||||
|
|
||||||
|
|
||||||
def resetQueue(self):
|
def resetQueue(self):
|
||||||
|
@ -117,95 +92,140 @@ class token:
|
||||||
self.queue = bytes()
|
self.queue = bytes()
|
||||||
|
|
||||||
|
|
||||||
def joinChannel(self, __channel):
|
def joinChannel(self, channel):
|
||||||
"""Add __channel to joined channels list
|
"""
|
||||||
|
Add channel to joined channels list
|
||||||
|
|
||||||
__channel -- channel name"""
|
channel -- channel name
|
||||||
|
"""
|
||||||
|
if channel not in self.joinedChannels:
|
||||||
|
self.joinedChannels.append(channel)
|
||||||
|
|
||||||
if __channel not in self.joinedChannels:
|
def partChannel(self, channel):
|
||||||
self.joinedChannels.append(__channel)
|
"""
|
||||||
|
Remove channel from joined channels list
|
||||||
|
|
||||||
|
channel -- channel name
|
||||||
|
"""
|
||||||
|
if channel in self.joinedChannels:
|
||||||
|
self.joinedChannels.remove(channel)
|
||||||
|
|
||||||
def partChannel(self, __channel):
|
def setLocation(self, location):
|
||||||
"""Remove __channel from joined channels list
|
"""
|
||||||
|
Set location (latitude and longitude)
|
||||||
__channel -- channel name"""
|
|
||||||
|
|
||||||
if __channel in self.joinedChannels:
|
|
||||||
self.joinedChannels.remove(__channel)
|
|
||||||
|
|
||||||
|
|
||||||
def setLocation(self, __location):
|
|
||||||
"""Set location (latitude and longitude)
|
|
||||||
|
|
||||||
__location -- [latitude, longitude]"""
|
|
||||||
|
|
||||||
self.location = __location
|
|
||||||
|
|
||||||
|
location -- [latitude, longitude]
|
||||||
|
"""
|
||||||
|
self.location = location
|
||||||
|
|
||||||
def getLatitude(self):
|
def getLatitude(self):
|
||||||
"""Get latitude
|
"""
|
||||||
|
Get latitude
|
||||||
return -- latitude"""
|
|
||||||
|
|
||||||
|
return -- latitude
|
||||||
|
"""
|
||||||
return self.location[0]
|
return self.location[0]
|
||||||
|
|
||||||
|
|
||||||
def getLongitude(self):
|
def getLongitude(self):
|
||||||
"""Get longitude
|
"""
|
||||||
|
Get longitude
|
||||||
|
|
||||||
return -- longitude"""
|
return -- longitude
|
||||||
|
"""
|
||||||
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):
|
||||||
"""Set the spectating user to 0, aka no user"""
|
# Remove our userID from host's spectators
|
||||||
|
target = self.spectating
|
||||||
|
targetToken = glob.tokens.getTokenFromUserID(target)
|
||||||
|
if targetToken != None:
|
||||||
|
# Remove us from host's spectators list
|
||||||
|
targetToken.removeSpectator(self.userID)
|
||||||
|
|
||||||
|
# Send the spectator left packet to host
|
||||||
|
targetToken.enqueue(serverPackets.removeSpectator(self.userID))
|
||||||
|
for c in targetToken.spectators:
|
||||||
|
spec = glob.tokens.getTokenFromUserID(c)
|
||||||
|
spec.enqueue(serverPackets.fellowSpectatorLeft(self.userID))
|
||||||
|
|
||||||
|
# If nobody is spectating the host anymore, close #spectator channel
|
||||||
|
if len(targetToken.spectators) == 0:
|
||||||
|
chat.partChannel(token=targetToken, channel="#spect_{}".format(target), kick=True)
|
||||||
|
|
||||||
|
# Part #spectator channel
|
||||||
|
chat.partChannel(token=self, channel="#spect_{}".format(target), kick=True)
|
||||||
|
|
||||||
|
# Set our spectating user to 0
|
||||||
self.spectating = 0
|
self.spectating = 0
|
||||||
|
|
||||||
|
# Console output
|
||||||
|
log.info("{} are no longer spectating {}".format(self.username, target))
|
||||||
|
|
||||||
|
def partMatch(self):
|
||||||
|
# Make sure we are in a match
|
||||||
|
if self.matchID == -1:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Part #multiplayer channel
|
||||||
|
chat.partChannel(token=self, channel="#multi_{}".format(self.matchID), kick=True)
|
||||||
|
|
||||||
|
# Make sure the match exists
|
||||||
|
if self.matchID not in glob.matches.matches:
|
||||||
|
return
|
||||||
|
|
||||||
|
# The match exists, get object
|
||||||
|
match = glob.matches.matches[self.matchID]
|
||||||
|
|
||||||
|
# Set slot to free
|
||||||
|
match.userLeft(self.userID)
|
||||||
|
|
||||||
|
# Set usertoken match to -1
|
||||||
|
self.matchID = -1
|
||||||
|
|
||||||
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):
|
||||||
|
"""
|
||||||
|
Set country to countryID
|
||||||
|
|
||||||
def setCountry(self, __countryID):
|
countryID -- numeric country ID. See countryHelper.py
|
||||||
"""Set country to __countryID
|
"""
|
||||||
|
self.country = countryID
|
||||||
__countryID -- numeric country ID. See countryHelper.py"""
|
|
||||||
|
|
||||||
self.country = __countryID
|
|
||||||
|
|
||||||
|
|
||||||
def getCountry(self):
|
def getCountry(self):
|
||||||
"""Get numeric country ID
|
"""
|
||||||
|
Get numeric country ID
|
||||||
return -- numeric country ID. See countryHelper.py"""
|
|
||||||
|
|
||||||
|
return -- numeric country ID. See countryHelper.py
|
||||||
|
"""
|
||||||
return self.country
|
return self.country
|
||||||
|
|
||||||
|
|
||||||
def updatePingTime(self):
|
def updatePingTime(self):
|
||||||
"""Update latest ping time"""
|
"""Update latest ping time"""
|
||||||
self.pingTime = int(time.time())
|
self.pingTime = int(time.time())
|
||||||
|
@ -214,23 +234,24 @@ class token:
|
||||||
"""Set a new away message"""
|
"""Set a new away message"""
|
||||||
self.awayMessage = __awayMessage
|
self.awayMessage = __awayMessage
|
||||||
|
|
||||||
def joinMatch(self, __matchID):
|
def joinMatch(self, matchID):
|
||||||
"""
|
"""
|
||||||
Set match to matchID
|
Set match to matchID
|
||||||
|
|
||||||
__matchID -- new match ID
|
matchID -- new match ID
|
||||||
"""
|
"""
|
||||||
self.matchID = __matchID
|
self.matchID = matchID
|
||||||
|
|
||||||
def partMatch(self):
|
|
||||||
"""Set match to -1"""
|
|
||||||
self.matchID = -1
|
|
||||||
|
|
||||||
def kick(self, message="You have been kicked from the server. Please login again."):
|
def kick(self, message="You have been kicked from the server. Please login again."):
|
||||||
"""Kick this user from the server"""
|
"""
|
||||||
|
Kick this user from the server
|
||||||
|
|
||||||
|
message -- Notification message to send to this user. Optional.
|
||||||
|
"""
|
||||||
# Send packet to target
|
# Send packet to target
|
||||||
log.info("{} has been disconnected. (kick)".format(self.username))
|
log.info("{} has been disconnected. (kick)".format(self.username))
|
||||||
self.enqueue(serverPackets.notification(message))
|
if message != "":
|
||||||
|
self.enqueue(serverPackets.notification(message))
|
||||||
self.enqueue(serverPackets.loginFailed())
|
self.enqueue(serverPackets.loginFailed())
|
||||||
|
|
||||||
# Logout event
|
# Logout event
|
||||||
|
|
|
@ -3,10 +3,9 @@ from objects import glob
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
from events import logoutEvent
|
from events import logoutEvent
|
||||||
from helpers import logHelper as log
|
|
||||||
from helpers import userHelper
|
from helpers import userHelper
|
||||||
|
|
||||||
class tokenList:
|
class tokenList():
|
||||||
"""
|
"""
|
||||||
List of connected osu tokens
|
List of connected osu tokens
|
||||||
|
|
||||||
|
@ -27,7 +26,6 @@ class tokenList:
|
||||||
irc -- if True, set this token as IRC client
|
irc -- if True, set this token as IRC client
|
||||||
return -- token object
|
return -- token object
|
||||||
"""
|
"""
|
||||||
|
|
||||||
newToken = osuToken.token(userID, ip=ip, irc=irc, timeOffset=timeOffset)
|
newToken = osuToken.token(userID, ip=ip, irc=irc, timeOffset=timeOffset)
|
||||||
self.tokens[newToken.token] = newToken
|
self.tokens[newToken.token] = newToken
|
||||||
return newToken
|
return newToken
|
||||||
|
@ -38,7 +36,6 @@ class tokenList:
|
||||||
|
|
||||||
token -- token string
|
token -- token string
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if token in self.tokens:
|
if token in self.tokens:
|
||||||
# Delete session from DB
|
# Delete session from DB
|
||||||
if self.tokens[token].ip != "":
|
if self.tokens[token].ip != "":
|
||||||
|
@ -47,16 +44,13 @@ class tokenList:
|
||||||
# Pop token from list
|
# Pop token from list
|
||||||
self.tokens.pop(token)
|
self.tokens.pop(token)
|
||||||
|
|
||||||
|
|
||||||
def getUserIDFromToken(self, token):
|
def getUserIDFromToken(self, token):
|
||||||
"""
|
"""
|
||||||
Get user ID from a token
|
Get user ID from a token
|
||||||
|
|
||||||
token -- token to find
|
token -- token to find
|
||||||
|
return -- false if not found, userID if found
|
||||||
return: false if not found, userID if found
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Make sure the token exists
|
# Make sure the token exists
|
||||||
if token not in self.tokens:
|
if token not in self.tokens:
|
||||||
return False
|
return False
|
||||||
|
@ -64,7 +58,6 @@ class tokenList:
|
||||||
# Get userID associated to that token
|
# Get userID associated to that token
|
||||||
return self.tokens[token].userID
|
return self.tokens[token].userID
|
||||||
|
|
||||||
|
|
||||||
def getTokenFromUserID(self, userID):
|
def getTokenFromUserID(self, userID):
|
||||||
"""
|
"""
|
||||||
Get token from a user ID
|
Get token from a user ID
|
||||||
|
@ -72,7 +65,6 @@ class tokenList:
|
||||||
userID -- user ID to find
|
userID -- user ID to find
|
||||||
return -- False if not found, token object if found
|
return -- False if not found, token object if found
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Make sure the token exists
|
# Make sure the token exists
|
||||||
for _, value in self.tokens.items():
|
for _, value in self.tokens.items():
|
||||||
if value.userID == userID:
|
if value.userID == userID:
|
||||||
|
@ -81,7 +73,6 @@ class tokenList:
|
||||||
# Return none if not found
|
# Return none if not found
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def getTokenFromUsername(self, username):
|
def getTokenFromUsername(self, username):
|
||||||
"""
|
"""
|
||||||
Get token from a username
|
Get token from a username
|
||||||
|
@ -89,7 +80,6 @@ class tokenList:
|
||||||
username -- username to find
|
username -- username to find
|
||||||
return -- False if not found, token object if found
|
return -- False if not found, token object if found
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# lowercase
|
# lowercase
|
||||||
who = username.lower()
|
who = username.lower()
|
||||||
|
|
||||||
|
@ -101,7 +91,6 @@ class tokenList:
|
||||||
# Return none if not found
|
# Return none if not found
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def deleteOldTokens(self, userID):
|
def deleteOldTokens(self, userID):
|
||||||
"""
|
"""
|
||||||
Delete old userID's tokens if found
|
Delete old userID's tokens if found
|
||||||
|
@ -114,11 +103,6 @@ class tokenList:
|
||||||
if value.userID == userID:
|
if value.userID == userID:
|
||||||
# Delete this token from the dictionary
|
# Delete this token from the dictionary
|
||||||
self.tokens[key].kick("You have logged in from somewhere else. You can't connect to Bancho/IRC from more than one device at the same time.")
|
self.tokens[key].kick("You have logged in from somewhere else. You can't connect to Bancho/IRC from more than one device at the same time.")
|
||||||
#self.tokens.pop(key)
|
|
||||||
|
|
||||||
# break or items() function throws errors
|
|
||||||
#break
|
|
||||||
|
|
||||||
|
|
||||||
def multipleEnqueue(self, packet, who, but = False):
|
def multipleEnqueue(self, packet, who, but = False):
|
||||||
"""
|
"""
|
||||||
|
@ -128,7 +112,6 @@ class tokenList:
|
||||||
who -- userIDs array
|
who -- userIDs array
|
||||||
but -- if True, enqueue to everyone but users in who array
|
but -- if True, enqueue to everyone but users in who array
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for _, value in self.tokens.items():
|
for _, value in self.tokens.items():
|
||||||
shouldEnqueue = False
|
shouldEnqueue = False
|
||||||
if value.userID in who and not but:
|
if value.userID in who and not but:
|
||||||
|
@ -145,22 +128,20 @@ class tokenList:
|
||||||
|
|
||||||
packet -- packet bytes to enqueue
|
packet -- packet bytes to enqueue
|
||||||
"""
|
"""
|
||||||
|
|
||||||
for _, value in self.tokens.items():
|
for _, value in self.tokens.items():
|
||||||
value.enqueue(packet)
|
value.enqueue(packet)
|
||||||
|
|
||||||
def usersTimeoutCheckLoop(self, __timeoutTime = 100, __checkTime = 100):
|
def usersTimeoutCheckLoop(self, timeoutTime = 100, checkTime = 100):
|
||||||
"""
|
"""
|
||||||
Deletes all timed out users.
|
Deletes all timed out users.
|
||||||
If called once, will recall after __checkTime seconds and so on, forever
|
If called once, will recall after checkTime seconds and so on, forever
|
||||||
CALL THIS FUNCTION ONLY ONCE!
|
CALL THIS FUNCTION ONLY ONCE!
|
||||||
|
|
||||||
__timeoutTime - seconds of inactivity required to disconnect someone (Default: 100)
|
timeoutTime - seconds of inactivity required to disconnect someone (Default: 100)
|
||||||
__checkTime - seconds between loops (Default: 100)
|
checkTime - seconds between loops (Default: 100)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
timedOutTokens = [] # timed out users
|
timedOutTokens = [] # timed out users
|
||||||
timeoutLimit = time.time()-__timeoutTime
|
timeoutLimit = time.time()-timeoutTime
|
||||||
for key, value in self.tokens.items():
|
for key, value in self.tokens.items():
|
||||||
# Check timeout (fokabot is ignored)
|
# Check timeout (fokabot is ignored)
|
||||||
if value.pingTime < timeoutLimit and value.userID != 999 and value.irc == False:
|
if value.pingTime < timeoutLimit and value.userID != 999 and value.irc == False:
|
||||||
|
@ -174,15 +155,13 @@ class tokenList:
|
||||||
logoutEvent.handle(self.tokens[i], None)
|
logoutEvent.handle(self.tokens[i], None)
|
||||||
|
|
||||||
# Schedule a new check (endless loop)
|
# Schedule a new check (endless loop)
|
||||||
threading.Timer(__checkTime, self.usersTimeoutCheckLoop, [__timeoutTime, __checkTime]).start()
|
threading.Timer(checkTime, self.usersTimeoutCheckLoop, [timeoutTime, checkTime]).start()
|
||||||
|
|
||||||
def spamProtectionResetLoop(self):
|
def spamProtectionResetLoop(self):
|
||||||
"""
|
"""
|
||||||
Reset spam rate every 10 seconds.
|
Reset spam rate every 10 seconds.
|
||||||
CALL THIS FUNCTION ONLY ONCE!
|
CALL THIS FUNCTION ONLY ONCE!
|
||||||
"""
|
"""
|
||||||
#log.debug("Resetting spam protection...")
|
|
||||||
|
|
||||||
# Reset spamRate for every token
|
# Reset spamRate for every token
|
||||||
for _, value in self.tokens.items():
|
for _, value in self.tokens.items():
|
||||||
value.spamRate = 0
|
value.spamRate = 0
|
||||||
|
|
Loading…
Reference in New Issue
Block a user