.BANCHO. Add IRC support, internal changes

This commit is contained in:
Nyo
2016-07-14 12:37:07 +02:00
parent 34be190aa3
commit 95df629e1c
32 changed files with 1191 additions and 351 deletions

View File

@@ -1,3 +1,5 @@
from objects import glob
class channel:
"""
A chat channel
@@ -10,15 +12,7 @@ class channel:
moderated -- bool
"""
name = ""
description = ""
connectedUsers = []
publicRead = False
publicWrite = False
moderated = False
def __init__(self, __name, __description, __publicRead, __publicWrite):
def __init__(self, __name, __description, __publicRead, __publicWrite, temp):
"""
Create a new chat channel object
@@ -26,13 +20,23 @@ class channel:
__description -- channel description
__publicRead -- bool, if true channel can be read by everyone, if false it can be read only by mods/admins
__publicWrite -- bool, same as public read but relative to write permissions
temp -- if True, channel will be deleted when there's no one in the channel. Optional. Default = False.
"""
self.name = __name
self.description = __description
self.publicRead = __publicRead
self.publicWrite = __publicWrite
self.connectedUsers = []
self.moderated = False
self.temp = temp
self.connectedUsers = [999] # Fokabot is always connected to every channels (otherwise it doesn't show up in IRC users list)
# Client name (#spectator/#multiplayer)
self.clientName = self.name
if self.name.startswith("#spect_"):
self.clientName = "#spectator"
elif self.name.startswith("#multi_"):
self.clientName = "#multiplayer"
def userJoin(self, __userID):
@@ -53,9 +57,13 @@ class channel:
__userID -- user ID that left the channel
"""
connectedUsers = self.connectedUsers
if __userID in connectedUsers:
connectedUsers.remove(__userID)
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)
def getConnectedUsers(self):
@@ -64,7 +72,6 @@ class channel:
return -- connectedUsers list
"""
return self.connectedUsers
@@ -74,5 +81,4 @@ class channel:
return -- connected users number
"""
return len(self.connectedUsers)

View File

@@ -1,5 +1,6 @@
from objects import glob
from objects import channel
from helpers import logHelper as log
class channelList:
"""
@@ -27,14 +28,40 @@ class channelList:
self.addChannel(i["name"], i["description"], publicRead, publicWrite)
def addChannel(self, __name, __description, __publicRead, __publicWrite):
def addChannel(self, name, description, publicRead, publicWrite, temp = False):
"""
Add a channel object to channels dictionary
__name -- channel name
__description -- channel description
__publicRead -- bool, if true channel can be read by everyone, if false it can be read only by mods/admins
__publicWrite -- bool, same as public read but relative to write permissions
name -- channel name
description -- channel description
publicRead -- bool, if true channel can be read by everyone, if false it can be read only by mods/admins
publicWrite -- bool, same as public read but relative to write permissions
temp -- if True, channel will be deleted when there's no one in the channel. Optional. Default = False.
"""
self.channels[name] = channel.channel(name, description, publicRead, publicWrite, temp)
log.info("Created channel {}".format(name))
self.channels[__name] = channel.channel(__name, __description, __publicRead, __publicWrite)
def addTempChannel(self, name):
"""
Add a temporary channel (like #spectator or #multiplayer), gets deleted when there's no one in the channel
name -- channel name
return -- True if channel was created, False if failed
"""
if name in self.channels:
return False
self.channels[name] = channel.channel(name, "Chat", True, True, True)
log.info("Created temp channel {}".format(name))
def removeChannel(self, name):
"""
Removes a channel from channels list
name -- channel name
"""
if name not in self.channels:
log.debug("{} is not in channels list".format(name))
return
self.channels.pop(name)
log.info("Removed channel {}".format(name))

View File

@@ -9,6 +9,8 @@ from raven import Client
try:
with open("version") as f:
VERSION = f.read()
if VERSION == "":
raise
except:
VERSION = "¯\_(xd)_/¯"

View File

