Updated submodules

This commit is contained in:
Sunpy
2018-09-02 01:45:33 +02:00
21 changed files with 285 additions and 104 deletions

View File

@@ -2,6 +2,7 @@
from common import generalUtils
from constants import serverPackets
from objects import glob
from common.log import logUtils as log
class banchoConfig:
@@ -30,7 +31,12 @@ class banchoConfig:
"""
self.config["banchoMaintenance"] = generalUtils.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'bancho_maintenance'")["value_int"])
self.config["freeDirect"] = generalUtils.stringToBool(glob.db.fetch("SELECT value_int FROM bancho_settings WHERE name = 'free_direct'")["value_int"])
self.config["menuIcon"] = glob.db.fetch("SELECT value_string FROM bancho_settings WHERE name = 'menu_icon'")["value_string"]
mainMenuIcon = glob.db.fetch("SELECT file_id, url FROM main_menu_icons WHERE is_current = 1 LIMIT 1")
if mainMenuIcon is None:
self.config["menuIcon"] = ""
else:
imageURL = "https://i.ppy.sh/{}.png".format(mainMenuIcon["file_id"])
self.config["menuIcon"] = "{}|{}".format(imageURL, mainMenuIcon["url"])
self.config["loginNotification"] = glob.db.fetch("SELECT value_string FROM bancho_settings WHERE name = 'login_notification'")["value_string"]
@@ -57,5 +63,5 @@ class banchoConfig:
glob.streams.broadcast("main", serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"]))
glob.streams.broadcast("main", serverPackets.channelInfoEnd())
for key, value in glob.channels.channels.items():
if value.publicRead == True and value.hidden == False:
if value.publicRead and not value.hidden:
glob.streams.broadcast("main", serverPackets.channelInfo(key))

View File

@@ -1,3 +1,6 @@
import logging
from constants import exceptions
from objects import glob
class channel:
@@ -20,14 +23,22 @@ class channel:
self.temp = temp
self.hidden = hidden
# Client name (#spectator/#multiplayer)
self.clientName = self.name
if self.name.startswith("#spect_"):
self.clientName = "#spectator"
elif self.name.startswith("#multi_"):
self.clientName = "#multiplayer"
# Make Foka join the channel
fokaToken = glob.tokens.getTokenFromUserID(999)
if fokaToken is not None:
fokaToken.joinChannel(self)
try:
fokaToken.joinChannel(self)
except exceptions.userAlreadyInChannelException:
logging.warning("FokaBot has already joined channel {}".format(self.name))
@property
def isSpecial(self):
return any(self.name.startswith(x) for x in ("#spect_", "#multi_"))
@property
def clientName(self):
if self.name.startswith("#spect_"):
return "#spectator"
elif self.name.startswith("#multi_"):
return "#multiplayer"
return self.name

View File

@@ -66,6 +66,8 @@ class match:
self.isStarting = False
self._lock = threading.Lock()
self.createTime = int(time.time())
self.vinseID = None
self.bloodcatAlert = False
# Create all slots and reset them
self.slots = []
@@ -433,9 +435,26 @@ class match:
# Console output
log.info("MPROOM{}: Match completed".format(self.matchID))
# Set vinse id if needed
chanName = "#multi_{}".format(self.matchID)
if self.vinseID is None:
self.vinseID = (int(time.time()) // (60 * 15)) << 32 | self.matchID
chat.sendMessage("FokaBot", chanName, "Match history available [{} here]".format(
"https://vinse.ripple.moe/match/{}".format(self.vinseID)
))
if not self.bloodcatAlert:
chat.sendMessage(
"FokaBot",
chanName,
"Oh by the way, in case you're playing unranked or broken maps "
"that are now available through ripple's osu!direct, you can "
"type '!bloodcat' in the chat to get a download link for the "
"currently selected map from Bloodcat!"
)
self.bloodcatAlert = True
# If this is a tournament match, then we send a notification in the chat
# saying that the match has completed.
chanName = "#multi_{}".format(self.matchID)
if self.isTourney and (chanName in glob.channels.channels):
chat.sendMessage(glob.BOT_NAME, chanName, "Match has just finished.")

View File

@@ -1,6 +1,8 @@
import threading
import time
from common.sentry import sentry
from constants.exceptions import periodicLoopException
from objects import match
from objects import glob
from constants import serverPackets
@@ -67,6 +69,7 @@ class matchList:
del self.matches[matchID]
log.info("MPROOM{}: Room disposed manually".format(_match.matchID))
@sentry.capture()
def cleanupLoop(self):
"""
Start match cleanup loop.
@@ -76,21 +79,34 @@ class matchList:
This method starts an infinite loop, call it only once!
:return:
"""
log.debug("Checking empty matches")
t = int(time.time())
emptyMatches = []
try:
log.debug("Checking empty matches")
t = int(time.time())
emptyMatches = []
exceptions = []
# Collect all empty matches
for key, m in self.matches.items():
if [x for x in m.slots if x.user is not None]:
continue
if t - m.createTime >= 120:
log.debug("Match #{} marked for cleanup".format(m.matchID))
emptyMatches.append(m.matchID)
# Collect all empty matches
for key, m in self.matches.items():
if [x for x in m.slots if x.user is not None]:
continue
if t - m.createTime >= 120:
log.debug("Match #{} marked for cleanup".format(m.matchID))
emptyMatches.append(m.matchID)
# Dispose all empty matches
for matchID in emptyMatches:
self.disposeMatch(matchID)
# Dispose all empty matches
for matchID in emptyMatches:
try:
self.disposeMatch(matchID)
except Exception as e:
exceptions.append(e)
log.error(
"Something wrong happened while disposing a timed out match. Reporting to Sentry when "
"the loop ends."
)
# Schedule a new check (endless loop)
threading.Timer(30, self.cleanupLoop).start()
# Re-raise exception if needed
if exceptions:
raise periodicLoopException(exceptions)
finally:
# Schedule a new check (endless loop)
threading.Timer(30, self.cleanupLoop).start()

View File

@@ -141,7 +141,7 @@ class token:
"""
if channelObject.name in self.joinedChannels:
raise exceptions.userAlreadyInChannelException()
if channelObject.publicRead == False and self.admin == False:
if not channelObject.publicRead and not self.admin:
raise exceptions.channelNoPermissionsException()
self.joinedChannels.append(channelObject.name)
self.joinStream("chat/{}".format(channelObject.name))
@@ -212,10 +212,10 @@ class token:
# Create and join #spectator (#spect_userid) channel
glob.channels.addTempChannel("#spect_{}".format(host.userID))
chat.joinChannel(token=self, channel="#spect_{}".format(host.userID))
chat.joinChannel(token=self, channel="#spect_{}".format(host.userID), force=True)
if len(host.spectators) == 1:
# First spectator, send #spectator join to host too
chat.joinChannel(token=host, channel="#spect_{}".format(host.userID))
chat.joinChannel(token=host, channel="#spect_{}".format(host.userID), force=True)
# Send fellow spectator join to all clients
glob.streams.broadcast(streamName, serverPackets.fellowSpectatorJoined(self.userID))
@@ -265,14 +265,14 @@ class token:
# If nobody is spectating the host anymore, close #spectator channel
# and remove host from spect stream too
if len(hostToken.spectators) == 0:
chat.partChannel(token=hostToken, channel="#spect_{}".format(hostToken.userID), kick=True)
chat.partChannel(token=hostToken, channel="#spect_{}".format(hostToken.userID), kick=True, force=True)
hostToken.leaveStream(streamName)
# Console output
log.info("{} is no longer spectating {}. Current spectators: {}".format(self.username, self.spectatingUserID, hostToken.spectators))
# Part #spectator channel
chat.partChannel(token=self, channel="#spect_{}".format(self.spectatingUserID), kick=True)
chat.partChannel(token=self, channel="#spect_{}".format(self.spectatingUserID), kick=True, force=True)
# Set our spectating user to 0
self.spectating = None
@@ -318,7 +318,7 @@ class token:
# Set matchID, join stream, channel and send packet
self.matchID = matchID
self.joinStream(match.streamName)
chat.joinChannel(token=self, channel="#multi_{}".format(self.matchID))
chat.joinChannel(token=self, channel="#multi_{}".format(self.matchID), force=True)
self.enqueue(serverPackets.matchJoinSuccess(matchID))
if match.isTourney:
@@ -339,7 +339,7 @@ class token:
return
# Part #multiplayer channel and streams (/ and /playing)
chat.partChannel(token=self, channel="#multi_{}".format(self.matchID), kick=True)
chat.partChannel(token=self, channel="#multi_{}".format(self.matchID), kick=True, force=True)
self.leaveStream("multi/{}".format(self.matchID))
self.leaveStream("multi/{}/playing".format(self.matchID)) # optional

