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
|
||||
filters.txt
|
||||
.data
|
||||
.idea
|
|
@ -57,13 +57,12 @@ def addRemoveFriend(stream):
|
|||
return packetHelper.readPacketData(stream, [["friendID", dataTypes.sInt32]])
|
||||
|
||||
|
||||
|
||||
""" SPECTATOR PACKETS """
|
||||
""" Spectator packets """
|
||||
def startSpectating(stream):
|
||||
return packetHelper.readPacketData(stream,[["userID", dataTypes.sInt32]])
|
||||
|
||||
|
||||
""" MULTIPLAYER PACKETS """
|
||||
""" Multiplayer packets """
|
||||
def matchSettings(stream):
|
||||
# Data to return, will be merged later
|
||||
data = []
|
||||
|
@ -115,9 +114,6 @@ def matchSettings(stream):
|
|||
# Read last part
|
||||
data.append(packetHelper.readPacketData(stream[start:], struct, False))
|
||||
|
||||
# Mods if freemod (not used)
|
||||
#if data[1]["freeMods"] == 1:
|
||||
|
||||
result = {}
|
||||
for i in data:
|
||||
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
|
||||
TODO: Change False to None, because False doesn't make any sense
|
||||
"""
|
||||
|
||||
def instantRestart(fro, chan, message):
|
||||
glob.tokens.enqueueAll(serverPackets.notification("We are restarting Bancho. Be right back!"))
|
||||
systemHelper.scheduleShutdown(0, True, delay=1)
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
"""Contains readable gamemodes with their codes"""
|
||||
std = 0
|
||||
taiko = 1
|
||||
ctb = 2
|
||||
|
@ -9,10 +8,8 @@ def getGameModeForDB(gameMode):
|
|||
Convert a gamemode number to string for database table/column
|
||||
|
||||
gameMode -- gameMode int or variable (ex: gameMode.std)
|
||||
|
||||
return -- game mode readable string for db
|
||||
"""
|
||||
|
||||
if gameMode == std:
|
||||
return "std"
|
||||
elif gameMode == taiko:
|
||||
|
@ -27,10 +24,8 @@ def getGameModeForPrinting(gameMode):
|
|||
Convert a gamemode number to string for showing to a user (e.g. !last)
|
||||
|
||||
gameMode -- gameMode int or variable (ex: gameMode.std)
|
||||
|
||||
return -- game mode readable string for a human
|
||||
"""
|
||||
|
||||
if gameMode == std:
|
||||
return "osu!"
|
||||
elif gameMode == taiko:
|
||||
|
|
|
@ -5,9 +5,9 @@ from helpers import userHelper
|
|||
from objects import glob
|
||||
from constants import userRanks
|
||||
from constants import packetIDs
|
||||
from constants import privileges
|
||||
|
||||
""" Login errors packets
|
||||
(userID packets derivates) """
|
||||
""" Login errors packets """
|
||||
def loginFailed():
|
||||
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 += notification("You are banned. You can ask to get unbanned after 1 month since your ban by contacting support@ripple.moe")
|
||||
return packets
|
||||
#return packetHelper.buildPacket(packetIDs.server_userID, [[-3, dataTypes.sInt32]])
|
||||
|
||||
def loginError():
|
||||
return packetHelper.buildPacket(packetIDs.server_userID, [[-5, dataTypes.sInt32]])
|
||||
|
@ -29,6 +28,7 @@ def needSupporter():
|
|||
def needVerification():
|
||||
return packetHelper.buildPacket(packetIDs.server_userID, [[-8, dataTypes.sInt32]])
|
||||
|
||||
|
||||
""" Login packets """
|
||||
def userID(uid):
|
||||
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]])
|
||||
|
||||
def friendList(userID):
|
||||
friendsData = []
|
||||
|
||||
# Get friend IDs from db
|
||||
friends = userHelper.getFriendList(userID)
|
||||
|
||||
# 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)
|
||||
return packetHelper.buildPacket(packetIDs.server_friendsList, [[friends, dataTypes.intList]])
|
||||
|
||||
def onlineUsers():
|
||||
userIDs = []
|
||||
|
@ -91,7 +80,7 @@ def userPanel(userID, force = False):
|
|||
|
||||
# Get user data
|
||||
username = userToken.username
|
||||
timezone = 24+userToken.timeOffset # TODO: Timezone
|
||||
timezone = 24+userToken.timeOffset
|
||||
country = userToken.country
|
||||
gameRank = userToken.gameRank
|
||||
latitude = userToken.getLatitude()
|
||||
|
@ -105,7 +94,7 @@ def userPanel(userID, force = False):
|
|||
userRank = userRanks.MOD
|
||||
elif userHelper.isInPrivilegeGroup(userID, "developer") == True:
|
||||
userRank = userRanks.ADMIN
|
||||
elif userHelper.isInPrivilegeGroup(userID, "donor") == True:
|
||||
elif (userToken.privileges & privileges.USER_DONOR) > 0:
|
||||
userRank = userRanks.SUPPORTER
|
||||
else:
|
||||
userRank = userRanks.NORMAL
|
||||
|
@ -126,10 +115,12 @@ def userPanel(userID, force = False):
|
|||
def userStats(userID, force = False):
|
||||
# Get userID's token from tokens list
|
||||
userToken = glob.tokens.getTokenFromUserID(userID)
|
||||
|
||||
if userToken == None:
|
||||
return bytes()
|
||||
if (userToken.restricted == True or userToken.irc == True) and force == False:
|
||||
return bytes()
|
||||
|
||||
return packetHelper.buildPacket(packetIDs.server_userStats,
|
||||
[
|
||||
[userID, dataTypes.uInt32],
|
||||
|
@ -150,14 +141,23 @@ def userStats(userID, force = False):
|
|||
|
||||
""" Chat packets """
|
||||
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):
|
||||
return packetHelper.buildPacket(packetIDs.server_channelJoinSuccess, [[chan, dataTypes.string]])
|
||||
|
||||
def channelInfo(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():
|
||||
return packetHelper.buildPacket(packetIDs.server_channelInfoEnd, [[0, dataTypes.uInt32]])
|
||||
|
@ -199,7 +199,6 @@ def createMatch(matchID):
|
|||
match = glob.matches.matches[matchID]
|
||||
return packetHelper.buildPacket(packetIDs.server_newMatch, match.getMatchData())
|
||||
|
||||
|
||||
def updateMatch(matchID):
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
|
@ -209,7 +208,6 @@ def updateMatch(matchID):
|
|||
match = glob.matches.matches[matchID]
|
||||
return packetHelper.buildPacket(packetIDs.server_updateMatch, match.getMatchData())
|
||||
|
||||
|
||||
def matchStart(matchID):
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
|
@ -219,9 +217,8 @@ def matchStart(matchID):
|
|||
match = glob.matches.matches[matchID]
|
||||
return packetHelper.buildPacket(packetIDs.server_matchStart, match.getMatchData())
|
||||
|
||||
|
||||
def disposeMatch(matchID):
|
||||
return packetHelper.buildPacket(packetIDs.server_disposeMatch, [[matchID, dataTypes.uInt16]])
|
||||
return packetHelper.buildPacket(packetIDs.server_disposeMatch, [[matchID, dataTypes.uInt32]])
|
||||
|
||||
def matchJoinSuccess(matchID):
|
||||
# Make sure the match exists
|
||||
|
@ -260,9 +257,10 @@ def playerFailed(slotID):
|
|||
def matchTransferHost():
|
||||
return packetHelper.buildPacket(packetIDs.server_matchTransferHost)
|
||||
|
||||
|
||||
""" Other packets """
|
||||
def notification(message):
|
||||
return packetHelper.buildPacket(packetIDs.server_notification, [[message, dataTypes.string]])
|
||||
|
||||
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 logHelper as log
|
||||
from constants import actions
|
||||
from helpers import chatHelper as chat
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Get usertoken data
|
||||
|
@ -24,9 +23,16 @@ def handle(userToken, packetData):
|
|||
# Change action packet
|
||||
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
|
||||
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
|
||||
userToken.gameMode = packetData["gameMode"]
|
||||
userToken.updateCachedStats()
|
||||
|
@ -55,12 +61,5 @@ def handle(userToken, packetData):
|
|||
token.enqueue(serverPackets.userPanel(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
|
||||
log.info("{} changed action: {} [{}][{}]".format(username, str(userToken.actionID), userToken.actionText, userToken.actionMd5))
|
||||
|
|
|
@ -16,6 +16,10 @@ def handle(userToken, packetData):
|
|||
return
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Host check
|
||||
if userID != match.hostUserID:
|
||||
return
|
||||
|
||||
# Set slot or match mods according to modType
|
||||
if match.matchModMode == matchModModes.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 (packetData["mods"] & mods.DoubleTime) > 0:
|
||||
match.changeMatchMods(mods.DoubleTime)
|
||||
# Nighcore
|
||||
# Nightcore
|
||||
if (packetData["mods"] & mods.Nightcore) > 0:
|
||||
match.changeMatchMods(match.mods+mods.Nightcore)
|
||||
elif (packetData["mods"] & mods.HalfTime) > 0:
|
||||
|
|
|
@ -13,5 +13,9 @@ def handle(userToken, packetData):
|
|||
# Get our match
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Host check
|
||||
if userToken.userID != match.hostUserID:
|
||||
return
|
||||
|
||||
# Update match password
|
||||
match.changePassword(packetData["matchPassword"])
|
||||
|
|
|
@ -6,6 +6,7 @@ from constants import matchTeamTypes
|
|||
from constants import matchTeams
|
||||
from constants import slotStatuses
|
||||
from helpers import logHelper as log
|
||||
from helpers import generalFunctions
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Read new settings
|
||||
|
@ -13,7 +14,7 @@ def handle(userToken, packetData):
|
|||
|
||||
# Get match ID
|
||||
matchID = userToken.matchID
|
||||
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
@ -21,6 +22,10 @@ def handle(userToken, packetData):
|
|||
# Get match object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Host check
|
||||
if userToken.userID != match.hostUserID:
|
||||
return
|
||||
|
||||
# Some dank memes easter egg
|
||||
memeTitles = [
|
||||
"RWC 2020",
|
||||
|
@ -53,7 +58,10 @@ def handle(userToken, packetData):
|
|||
|
||||
# Update match settings
|
||||
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.beatmapID = packetData["beatmapID"]
|
||||
match.hostUserID = packetData["hostUserID"]
|
||||
|
@ -71,14 +79,14 @@ def handle(userToken, packetData):
|
|||
# Reset ready if needed
|
||||
if oldMods != match.mods or oldBeatmapMD5 != match.beatmapMD5:
|
||||
for i in range(0,16):
|
||||
if match.slots[i]["status"] == slotStatuses.ready:
|
||||
match.slots[i]["status"] = slotStatuses.notReady
|
||||
if match.slots[i].status == slotStatuses.ready:
|
||||
match.slots[i].status = slotStatuses.notReady
|
||||
|
||||
# Reset mods if needed
|
||||
if match.matchModMode == matchModModes.normal:
|
||||
# Reset slot mods if not freeMods
|
||||
for i in range(0,16):
|
||||
match.slots[i]["mods"] = 0
|
||||
match.slots[i].mods = 0
|
||||
else:
|
||||
# Reset match mods if freemod
|
||||
match.mods = 0
|
||||
|
@ -88,13 +96,13 @@ def handle(userToken, packetData):
|
|||
# Set teams
|
||||
c=0
|
||||
for i in range(0,16):
|
||||
if match.slots[i]["team"] == matchTeams.noTeam:
|
||||
match.slots[i]["team"] = matchTeams.red if c % 2 == 0 else matchTeams.blue
|
||||
if match.slots[i].team == matchTeams.noTeam:
|
||||
match.slots[i].team = matchTeams.red if c % 2 == 0 else matchTeams.blue
|
||||
c+=1
|
||||
else:
|
||||
# Reset teams
|
||||
for i in range(0,16):
|
||||
match.slots[i]["team"] = matchTeams.noTeam
|
||||
match.slots[i].team = matchTeams.noTeam
|
||||
|
||||
# Force no freemods if tag coop
|
||||
if match.matchTeamType == matchTeamTypes.tagCoop or match.matchTeamType == matchTeamTypes.tagTeamVs:
|
||||
|
@ -105,4 +113,3 @@ def handle(userToken, packetData):
|
|||
|
||||
# Console output
|
||||
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 helpers import logHelper as log
|
||||
from helpers import chatHelper as chat
|
||||
from helpers import generalFunctions
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# read packet data
|
||||
|
@ -12,12 +13,15 @@ def handle(userToken, packetData):
|
|||
# Get match from ID
|
||||
joinMatch(userToken, packetData["matchID"], packetData["password"])
|
||||
|
||||
def joinMatch(userToken, matchID, password):
|
||||
def joinMatch(userToken, matchID, password, isPasswordHashed = False):
|
||||
try:
|
||||
# TODO: leave other matches
|
||||
# TODO: Stop spectating
|
||||
# Stop spectating
|
||||
userToken.stopSpectating()
|
||||
|
||||
# get usertoken data
|
||||
# Leave other matches
|
||||
userToken.partMatch()
|
||||
|
||||
# Get usertoken data
|
||||
userID = userToken.userID
|
||||
|
||||
# Make sure the match exists
|
||||
|
@ -27,6 +31,10 @@ def joinMatch(userToken, matchID, password):
|
|||
# Match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Hash password if needed
|
||||
if isPasswordHashed == False and password != "":
|
||||
password = generalFunctions.stringMd5(password)
|
||||
|
||||
# Check password
|
||||
# TODO: Admins can enter every match
|
||||
if match.matchPassword != "":
|
||||
|
|
|
@ -2,16 +2,10 @@ from helpers import userHelper
|
|||
from constants import serverPackets
|
||||
from constants import exceptions
|
||||
from objects import glob
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from helpers import locationHelper
|
||||
from helpers import countryHelper
|
||||
import time
|
||||
from helpers import generalFunctions
|
||||
import sys
|
||||
import traceback
|
||||
from helpers import requestHelper
|
||||
from helpers import discordBotHelper
|
||||
from helpers import logHelper as log
|
||||
from helpers import chatHelper as chat
|
||||
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
|
||||
# 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:
|
||||
# Stop spectating if needed
|
||||
# TODO: Call stopSpectatingEvent!!!!!!!!!
|
||||
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))
|
||||
# Stop spectating
|
||||
userToken.stopSpectating()
|
||||
|
||||
# Part matches
|
||||
userToken.partMatch()
|
||||
|
||||
# Part all joined channels
|
||||
for i in userToken.joinedChannels:
|
||||
chat.partChannel(token=userToken, channel=i)
|
||||
|
||||
# TODO: Lobby left if joined
|
||||
|
||||
# Enqueue our disconnection to everyone else
|
||||
glob.tokens.enqueueAll(serverPackets.userLogout(userID))
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ def handle(userToken, packetData):
|
|||
|
||||
# Enqueue frames to who's playing
|
||||
for i in range(0,16):
|
||||
if match.slots[i]["userID"] > -1 and match.slots[i]["status"] == slotStatuses.playing:
|
||||
token = glob.tokens.getTokenFromUserID(match.slots[i]["userID"])
|
||||
if match.slots[i].userID > -1 and match.slots[i].status == slotStatuses.playing:
|
||||
token = glob.tokens.getTokenFromUserID(match.slots[i].userID)
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.matchFrames(slotID, packetData))
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from events import matchBeatmapEvent
|
||||
|
||||
def handle(userToken, packetData):
|
||||
matchBeatmapEvent.handle(userToken, packetData, True)
|
||||
|
|
|
@ -14,6 +14,10 @@ def handle(userToken, packetData):
|
|||
return
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Host check
|
||||
if userID != match.hostUserID:
|
||||
return
|
||||
|
||||
# Make sure we aren't locking our slot
|
||||
ourSlot = match.getUserSlotID(userID)
|
||||
if packetData["slotID"] == ourSlot:
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from events import matchBeatmapEvent
|
||||
|
||||
def handle(userToken, packetData):
|
||||
matchBeatmapEvent.handle(userToken, packetData, False)
|
||||
|
|
|
@ -3,7 +3,6 @@ from constants import slotStatuses
|
|||
from constants import serverPackets
|
||||
|
||||
def handle(userToken, _):
|
||||
# TODO: Host check
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
@ -19,10 +18,12 @@ def handle(userToken, _):
|
|||
# The match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
force = False # TODO: Force thing
|
||||
# Host check
|
||||
if userToken.userID != match.hostUserID:
|
||||
return
|
||||
|
||||
# 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
|
||||
|
||||
# Change inProgress value
|
||||
|
@ -30,16 +31,16 @@ def handle(userToken, _):
|
|||
|
||||
# Set playing to ready players and set load, skip and complete to False
|
||||
for i in range(0,16):
|
||||
if (match.slots[i]["status"] & slotStatuses.ready) > 0:
|
||||
match.slots[i]["status"] = slotStatuses.playing
|
||||
match.slots[i]["loaded"] = False
|
||||
match.slots[i]["skip"] = False
|
||||
match.slots[i]["complete"] = False
|
||||
if (match.slots[i].status & slotStatuses.ready) > 0:
|
||||
match.slots[i].status = slotStatuses.playing
|
||||
match.slots[i].loaded = False
|
||||
match.slots[i].skip = False
|
||||
match.slots[i].complete = False
|
||||
|
||||
# Send match start packet
|
||||
for i in range(0,16):
|
||||
if (match.slots[i]["status"] & slotStatuses.playing) > 0 and match.slots[i]["userID"] != -1:
|
||||
token = glob.tokens.getTokenFromUserID(match.slots[i]["userID"])
|
||||
if (match.slots[i].status & slotStatuses.playing) > 0 and match.slots[i].userID != -1:
|
||||
token = glob.tokens.getTokenFromUserID(match.slots[i].userID)
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.matchStart(matchID))
|
||||
|
||||
|
|
|
@ -19,5 +19,9 @@ def handle(userToken, packetData):
|
|||
# Match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Host check
|
||||
if userToken.userID != match.hostUserID:
|
||||
return
|
||||
|
||||
# Transfer host
|
||||
match.transferHost(packetData["slotID"])
|
||||
|
|
|
@ -1,28 +1,2 @@
|
|||
from objects import glob
|
||||
|
||||
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()
|
||||
def handle(userToken, _=None):
|
||||
userToken.partMatch()
|
|
@ -2,8 +2,6 @@ from constants import serverPackets
|
|||
from helpers import logHelper as log
|
||||
|
||||
def handle(userToken, packetData):
|
||||
log.debug("Requested status update")
|
||||
|
||||
# Update cache and send new stats
|
||||
userToken.updateCachedStats()
|
||||
userToken.enqueue(serverPackets.userStats(userToken.userID))
|
||||
|
|
|
@ -1,37 +1,2 @@
|
|||
from objects import glob
|
||||
from constants import serverPackets
|
||||
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()
|
||||
def handle(userToken, _=None):
|
||||
userToken.stopSpectating()
|
||||
|
|
|
@ -33,7 +33,5 @@ class handler(requestHelper.asyncRequestHandler):
|
|||
data["status"] = statusCode
|
||||
|
||||
# Send response
|
||||
#self.clear()
|
||||
self.write(json.dumps(data))
|
||||
self.set_status(statusCode)
|
||||
#self.finish(json.dumps(data))
|
||||
|
|
|
@ -226,8 +226,8 @@ class handler(SentryMixin, requestHelper.asyncRequestHandler):
|
|||
self.set_status(200)
|
||||
self.add_header("cho-token", responseTokenString)
|
||||
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")
|
||||
except:
|
||||
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 += "</marquee><br><strike>reverse engineering a protocol impossible to reverse engineer since always</strike><br>we are actually reverse engineering bancho successfully. for the third time.<br><br><i>© Ripple team, 2016</i></pre></body></html>"
|
||||
self.write(html)
|
||||
#yield tornado.gen.Task(self.captureMessage, "test")
|
||||
#self.finish()
|
||||
self.write(html)
|
|
@ -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")
|
||||
return 442 # idk
|
||||
|
||||
|
||||
|
||||
|
||||
def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||
"""
|
||||
Send a message to osu!bancho and IRC server
|
||||
|
@ -299,8 +296,13 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
|||
return 401
|
||||
|
||||
|
||||
|
||||
""" IRC-Bancho Connect/Disconnect/Join/Part interfaces"""
|
||||
def fixUsernameForBancho(username):
|
||||
return username.replace("_", " ")
|
||||
|
||||
def fixUsernameForIRC(username):
|
||||
return username.replace(" ", "_")
|
||||
|
||||
def IRCConnect(username):
|
||||
userID = userHelper.getID(username)
|
||||
if userID == False:
|
||||
|
|
|
@ -1,18 +1,7 @@
|
|||
import os
|
||||
import configparser
|
||||
|
||||
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
|
||||
|
||||
class config():
|
||||
# Check if config.ini exists and load/generate it
|
||||
def __init__(self, file):
|
||||
"""
|
||||
|
@ -20,7 +9,8 @@ class config:
|
|||
|
||||
file -- filename
|
||||
"""
|
||||
|
||||
self.config = configparser.ConfigParser()
|
||||
self.default = True
|
||||
self.fileName = file
|
||||
if os.path.isfile(self.fileName):
|
||||
# config.ini found, load it
|
||||
|
@ -39,7 +29,6 @@ class config:
|
|||
|
||||
return -- True if valid, False if not
|
||||
"""
|
||||
|
||||
try:
|
||||
# Try to get all the required keys
|
||||
self.config.get("db","host")
|
||||
|
@ -75,11 +64,10 @@ class config:
|
|||
except:
|
||||
return False
|
||||
|
||||
|
||||
# Generate a default config.ini
|
||||
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
|
||||
f = open(self.fileName, "w")
|
||||
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
"""Some console related functions"""
|
||||
|
||||
from constants import bcolors
|
||||
from objects import glob
|
||||
|
||||
def printServerStartHeader(asciiArt):
|
||||
"""Print server start header with optional ascii art
|
||||
|
||||
asciiArt -- if True, will print ascii art too"""
|
||||
"""
|
||||
Print server start header with optional ascii art
|
||||
|
||||
asciiArt -- if True, will print ascii art too
|
||||
"""
|
||||
if asciiArt == True:
|
||||
print("{} _ __".format(bcolors.GREEN))
|
||||
print(" (_) / /")
|
||||
|
@ -28,20 +27,17 @@ def printServerStartHeader(asciiArt):
|
|||
|
||||
printColored("> Welcome to pep.py osu!bancho server v{}".format(glob.VERSION), 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)
|
||||
|
||||
|
||||
def printNoNl(string):
|
||||
"""
|
||||
Print string without new line at the end
|
||||
|
||||
string -- string to print
|
||||
"""
|
||||
|
||||
print(string, end="")
|
||||
|
||||
|
||||
def printColored(string, color):
|
||||
"""
|
||||
Print colored string
|
||||
|
@ -49,23 +45,22 @@ def printColored(string, color):
|
|||
string -- string to print
|
||||
color -- see bcolors.py
|
||||
"""
|
||||
|
||||
print("{}{}{}".format(color, string, bcolors.ENDC))
|
||||
|
||||
|
||||
def printError():
|
||||
"""Print error text FOR LOADING"""
|
||||
|
||||
"""
|
||||
Print error text FOR LOADING
|
||||
"""
|
||||
printColored("Error", bcolors.RED)
|
||||
|
||||
|
||||
def printDone():
|
||||
"""Print error text FOR LOADING"""
|
||||
|
||||
"""
|
||||
Print error text FOR LOADING
|
||||
"""
|
||||
printColored("Done", bcolors.GREEN)
|
||||
|
||||
|
||||
def printWarning():
|
||||
"""Print error text FOR LOADING"""
|
||||
|
||||
"""
|
||||
Print error text FOR LOADING
|
||||
"""
|
||||
printColored("Warning", bcolors.YELLOW)
|
||||
|
|
|
@ -253,7 +253,6 @@ countryCodes = {
|
|||
"AI": 7
|
||||
}
|
||||
|
||||
|
||||
def getCountryID(code):
|
||||
"""
|
||||
Get country ID for osu client
|
||||
|
|
|
@ -2,13 +2,13 @@ import MySQLdb
|
|||
import threading
|
||||
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):
|
||||
"""
|
||||
Create a pettirosso meme (mysql worker)
|
||||
Create a mysql worker
|
||||
|
||||
wid -- worker id
|
||||
host -- hostname
|
||||
|
@ -22,11 +22,10 @@ class mysqlWorker:
|
|||
self.ready = True
|
||||
self.lock = threading.Lock()
|
||||
|
||||
class db:
|
||||
class db():
|
||||
"""
|
||||
A MySQL db connection with multiple workers
|
||||
"""
|
||||
|
||||
def __init__(self, host, username, password, database, workers):
|
||||
"""
|
||||
Create MySQL workers aka pettirossi meme
|
||||
|
@ -37,9 +36,6 @@ class db:
|
|||
database -- MySQL database name
|
||||
workers -- Number of workers to spawn
|
||||
"""
|
||||
#self.lock = threading.Lock()
|
||||
#self.connection = MySQLdb.connect(host, username, password, database)
|
||||
|
||||
self.workers = []
|
||||
self.lastWorker = 0
|
||||
self.workersNumber = workers
|
||||
|
@ -57,7 +53,6 @@ class db:
|
|||
self.lastWorker = 0
|
||||
else:
|
||||
self.lastWorker += 1
|
||||
#print("Using worker {}".format(self.lastWorker))
|
||||
return self.workers[self.lastWorker]
|
||||
|
||||
def execute(self, query, params = ()):
|
||||
|
|
|
@ -1,9 +1,6 @@
|
|||
import requests
|
||||
from objects import glob
|
||||
from helpers import generalFunctions
|
||||
from urllib.parse import urlencode
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
|
||||
def sendDiscordMessage(channel, message, alertDev = False, prefix = "**pep.py**"):
|
||||
"""
|
||||
|
@ -24,7 +21,6 @@ def sendDiscordMessage(channel, message, alertDev = False, prefix = "**pep.py**"
|
|||
except:
|
||||
continue
|
||||
|
||||
|
||||
def sendConfidential(message, alertDev = False):
|
||||
"""
|
||||
Send a message to #bunker
|
||||
|
@ -33,7 +29,6 @@ def sendConfidential(message, alertDev = False):
|
|||
"""
|
||||
sendDiscordMessage("bunk", message, alertDev)
|
||||
|
||||
|
||||
def sendStaff(message):
|
||||
"""
|
||||
Send a message to #staff
|
||||
|
@ -42,7 +37,6 @@ def sendStaff(message):
|
|||
"""
|
||||
sendDiscordMessage("staff", message)
|
||||
|
||||
|
||||
def sendGeneral(message):
|
||||
"""
|
||||
Send a message to #general
|
||||
|
@ -51,7 +45,6 @@ def sendGeneral(message):
|
|||
"""
|
||||
sendDiscordMessage("general", message)
|
||||
|
||||
|
||||
def sendChatlog(message):
|
||||
"""
|
||||
Send a message to #chatlog
|
||||
|
|
|
@ -1,6 +1,17 @@
|
|||
"""Some functions that don't fit in any other file"""
|
||||
from constants import mods
|
||||
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):
|
||||
"""
|
||||
|
@ -9,10 +20,8 @@ def stringToBool(s):
|
|||
s -- string/int value
|
||||
return -- True/False
|
||||
"""
|
||||
|
||||
return (s == "True" or s== "true" or s == "1" or s == 1)
|
||||
|
||||
|
||||
def hexString(s):
|
||||
"""
|
||||
Output s' bytes in HEX
|
||||
|
@ -20,7 +29,6 @@ def hexString(s):
|
|||
s -- string
|
||||
return -- string with hex value
|
||||
"""
|
||||
|
||||
return ":".join("{:02x}".format(ord(str(c))) for c in s)
|
||||
|
||||
def readableMods(__mods):
|
||||
|
|
|
@ -11,7 +11,6 @@ def getCountry(ip):
|
|||
ip -- IP Address
|
||||
return -- Country code (2 letters)
|
||||
"""
|
||||
|
||||
try:
|
||||
# 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"]
|
||||
|
@ -20,7 +19,6 @@ def getCountry(ip):
|
|||
log.error("Error in get country")
|
||||
return "XX"
|
||||
|
||||
|
||||
def getLocation(ip):
|
||||
"""
|
||||
Get latitude and longitude from IP address
|
||||
|
@ -28,7 +26,6 @@ def getLocation(ip):
|
|||
ip -- IP address
|
||||
return -- [latitude, longitude]
|
||||
"""
|
||||
|
||||
try:
|
||||
# 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(",")
|
||||
|
|
|
@ -8,7 +8,6 @@ def uleb128Encode(num):
|
|||
num -- int to encode
|
||||
return -- bytearray with encoded number
|
||||
"""
|
||||
|
||||
arr = bytearray()
|
||||
length = 0
|
||||
|
||||
|
@ -24,7 +23,6 @@ def uleb128Encode(num):
|
|||
|
||||
return arr
|
||||
|
||||
|
||||
def uleb128Decode(num):
|
||||
"""
|
||||
Decode uleb128 -> int
|
||||
|
@ -32,9 +30,7 @@ def uleb128Decode(num):
|
|||
num -- encoded uleb128
|
||||
return -- list. [total, length]
|
||||
"""
|
||||
|
||||
shift = 0
|
||||
|
||||
arr = [0,0] #total, length
|
||||
|
||||
while True:
|
||||
|
@ -47,42 +43,40 @@ def uleb128Decode(num):
|
|||
|
||||
return arr
|
||||
|
||||
|
||||
def unpackData(__data, __dataType):
|
||||
def unpackData(data, dataType):
|
||||
"""
|
||||
Unpacks data according to dataType
|
||||
|
||||
__data -- bytes array to unpack
|
||||
__dataType -- data type. See dataTypes.py
|
||||
data -- bytes array to unpack
|
||||
dataType -- data type. See dataTypes.py
|
||||
|
||||
return -- unpacked bytes
|
||||
"""
|
||||
|
||||
# Get right pack Type
|
||||
if __dataType == dataTypes.uInt16:
|
||||
if dataType == dataTypes.uInt16:
|
||||
unpackType = "<H"
|
||||
elif __dataType == dataTypes.sInt16:
|
||||
elif dataType == dataTypes.sInt16:
|
||||
unpackType = "<h"
|
||||
elif __dataType == dataTypes.uInt32:
|
||||
elif dataType == dataTypes.uInt32:
|
||||
unpackType = "<L"
|
||||
elif __dataType == dataTypes.sInt32:
|
||||
elif dataType == dataTypes.sInt32:
|
||||
unpackType = "<l"
|
||||
elif __dataType == dataTypes.uInt64:
|
||||
elif dataType == dataTypes.uInt64:
|
||||
unpackType = "<Q"
|
||||
elif __dataType == dataTypes.sInt64:
|
||||
elif dataType == dataTypes.sInt64:
|
||||
unpackType = "<q"
|
||||
elif __dataType == dataTypes.string:
|
||||
elif dataType == dataTypes.string:
|
||||
unpackType = "<s"
|
||||
elif __dataType == dataTypes.ffloat:
|
||||
elif dataType == dataTypes.ffloat:
|
||||
unpackType = "<f"
|
||||
else:
|
||||
unpackType = "<B"
|
||||
|
||||
# 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
|
||||
|
||||
|
@ -96,11 +90,11 @@ def packData(__data, __dataType):
|
|||
pack = True # if True, use pack. False only with strings
|
||||
|
||||
# Get right pack Type
|
||||
if __dataType == dataTypes.bbytes:
|
||||
if dataType == dataTypes.bbytes:
|
||||
# Bytes, do not use pack, do manually
|
||||
pack = False
|
||||
data = __data
|
||||
elif __dataType == dataTypes.intList:
|
||||
elif dataType == dataTypes.intList:
|
||||
# Pack manually
|
||||
pack = False
|
||||
# Add length
|
||||
|
@ -108,7 +102,7 @@ def packData(__data, __dataType):
|
|||
# Add all elements
|
||||
for i in __data:
|
||||
data += packData(i, dataTypes.sInt32)
|
||||
elif __dataType == dataTypes.string:
|
||||
elif dataType == dataTypes.string:
|
||||
# String, do not use pack, do manually
|
||||
pack = False
|
||||
if len(__data) == 0:
|
||||
|
@ -119,21 +113,21 @@ def packData(__data, __dataType):
|
|||
data += b"\x0B"
|
||||
data += uleb128Encode(len(__data))
|
||||
data += str.encode(__data, "latin_1", "ignore")
|
||||
elif __dataType == dataTypes.uInt16:
|
||||
elif dataType == dataTypes.uInt16:
|
||||
packType = "<H"
|
||||
elif __dataType == dataTypes.sInt16:
|
||||
elif dataType == dataTypes.sInt16:
|
||||
packType = "<h"
|
||||
elif __dataType == dataTypes.uInt32:
|
||||
elif dataType == dataTypes.uInt32:
|
||||
packType = "<L"
|
||||
elif __dataType == dataTypes.sInt32:
|
||||
elif dataType == dataTypes.sInt32:
|
||||
packType = "<l"
|
||||
elif __dataType == dataTypes.uInt64:
|
||||
elif dataType == dataTypes.uInt64:
|
||||
packType = "<Q"
|
||||
elif __dataType == dataTypes.sInt64:
|
||||
elif dataType == dataTypes.sInt64:
|
||||
packType = "<q"
|
||||
elif __dataType == dataTypes.string:
|
||||
elif dataType == dataTypes.string:
|
||||
packType = "<s"
|
||||
elif __dataType == dataTypes.ffloat:
|
||||
elif dataType == dataTypes.ffloat:
|
||||
packType = "<f"
|
||||
else:
|
||||
packType = "<B"
|
||||
|
@ -144,7 +138,6 @@ def packData(__data, __dataType):
|
|||
|
||||
return data
|
||||
|
||||
# TODO: Wat dangerous
|
||||
def buildPacket(__packet, __packetData = []):
|
||||
"""
|
||||
Build a packet
|
||||
|
@ -154,7 +147,6 @@ def buildPacket(__packet, __packetData = []):
|
|||
|
||||
return -- packet bytes
|
||||
"""
|
||||
|
||||
# Set some variables
|
||||
packetData = bytes()
|
||||
packetLength = 0
|
||||
|
@ -174,7 +166,6 @@ def buildPacket(__packet, __packetData = []):
|
|||
packetBytes += packetData # packet data
|
||||
return packetBytes
|
||||
|
||||
|
||||
def readPacketID(stream):
|
||||
"""
|
||||
Read packetID from stream (0-1 bytes)
|
||||
|
@ -182,10 +173,8 @@ def readPacketID(stream):
|
|||
stream -- data stream
|
||||
return -- packet ID (int)
|
||||
"""
|
||||
|
||||
return unpackData(stream[0:2], dataTypes.uInt16)
|
||||
|
||||
|
||||
def readPacketLength(stream):
|
||||
"""
|
||||
Read packet length from stream (3-4-5-6 bytes)
|
||||
|
@ -193,7 +182,6 @@ def readPacketLength(stream):
|
|||
stream -- data stream
|
||||
return -- packet length (int)
|
||||
"""
|
||||
|
||||
return unpackData(stream[3:7], dataTypes.uInt32)
|
||||
|
||||
|
||||
|
@ -208,7 +196,6 @@ def readPacketData(stream, structure = [], hasFirstBytes = True):
|
|||
Optional. Default: True
|
||||
return -- dictionary. key: name, value: read data
|
||||
"""
|
||||
|
||||
# Read packet ID (first 2 bytes)
|
||||
data = {}
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@ def checkOldPassword(password, salt, rightPassword):
|
|||
rightPassword -- right password
|
||||
return -- bool
|
||||
"""
|
||||
|
||||
return (rightPassword == cryptHelper.crypt(password, "$2y$"+str(base64.b64decode(salt))))
|
||||
|
||||
def checkNewPassword(password, dbPassword):
|
||||
|
|
|
@ -3,8 +3,6 @@ import tornado.web
|
|||
import tornado.gen
|
||||
from tornado.ioloop import IOLoop
|
||||
from objects import glob
|
||||
from raven.contrib.tornado import SentryMixin
|
||||
from raven.contrib.tornado import AsyncSentryClient
|
||||
import gevent
|
||||
|
||||
class asyncRequestHandler(tornado.web.RequestHandler):
|
||||
|
@ -50,7 +48,6 @@ class asyncRequestHandler(tornado.web.RequestHandler):
|
|||
return realIP
|
||||
return self.request.remote_ip
|
||||
|
||||
|
||||
def runBackground(data, callback):
|
||||
"""
|
||||
Run a function in the background.
|
||||
|
@ -59,7 +56,6 @@ def runBackground(data, callback):
|
|||
func, args, kwargs = data
|
||||
def _callback(result):
|
||||
IOLoop.instance().add_callback(lambda: callback(result))
|
||||
#glob.pool.apply_async(func, args, kwargs, _callback)
|
||||
g = gevent.Greenlet(func, *args, **kwargs)
|
||||
g.link(_callback)
|
||||
g.start()
|
||||
|
|
|
@ -15,10 +15,8 @@ def runningUnderUnix():
|
|||
|
||||
return --- True if running under UNIX, otherwise False
|
||||
"""
|
||||
|
||||
return True if os.name == "posix" else False
|
||||
|
||||
|
||||
def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
|
||||
"""
|
||||
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
|
||||
message -- if set, send that message to every client to warn about the shutdown/restart
|
||||
"""
|
||||
|
||||
# Console output
|
||||
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))
|
||||
|
@ -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
|
||||
threading.Timer(sendRestartTime+delay, action).start()
|
||||
|
||||
|
||||
def restartServer():
|
||||
"""Restart pep.py script"""
|
||||
log.info("Restarting pep.py...")
|
||||
os.execv(sys.executable, [sys.executable] + sys.argv)
|
||||
|
||||
|
||||
def shutdownServer():
|
||||
"""Shutdown pep.py"""
|
||||
log.info("Shutting down pep.py...")
|
||||
sig = signal.SIGKILL if runningUnderUnix() else signal.CTRL_C_EVENT
|
||||
os.kill(os.getpid(), sig)
|
||||
|
||||
|
||||
def getSystemInfo():
|
||||
"""
|
||||
Get a dictionary with some system/server info
|
||||
|
||||
return -- ["unix", "connectedUsers", "webServer", "cpuUsage", "totalMemory", "usedMemory", "loadAverage"]
|
||||
"""
|
||||
|
||||
data = {}
|
||||
|
||||
# Get if server is running under unix/nt
|
||||
|
|
|
@ -14,9 +14,8 @@ def getID(username):
|
|||
username -- user
|
||||
return -- user id or False
|
||||
"""
|
||||
|
||||
# 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
|
||||
if userID == None:
|
||||
|
@ -25,7 +24,6 @@ def getID(username):
|
|||
# Return user ID
|
||||
return userID["id"]
|
||||
|
||||
|
||||
def checkLogin(userID, password):
|
||||
"""
|
||||
Check userID's login with specified password
|
||||
|
@ -35,9 +33,8 @@ def checkLogin(userID, password):
|
|||
password -- plain md5 password
|
||||
return -- True or False
|
||||
"""
|
||||
|
||||
# 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
|
||||
if passwordData == None:
|
||||
|
@ -51,8 +48,7 @@ def checkLogin(userID, password):
|
|||
ok = passwordHelper.checkOldPassword(password, passwordData["salt"], passwordData["password_md5"])
|
||||
if not ok: return False
|
||||
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):
|
||||
"""
|
||||
|
@ -61,8 +57,7 @@ def exists(userID):
|
|||
userID -- user ID to check
|
||||
return -- bool
|
||||
"""
|
||||
|
||||
result = glob.db.fetch("SELECT id FROM users WHERE id = %s", [userID])
|
||||
result = glob.db.fetch("SELECT id FROM users WHERE id = %s LIMIT 1", [userID])
|
||||
if result == None:
|
||||
return False
|
||||
else:
|
||||
|
@ -76,8 +71,7 @@ def getSilenceEnd(userID):
|
|||
userID -- userID
|
||||
return -- UNIX time
|
||||
"""
|
||||
|
||||
return glob.db.fetch("SELECT silence_end FROM users WHERE id = %s", [userID])["silence_end"]
|
||||
return glob.db.fetch("SELECT silence_end FROM users WHERE id = %s LIMIT 1", [userID])["silence_end"]
|
||||
|
||||
|
||||
def silence(userID, seconds, silenceReason, author = 999):
|
||||
|
@ -91,7 +85,7 @@ def silence(userID, seconds, silenceReason, author = 999):
|
|||
"""
|
||||
# db qurey
|
||||
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
|
||||
targetUsername = getUsername(userID)
|
||||
|
@ -109,9 +103,8 @@ def getRankedScore(userID, gameMode):
|
|||
gameMode -- int value, see gameModes
|
||||
return -- ranked score
|
||||
"""
|
||||
|
||||
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):
|
||||
|
@ -122,10 +115,8 @@ def getTotalScore(userID, gameMode):
|
|||
gameMode -- int value, see gameModes
|
||||
return -- total score
|
||||
"""
|
||||
|
||||
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):
|
||||
"""
|
||||
|
@ -135,10 +126,8 @@ def getAccuracy(userID, gameMode):
|
|||
gameMode -- int value, see gameModes
|
||||
return -- accuracy
|
||||
"""
|
||||
|
||||
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):
|
||||
"""
|
||||
|
@ -150,13 +139,12 @@ def getGameRank(userID, 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:
|
||||
return 0
|
||||
else:
|
||||
return result["position"]
|
||||
|
||||
|
||||
def getPlaycount(userID, gameMode):
|
||||
"""
|
||||
Get userID's playcount relative to gameMode
|
||||
|
@ -167,8 +155,7 @@ def getPlaycount(userID, 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):
|
||||
"""
|
||||
|
@ -178,8 +165,7 @@ def getUsername(userID):
|
|||
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):
|
||||
"""
|
||||
|
@ -202,7 +188,6 @@ def getFriendList(userID):
|
|||
# Return friend IDs
|
||||
return friends
|
||||
|
||||
|
||||
def addFriend(userID, friendID):
|
||||
"""
|
||||
Add friendID to userID's friend list
|
||||
|
@ -216,7 +201,7 @@ def addFriend(userID, friendID):
|
|||
return
|
||||
|
||||
# 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
|
||||
|
||||
# Set new value
|
||||
|
@ -230,7 +215,6 @@ def removeFriend(userID, friendID):
|
|||
userID -- user
|
||||
friendID -- old friend
|
||||
"""
|
||||
|
||||
# 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. ¯\_(ツ)_/¯
|
||||
glob.db.execute("DELETE FROM users_relationships WHERE user1 = %s AND user2 = %s", [userID, friendID])
|
||||
|
@ -245,8 +229,7 @@ def getCountry(userID):
|
|||
userID -- user
|
||||
return -- country code (two letters)
|
||||
"""
|
||||
|
||||
return glob.db.fetch("SELECT country FROM users_stats WHERE id = %s", [userID])["country"]
|
||||
return glob.db.fetch("SELECT country FROM users_stats WHERE id = %s LIMIT 1", [userID])["country"]
|
||||
|
||||
def getPP(userID, gameMode):
|
||||
"""
|
||||
|
@ -257,7 +240,7 @@ def getPP(userID, 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):
|
||||
"""
|
||||
|
@ -266,7 +249,7 @@ def setCountry(userID, country):
|
|||
userID -- userID
|
||||
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):
|
||||
"""
|
||||
|
@ -275,7 +258,7 @@ def getShowCountry(userID):
|
|||
userID -- userID
|
||||
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:
|
||||
return False
|
||||
return generalFunctions.stringToBool(country)
|
||||
|
@ -292,25 +275,42 @@ def saveBanchoSession(userID, ip):
|
|||
"""
|
||||
Save userid and ip of this token in bancho_sessions table.
|
||||
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])
|
||||
|
||||
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:
|
||||
glob.db.execute("DELETE FROM bancho_sessions WHERE userid = %s AND ip = %s", [userID, ip])
|
||||
except:
|
||||
log.warning("Token for user: {} ip: {} doesn't exist".format(userID, ip))
|
||||
|
||||
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])
|
||||
return True if result is not None else False
|
||||
|
||||
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:
|
||||
return False
|
||||
|
||||
|
@ -353,7 +353,7 @@ def isAllowed(userID):
|
|||
userID -- id of the user
|
||||
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:
|
||||
return (result["privileges"] & privileges.USER_NORMAL) and (result["privileges"] & privileges.USER_PUBLIC)
|
||||
else:
|
||||
|
@ -366,7 +366,7 @@ def isRestricted(userID):
|
|||
userID -- id of the user
|
||||
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:
|
||||
return (result["privileges"] & privileges.USER_NORMAL) and not (result["privileges"] & privileges.USER_PUBLIC)
|
||||
else:
|
||||
|
@ -379,7 +379,7 @@ def isBanned(userID):
|
|||
userID -- id of the user
|
||||
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:
|
||||
return not (result["privileges"] & 3 > 0)
|
||||
else:
|
||||
|
@ -392,7 +392,7 @@ def ban(userID):
|
|||
userID -- id of user
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
|
@ -400,7 +400,7 @@ def unban(userID):
|
|||
|
||||
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):
|
||||
"""
|
||||
|
@ -409,7 +409,7 @@ def restrict(userID):
|
|||
userID -- id of user
|
||||
"""
|
||||
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):
|
||||
"""
|
||||
|
@ -427,7 +427,7 @@ def getPrivileges(userID):
|
|||
userID -- id of user
|
||||
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:
|
||||
return result["privileges"]
|
||||
else:
|
||||
|
@ -440,10 +440,10 @@ def setPrivileges(userID, priv):
|
|||
userID -- id of user
|
||||
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):
|
||||
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:
|
||||
return False
|
||||
groupPrivileges = groupPrivileges["privileges"]
|
||||
|
@ -465,7 +465,7 @@ def appendNotes(userID, notes, addNl = True):
|
|||
"""
|
||||
if addNl == True:
|
||||
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):
|
||||
|
|
|
@ -19,7 +19,7 @@ from objects import glob
|
|||
from helpers import chatHelper as chat
|
||||
import raven
|
||||
|
||||
class Client:
|
||||
class Client():
|
||||
"""
|
||||
IRC Client object
|
||||
"""
|
||||
|
@ -43,6 +43,7 @@ class Client:
|
|||
self.socket = sock
|
||||
(self.ip, self.port) = sock.getpeername()
|
||||
self.username = ""
|
||||
self.banchoUsername = ""
|
||||
self.supposedUsername = ""
|
||||
self.joinedChannels = []
|
||||
|
||||
|
@ -275,12 +276,12 @@ class Client:
|
|||
return
|
||||
|
||||
# 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")
|
||||
return
|
||||
|
||||
# Make sure we are not connected to Bancho
|
||||
token = glob.tokens.getTokenFromUsername(nick)
|
||||
token = glob.tokens.getTokenFromUsername(chat.fixUsernameForBancho(nick))
|
||||
if token != None:
|
||||
self.reply("433 * {} :Nickname is already in use".format(nick))
|
||||
return
|
||||
|
@ -293,6 +294,7 @@ class Client:
|
|||
|
||||
# Everything seems fine, set username (nickname)
|
||||
self.username = nick
|
||||
self.banchoUsername = chat.fixUsernameForBancho(self.username)
|
||||
elif command == "USER":
|
||||
# Ignore USER command, we use nickname only
|
||||
return
|
||||
|
@ -307,7 +309,7 @@ class Client:
|
|||
# If we now have a valid username, connect to bancho and send IRC welcome stuff
|
||||
if self.username != "":
|
||||
# Bancho connection
|
||||
chat.IRCConnect(self.username)
|
||||
chat.IRCConnect(self.banchoUsername)
|
||||
|
||||
# IRC reply
|
||||
self.replyCode(1, "Welcome to the Internet Relay Network")
|
||||
|
@ -329,7 +331,7 @@ class Client:
|
|||
return
|
||||
|
||||
# Get bancho token object
|
||||
token = glob.tokens.getTokenFromUsername(self.username)
|
||||
token = glob.tokens.getTokenFromUsername(self.banchoUsername)
|
||||
if token == None:
|
||||
return
|
||||
|
||||
|
@ -354,7 +356,7 @@ class Client:
|
|||
continue
|
||||
|
||||
# Attempt to join the channel
|
||||
response = chat.IRCJoinChannel(self.username, channel)
|
||||
response = chat.IRCJoinChannel(self.banchoUsername, channel)
|
||||
if response == 0:
|
||||
# Joined successfully
|
||||
self.joinedChannels.append(channel)
|
||||
|
@ -376,7 +378,7 @@ class Client:
|
|||
token = glob.tokens.getTokenFromUserID(user)
|
||||
if token == None:
|
||||
continue
|
||||
usernames.append(token.username)
|
||||
usernames.append(chat.fixUsernameForIRC(token.username))
|
||||
usernames = " ".join(usernames)
|
||||
|
||||
# Send IRC users lis
|
||||
|
@ -394,7 +396,7 @@ class Client:
|
|||
return
|
||||
|
||||
# Get bancho token object
|
||||
token = glob.tokens.getTokenFromUsername(self.username)
|
||||
token = glob.tokens.getTokenFromUsername(self.banchoUsername)
|
||||
if token == None:
|
||||
return
|
||||
|
||||
|
@ -409,7 +411,7 @@ class Client:
|
|||
continue
|
||||
|
||||
# Attempt to part the channel
|
||||
response = chat.IRCPartChannel(self.username, channel)
|
||||
response = chat.IRCPartChannel(self.banchoUsername, channel)
|
||||
if response == 0:
|
||||
# No errors, remove channel from joinedChannels
|
||||
self.joinedChannels.remove(channel)
|
||||
|
@ -433,7 +435,7 @@ class Client:
|
|||
message = arguments[1]
|
||||
|
||||
# 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:
|
||||
self.replyCode(404, "Cannot send to channel", channel=recipient)
|
||||
return
|
||||
|
@ -453,7 +455,6 @@ class Client:
|
|||
for _, value in self.server.clients.items():
|
||||
if recipient in value.joinedChannels and value != self:
|
||||
value.message(":{} PRIVMSG {} :{}".format(self.username, recipient, message))
|
||||
#self.messageChannel(recipient, command, "{} :{}".format(recipient, message))
|
||||
else:
|
||||
# Private message (IRC)
|
||||
for _, value in self.server.clients.items():
|
||||
|
@ -513,7 +514,7 @@ class Client:
|
|||
|
||||
|
||||
|
||||
class Server:
|
||||
class Server():
|
||||
def __init__(self, port):
|
||||
self.host = socket.getfqdn("127.0.0.1")[:63]
|
||||
self.port = port
|
||||
|
@ -529,7 +530,7 @@ class Server:
|
|||
for _, value in self.clients.items():
|
||||
if value.username == username:
|
||||
value.disconnect(callLogout=False)
|
||||
break# or dictionary changes size during iteration
|
||||
break # or dictionary changes size during iteration
|
||||
|
||||
def banchoJoinChannel(self, username, channel):
|
||||
"""
|
||||
|
@ -538,6 +539,7 @@ class Server:
|
|||
username -- username of bancho user
|
||||
channel -- joined channel name
|
||||
"""
|
||||
username = chat.fixUsernameForIRC(username)
|
||||
for _, value in self.clients.items():
|
||||
if channel in value.joinedChannels:
|
||||
value.message(":{} JOIN {}".format(username, channel))
|
||||
|
@ -549,6 +551,7 @@ class Server:
|
|||
username -- username of bancho user
|
||||
channel -- joined channel name
|
||||
"""
|
||||
username = chat.fixUsernameForIRC(username)
|
||||
for _, value in self.clients.items():
|
||||
if channel in value.joinedChannels:
|
||||
value.message(":{} PART {}".format(username, channel))
|
||||
|
@ -561,6 +564,8 @@ class Server:
|
|||
to -- receiver username
|
||||
message -- text of the message
|
||||
"""
|
||||
fro = chat.fixUsernameForIRC(fro)
|
||||
to = chat.fixUsernameForIRC(to)
|
||||
if to.startswith("#"):
|
||||
# Public message
|
||||
for _, value in self.clients.items():
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
# TODO: Rewrite this shit
|
||||
from objects import glob
|
||||
from helpers import generalFunctions
|
||||
|
||||
class banchoConfig:
|
||||
class banchoConfig():
|
||||
"""
|
||||
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)
|
||||
|
||||
[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:
|
||||
try:
|
||||
self.loadSettings()
|
||||
except:
|
||||
raise
|
||||
|
||||
|
||||
def loadSettings(self):
|
||||
"""
|
||||
(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["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["loginNotification"] = glob.db.fetch("SELECT value_string FROM bancho_settings WHERE name = 'login_notification'")["value_string"]
|
||||
|
||||
|
||||
def setMaintenance(self, maintenance):
|
||||
"""
|
||||
Turn on/off bancho maintenance mode. Write new value to db too
|
||||
|
||||
maintenance -- if True, turn on maintenance mode. If false, turn it off
|
||||
"""
|
||||
|
||||
self.config["banchoMaintenance"] = maintenance
|
||||
glob.db.execute("UPDATE bancho_settings SET value_int = %s WHERE name = 'bancho_maintenance'", [int(maintenance)])
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from objects import glob
|
||||
|
||||
class channel:
|
||||
class 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
|
||||
hidden -- if True, channel won't be shown in channels list
|
||||
"""
|
||||
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.publicRead = publicRead
|
||||
|
@ -33,25 +32,21 @@ class channel:
|
|||
elif self.name.startswith("#multi_"):
|
||||
self.clientName = "#multiplayer"
|
||||
|
||||
|
||||
def userJoin(self, userID):
|
||||
"""
|
||||
Add a user to connected users
|
||||
|
||||
userID -- user ID that joined the channel
|
||||
"""
|
||||
|
||||
if userID not in self.connectedUsers:
|
||||
self.connectedUsers.append(userID)
|
||||
|
||||
|
||||
def userPart(self, userID):
|
||||
"""
|
||||
Remove a user from connected users
|
||||
|
||||
userID -- user ID that left the channel
|
||||
"""
|
||||
|
||||
if userID in self.connectedUsers:
|
||||
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)):
|
||||
glob.channels.removeChannel(self.name)
|
||||
|
||||
|
||||
def getConnectedUsers(self):
|
||||
"""
|
||||
Get connected user IDs list
|
||||
|
@ -69,7 +63,6 @@ class channel:
|
|||
"""
|
||||
return self.connectedUsers
|
||||
|
||||
|
||||
def getConnectedUsersCount(self):
|
||||
"""
|
||||
Count connected users
|
||||
|
|
|
@ -2,16 +2,14 @@ from objects import glob
|
|||
from objects import channel
|
||||
from helpers import logHelper as log
|
||||
|
||||
class channelList:
|
||||
class channelList():
|
||||
"""
|
||||
Channel list
|
||||
|
||||
channels -- dictionary. key: channel name, value: channel object
|
||||
"""
|
||||
|
||||
channels = {}
|
||||
|
||||
|
||||
def loadChannels(self):
|
||||
"""
|
||||
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
|
||||
self.addChannel(i["name"], i["description"], publicRead, publicWrite)
|
||||
|
||||
|
||||
def addChannel(self, name, description, publicRead, publicWrite, temp = False, hidden = False):
|
||||
"""
|
||||
Add a channel object to channels dictionary
|
||||
|
@ -42,7 +39,6 @@ class channelList:
|
|||
self.channels[name] = channel.channel(name, description, publicRead, publicWrite, temp, hidden)
|
||||
log.info("Created channel {}".format(name))
|
||||
|
||||
|
||||
def addTempChannel(self, name):
|
||||
"""
|
||||
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)
|
||||
log.info("Created temp channel {}".format(name))
|
||||
|
||||
|
||||
def removeChannel(self, name):
|
||||
"""
|
||||
Removes a channel from channels list
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
class chatFilters:
|
||||
class chatFilters():
|
||||
def __init__(self, fileName="filters.txt"):
|
||||
self.filters = {}
|
||||
self.loadFilters(fileName)
|
||||
|
|
|
@ -17,12 +17,10 @@ def connect():
|
|||
glob.tokens.enqueueAll(serverPackets.userPanel(999))
|
||||
glob.tokens.enqueueAll(serverPackets.userStats(999))
|
||||
|
||||
|
||||
def disconnect():
|
||||
"""Remove FokaBot from connected users"""
|
||||
glob.tokens.deleteToken(glob.tokens.getTokenFromUserID(999))
|
||||
|
||||
|
||||
def fokabotResponse(fro, chan, message):
|
||||
"""
|
||||
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:])
|
||||
|
||||
# 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 helpers import logHelper as log
|
||||
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"""
|
||||
matchID = 0
|
||||
inProgress = False
|
||||
|
@ -21,7 +33,7 @@ class match:
|
|||
beatmapName = ""
|
||||
beatmapID = 0
|
||||
beatmapMD5 = ""
|
||||
slots = [] # list of dictionaries {"status": 0, "team": 0, "userID": -1, "mods": 0, "loaded": False, "skip": False, "complete": False}
|
||||
slots = []
|
||||
hostUserID = 0
|
||||
gameMode = gameModes.std
|
||||
matchScoringType = matchScoringTypes.score
|
||||
|
@ -46,7 +58,10 @@ class match:
|
|||
self.inProgress = False
|
||||
self.mods = 0
|
||||
self.matchName = matchName
|
||||
self.matchPassword = matchPassword
|
||||
if matchPassword != "":
|
||||
self.matchPassword = generalFunctions.stringMd5(matchPassword)
|
||||
else:
|
||||
self.matchPassword = ""
|
||||
self.beatmapID = beatmapID
|
||||
self.beatmapName = beatmapName
|
||||
self.beatmapMD5 = beatmapMD5
|
||||
|
@ -60,12 +75,11 @@ class match:
|
|||
# Create all slots and reset them
|
||||
self.slots = []
|
||||
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
|
||||
glob.channels.addTempChannel("#multi_{}".format(self.matchID))
|
||||
|
||||
|
||||
def getMatchData(self):
|
||||
"""
|
||||
Return binary match data structure for packetHelper
|
||||
|
@ -85,15 +99,15 @@ class match:
|
|||
|
||||
# Slots status IDs, always 16 elements
|
||||
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
|
||||
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
|
||||
for i in range(0,16):
|
||||
uid = self.slots[i]["userID"]
|
||||
uid = self.slots[i].userID
|
||||
if uid > -1:
|
||||
struct.append([uid, dataTypes.uInt32])
|
||||
|
||||
|
@ -109,15 +123,13 @@ class match:
|
|||
# Slot mods if free mod is enabled
|
||||
if self.matchModMode == matchModModes.freeMod:
|
||||
for i in range(0,16):
|
||||
struct.append([self.slots[i]["mods"], dataTypes.uInt32])
|
||||
struct.append([self.slots[i].mods, dataTypes.uInt32])
|
||||
|
||||
# Seed idk
|
||||
struct.append([self.seed, dataTypes.uInt32])
|
||||
|
||||
return struct
|
||||
|
||||
|
||||
|
||||
def setHost(self, newHost):
|
||||
"""
|
||||
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 slotStatus != None:
|
||||
self.slots[slotID]["status"] = slotStatus
|
||||
self.slots[slotID].status = slotStatus
|
||||
|
||||
if slotTeam != None:
|
||||
self.slots[slotID]["team"] = slotTeam
|
||||
self.slots[slotID].team = slotTeam
|
||||
|
||||
if slotUserID != None:
|
||||
self.slots[slotID]["userID"] = slotUserID
|
||||
self.slots[slotID].userID = slotUserID
|
||||
|
||||
if slotMods != None:
|
||||
self.slots[slotID]["mods"] = slotMods
|
||||
self.slots[slotID].mods = slotMods
|
||||
|
||||
if slotLoaded != None:
|
||||
self.slots[slotID]["loaded"] = slotLoaded
|
||||
self.slots[slotID].loaded = slotLoaded
|
||||
|
||||
if slotSkip != None:
|
||||
self.slots[slotID]["skip"] = slotSkip
|
||||
self.slots[slotID].skip = slotSkip
|
||||
|
||||
if slotComplete != None:
|
||||
self.slots[slotID]["complete"] = slotComplete
|
||||
|
||||
self.slots[slotID].complete = slotComplete
|
||||
|
||||
def setSlotMods(self, slotID, mods):
|
||||
"""
|
||||
|
@ -182,7 +193,6 @@ class match:
|
|||
self.sendUpdate()
|
||||
log.info("MPROOM{}: Slot{} mods changed to {}".format(self.matchID, slotID, mods))
|
||||
|
||||
|
||||
def toggleSlotReady(self, slotID):
|
||||
"""
|
||||
Switch slotID ready/not ready status
|
||||
|
@ -191,14 +201,14 @@ class match:
|
|||
slotID -- slot number
|
||||
"""
|
||||
# Update ready status and setnd update
|
||||
oldStatus = self.slots[slotID]["status"]
|
||||
oldStatus = self.slots[slotID].status
|
||||
if oldStatus == slotStatuses.ready:
|
||||
newStatus = slotStatuses.notReady
|
||||
else:
|
||||
newStatus = slotStatuses.ready
|
||||
self.setSlot(slotID, newStatus, None, None, None)
|
||||
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):
|
||||
"""
|
||||
|
@ -208,13 +218,13 @@ class match:
|
|||
slotID -- slot number
|
||||
"""
|
||||
# Get token of user in that slot (if there's someone)
|
||||
if self.slots[slotID]["userID"] > -1:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[slotID]["userID"])
|
||||
if self.slots[slotID].userID > -1:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[slotID].userID)
|
||||
else:
|
||||
token = None
|
||||
|
||||
# Check if slot is already locked
|
||||
if self.slots[slotID]["status"] == slotStatuses.locked:
|
||||
if self.slots[slotID].status == slotStatuses.locked:
|
||||
newStatus = slotStatuses.free
|
||||
else:
|
||||
newStatus = slotStatuses.locked
|
||||
|
@ -240,33 +250,31 @@ class match:
|
|||
return
|
||||
|
||||
# Set loaded to True
|
||||
self.slots[slotID]["loaded"] = True
|
||||
self.slots[slotID].loaded = True
|
||||
log.info("MPROOM{}: User {} loaded".format(self.matchID, userID))
|
||||
|
||||
# Check all loaded
|
||||
total = 0
|
||||
loaded = 0
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["status"] == slotStatuses.playing:
|
||||
if self.slots[i].status == slotStatuses.playing:
|
||||
total+=1
|
||||
if self.slots[i]["loaded"] == True:
|
||||
if self.slots[i].loaded == True:
|
||||
loaded+=1
|
||||
|
||||
if total == loaded:
|
||||
self.allPlayersLoaded()
|
||||
|
||||
|
||||
def allPlayersLoaded(self):
|
||||
"""Send allPlayersLoaded packet to every playing usr in match"""
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["userID"] > -1 and self.slots[i]["status"] == slotStatuses.playing:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"])
|
||||
if self.slots[i].userID > -1 and self.slots[i].status == slotStatuses.playing:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[i].userID)
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.allPlayersLoaded())
|
||||
|
||||
log.info("MPROOM{}: All players loaded! Match starting...".format(self.matchID))
|
||||
|
||||
|
||||
def playerSkip(self, userID):
|
||||
"""
|
||||
Set a player skip status to True
|
||||
|
@ -278,13 +286,13 @@ class match:
|
|||
return
|
||||
|
||||
# Set skip to True
|
||||
self.slots[slotID]["skip"] = True
|
||||
self.slots[slotID].skip = True
|
||||
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):
|
||||
uid = self.slots[i]["userID"]
|
||||
if self.slots[i]["status"] == slotStatuses.playing and uid > -1:
|
||||
uid = self.slots[i].userID
|
||||
if (self.slots[i].status & slotStatuses.playing > 0) and uid > -1:
|
||||
token = glob.tokens.getTokenFromUserID(uid)
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.playerSkipped(uid))
|
||||
|
@ -293,9 +301,9 @@ class match:
|
|||
total = 0
|
||||
skipped = 0
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["status"] == slotStatuses.playing:
|
||||
if self.slots[i].status == slotStatuses.playing:
|
||||
total+=1
|
||||
if self.slots[i]["skip"] == True:
|
||||
if self.slots[i].skip == True:
|
||||
skipped+=1
|
||||
|
||||
if total == skipped:
|
||||
|
@ -304,8 +312,8 @@ class match:
|
|||
def allPlayersSkipped(self):
|
||||
"""Send allPlayersSkipped packet to every playing usr in match"""
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["userID"] > -1 and self.slots[i]["status"] == slotStatuses.playing:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"])
|
||||
if self.slots[i].userID > -1 and self.slots[i].status == slotStatuses.playing:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[i].userID)
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.allPlayersSkipped())
|
||||
|
||||
|
@ -329,9 +337,9 @@ class match:
|
|||
total = 0
|
||||
completed = 0
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["status"] == slotStatuses.playing:
|
||||
if self.slots[i].status == slotStatuses.playing:
|
||||
total+=1
|
||||
if self.slots[i]["complete"] == True:
|
||||
if self.slots[i].complete == True:
|
||||
completed+=1
|
||||
|
||||
if total == completed:
|
||||
|
@ -345,38 +353,34 @@ class match:
|
|||
|
||||
# Reset slots
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["userID"] > -1 and self.slots[i]["status"] == slotStatuses.playing:
|
||||
self.slots[i]["status"] = slotStatuses.notReady
|
||||
self.slots[i]["loaded"] = False
|
||||
self.slots[i]["skip"] = False
|
||||
self.slots[i]["complete"] = False
|
||||
if self.slots[i].userID > -1 and self.slots[i].status == slotStatuses.playing:
|
||||
self.slots[i].status = slotStatuses.notReady
|
||||
self.slots[i].loaded = False
|
||||
self.slots[i].skip = False
|
||||
self.slots[i].complete = False
|
||||
|
||||
# Send match update
|
||||
self.sendUpdate()
|
||||
|
||||
# Send match complete
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["userID"] > -1:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"])
|
||||
if self.slots[i].userID > -1:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[i].userID)
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.matchComplete())
|
||||
|
||||
# Console output
|
||||
log.info("MPROOM{}: Match completed".format(self.matchID))
|
||||
|
||||
|
||||
|
||||
def getUserSlotID(self, userID):
|
||||
"""
|
||||
Get slot ID occupied by userID
|
||||
|
||||
return -- slot id if found, None if user is not in room
|
||||
"""
|
||||
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["userID"] == userID:
|
||||
if self.slots[i].userID == userID:
|
||||
return i
|
||||
|
||||
return None
|
||||
|
||||
def userJoin(self, userID):
|
||||
|
@ -389,7 +393,7 @@ class match:
|
|||
|
||||
# Find first free slot
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["status"] == slotStatuses.free:
|
||||
if self.slots[i].status == slotStatuses.free:
|
||||
# Occupy slot
|
||||
self.setSlot(i, slotStatuses.notReady, 0, userID, 0)
|
||||
|
||||
|
@ -409,7 +413,6 @@ class match:
|
|||
|
||||
userID -- user if of the user
|
||||
"""
|
||||
|
||||
# Make sure the user is in room
|
||||
slotID = self.getUserSlotID(userID)
|
||||
if slotID == None:
|
||||
|
@ -429,7 +432,7 @@ class match:
|
|||
if userID == self.hostUserID:
|
||||
# Give host to someone else
|
||||
for i in range(0,16):
|
||||
uid = self.slots[i]["userID"]
|
||||
uid = self.slots[i].userID
|
||||
if uid > -1:
|
||||
self.setHost(uid)
|
||||
break
|
||||
|
@ -440,7 +443,6 @@ class match:
|
|||
# Console output
|
||||
log.info("MPROOM{}: {} left the room".format(self.matchID, userID))
|
||||
|
||||
|
||||
def userChangeSlot(self, userID, newSlotID):
|
||||
"""
|
||||
Change userID slot to newSlotID
|
||||
|
@ -448,24 +450,23 @@ class match:
|
|||
userID -- user that changed slot
|
||||
newSlotID -- slot id of new slot
|
||||
"""
|
||||
|
||||
# Make sure the user is in room
|
||||
oldSlotID = self.getUserSlotID(userID)
|
||||
if oldSlotID == None:
|
||||
return
|
||||
|
||||
# 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
|
||||
|
||||
# Get old slot data
|
||||
oldData = self.slots[oldSlotID].copy()
|
||||
oldData = copy.deepcopy(self.slots[oldSlotID])
|
||||
|
||||
# Free old slot
|
||||
self.setSlot(oldSlotID, slotStatuses.free, 0, -1, 0)
|
||||
|
||||
# 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
|
||||
self.sendUpdate()
|
||||
|
@ -479,12 +480,15 @@ class match:
|
|||
|
||||
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
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["userID"] > -1:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"])
|
||||
if self.slots[i].userID > -1:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[i].userID)
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.changeMatchPassword(self.matchPassword))
|
||||
|
||||
|
@ -494,7 +498,6 @@ class match:
|
|||
# Console output
|
||||
log.info("MPROOM{}: Password changed to {}".format(self.matchID, self.matchPassword))
|
||||
|
||||
|
||||
def changeMatchMods(self, mods):
|
||||
"""
|
||||
Set match global mods
|
||||
|
@ -531,7 +534,7 @@ class match:
|
|||
slotID -- ID of slot
|
||||
"""
|
||||
# Make sure there is someone in that slot
|
||||
uid = self.slots[slotID]["userID"]
|
||||
uid = self.slots[slotID].userID
|
||||
if uid == -1:
|
||||
return
|
||||
|
||||
|
@ -541,7 +544,6 @@ class match:
|
|||
# Send updates
|
||||
self.sendUpdate()
|
||||
|
||||
|
||||
def playerFailed(self, userID):
|
||||
"""
|
||||
Send userID's failed packet to everyone in match
|
||||
|
@ -555,7 +557,7 @@ class match:
|
|||
|
||||
# Send packet to everyone
|
||||
for i in range(0,16):
|
||||
uid = self.slots[i]["userID"]
|
||||
uid = self.slots[i].userID
|
||||
if uid > -1:
|
||||
token = glob.tokens.getTokenFromUserID(uid)
|
||||
if token != None:
|
||||
|
@ -564,7 +566,6 @@ class match:
|
|||
# Console output
|
||||
log.info("MPROOM{}: {} has failed!".format(self.matchID, userID))
|
||||
|
||||
|
||||
def invite(self, fro, to):
|
||||
"""
|
||||
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)
|
||||
chat.sendMessage(token=froToken, to=toToken.username, message=message)
|
||||
|
||||
|
||||
def countUsers(self):
|
||||
"""
|
||||
Return how many players are in that match
|
||||
|
||||
return -- number of users
|
||||
"""
|
||||
|
||||
c = 0
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["userID"] > -1:
|
||||
if self.slots[i].userID > -1:
|
||||
c+=1
|
||||
|
||||
return c
|
||||
|
||||
def changeTeam(self, userID):
|
||||
|
@ -614,15 +612,15 @@ class match:
|
|||
return
|
||||
|
||||
# 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.sendUpdate()
|
||||
|
||||
def sendUpdate(self):
|
||||
# Send to users in room
|
||||
for i in range(0,16):
|
||||
if self.slots[i]["userID"] > -1:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[i]["userID"])
|
||||
if self.slots[i].userID > -1:
|
||||
token = glob.tokens.getTokenFromUserID(self.slots[i].userID)
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.updateMatch(self.matchID))
|
||||
|
||||
|
@ -645,10 +643,10 @@ class match:
|
|||
# We have teams, check if they are valid
|
||||
firstTeam = -1
|
||||
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:
|
||||
firstTeam = self.slots[i]["team"]
|
||||
elif firstTeam != self.slots[i]["teams"]:
|
||||
firstTeam = self.slots[i].team
|
||||
elif firstTeam != self.slots[i].team:
|
||||
log.info("MPROOM{}: Teams are valid".format(self.matchID))
|
||||
return True
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ from objects import match
|
|||
from objects import glob
|
||||
from constants import serverPackets
|
||||
|
||||
class matchList:
|
||||
class matchList():
|
||||
matches = {}
|
||||
usersInLobby = []
|
||||
lastID = 1
|
||||
|
@ -32,49 +32,43 @@ class matchList:
|
|||
self.matches[matchID] = match.match(matchID, matchName, matchPassword, beatmapID, beatmapName, beatmapMD5, gameMode, hostUserID)
|
||||
return matchID
|
||||
|
||||
|
||||
def lobbyUserJoin(self, userID):
|
||||
"""
|
||||
Add userID to users in lobby
|
||||
|
||||
userID -- user who joined mp lobby
|
||||
"""
|
||||
|
||||
# Make sure the user is not already in mp lobby
|
||||
if userID not in self.usersInLobby:
|
||||
# We don't need to join #lobby, client will automatically send a packet for it
|
||||
self.usersInLobby.append(userID)
|
||||
|
||||
|
||||
def lobbyUserPart(self, userID):
|
||||
"""
|
||||
Remove userID from users in lobby
|
||||
|
||||
userID -- user who left mp lobby
|
||||
"""
|
||||
|
||||
# Make sure the user is in mp lobby
|
||||
if userID in self.usersInLobby:
|
||||
# Part lobby and #lobby channel
|
||||
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
|
||||
if __matchID not in self.matches:
|
||||
if matchID not in self.matches:
|
||||
return
|
||||
|
||||
# Remove match object
|
||||
self.matches.pop(__matchID)
|
||||
self.matches.pop(matchID)
|
||||
|
||||
# Send match dispose packet to everyone in lobby
|
||||
for i in self.usersInLobby:
|
||||
token = glob.tokens.getTokenFromUserID(i)
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.disposeMatch(__matchID))
|
||||
token.enqueue(serverPackets.disposeMatch(matchID))
|
||||
|
|
|
@ -8,33 +8,9 @@ from objects import glob
|
|||
import uuid
|
||||
import time
|
||||
import threading
|
||||
from helpers import logHelper as log
|
||||
from helpers import chatHelper as chat
|
||||
|
||||
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
|
||||
"""
|
||||
|
||||
|
||||
class token():
|
||||
def __init__(self, userID, token = None, ip = "", irc = False, timeOffset = 0):
|
||||
"""
|
||||
Create a token object and set userID and token
|
||||
|
@ -44,8 +20,8 @@ class token:
|
|||
if not passed, token will be generated
|
||||
ip -- client ip. optional.
|
||||
irc -- if True, set this token as IRC client. optional.
|
||||
timeOffset -- the time offset from UTC for this user. optional.
|
||||
"""
|
||||
|
||||
# Set stuff
|
||||
self.userID = userID
|
||||
self.username = userHelper.getUsername(self.userID)
|
||||
|
@ -71,7 +47,6 @@ class token:
|
|||
self.tillerino = [0,0,-1.0] # beatmap, mods, acc
|
||||
self.silenceEndTime = 0
|
||||
self.queue = bytes()
|
||||
self.osuDirectAlert = False # NOTE: Remove this when osu!direct will be fixed
|
||||
|
||||
# Spam protection
|
||||
self.spamRate = 0
|
||||
|
@ -102,14 +77,14 @@ class token:
|
|||
if ip != "":
|
||||
userHelper.saveBanchoSession(self.userID, self.ip)
|
||||
|
||||
def enqueue(self, __bytes):
|
||||
def enqueue(self, bytes):
|
||||
"""
|
||||
Add bytes (packets) to queue
|
||||
|
||||
__bytes -- (packet) bytes to enqueue
|
||||
bytes -- (packet) bytes to enqueue
|
||||
"""
|
||||
if self.irc == False:
|
||||
self.queue += __bytes
|
||||
self.queue += bytes
|
||||
|
||||
|
||||
def resetQueue(self):
|
||||
|
@ -117,95 +92,140 @@ class token:
|
|||
self.queue = bytes()
|
||||
|
||||
|
||||
def joinChannel(self, __channel):
|
||||
"""Add __channel to joined channels list
|
||||
def joinChannel(self, channel):
|
||||
"""
|
||||
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:
|
||||
self.joinedChannels.append(__channel)
|
||||
def partChannel(self, channel):
|
||||
"""
|
||||
Remove channel from joined channels list
|
||||
|
||||
channel -- channel name
|
||||
"""
|
||||
if channel in self.joinedChannels:
|
||||
self.joinedChannels.remove(channel)
|
||||
|
||||
def partChannel(self, __channel):
|
||||
"""Remove __channel from joined channels list
|
||||
|
||||
__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
|
||||
def setLocation(self, location):
|
||||
"""
|
||||
Set location (latitude and longitude)
|
||||
|
||||
location -- [latitude, longitude]
|
||||
"""
|
||||
self.location = location
|
||||
|
||||
def getLatitude(self):
|
||||
"""Get latitude
|
||||
|
||||
return -- latitude"""
|
||||
"""
|
||||
Get latitude
|
||||
|
||||
return -- latitude
|
||||
"""
|
||||
return self.location[0]
|
||||
|
||||
|
||||
def getLongitude(self):
|
||||
"""Get longitude
|
||||
"""
|
||||
Get longitude
|
||||
|
||||
return -- longitude"""
|
||||
return -- longitude
|
||||
"""
|
||||
return self.location[1]
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
||||
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
|
||||
|
||||
# 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):
|
||||
"""Add userID to our spectators
|
||||
|
||||
userID -- new spectator userID"""
|
||||
"""
|
||||
Add userID to our spectators
|
||||
|
||||
userID -- new spectator userID
|
||||
"""
|
||||
# Add userID to spectators if not already in
|
||||
if userID not in self.spectators:
|
||||
self.spectators.append(userID)
|
||||
|
||||
|
||||
def removeSpectator(self, userID):
|
||||
"""Remove userID from our spectators
|
||||
|
||||
userID -- old spectator userID"""
|
||||
"""
|
||||
Remove userID from our spectators
|
||||
|
||||
userID -- old spectator userID
|
||||
"""
|
||||
# Remove spectator
|
||||
if userID in self.spectators:
|
||||
self.spectators.remove(userID)
|
||||
|
||||
def setCountry(self, countryID):
|
||||
"""
|
||||
Set country to countryID
|
||||
|
||||
def setCountry(self, __countryID):
|
||||
"""Set country to __countryID
|
||||
|
||||
__countryID -- numeric country ID. See countryHelper.py"""
|
||||
|
||||
self.country = __countryID
|
||||
|
||||
countryID -- numeric country ID. See countryHelper.py
|
||||
"""
|
||||
self.country = countryID
|
||||
|
||||
def getCountry(self):
|
||||
"""Get numeric country ID
|
||||
|
||||
return -- numeric country ID. See countryHelper.py"""
|
||||
"""
|
||||
Get numeric country ID
|
||||
|
||||
return -- numeric country ID. See countryHelper.py
|
||||
"""
|
||||
return self.country
|
||||
|
||||
|
||||
def updatePingTime(self):
|
||||
"""Update latest ping time"""
|
||||
self.pingTime = int(time.time())
|
||||
|
@ -214,23 +234,24 @@ class token:
|
|||
"""Set a new away message"""
|
||||
self.awayMessage = __awayMessage
|
||||
|
||||
def joinMatch(self, __matchID):
|
||||
def joinMatch(self, matchID):
|
||||
"""
|
||||
Set match to matchID
|
||||
|
||||
__matchID -- new match ID
|
||||
matchID -- new match ID
|
||||
"""
|
||||
self.matchID = __matchID
|
||||
|
||||
def partMatch(self):
|
||||
"""Set match to -1"""
|
||||
self.matchID = -1
|
||||
self.matchID = matchID
|
||||
|
||||
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
|
||||
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())
|
||||
|
||||
# Logout event
|
||||
|
|
|
@ -3,10 +3,9 @@ from objects import glob
|
|||
import time
|
||||
import threading
|
||||
from events import logoutEvent
|
||||
from helpers import logHelper as log
|
||||
from helpers import userHelper
|
||||
|
||||
class tokenList:
|
||||
class tokenList():
|
||||
"""
|
||||
List of connected osu tokens
|
||||
|
||||
|
@ -27,7 +26,6 @@ class tokenList:
|
|||
irc -- if True, set this token as IRC client
|
||||
return -- token object
|
||||
"""
|
||||
|
||||
newToken = osuToken.token(userID, ip=ip, irc=irc, timeOffset=timeOffset)
|
||||
self.tokens[newToken.token] = newToken
|
||||
return newToken
|
||||
|
@ -38,7 +36,6 @@ class tokenList:
|
|||
|
||||
token -- token string
|
||||
"""
|
||||
|
||||
if token in self.tokens:
|
||||
# Delete session from DB
|
||||
if self.tokens[token].ip != "":
|
||||
|
@ -47,16 +44,13 @@ class tokenList:
|
|||
# Pop token from list
|
||||
self.tokens.pop(token)
|
||||
|
||||
|
||||
def getUserIDFromToken(self, token):
|
||||
"""
|
||||
Get user ID from a token
|
||||
|
||||
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
|
||||
if token not in self.tokens:
|
||||
return False
|
||||
|
@ -64,7 +58,6 @@ class tokenList:
|
|||
# Get userID associated to that token
|
||||
return self.tokens[token].userID
|
||||
|
||||
|
||||
def getTokenFromUserID(self, userID):
|
||||
"""
|
||||
Get token from a user ID
|
||||
|
@ -72,7 +65,6 @@ class tokenList:
|
|||
userID -- user ID to find
|
||||
return -- False if not found, token object if found
|
||||
"""
|
||||
|
||||
# Make sure the token exists
|
||||
for _, value in self.tokens.items():
|
||||
if value.userID == userID:
|
||||
|
@ -81,7 +73,6 @@ class tokenList:
|
|||
# Return none if not found
|
||||
return None
|
||||
|
||||
|
||||
def getTokenFromUsername(self, username):
|
||||
"""
|
||||
Get token from a username
|
||||
|
@ -89,7 +80,6 @@ class tokenList:
|
|||
username -- username to find
|
||||
return -- False if not found, token object if found
|
||||
"""
|
||||
|
||||
# lowercase
|
||||
who = username.lower()
|
||||
|
||||
|
@ -101,7 +91,6 @@ class tokenList:
|
|||
# Return none if not found
|
||||
return None
|
||||
|
||||
|
||||
def deleteOldTokens(self, userID):
|
||||
"""
|
||||
Delete old userID's tokens if found
|
||||
|
@ -114,11 +103,6 @@ class tokenList:
|
|||
if value.userID == userID:
|
||||
# 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.pop(key)
|
||||
|
||||
# break or items() function throws errors
|
||||
#break
|
||||
|
||||
|
||||
def multipleEnqueue(self, packet, who, but = False):
|
||||
"""
|
||||
|
@ -128,7 +112,6 @@ class tokenList:
|
|||
who -- userIDs array
|
||||
but -- if True, enqueue to everyone but users in who array
|
||||
"""
|
||||
|
||||
for _, value in self.tokens.items():
|
||||
shouldEnqueue = False
|
||||
if value.userID in who and not but:
|
||||
|
@ -145,22 +128,20 @@ class tokenList:
|
|||
|
||||
packet -- packet bytes to enqueue
|
||||
"""
|
||||
|
||||
for _, value in self.tokens.items():
|
||||
value.enqueue(packet)
|
||||
|
||||
def usersTimeoutCheckLoop(self, __timeoutTime = 100, __checkTime = 100):
|
||||
def usersTimeoutCheckLoop(self, timeoutTime = 100, checkTime = 100):
|
||||
"""
|
||||
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!
|
||||
|
||||
__timeoutTime - seconds of inactivity required to disconnect someone (Default: 100)
|
||||
__checkTime - seconds between loops (Default: 100)
|
||||
timeoutTime - seconds of inactivity required to disconnect someone (Default: 100)
|
||||
checkTime - seconds between loops (Default: 100)
|
||||
"""
|
||||
|
||||
timedOutTokens = [] # timed out users
|
||||
timeoutLimit = time.time()-__timeoutTime
|
||||
timeoutLimit = time.time()-timeoutTime
|
||||
for key, value in self.tokens.items():
|
||||
# Check timeout (fokabot is ignored)
|
||||
if value.pingTime < timeoutLimit and value.userID != 999 and value.irc == False:
|
||||
|
@ -174,15 +155,13 @@ class tokenList:
|
|||
logoutEvent.handle(self.tokens[i], None)
|
||||
|
||||
# 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):
|
||||
"""
|
||||
Reset spam rate every 10 seconds.
|
||||
CALL THIS FUNCTION ONLY ONCE!
|
||||
"""
|
||||
#log.debug("Resetting spam protection...")
|
||||
|
||||
# Reset spamRate for every token
|
||||
for _, value in self.tokens.items():
|
||||
value.spamRate = 0
|
||||
|
|
Loading…
Reference in New Issue
Block a user