@@ -9,6 +9,7 @@ from constants import serverPackets
from constants import dataTypes
from constants import matchTeams
from helpers import logHelper as log
from helpers import chatHelper as chat
class match:
"""Multiplayer match object"""
@@ -61,6 +62,9 @@ class match:
for _ in range(0,16):
self.slots.append({"status": slotStatuses.free, "team": 0, "userID": -1, "mods": 0, "loaded": False, "skip": False, "complete": False})
# Create #multiplayer channel
glob.channels.addTempChannel("#multi_{}".format(self.matchID))
def getMatchData(self):
"""
@@ -577,11 +581,11 @@ class match:
# FokaBot is too busy
if to == 999:
froToken.enqueue(serverPackets.sendMessage("FokaBot", froToken.username, "I would love to join your match, but I'm busy keeping ripple up and running. Sorry. Beep Boop."))
chat.sendMessage("FokaBot", froToken.username, "I would love to join your match, but I'm busy keeping ripple up and running. Sorry. Beep Boop.")
# Send message
message = "Come join my multiplayer match: \"[osump://{}/{} {}]\"".format(self.matchID, self.matchPassword.replace(" ", "_"), self.matchName)
toToken.enqueue(serverPackets.sendMessage(froToken.username, toToken.username, message))
chat.sendMessage(token=froToken, to=toToken.username, message=message)
def countUsers(self):

View File

@@ -9,6 +9,7 @@ import uuid
import time
import threading
from helpers import logHelper as log
from helpers import chatHelper as chat
class token:
"""
@@ -34,7 +35,7 @@ class token:
"""
def __init__(self, __userID, token = None, ip = ""):
def __init__(self, __userID, token = None, ip = "", irc = False):
"""
Create a token object and set userID and token
@@ -42,6 +43,7 @@ class token:
token -- if passed, set token to that value
if not passed, token will be generated
ip -- client ip. optional.
irc -- if True, set this token as IRC client. optional.
"""
# Set stuff
@@ -49,6 +51,7 @@ class token:
self.username = userHelper.getUsername(self.userID)
self.privileges = userHelper.getPrivileges(self.userID)
self.admin = userHelper.isInPrivilegeGroup(self.userID, "developer") or userHelper.isInPrivilegeGroup(self.userID, "community manager")
self.irc = irc
self.restricted = userHelper.isRestricted(self.userID)
self.loginTime = int(time.time())
self.pingTime = self.loginTime
@@ -78,7 +81,6 @@ class token:
self.actionMd5 = ""
self.actionMods = 0
self.gameMode = gameModes.std
self.rankedScore = 0
self.accuracy = 0.0
self.playcount = 0
@@ -100,8 +102,9 @@ class token:
userHelper.saveBanchoSession(self.userID, self.ip)
# If we are restricted, send message from FokaBot to user
if self.restricted == True:
self.setRestricted()
# NOTE: Sent later
#if self.restricted == True:
# self.setRestricted()
def enqueue(self, __bytes):
@@ -110,8 +113,8 @@ class token:
__bytes -- (packet) bytes to enqueue
"""
self.queue += __bytes
if self.irc == False:
self.queue += __bytes
def resetQueue(self):
@@ -228,11 +231,11 @@ class token:
"""Set match to -1"""
self.matchID = -1
def kick(self):
def kick(self, message="You have been kicked from the server. Please login again."):
"""Kick this user from the server"""
# Send packet to target
log.info("{} has been disconnected. (kick)".format(self.username))
self.enqueue(serverPackets.notification("You have been kicked from the server. Please login again."))
self.enqueue(serverPackets.notification(message))
self.enqueue(serverPackets.loginFailed())
# Logout event
@@ -301,10 +304,22 @@ class token:
self.gameRank = stats["gameRank"]
self.pp = stats["pp"]
def checkRestricted(self, force=False):
"""
Check if this token is restricted. If so, send fokabot message
force -- If True, get restricted value from db.
If false, get the cached one. Optional. Default: False
"""
if force == True:
self.restricted = userHelper.isRestricted(self.userID)
if self.restricted == True:
self.setRestricted()
def setRestricted(self):
"""
Set this token as restricted, send FokaBot message to user
and send offline packet to everyone
"""
self.restricted = True
self.enqueue(serverPackets.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.")

View File

@@ -19,15 +19,16 @@ class tokenList:
"""
self.tokens = {}
def addToken(self, userID, ip = ""):
def addToken(self, userID, ip = "", irc = False):
"""
Add a token object to tokens list
userID -- user id associated to that token
irc -- if True, set this token as IRC client
return -- token object
"""
newToken = osuToken.token(userID, ip=ip)
newToken = osuToken.token(userID, ip=ip, irc=irc)
self.tokens[newToken.token] = newToken
return newToken
@@ -40,7 +41,8 @@ class tokenList:
if token in self.tokens:
# Delete session from DB
userHelper.deleteBanchoSessions(self.tokens[token].userID, self.tokens[token].ip)
if self.tokens[token].ip != "":
userHelper.deleteBanchoSessions(self.tokens[token].userID, self.tokens[token].ip)
# Pop token from list
self.tokens.pop(token)
@@ -108,13 +110,14 @@ class tokenList:
"""
# Delete older tokens
for key, value in self.tokens.items():
for key, value in list(self.tokens.items()):
if value.userID == userID:
# Delete this token from the dictionary
self.tokens.pop(key)
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
#break
def multipleEnqueue(self, packet, who, but = False):
@@ -136,8 +139,6 @@ class tokenList:
if shouldEnqueue:
value.enqueue(packet)
def enqueueAll(self, packet):
"""
Enqueue packet(s) to every connected user
@@ -162,7 +163,7 @@ class tokenList:
timeoutLimit = time.time()-__timeoutTime
for key, value in self.tokens.items():
# Check timeout (fokabot is ignored)
if value.pingTime < timeoutLimit and value.userID != 999:
if value.pingTime < timeoutLimit and value.userID != 999 and value.irc == 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)
@@ -195,3 +196,18 @@ class tokenList:
Call at bancho startup to delete old cached sessions
"""
glob.db.execute("TRUNCATE TABLE bancho_sessions")
def tokenExists(self, username = "", userID = -1):
"""
Check if a token exists (aka check if someone is connected)
username -- Optional.
userID -- Optional.
return -- True if it exists, otherwise False
Use username or userid, not both at the same time.
"""
if userID > -1:
return True if self.getTokenFromUserID(userID) is not None else False
else:
return True if self.getTokenFromUsername(username) is not None else False