View File

@@ -5,11 +5,14 @@ import redis
from common.ripple import userUtils
from common.log import logUtils as log
from common.sentry import sentry
from constants import serverPackets
from constants.exceptions import periodicLoopException
from events import logoutEvent
from objects import glob
from objects import osuToken
class tokenList:
def __init__(self):
self.tokens = {}
@@ -171,6 +174,7 @@ class tokenList:
for _, value in self.tokens.items():
value.enqueue(packet)
@sentry.capture()
def usersTimeoutCheckLoop(self):
"""
Start timed out users disconnect loop.
@@ -178,27 +182,41 @@ class tokenList:
CALL THIS FUNCTION ONLY ONCE!
:return:
"""
log.debug("Checking timed out clients")
timedOutTokens = [] # timed out users
timeoutLimit = int(time.time()) - 100
for key, value in self.tokens.items():
# Check timeout (fokabot is ignored)
if value.pingTime < timeoutLimit and value.userID != 999 and value.irc == False and value.tournament == False:
# That user has timed out, add to disconnected tokens
# We can't delete it while iterating or items() throws an error
timedOutTokens.append(key)
try:
log.debug("Checking timed out clients")
exceptions = []
timedOutTokens = [] # timed out users
timeoutLimit = int(time.time()) - 100
for key, value in self.tokens.items():
# Check timeout (fokabot is ignored)
if value.pingTime < timeoutLimit and value.userID != 999 and not value.irc and not value.tournament:
# That user has timed out, add to disconnected tokens
# We can't delete it while iterating or items() throws an error
timedOutTokens.append(key)
# Delete timed out users from self.tokens
# i is token string (dictionary key)
for i in timedOutTokens:
log.debug("{} timed out!!".format(self.tokens[i].username))
self.tokens[i].enqueue(serverPackets.notification("Your connection to the server timed out."))
logoutEvent.handle(self.tokens[i], None)
del timedOutTokens
# Delete timed out users from self.tokens
# i is token string (dictionary key)
for i in timedOutTokens:
log.debug("{} timed out!!".format(self.tokens[i].username))
self.tokens[i].enqueue(serverPackets.notification("Your connection to the server timed out."))
try:
logoutEvent.handle(self.tokens[i], None)
except Exception as e:
exceptions.append(e)
log.error(
"Something wrong happened while disconnecting a timed out client. Reporting to Sentry "
"when the loop ends."
)
del timedOutTokens
# Schedule a new check (endless loop)
threading.Timer(100, self.usersTimeoutCheckLoop).start()
# Re-raise exceptions if needed
if exceptions:
raise periodicLoopException(exceptions)
finally:
# Schedule a new check (endless loop)
threading.Timer(100, self.usersTimeoutCheckLoop).start()
@sentry.capture()
def spamProtectionResetLoop(self):
"""
Start spam protection reset loop.
@@ -207,12 +225,13 @@ class tokenList:
:return:
"""
# Reset spamRate for every token
for _, value in self.tokens.items():
value.spamRate = 0
# Schedule a new check (endless loop)
threading.Timer(10, self.spamProtectionResetLoop).start()
try:
# Reset spamRate for every token
for _, value in self.tokens.items():
value.spamRate = 0
finally:
# Schedule a new check (endless loop)
threading.Timer(10, self.spamProtectionResetLoop).start()
def deleteBanchoSessions(self):
"""