.BANCHO. Add streams and streamList object, add 'main' stream

This commit is contained in:
Nyo 2016-10-01 21:19:03 +02:00
parent 2213a99147
commit 40264ceffe
14 changed files with 163 additions and 23 deletions

View File

@ -86,3 +86,6 @@ class forceUpdateException(Exception):
class loginLockedException(Exception): class loginLockedException(Exception):
pass pass
class unknownStreamException(Exception):
pass

View File

@ -28,7 +28,7 @@ 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 TODO: Change False to None, because False doesn't make any sense
""" """
def instantRestart(fro, chan, message): def instantRestart(fro, chan, message):
glob.tokens.enqueueAll(serverPackets.notification("We are restarting Bancho. Be right back!")) glob.streams.broadcast("main", serverPackets.notification("We are restarting Bancho. Be right back!"))
systemHelper.scheduleShutdown(0, True, delay=1) systemHelper.scheduleShutdown(0, True, delay=1)
return False return False
@ -69,7 +69,7 @@ def roll(fro, chan, message):
# return random.choice(["yes", "no", "maybe"]) # return random.choice(["yes", "no", "maybe"])
def alert(fro, chan, message): def alert(fro, chan, message):
glob.tokens.enqueueAll(serverPackets.notification(' '.join(message[:]))) glob.streams.broadcast("main", serverPackets.notification(' '.join(message[:])))
return False return False
def alertUser(fro, chan, message): def alertUser(fro, chan, message):
@ -311,11 +311,11 @@ def systemReload(fro, chan, message):
glob.chatFilters.loadFilters() glob.chatFilters.loadFilters()
# Send new channels and new bottom icon to everyone # Send new channels and new bottom icon to everyone
glob.tokens.enqueueAll(serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"])) glob.streams.broadcast("main", serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"]))
glob.tokens.enqueueAll(serverPackets.channelInfoEnd()) glob.streams.broadcast("main", serverPackets.channelInfoEnd())
for key, value in glob.channels.channels.items(): for key, value in glob.channels.channels.items():
if value.publicRead == True and value.hidden == False: if value.publicRead == True and value.hidden == False:
glob.tokens.enqueueAll(serverPackets.channelInfo(key)) glob.streams.broadcast("main", serverPackets.channelInfo(key))
return "Bancho settings reloaded!" return "Bancho settings reloaded!"
@ -341,7 +341,7 @@ def systemMaintenance(fro, chan, message):
if not value.admin: if not value.admin:
who.append(value.userID) who.append(value.userID)
glob.tokens.enqueueAll(serverPackets.notification("Our bancho server is in maintenance mode. Please try to login again later.")) glob.streams.broadcast("main", serverPackets.notification("Our bancho server is in maintenance mode. Please try to login again later."))
glob.tokens.multipleEnqueue(serverPackets.loginError(), who) glob.tokens.multipleEnqueue(serverPackets.loginError(), who)
msg = "The server is now in maintenance mode!" msg = "The server is now in maintenance mode!"
else: else:

View File

@ -205,7 +205,7 @@ def handle(tornadoRequest):
# Send to everyone our userpanel if we are not restricted # Send to everyone our userpanel if we are not restricted
if not responseToken.restricted: if not responseToken.restricted:
glob.tokens.enqueueAll(serverPackets.userPanel(userID)) glob.streams.broadcast("main", serverPackets.userPanel(userID))
# Set reponse data to right value and reset our queue # Set reponse data to right value and reset our queue
responseData = responseToken.queue responseData = responseToken.queue

View File

@ -25,8 +25,11 @@ def handle(userToken, _=None):
for i in userToken.joinedChannels: for i in userToken.joinedChannels:
chat.partChannel(token=userToken, channel=i) chat.partChannel(token=userToken, channel=i)
# Leave all joined streams
userToken.leaveAllStreams()
# Enqueue our disconnection to everyone else # Enqueue our disconnection to everyone else
glob.tokens.enqueueAll(serverPackets.userLogout(userID)) glob.streams.broadcast("main", serverPackets.userLogout(userID))
# Disconnect from IRC if needed # Disconnect from IRC if needed
if userToken.irc == True and glob.irc == True: if userToken.irc == True and glob.irc == True:

View File

@ -320,7 +320,7 @@ def IRCConnect(username):
return return
glob.tokens.deleteOldTokens(userID) glob.tokens.deleteOldTokens(userID)
glob.tokens.addToken(userID, irc=True) glob.tokens.addToken(userID, irc=True)
glob.tokens.enqueueAll(serverPackets.userPanel(userID)) glob.streams.broadcast("main", serverPackets.userPanel(userID))
log.info("{} logged in from IRC".format(username)) log.info("{} logged in from IRC".format(username))
def IRCDisconnect(username): def IRCDisconnect(username):

