pep.py/objects/tokenList.py

206 lines
5.8 KiB
Python
Raw Normal View History

2016-04-19 17:40:59 +00:00
import threading
2016-10-02 20:48:14 +00:00
import time
from common.ripple import userUtils
from common.log import logUtils as log
from constants import serverPackets
2016-05-18 17:12:46 +00:00
from events import logoutEvent
2016-10-02 20:48:14 +00:00
from objects import glob
from objects import osuToken
2016-04-19 17:40:59 +00:00
2016-09-02 15:45:10 +00:00
class tokenList:
2016-04-19 17:40:59 +00:00
"""
List of connected osu tokens
tokens -- dictionary. key: token string, value: token object
"""
2016-06-10 14:22:14 +00:00
def __init__(self):
"""
Initialize a tokens list
"""
self.tokens = {}
2016-04-19 17:40:59 +00:00
def addToken(self, userID, ip = "", irc = False, timeOffset=0, tournament=False):
2016-04-19 17:40:59 +00:00
"""
Add a token object to tokens list
2016-06-10 11:15:42 +00:00
userID -- user id associated to that token
irc -- if True, set this token as IRC client
2016-04-19 17:40:59 +00:00
return -- token object
"""
newToken = osuToken.token(userID, ip=ip, irc=irc, timeOffset=timeOffset, tournament=tournament)
2016-04-19 17:40:59 +00:00
self.tokens[newToken.token] = newToken
return newToken
2016-06-10 11:15:42 +00:00
def deleteToken(self, token):
2016-04-19 17:40:59 +00:00
"""
Delete a token from token list if it exists
2016-06-10 11:15:42 +00:00
token -- token string
2016-04-19 17:40:59 +00:00
"""
2016-06-10 11:15:42 +00:00
if token in self.tokens:
# Delete session from DB
if self.tokens[token].ip != "":
2016-10-02 20:48:14 +00:00
userUtils.deleteBanchoSessions(self.tokens[token].userID, self.tokens[token].ip)
2016-04-19 17:40:59 +00:00
2016-06-10 11:15:42 +00:00
# Pop token from list
self.tokens.pop(token)
2016-04-19 17:40:59 +00:00
2016-06-10 11:15:42 +00:00
def getUserIDFromToken(self, token):
2016-04-19 17:40:59 +00:00
"""
Get user ID from a token
2016-06-10 11:15:42 +00:00
token -- token to find
return -- false if not found, userID if found
2016-04-19 17:40:59 +00:00
"""
# Make sure the token exists
2016-06-10 11:15:42 +00:00
if token not in self.tokens:
2016-04-19 17:40:59 +00:00
return False
# Get userID associated to that token
2016-06-10 11:15:42 +00:00
return self.tokens[token].userID
2016-04-19 17:40:59 +00:00
def getTokenFromUserID(self, userID, ignoreIRC=False):
2016-04-19 17:40:59 +00:00
"""
Get token from a user ID
2016-06-10 11:15:42 +00:00
userID -- user ID to find
2016-04-19 17:40:59 +00:00
return -- False if not found, token object if found
"""
# Make sure the token exists
for _, value in self.tokens.items():
2016-06-10 11:15:42 +00:00
if value.userID == userID:
if ignoreIRC and value.irc:
continue
2016-04-19 17:40:59 +00:00
return value
# Return none if not found
return None
def getTokenFromUsername(self, username, ignoreIRC=False, safe=False):
2016-04-19 17:40:59 +00:00
"""
Get an osuToken object from an username
2016-04-19 17:40:59 +00:00
:param username: normal username or safe username
:param ignoreIRC: if True, consider bancho clients only and skip IRC clients
:param safe: if True, username is a safe username,
compare it with token's safe username rather than normal username
:return: osuToken object or None
2016-04-19 17:40:59 +00:00
"""
# lowercase
who = username.lower() if not safe else username
2016-04-19 17:40:59 +00:00
# Make sure the token exists
for _, value in self.tokens.items():
if (not safe and value.username.lower() == who) or (safe and value.safeUsername == who):
if ignoreIRC and value.irc:
continue
2016-04-19 17:40:59 +00:00
return value
# Return none if not found
return None
2016-06-10 11:15:42 +00:00
def deleteOldTokens(self, userID):
2016-04-19 17:40:59 +00:00
"""
Delete old userID's tokens if found
2016-06-10 11:15:42 +00:00
userID -- tokens associated to this user will be deleted
2016-04-19 17:40:59 +00:00
"""
# Delete older tokens
for key, value in list(self.tokens.items()):
2016-06-10 11:15:42 +00:00
if value.userID == userID:
2016-04-19 17:40:59 +00:00
# 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.", "kicked, multiple clients")
2016-04-19 17:40:59 +00:00
2016-06-10 11:15:42 +00:00
def multipleEnqueue(self, packet, who, but = False):
2016-04-19 17:40:59 +00:00
"""
Enqueue a packet to multiple users
2016-06-10 11:15:42 +00:00
packet -- packet bytes to enqueue
who -- userIDs array
but -- if True, enqueue to everyone but users in who array
2016-04-19 17:40:59 +00:00
"""
for _, value in self.tokens.items():
shouldEnqueue = False
2016-06-10 11:15:42 +00:00
if value.userID in who and not but:
2016-04-19 17:40:59 +00:00
shouldEnqueue = True
2016-06-10 11:15:42 +00:00
elif value.userID not in who and but:
2016-04-19 17:40:59 +00:00
shouldEnqueue = True
if shouldEnqueue:
2016-06-10 11:15:42 +00:00
value.enqueue(packet)
2016-04-19 17:40:59 +00:00
2016-06-10 11:15:42 +00:00
def enqueueAll(self, packet):
2016-04-19 17:40:59 +00:00
"""
Enqueue packet(s) to every connected user
2016-06-10 11:15:42 +00:00
packet -- packet bytes to enqueue
2016-04-19 17:40:59 +00:00
"""
for _, value in self.tokens.items():
2016-06-10 11:15:42 +00:00
value.enqueue(packet)
2016-04-19 17:40:59 +00:00
def usersTimeoutCheckLoop(self, timeoutTime = 100, checkTime = 100):
2016-04-19 17:40:59 +00:00
"""
Deletes all timed out users.
If called once, will recall after checkTime seconds and so on, forever
2016-04-19 17:40:59 +00:00
CALL THIS FUNCTION ONLY ONCE!
timeoutTime - seconds of inactivity required to disconnect someone (Default: 100)
checkTime - seconds between loops (Default: 100)
2016-04-19 17:40:59 +00:00
"""
log.debug("Checking timed out clients")
2016-04-19 17:40:59 +00:00
timedOutTokens = [] # timed out users
timeoutLimit = int(time.time())-timeoutTime
2016-04-19 17:40:59 +00:00
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:
2016-04-19 17:40:59 +00:00
# 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."))
2016-04-19 17:40:59 +00:00
logoutEvent.handle(self.tokens[i], None)
# Schedule a new check (endless loop)
threading.Timer(checkTime, self.usersTimeoutCheckLoop, [timeoutTime, checkTime]).start()
2016-06-10 14:22:14 +00:00
def spamProtectionResetLoop(self):
"""
Reset spam rate every 10 seconds.
CALL THIS FUNCTION ONLY ONCE!
"""
# 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()
2016-06-10 11:15:42 +00:00
def deleteBanchoSessions(self):
"""
Truncate bancho_sessions table.
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