.BANCHO. Use streams for public chat
This commit is contained in:
parent
c4a6c84cec
commit
44545c3bcb
|
@ -89,4 +89,10 @@ class unknownStreamException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class userTournamentException(Exception):
|
class userTournamentException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class userAlreadyInChannelException(Exception):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class userNotInChannelException(Exception):
|
||||||
pass
|
pass
|
|
@ -656,7 +656,7 @@ def pp(fro, chan, message):
|
||||||
pp = userUtils.getPP(token.userID, gameMode)
|
pp = userUtils.getPP(token.userID, gameMode)
|
||||||
return "You have {:,} pp".format(pp)
|
return "You have {:,} pp".format(pp)
|
||||||
|
|
||||||
def updateBeatmap(fro, chan, to):
|
def updateBeatmap(fro, chan, message):
|
||||||
try:
|
try:
|
||||||
# Run the command in PM only
|
# Run the command in PM only
|
||||||
if chan.startswith("#"):
|
if chan.startswith("#"):
|
||||||
|
|
|
@ -155,11 +155,13 @@ def channelJoinSuccess(userID, chan):
|
||||||
return packetHelper.buildPacket(packetIDs.server_channelJoinSuccess, [[chan, dataTypes.STRING]])
|
return packetHelper.buildPacket(packetIDs.server_channelJoinSuccess, [[chan, dataTypes.STRING]])
|
||||||
|
|
||||||
def channelInfo(chan):
|
def channelInfo(chan):
|
||||||
|
if chan not in glob.channels.channels:
|
||||||
|
return bytes()
|
||||||
channel = glob.channels.channels[chan]
|
channel = glob.channels.channels[chan]
|
||||||
return packetHelper.buildPacket(packetIDs.server_channelInfo, [
|
return packetHelper.buildPacket(packetIDs.server_channelInfo, [
|
||||||
[chan, dataTypes.STRING],
|
[channel.name, dataTypes.STRING],
|
||||||
[channel.description, dataTypes.STRING],
|
[channel.description, dataTypes.STRING],
|
||||||
[len(channel.connectedUsers), dataTypes.UINT16]
|
[len(glob.streams.streams["chat/{}".format(chan)].clients), dataTypes.UINT16]
|
||||||
])
|
])
|
||||||
|
|
||||||
def channelInfoEnd():
|
def channelInfoEnd():
|
||||||
|
|
|
@ -5,13 +5,13 @@ from objects import glob
|
||||||
|
|
||||||
def handle(userToken, _):
|
def handle(userToken, _):
|
||||||
# Get usertoken data
|
# Get usertoken data
|
||||||
userID = userToken.userID
|
|
||||||
username = userToken.username
|
username = userToken.username
|
||||||
|
|
||||||
# Remove user from users in lobby
|
# Remove user from users in lobby
|
||||||
userToken.leaveStream("lobby")
|
userToken.leaveStream("lobby")
|
||||||
|
|
||||||
# Part lobby channel
|
# Part lobby channel
|
||||||
|
# Done automatically by the client
|
||||||
chat.partChannel(channel="#lobby", token=userToken, kick=True)
|
chat.partChannel(channel="#lobby", token=userToken, kick=True)
|
||||||
|
|
||||||
# Console output
|
# Console output
|
||||||
|
|
|
@ -27,44 +27,32 @@ def joinChannel(userID = 0, channel = "", token = None, toIRC = True):
|
||||||
raise exceptions.userNotFoundException
|
raise exceptions.userNotFoundException
|
||||||
else:
|
else:
|
||||||
token = token
|
token = token
|
||||||
userID = token.userID
|
|
||||||
|
|
||||||
# Get usertoken data
|
|
||||||
username = token.username
|
|
||||||
|
|
||||||
# Normal channel, do check stuff
|
# Normal channel, do check stuff
|
||||||
# Make sure the channel exists
|
# Make sure the channel exists
|
||||||
if channel not in glob.channels.channels:
|
if channel not in glob.channels.channels:
|
||||||
raise exceptions.channelUnknownException
|
raise exceptions.channelUnknownException()
|
||||||
|
|
||||||
# Check channel permissions
|
|
||||||
channelObject = glob.channels.channels[channel]
|
|
||||||
if channelObject.publicRead == False and token.admin == False:
|
|
||||||
raise exceptions.channelNoPermissionsException
|
|
||||||
|
|
||||||
# Add our userID to users in that channel
|
|
||||||
channelObject.userJoin(userID)
|
|
||||||
|
|
||||||
# Add the channel to our joined channel
|
# Add the channel to our joined channel
|
||||||
token.joinChannel(channel)
|
token.joinChannel(glob.channels.channels[channel])
|
||||||
|
|
||||||
# Send channel joined (bancho). We use clientName here because of #multiplayer and #spectator channels
|
|
||||||
token.enqueue(serverPackets.channelJoinSuccess(userID, channelObject.clientName))
|
|
||||||
|
|
||||||
# Send channel joined (IRC)
|
# Send channel joined (IRC)
|
||||||
if glob.irc == True and toIRC == True:
|
if glob.irc == True and toIRC == True:
|
||||||
glob.ircServer.banchoJoinChannel(username, channel)
|
glob.ircServer.banchoJoinChannel(token.username, channel)
|
||||||
|
|
||||||
# Console output
|
# Console output
|
||||||
log.info("{} joined channel {}".format(username, channel))
|
log.info("{} joined channel {}".format(token.username, channel))
|
||||||
|
|
||||||
# IRC code return
|
# IRC code return
|
||||||
return 0
|
return 0
|
||||||
except exceptions.channelNoPermissionsException:
|
except exceptions.channelNoPermissionsException:
|
||||||
log.warning("{} attempted to join channel {}, but they have no read permissions".format(username, channel))
|
log.warning("{} attempted to join channel {}, but they have no read permissions".format(token.username, channel))
|
||||||
return 403
|
return 403
|
||||||
except exceptions.channelUnknownException:
|
except exceptions.channelUnknownException:
|
||||||
log.warning("{} attempted to join an unknown channel ({})".format(username, channel))
|
log.warning("{} attempted to join an unknown channel ({})".format(token.username, channel))
|
||||||
|
return 403
|
||||||
|
except exceptions.userAlreadyInChannelException:
|
||||||
|
log.warning("User {} already in channel {}".format(token.username, channel))
|
||||||
return 403
|
return 403
|
||||||
except exceptions.userNotFoundException:
|
except exceptions.userNotFoundException:
|
||||||
log.warning("User not connected to IRC/Bancho")
|
log.warning("User not connected to IRC/Bancho")
|
||||||
|
@ -82,6 +70,10 @@ def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = Fal
|
||||||
:return: 0 if joined or other IRC code in case of error. Needed only on IRC-side
|
:return: 0 if joined or other IRC code in case of error. Needed only on IRC-side
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
# Make sure the client is not drunk and sends partChannel when closing a PM tab
|
||||||
|
if not channel.startswith("#"):
|
||||||
|
return
|
||||||
|
|
||||||
# Get token if not defined
|
# Get token if not defined
|
||||||
if token is None:
|
if token is None:
|
||||||
token = glob.tokens.getTokenFromUserID(userID)
|
token = glob.tokens.getTokenFromUserID(userID)
|
||||||
|
@ -90,10 +82,6 @@ def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = Fal
|
||||||
raise exceptions.userNotFoundException
|
raise exceptions.userNotFoundException
|
||||||
else:
|
else:
|
||||||
token = token
|
token = token
|
||||||
userID = token.userID
|
|
||||||
|
|
||||||
# Get usertoken data
|
|
||||||
username = token.username
|
|
||||||
|
|
||||||
# Determine internal/client name if needed
|
# Determine internal/client name if needed
|
||||||
# (toclient is used clientwise for #multiplayer and #spectator channels)
|
# (toclient is used clientwise for #multiplayer and #spectator channels)
|
||||||
|
@ -113,12 +101,22 @@ def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = Fal
|
||||||
|
|
||||||
# Make sure the channel exists
|
# Make sure the channel exists
|
||||||
if channel not in glob.channels.channels:
|
if channel not in glob.channels.channels:
|
||||||
raise exceptions.channelUnknownException
|
raise exceptions.channelUnknownException()
|
||||||
|
|
||||||
|
# Make sure the user is in the channel
|
||||||
|
if channel not in token.joinedChannels:
|
||||||
|
raise exceptions.userNotInChannelException()
|
||||||
|
|
||||||
# Part channel (token-side and channel-side)
|
# Part channel (token-side and channel-side)
|
||||||
channelObject = glob.channels.channels[channel]
|
channelObject = glob.channels.channels[channel]
|
||||||
token.partChannel(channel)
|
token.partChannel(channelObject)
|
||||||
channelObject.userPart(userID)
|
|
||||||
|
# Delete temporary channel if everyone left
|
||||||
|
if "chat/{}".format(channelObject.name) in glob.streams.streams:
|
||||||
|
sas = len(glob.streams.streams["chat/{}".format(channelObject.name)].clients)
|
||||||
|
print(str(sas - 1))
|
||||||
|
if channelObject.temp == True and sas - 1 == 0:
|
||||||
|
glob.channels.removeChannel(channelObject.name)
|
||||||
|
|
||||||
# Force close tab if needed
|
# Force close tab if needed
|
||||||
# NOTE: Maybe always needed, will check later
|
# NOTE: Maybe always needed, will check later
|
||||||
|
@ -127,16 +125,19 @@ def partChannel(userID = 0, channel = "", token = None, toIRC = True, kick = Fal
|
||||||
|
|
||||||
# IRC part
|
# IRC part
|
||||||
if glob.irc == True and toIRC == True:
|
if glob.irc == True and toIRC == True:
|
||||||
glob.ircServer.banchoPartChannel(username, channel)
|
glob.ircServer.banchoPartChannel(token.username, channel)
|
||||||
|
|
||||||
# Console output
|
# Console output
|
||||||
log.info("{} parted channel {} ({})".format(username, channel, channelClient))
|
log.info("{} parted channel {} ({})".format(token.username, channel, channelClient))
|
||||||
|
|
||||||
# Return IRC code
|
# Return IRC code
|
||||||
return 0
|
return 0
|
||||||
except exceptions.channelUnknownException:
|
except exceptions.channelUnknownException:
|
||||||
log.warning("{} attempted to part an unknown channel ({})".format(username, channel))
|
log.warning("{} attempted to part an unknown channel ({})".format(token.username, channel))
|
||||||
return 403
|
return 403
|
||||||
|
except exceptions.userNotInChannelException:
|
||||||
|
log.warning("{} attempted to part {}, but he's not in that channel".format(token.username, channel))
|
||||||
|
return 442
|
||||||
except exceptions.userNotFoundException:
|
except exceptions.userNotFoundException:
|
||||||
log.warning("User not connected to IRC/Bancho")
|
log.warning("User not connected to IRC/Bancho")
|
||||||
return 442 # idk
|
return 442 # idk
|
||||||
|
@ -153,7 +154,7 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||||
:return: 0 if joined or other IRC code in case of error. Needed only on IRC-side
|
:return: 0 if joined or other IRC code in case of error. Needed only on IRC-side
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
tokenString = ""
|
#tokenString = ""
|
||||||
# Get token object if not passed
|
# Get token object if not passed
|
||||||
if token is None:
|
if token is None:
|
||||||
token = glob.tokens.getTokenFromUsername(fro)
|
token = glob.tokens.getTokenFromUsername(fro)
|
||||||
|
@ -162,11 +163,7 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||||
else:
|
else:
|
||||||
# token object alredy passed, get its string and its username (fro)
|
# token object alredy passed, get its string and its username (fro)
|
||||||
fro = token.username
|
fro = token.username
|
||||||
tokenString = token.token
|
#tokenString = token.token
|
||||||
|
|
||||||
# Set some variables
|
|
||||||
userID = token.userID
|
|
||||||
username = token.username
|
|
||||||
|
|
||||||
# Make sure this is not a tournament client
|
# Make sure this is not a tournament client
|
||||||
if token.tournament:
|
if token.tournament:
|
||||||
|
@ -185,7 +182,7 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||||
toClient = to
|
toClient = to
|
||||||
if to == "#spectator":
|
if to == "#spectator":
|
||||||
if token.spectating is None:
|
if token.spectating is None:
|
||||||
s = userID
|
s = token.userID
|
||||||
else:
|
else:
|
||||||
s = token.spectatingUserID
|
s = token.spectatingUserID
|
||||||
to = "#spect_{}".format(s)
|
to = "#spect_{}".format(s)
|
||||||
|
@ -203,7 +200,7 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||||
message = glob.chatFilters.filterMessage(message)
|
message = glob.chatFilters.filterMessage(message)
|
||||||
|
|
||||||
# Build packet bytes
|
# Build packet bytes
|
||||||
packet = serverPackets.sendMessage(username, toClient, message)
|
packet = serverPackets.sendMessage(token.username, toClient, message)
|
||||||
|
|
||||||
# Send the message
|
# Send the message
|
||||||
isChannel = to.startswith("#")
|
isChannel = to.startswith("#")
|
||||||
|
@ -211,35 +208,28 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||||
# CHANNEL
|
# CHANNEL
|
||||||
# Make sure the channel exists
|
# Make sure the channel exists
|
||||||
if to not in glob.channels.channels:
|
if to not in glob.channels.channels:
|
||||||
raise exceptions.channelUnknownException
|
raise exceptions.channelUnknownException()
|
||||||
|
|
||||||
# Make sure the channel is not in moderated mode
|
# Make sure the channel is not in moderated mode
|
||||||
if glob.channels.channels[to].moderated == True and token.admin == False:
|
if glob.channels.channels[to].moderated == True and token.admin == False:
|
||||||
raise exceptions.channelModeratedException
|
raise exceptions.channelModeratedException()
|
||||||
|
|
||||||
# Make sure we have write permissions
|
# Make sure we have write permissions
|
||||||
if glob.channels.channels[to].publicWrite == False and token.admin == False:
|
if glob.channels.channels[to].publicWrite == False and token.admin == False:
|
||||||
raise exceptions.channelNoPermissionsException
|
raise exceptions.channelNoPermissionsException()
|
||||||
|
|
||||||
# Everything seems fine, build recipients list and send packet
|
# Everything seems fine, build recipients list and send packet
|
||||||
recipients = glob.channels.channels[to].connectedUsers[:]
|
glob.streams.broadcast("chat/{}".format(to), packet, but=[token.token])
|
||||||
for key, value in glob.tokens.tokens.items():
|
|
||||||
# Skip our client and irc clients
|
|
||||||
if key == tokenString or value.irc == True:
|
|
||||||
continue
|
|
||||||
# Send to this client if it's connected to the channel
|
|
||||||
if value.userID in recipients:
|
|
||||||
value.enqueue(packet)
|
|
||||||
else:
|
else:
|
||||||
# USER
|
# USER
|
||||||
# Make sure recipient user is connected
|
# Make sure recipient user is connected
|
||||||
recipientToken = glob.tokens.getTokenFromUsername(to)
|
recipientToken = glob.tokens.getTokenFromUsername(to)
|
||||||
if recipientToken is None:
|
if recipientToken is None:
|
||||||
raise exceptions.userNotFoundException
|
raise exceptions.userNotFoundException()
|
||||||
|
|
||||||
# Make sure the recipient is not a tournament client
|
# Make sure the recipient is not a tournament client
|
||||||
if recipientToken.tournament:
|
#if recipientToken.tournament:
|
||||||
raise exceptions.userTournamentException()
|
# raise exceptions.userTournamentException()
|
||||||
|
|
||||||
# Make sure the recipient is not restricted or we are FokaBot
|
# Make sure the recipient is not restricted or we are FokaBot
|
||||||
if recipientToken.restricted == True and fro.lower() != "fokabot":
|
if recipientToken.restricted == True and fro.lower() != "fokabot":
|
||||||
|
@ -248,7 +238,7 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||||
# TODO: Make sure the recipient has not disabled PMs for non-friends or he's our friend
|
# TODO: Make sure the recipient has not disabled PMs for non-friends or he's our friend
|
||||||
|
|
||||||
# Away check
|
# Away check
|
||||||
if recipientToken.awayCheck(userID):
|
if recipientToken.awayCheck(token.userID):
|
||||||
sendMessage(to, fro, "\x01ACTION is away: {message}\x01".format(code=chr(int(1)), message=recipientToken.awayMessage))
|
sendMessage(to, fro, "\x01ACTION is away: {message}\x01".format(code=chr(int(1)), message=recipientToken.awayMessage))
|
||||||
|
|
||||||
# Check message templates (mods/admins only)
|
# Check message templates (mods/admins only)
|
||||||
|
@ -263,38 +253,38 @@ def sendMessage(fro = "", to = "", message = "", token = None, toIRC = True):
|
||||||
glob.ircServer.banchoMessage(fro, to, message)
|
glob.ircServer.banchoMessage(fro, to, message)
|
||||||
|
|
||||||
# Spam protection (ignore FokaBot)
|
# Spam protection (ignore FokaBot)
|
||||||
if userID > 999:
|
if token.userID > 999:
|
||||||
token.spamProtection()
|
token.spamProtection()
|
||||||
|
|
||||||
# Fokabot message
|
# Fokabot message
|
||||||
if isChannel == True or to.lower() == "fokabot":
|
if isChannel == True or to.lower() == "fokabot":
|
||||||
fokaMessage = fokabot.fokabotResponse(username, to, message)
|
fokaMessage = fokabot.fokabotResponse(token.username, to, message)
|
||||||
if fokaMessage:
|
if fokaMessage:
|
||||||
sendMessage("FokaBot", to if isChannel else fro, fokaMessage)
|
sendMessage("FokaBot", to if isChannel else fro, fokaMessage)
|
||||||
|
|
||||||
# File and discord logs (public chat only)
|
# File and discord logs (public chat only)
|
||||||
if to.startswith("#") and not (message.startswith("\x01ACTION is playing") and to.startswith("#spect_")):
|
if to.startswith("#") and not (message.startswith("\x01ACTION is playing") and to.startswith("#spect_")):
|
||||||
log.chat("{fro} @ {to}: {message}".format(fro=username, to=to, message=str(message.encode("utf-8"))))
|
log.chat("{fro} @ {to}: {message}".format(fro=token.username, to=to, message=str(message.encode("utf-8"))))
|
||||||
glob.schiavo.sendChatlog("**{fro} @ {to}:** {message}".format(fro=username, to=to, message=str(message.encode("utf-8"))[2:-1]))
|
glob.schiavo.sendChatlog("**{fro} @ {to}:** {message}".format(fro=token.username, to=to, message=str(message.encode("utf-8"))[2:-1]))
|
||||||
return 0
|
return 0
|
||||||
except exceptions.userSilencedException:
|
except exceptions.userSilencedException:
|
||||||
token.enqueue(serverPackets.silenceEndTime(token.getSilenceSecondsLeft()))
|
token.enqueue(serverPackets.silenceEndTime(token.getSilenceSecondsLeft()))
|
||||||
log.warning("{} tried to send a message during silence".format(username))
|
log.warning("{} tried to send a message during silence".format(token.username))
|
||||||
return 404
|
return 404
|
||||||
except exceptions.channelModeratedException:
|
except exceptions.channelModeratedException:
|
||||||
log.warning("{} tried to send a message to a channel that is in moderated mode ({})".format(username, to))
|
log.warning("{} tried to send a message to a channel that is in moderated mode ({})".format(token.username, to))
|
||||||
return 404
|
return 404
|
||||||
except exceptions.channelUnknownException:
|
except exceptions.channelUnknownException:
|
||||||
log.warning("{} tried to send a message to an unknown channel ({})".format(username, to))
|
log.warning("{} tried to send a message to an unknown channel ({})".format(token.username, to))
|
||||||
return 403
|
return 403
|
||||||
except exceptions.channelNoPermissionsException:
|
except exceptions.channelNoPermissionsException:
|
||||||
log.warning("{} tried to send a message to channel {}, but they have no write permissions".format(username, to))
|
log.warning("{} tried to send a message to channel {}, but they have no write permissions".format(token.username, to))
|
||||||
return 404
|
return 404
|
||||||
except exceptions.userRestrictedException:
|
except exceptions.userRestrictedException:
|
||||||
log.warning("{} tried to send a message {}, but the recipient is in restricted mode".format(username, to))
|
log.warning("{} tried to send a message {}, but the recipient is in restricted mode".format(token.username, to))
|
||||||
return 404
|
return 404
|
||||||
except exceptions.userTournamentException:
|
except exceptions.userTournamentException:
|
||||||
log.warning("{} tried to send a message {}, but the recipient is a tournament client".format(username, to))
|
log.warning("{} tried to send a message {}, but the recipient is a tournament client".format(token.username, to))
|
||||||
return 404
|
return 404
|
||||||
except exceptions.userNotFoundException:
|
except exceptions.userNotFoundException:
|
||||||
log.warning("User not connected to IRC/Bancho")
|
log.warning("User not connected to IRC/Bancho")
|
||||||
|
|
|
@ -18,7 +18,6 @@ class channel:
|
||||||
self.publicWrite = publicWrite
|
self.publicWrite = publicWrite
|
||||||
self.moderated = False
|
self.moderated = False
|
||||||
self.temp = temp
|
self.temp = temp
|
||||||
self.connectedUsers = [999] # Fokabot is always connected to every channels (otherwise it doesn't show up in IRC users list)
|
|
||||||
self.hidden = hidden
|
self.hidden = hidden
|
||||||
|
|
||||||
# Client name (#spectator/#multiplayer)
|
# Client name (#spectator/#multiplayer)
|
||||||
|
@ -28,27 +27,7 @@ class channel:
|
||||||
elif self.name.startswith("#multi_"):
|
elif self.name.startswith("#multi_"):
|
||||||
self.clientName = "#multiplayer"
|
self.clientName = "#multiplayer"
|
||||||
|
|
||||||
def userJoin(self, userID):
|
# Make Foka join the channel
|
||||||
"""
|
fokaToken = glob.tokens.getTokenFromUserID(999)
|
||||||
Add a user to connected users
|
if fokaToken is not None:
|
||||||
|
fokaToken.joinChannel(self)
|
||||||
:param userID:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
if userID not in self.connectedUsers:
|
|
||||||
self.connectedUsers.append(userID)
|
|
||||||
|
|
||||||
def userPart(self, userID):
|
|
||||||
"""
|
|
||||||
Remove a user from connected users
|
|
||||||
|
|
||||||
:param userID:
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
if userID in self.connectedUsers:
|
|
||||||
self.connectedUsers.remove(userID)
|
|
||||||
|
|
||||||
# Remove temp channels if empty or there's only fokabot connected
|
|
||||||
l = len(self.connectedUsers)
|
|
||||||
if self.temp == True and ((l == 0) or (l == 1 and 999 in self.connectedUsers)):
|
|
||||||
glob.channels.removeChannel(self.name)
|
|
|
@ -1,4 +1,5 @@
|
||||||
from common.log import logUtils as log
|
from common.log import logUtils as log
|
||||||
|
from constants import serverPackets
|
||||||
from objects import channel
|
from objects import channel
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
|
||||||
|
@ -34,6 +35,7 @@ class channelList:
|
||||||
:param hidden: if True, thic channel won't be shown in channels list
|
:param hidden: if True, thic channel won't be shown in channels list
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
|
glob.streams.add("chat/{}".format(name))
|
||||||
self.channels[name] = channel.channel(name, description, publicRead, publicWrite, temp, hidden)
|
self.channels[name] = channel.channel(name, description, publicRead, publicWrite, temp, hidden)
|
||||||
log.info("Created channel {}".format(name))
|
log.info("Created channel {}".format(name))
|
||||||
|
|
||||||
|
@ -47,6 +49,7 @@ class channelList:
|
||||||
"""
|
"""
|
||||||
if name in self.channels:
|
if name in self.channels:
|
||||||
return False
|
return False
|
||||||
|
glob.streams.add("chat/{}".format(name))
|
||||||
self.channels[name] = channel.channel(name, "Chat", True, True, True, True)
|
self.channels[name] = channel.channel(name, "Chat", True, True, True, True)
|
||||||
log.info("Created temp channel {}".format(name))
|
log.info("Created temp channel {}".format(name))
|
||||||
|
|
||||||
|
@ -60,5 +63,8 @@ class channelList:
|
||||||
if name not in self.channels:
|
if name not in self.channels:
|
||||||
log.debug("{} is not in channels list".format(name))
|
log.debug("{} is not in channels list".format(name))
|
||||||
return
|
return
|
||||||
|
glob.streams.broadcast("chat/{}".format(name), serverPackets.channelKicked(name))
|
||||||
|
glob.streams.dispose("chat/{}".format(name))
|
||||||
|
glob.streams.remove("chat/{}".format(name))
|
||||||
self.channels.pop(name)
|
self.channels.pop(name)
|
||||||
log.info("Removed channel {}".format(name))
|
log.info("Removed channel {}".format(name))
|
||||||
|
|
|
@ -5,6 +5,7 @@ import uuid
|
||||||
from common.constants import gameModes, actions
|
from common.constants import gameModes, actions
|
||||||
from common.log import logUtils as log
|
from common.log import logUtils as log
|
||||||
from common.ripple import userUtils
|
from common.ripple import userUtils
|
||||||
|
from constants import exceptions
|
||||||
from constants import serverPackets
|
from constants import serverPackets
|
||||||
from events import logoutEvent
|
from events import logoutEvent
|
||||||
from helpers import chatHelper as chat
|
from helpers import chatHelper as chat
|
||||||
|
@ -98,7 +99,12 @@ class token:
|
||||||
|
|
||||||
:param bytes: (packet) bytes to enqueue
|
:param bytes: (packet) bytes to enqueue
|
||||||
"""
|
"""
|
||||||
# TODO: reduce max queue size
|
|
||||||
|
# Never enqueue for IRC clients or Foka
|
||||||
|
if self.irc or self.userID < 999:
|
||||||
|
return
|
||||||
|
|
||||||
|
# Avoid memory leaks
|
||||||
if len(bytes_) < 10 * 10 ** 6:
|
if len(bytes_) < 10 * 10 ** 6:
|
||||||
self.queue += bytes_
|
self.queue += bytes_
|
||||||
else:
|
else:
|
||||||
|
@ -108,23 +114,30 @@ class token:
|
||||||
"""Resets the queue. Call when enqueued packets have been sent"""
|
"""Resets the queue. Call when enqueued packets have been sent"""
|
||||||
self.queue = bytes()
|
self.queue = bytes()
|
||||||
|
|
||||||
def joinChannel(self, channel):
|
def joinChannel(self, channelObject):
|
||||||
"""
|
"""
|
||||||
Add channel to joined channels list
|
Join a channel
|
||||||
|
|
||||||
:param channel: channel name
|
:param channelObject: channel object
|
||||||
|
:raises: exceptions.userAlreadyInChannelException()
|
||||||
|
exceptions.channelNoPermissionsException()
|
||||||
"""
|
"""
|
||||||
if channel not in self.joinedChannels:
|
if channelObject.name in self.joinedChannels:
|
||||||
self.joinedChannels.append(channel)
|
raise exceptions.userAlreadyInChannelException()
|
||||||
|
if channelObject.publicRead == False and self.admin == False:
|
||||||
|
raise exceptions.channelNoPermissionsException()
|
||||||
|
self.joinedChannels.append(channelObject.name)
|
||||||
|
self.joinStream("chat/{}".format(channelObject.name))
|
||||||
|
self.enqueue(serverPackets.channelJoinSuccess(self.userID, channelObject.clientName))
|
||||||
|
|
||||||
def partChannel(self, channel):
|
def partChannel(self, channelObject):
|
||||||
"""
|
"""
|
||||||
Remove channel from joined channels list
|
Remove channel from joined channels list
|
||||||
|
|
||||||
:param channel: channel name
|
:param channelObject: channel object
|
||||||
"""
|
"""
|
||||||
if channel in self.joinedChannels:
|
self.joinedChannels.remove(channelObject.name)
|
||||||
self.joinedChannels.remove(channel)
|
self.leaveStream("chat/{}".format(channelObject.name))
|
||||||
|
|
||||||
def setLocation(self, latitude, longitude):
|
def setLocation(self, latitude, longitude):
|
||||||
"""
|
"""
|
||||||
|
@ -233,7 +246,7 @@ class token:
|
||||||
chat.partChannel(token=self, channel="#spect_{}".format(self.spectatingUserID), kick=True)
|
chat.partChannel(token=self, channel="#spect_{}".format(self.spectatingUserID), kick=True)
|
||||||
|
|
||||||
# Console output
|
# Console output
|
||||||
log.info("{} is no longer spectating {}".format(self.username, self.spectatingUserID))
|
log.info("{} is no longer spectating {}. Current spectators: {}".format(self.username, self.spectatingUserID, hostToken.spectators))
|
||||||
|
|
||||||
# Set our spectating user to 0
|
# Set our spectating user to 0
|
||||||
self.spectating = None
|
self.spectating = None
|
||||||
|
|
|
@ -43,15 +43,29 @@ class stream:
|
||||||
log.info("{} has left stream {}".format(token, self.name))
|
log.info("{} has left stream {}".format(token, self.name))
|
||||||
self.clients.remove(token)
|
self.clients.remove(token)
|
||||||
|
|
||||||
def broadcast(self, data):
|
def broadcast(self, data, but=None):
|
||||||
"""
|
"""
|
||||||
Send some data to all clients connected to this stream
|
Send some data to all (or some) clients connected to this stream
|
||||||
|
|
||||||
:param data: data to send
|
:param data: data to send
|
||||||
|
:param but: array of tokens to ignore. Default: None (send to everyone)
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
if but is None:
|
||||||
|
but = []
|
||||||
|
for i in self.clients:
|
||||||
|
if i in glob.tokens.tokens:
|
||||||
|
if i not in but:
|
||||||
|
glob.tokens.tokens[i].enqueue(data)
|
||||||
|
else:
|
||||||
|
self.removeClient(token=i)
|
||||||
|
|
||||||
|
def dispose(self):
|
||||||
|
"""
|
||||||
|
Tell every client in this stream to leave the stream
|
||||||
|
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
for i in self.clients:
|
for i in self.clients:
|
||||||
if i in glob.tokens.tokens:
|
if i in glob.tokens.tokens:
|
||||||
glob.tokens.tokens[i].enqueue(data)
|
glob.tokens.tokens[i].leaveStream(self.name)
|
||||||
else:
|
|
||||||
self.removeClient(token=i)
|
|
|
@ -1,6 +1,7 @@
|
||||||
from objects import stream
|
from objects import stream
|
||||||
from objects import glob
|
from objects import glob
|
||||||
|
|
||||||
|
# TODO: use *args and **kwargs
|
||||||
class streamList:
|
class streamList:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.streams = {}
|
self.streams = {}
|
||||||
|
@ -55,25 +56,28 @@ class streamList:
|
||||||
return
|
return
|
||||||
self.streams[streamName].removeClient(client=client, token=token)
|
self.streams[streamName].removeClient(client=client, token=token)
|
||||||
|
|
||||||
def broadcast(self, streamName, data):
|
def broadcast(self, streamName, data, but=None):
|
||||||
"""
|
"""
|
||||||
Send some data to all clients in a stream
|
Send some data to all clients in a stream
|
||||||
|
|
||||||
:param streamName: stream name
|
:param streamName: stream name
|
||||||
:param data: data to send
|
:param data: data to send
|
||||||
|
:param but: array of tokens to ignore. Default: None (send to everyone)
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
if streamName not in self.streams:
|
if streamName not in self.streams:
|
||||||
return
|
return
|
||||||
self.streams[streamName].broadcast(data)
|
self.streams[streamName].broadcast(data, but)
|
||||||
|
|
||||||
'''def getClients(self, streamName):
|
def dispose(self, streamName, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Get all clients in a stream
|
Call `dispose` on `streamName`
|
||||||
|
|
||||||
:param streamName: name of the stream
|
:param streamName: name of the stream
|
||||||
|
:param args:
|
||||||
|
:param kwargs:
|
||||||
:return:
|
:return:
|
||||||
"""
|
"""
|
||||||
if streamName not in self.streams:
|
if streamName not in self.streams:
|
||||||
return
|
return
|
||||||
return self.streams[streamName].clients'''
|
self.streams[streamName].dispose(*args, **kwargs)
|
10
pep.py
10
pep.py
|
@ -154,6 +154,11 @@ if __name__ == "__main__":
|
||||||
consoleHelper.printColored("[!] Error while loading chat filters. Make sure there is a filters.txt file present", bcolors.RED)
|
consoleHelper.printColored("[!] Error while loading chat filters. Make sure there is a filters.txt file present", bcolors.RED)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
|
# Start fokabot
|
||||||
|
consoleHelper.printNoNl("> Connecting FokaBot... ")
|
||||||
|
fokabot.connect()
|
||||||
|
consoleHelper.printDone()
|
||||||
|
|
||||||
# Initialize chat channels
|
# Initialize chat channels
|
||||||
print("> Initializing chat channels... ")
|
print("> Initializing chat channels... ")
|
||||||
glob.channels.loadChannels()
|
glob.channels.loadChannels()
|
||||||
|
@ -165,11 +170,6 @@ if __name__ == "__main__":
|
||||||
glob.streams.add("lobby")
|
glob.streams.add("lobby")
|
||||||
consoleHelper.printDone()
|
consoleHelper.printDone()
|
||||||
|
|
||||||
# Start fokabot
|
|
||||||
consoleHelper.printNoNl("> Connecting FokaBot... ")
|
|
||||||
fokabot.connect()
|
|
||||||
consoleHelper.printDone()
|
|
||||||
|
|
||||||
# Initialize user timeout check loop
|
# Initialize user timeout check loop
|
||||||
consoleHelper.printNoNl("> Initializing user timeout check loop... ")
|
consoleHelper.printNoNl("> Initializing user timeout check loop... ")
|
||||||
glob.tokens.usersTimeoutCheckLoop()
|
glob.tokens.usersTimeoutCheckLoop()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user