View File

@ -42,10 +42,10 @@ def scheduleShutdown(sendRestartTime, restart, message = "", delay=20):
# Send notification if set # Send notification if set
if message != "": if message != "":
glob.tokens.enqueueAll(serverPackets.notification(message)) glob.streams.broadcast("main", serverPackets.notification(message))
# Schedule server restart packet # Schedule server restart packet
threading.Timer(sendRestartTime, glob.tokens.enqueueAll, [serverPackets.banchoRestart(delay*2*1000)]).start() threading.Timer(sendRestartTime, glob.streams.broadcast, ["main", serverPackets.banchoRestart(delay*2*1000)]).start()
glob.restarting = True glob.restarting = True
# Restart/shutdown # Restart/shutdown

View File

@ -282,20 +282,21 @@ class Client:
return return
# Make sure we are not connected to Bancho # Make sure we are not connected to Bancho
token = glob.tokens.getTokenFromUsername(chat.fixUsernameForBancho(nick)) token = glob.tokens.getTokenFromUsername(chat.fixUsernameForBancho(nick), True)
if token is not None: if token is not None:
self.reply("433 * {} :Nickname is already in use".format(nick)) self.reply("433 * {} :Nickname is already in use".format(nick))
return return
# Make sure we are not already connected from IRC with that name
for _, value in self.server.clients.items():
if value.IRCUsername == self.IRCUsername and value != self:
self.reply("433 * {} :Nickname is already in use".format(nick))
return
# Everything seems fine, set username (nickname) # Everything seems fine, set username (nickname)
self.IRCUsername = nick # username for IRC self.IRCUsername = nick # username for IRC
self.banchoUsername = chat.fixUsernameForBancho(self.IRCUsername) # username for bancho self.banchoUsername = chat.fixUsernameForBancho(self.IRCUsername) # username for bancho
# Disconnect other IRC clients from the same user
for _, value in self.server.clients.items():
if value.IRCUsername.lower() == self.IRCUsername.lower() and value != self:
print("DISCONNECTERINOOOOOOOOOOOOOOOOOOOOO")
value.disconnect(quitmsg="Connected from another client")
return
elif command == "USER": elif command == "USER":
# Ignore USER command, we use nickname only # Ignore USER command, we use nickname only
return return

View File

@ -14,8 +14,8 @@ def connect():
"""Add FokaBot to connected users and send userpanel/stats packet to everyone""" """Add FokaBot to connected users and send userpanel/stats packet to everyone"""
token = glob.tokens.addToken(999) token = glob.tokens.addToken(999)
token.actionID = actions.IDLE token.actionID = actions.IDLE
glob.tokens.enqueueAll(serverPackets.userPanel(999)) glob.streams.broadcast("main", serverPackets.userPanel(999))
glob.tokens.enqueueAll(serverPackets.userStats(999)) glob.streams.broadcast("main", serverPackets.userStats(999))
def disconnect(): def disconnect():
"""Remove FokaBot from connected users""" """Remove FokaBot from connected users"""

View File

@ -5,6 +5,7 @@ from objects import channelList
from objects import matchList from objects import matchList
from objects import fileLocks from objects import fileLocks
from objects import fileBuffer from objects import fileBuffer
from objects import streamList
import time import time
try: try:
@ -42,3 +43,6 @@ sentry = False
irc = False irc = False
startTime = int(time.time()) startTime = int(time.time())
streams = streamList.streamList()

View File

@ -34,6 +34,7 @@ class token:
self.pingTime = self.loginTime self.pingTime = self.loginTime
self.timeOffset = timeOffset self.timeOffset = timeOffset
self.lock = threading.Lock() # Sync primitive self.lock = threading.Lock() # Sync primitive
self.streams = []
# Default variables # Default variables
self.spectators = [] self.spectators = []
@ -79,6 +80,9 @@ class token:
if ip != "": if ip != "":
userHelper.saveBanchoSession(self.userID, self.ip) userHelper.saveBanchoSession(self.userID, self.ip)
# Join main stream
self.joinStream("main")
def enqueue(self, bytes_): def enqueue(self, bytes_):
""" """
Add bytes (packets) to queue Add bytes (packets) to queue
@ -277,7 +281,7 @@ class token:
self.enqueue(serverPackets.silenceEndTime(seconds)) self.enqueue(serverPackets.silenceEndTime(seconds))
# Send silenced packet to everyone else # Send silenced packet to everyone else
glob.tokens.enqueueAll(serverPackets.userSilenced(self.userID)) glob.streams.broadcast("main", serverPackets.userSilenced(self.userID))
def spamProtection(self, increaseSpamRate = True): def spamProtection(self, increaseSpamRate = True):
""" """
@ -343,3 +347,17 @@ class token:
""" """
self.restricted = True self.restricted = True
chat.sendMessage("FokaBot",self.username, "Your account is currently in restricted mode. Please visit ripple's website for more information.") chat.sendMessage("FokaBot",self.username, "Your account is currently in restricted mode. Please visit ripple's website for more information.")
def joinStream(self, name):
glob.streams.join(name, self)
if name not in self.streams:
self.streams.append(name)
def leaveStream(self, name):
glob.streams.leave(name, self)
if name in self.streams:
self.streams.remove(name)
def leaveAllStreams(self):
for i in self.streams:
self.leaveStream(i)

39
objects/stream.py Normal file
View File

@ -0,0 +1,39 @@
class stream():
def __init__(self, name):
"""
Initialize a stream object
:param name: stream name
"""
self.name = name
self.clients = []
def addClient(self, client):
"""
Add a client to this stream if not already in
:param client: client (osuToken) object
:return:
"""
if client not in self.clients:
self.clients.append(client)
def removeClient(self, client):
"""
Remove a client from this stream if in
:param client: client (osuToken) object
:return:
"""
if client in self.clients:
self.clients.remove(client)
def broadcast(self, data):
"""
Send some data to all clients connected to this stream
:param data: data to send
:return:
"""
for i in self.clients:
i.enqueue(data)

63
objects/streamList.py Normal file
View File

@ -0,0 +1,63 @@
from objects import stream
class streamList():
def __init__(self):
self.streams = {}
def add(self, name):
"""
Create a new stream list if it doesn't already exist
:param name: stream name
:return:
"""
if name not in self.streams:
self.streams[name] = stream.stream(name)
def remove(self, name):
"""
Removes an existing stream and kick every user in it
:param name: stream name
:return:
"""
if name in self.streams:
for i in self.streams[name].clients:
i.leaveStream(name)
self.streams.pop(name)
def broadcast(self, streamName, data):
"""
Send some data to all clients in a stream
:param streamName: stream name
:param data: data to send
:return:
"""
if streamName not in self.streams:
return
self.streams[streamName].broadcast(data)
def join(self, streamName, client):
"""
Add a client to a stream
:param streamName: stream name
:param client: client (osuToken) object
:return:
"""
if streamName not in self.streams:
return
self.streams[streamName].addClient(client)
def leave(self, streamName, client):
"""
Remove a client from a stream
:param streamName: stream name
:param client: client (osuToken) object
:return:
"""
if streamName not in self.streams:
return
self.streams[streamName].removeClient(client)

View File

@ -58,7 +58,7 @@ class tokenList:
# Get userID associated to that token # Get userID associated to that token
return self.tokens[token].userID return self.tokens[token].userID
def getTokenFromUserID(self, userID): def getTokenFromUserID(self, userID, ignoreIRC=False):
""" """
Get token from a user ID Get token from a user ID
@ -68,12 +68,14 @@ class tokenList:
# Make sure the token exists # Make sure the token exists
for _, value in self.tokens.items(): for _, value in self.tokens.items():
if value.userID == userID: if value.userID == userID:
if ignoreIRC and value.irc:
continue
return value return value
# Return none if not found # Return none if not found
return None return None
def getTokenFromUsername(self, username): def getTokenFromUsername(self, username, ignoreIRC=False):
""" """
Get token from a username Get token from a username
@ -86,6 +88,8 @@ class tokenList:
# Make sure the token exists # Make sure the token exists
for _, value in self.tokens.items(): for _, value in self.tokens.items():
if value.username.lower() == who: if value.username.lower() == who:
if ignoreIRC and value.irc:
continue
return value return value
# Return none if not found # Return none if not found

5
pep.py
View File

@ -130,6 +130,11 @@ if __name__ == "__main__":
glob.channels.loadChannels() glob.channels.loadChannels()
consoleHelper.printDone() consoleHelper.printDone()
# Initialize stremas
consoleHelper.printNoNl("> Creating main stream... ")
glob.streams.add("main")
consoleHelper.printDone()
# Start fokabot # Start fokabot
consoleHelper.printNoNl("> Connecting FokaBot... ") consoleHelper.printNoNl("> Connecting FokaBot... ")
fokabot.connect() fokabot.connect()