.BANCHO. New privileges system, add restricted mode
This commit is contained in:
parent
99276d83b3
commit
6ac3b853f4
|
@ -74,3 +74,6 @@ class userSilencedException(Exception):
|
||||||
|
|
||||||
class need2FAException(Exception):
|
class need2FAException(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
class userRestrictedException(Exception):
|
||||||
|
pass
|
||||||
|
|
|
@ -11,6 +11,7 @@ from constants import mods
|
||||||
from helpers import generalFunctions
|
from helpers import generalFunctions
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
from constants import gameModes
|
from constants import gameModes
|
||||||
|
from constants import privileges
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Commands callbacks
|
Commands callbacks
|
||||||
|
@ -98,7 +99,7 @@ def kickAll(fro, chan, message):
|
||||||
# Kick everyone but mods/admins
|
# Kick everyone but mods/admins
|
||||||
toKick = []
|
toKick = []
|
||||||
for key, value in glob.tokens.tokens.items():
|
for key, value in glob.tokens.tokens.items():
|
||||||
if value.rank < 3:
|
if value.admin == False:
|
||||||
toKick.append(key)
|
toKick.append(key)
|
||||||
|
|
||||||
# Loop though users to kick (we can't change dictionary size while iterating)
|
# Loop though users to kick (we can't change dictionary size while iterating)
|
||||||
|
@ -213,7 +214,7 @@ def ban(fro, chan, message):
|
||||||
return "{}: user not found".format(target)
|
return "{}: user not found".format(target)
|
||||||
|
|
||||||
# Set allowed to 0
|
# Set allowed to 0
|
||||||
userHelper.setAllowed(targetUserID, 0)
|
userHelper.ban(targetUserID)
|
||||||
|
|
||||||
# Send ban packet to the user if he's online
|
# Send ban packet to the user if he's online
|
||||||
targetToken = glob.tokens.getTokenFromUsername(target)
|
targetToken = glob.tokens.getTokenFromUsername(target)
|
||||||
|
@ -236,11 +237,52 @@ def unban(fro, chan, message):
|
||||||
return "{}: user not found".format(target)
|
return "{}: user not found".format(target)
|
||||||
|
|
||||||
# Set allowed to 1
|
# Set allowed to 1
|
||||||
userHelper.setAllowed(targetUserID, 1)
|
userHelper.unban(targetUserID)
|
||||||
|
|
||||||
log.rap(userID, "has unbanned {}".format(target), True)
|
log.rap(userID, "has unbanned {}".format(target), True)
|
||||||
return "Welcome back {}!".format(target)
|
return "Welcome back {}!".format(target)
|
||||||
|
|
||||||
|
def restrict(fro, chan, message):
|
||||||
|
# Get parameters
|
||||||
|
for i in message:
|
||||||
|
i = i.lower()
|
||||||
|
target = message[0].replace("_", " ")
|
||||||
|
|
||||||
|
# Make sure the user exists
|
||||||
|
targetUserID = userHelper.getID(target)
|
||||||
|
userID = userHelper.getID(fro)
|
||||||
|
if targetUserID == False:
|
||||||
|
return "{}: user not found".format(target)
|
||||||
|
|
||||||
|
# Put this user in restricted mode
|
||||||
|
userHelper.restrict(targetUserID)
|
||||||
|
|
||||||
|
# Send restricted mode packet to this user if he's online
|
||||||
|
targetToken = glob.tokens.getTokenFromUsername(target)
|
||||||
|
if targetToken != None:
|
||||||
|
targetToken.setRestricted()
|
||||||
|
|
||||||
|
log.rap(userID, "has put {} in restricted mode".format(target), True)
|
||||||
|
return "Bye bye {}. See you later, maybe.".format(target)
|
||||||
|
|
||||||
|
def unrestrict(fro, chan, message):
|
||||||
|
# Get parameters
|
||||||
|
for i in message:
|
||||||
|
i = i.lower()
|
||||||
|
target = message[0].replace("_", " ")
|
||||||
|
|
||||||
|
# Make sure the user exists
|
||||||
|
targetUserID = userHelper.getID(target)
|
||||||
|
userID = userHelper.getID(fro)
|
||||||
|
if targetUserID == False:
|
||||||
|
return "{}: user not found".format(target)
|
||||||
|
|
||||||
|
# Set allowed to 1
|
||||||
|
userHelper.unrestrict(targetUserID)
|
||||||
|
|
||||||
|
log.rap(userID, "has removed restricted mode from {}".format(target), True)
|
||||||
|
return "Welcome back {}!".format(target)
|
||||||
|
|
||||||
def restartShutdown(restart):
|
def restartShutdown(restart):
|
||||||
"""Restart (if restart = True) or shutdown (if restart = False) pep.py safely"""
|
"""Restart (if restart = True) or shutdown (if restart = False) pep.py safely"""
|
||||||
msg = "We are performing some maintenance. Bancho will {} in 5 seconds. Thank you for your patience.".format("restart" if restart else "shutdown")
|
msg = "We are performing some maintenance. Bancho will {} in 5 seconds. Thank you for your patience.".format("restart" if restart else "shutdown")
|
||||||
|
@ -287,7 +329,7 @@ def systemMaintenance(fro, chan, message):
|
||||||
|
|
||||||
# Disconnect everyone but mod/admins
|
# Disconnect everyone but mod/admins
|
||||||
for _, value in glob.tokens.tokens.items():
|
for _, value in glob.tokens.tokens.items():
|
||||||
if value.rank < 3:
|
if value.admin == False:
|
||||||
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.tokens.enqueueAll(serverPackets.notification("Our bancho server is in maintenance mode. Please try to login again later."))
|
||||||
|
@ -306,7 +348,7 @@ def systemStatus(fro, chan, message):
|
||||||
data = systemHelper.getSystemInfo()
|
data = systemHelper.getSystemInfo()
|
||||||
|
|
||||||
# Final message
|
# Final message
|
||||||
msg = "pep.py bancho server v{}\n".format(glob.VERSION)
|
msg = "pep.py bancho server v{}".format(glob.VERSION)
|
||||||
msg += "made by the Ripple team\n"
|
msg += "made by the Ripple team\n"
|
||||||
msg += "\n"
|
msg += "\n"
|
||||||
msg += "=== BANCHO STATS ===\n"
|
msg += "=== BANCHO STATS ===\n"
|
||||||
|
@ -555,14 +597,7 @@ trigger: message that triggers the command
|
||||||
callback: function to call when the command is triggered. Optional.
|
callback: function to call when the command is triggered. Optional.
|
||||||
response: text to return when the command is triggered. Optional.
|
response: text to return when the command is triggered. Optional.
|
||||||
syntax: command syntax. Arguments must be separated by spaces (eg: <arg1> <arg2>)
|
syntax: command syntax. Arguments must be separated by spaces (eg: <arg1> <arg2>)
|
||||||
minRank: minimum rank to execute that command. Optional (default = 1)
|
privileges: privileges needed to execute the command. Optional.
|
||||||
rank: EXACT rank used to execute that command. Optional.
|
|
||||||
|
|
||||||
RANKS:
|
|
||||||
1: Normal user
|
|
||||||
2: Supporter
|
|
||||||
3: Developer
|
|
||||||
4: Community manager
|
|
||||||
|
|
||||||
NOTES:
|
NOTES:
|
||||||
- You CAN'T use both rank and minRank at the same time.
|
- You CAN'T use both rank and minRank at the same time.
|
||||||
|
@ -593,70 +628,80 @@ commands = [
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!alert",
|
"trigger": "!alert",
|
||||||
"syntax": "<message>",
|
"syntax": "<message>",
|
||||||
"minRank": 3,
|
"privileges": privileges.ADMIN_SEND_ALERTS,
|
||||||
"callback": alert
|
"callback": alert
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!alertuser",
|
"trigger": "!alertuser",
|
||||||
"syntax": "<username> <message>",
|
"syntax": "<username> <message>",
|
||||||
"minRank": 3,
|
"privileges": privileges.ADMIN_SEND_ALERTS,
|
||||||
"callback": alertUser,
|
"callback": alertUser,
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!moderated",
|
"trigger": "!moderated",
|
||||||
"minRank": 3,
|
"privileges": privileges.ADMIN_CHAT_MOD,
|
||||||
"callback": moderated
|
"callback": moderated
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!kickall",
|
"trigger": "!kickall",
|
||||||
"rank": 3,
|
"privileges": privileges.ADMIN_KICK_USERS,
|
||||||
"callback": kickAll
|
"callback": kickAll
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!kick",
|
"trigger": "!kick",
|
||||||
"syntax": "<target>",
|
"syntax": "<target>",
|
||||||
"minRank": 3,
|
"privileges": privileges.ADMIN_KICK_USERS,
|
||||||
"callback": kick
|
"callback": kick
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!fokabot reconnect",
|
"trigger": "!fokabot reconnect",
|
||||||
"minRank": 3,
|
"privileges": privileges.ADMIN_MANAGE_SERVERS,
|
||||||
"callback": fokabotReconnect
|
"callback": fokabotReconnect
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!silence",
|
"trigger": "!silence",
|
||||||
"syntax": "<target> <amount> <unit(s/m/h/d)> <reason>",
|
"syntax": "<target> <amount> <unit(s/m/h/d)> <reason>",
|
||||||
"minRank": 3,
|
"privileges": privileges.ADMIN_SILENCE_USERS,
|
||||||
"callback": silence
|
"callback": silence
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!removesilence",
|
"trigger": "!removesilence",
|
||||||
"syntax": "<target>",
|
"syntax": "<target>",
|
||||||
"minRank": 3,
|
"privileges": privileges.ADMIN_SILENCE_USERS,
|
||||||
"callback": removeSilence
|
"callback": removeSilence
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!system restart",
|
"trigger": "!system restart",
|
||||||
"rank": 3,
|
"privileges": privileges.ADMIN_MANAGE_SERVERS,
|
||||||
"callback": systemRestart
|
"callback": systemRestart
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!system shutdown",
|
"trigger": "!system shutdown",
|
||||||
"rank": 3,
|
"privileges": privileges.ADMIN_MANAGE_SERVERS,
|
||||||
"callback": systemShutdown
|
"callback": systemShutdown
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!system reload",
|
"trigger": "!system reload",
|
||||||
"minRank": 3,
|
"privileges": privileges.ADMIN_MANAGE_SETTINGS,
|
||||||
"callback": systemReload
|
"callback": systemReload
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!system maintenance",
|
"trigger": "!system maintenance",
|
||||||
"rank": 3,
|
"privileges": privileges.ADMIN_MANAGE_SERVERS,
|
||||||
"callback": systemMaintenance
|
"callback": systemMaintenance
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!system status",
|
"trigger": "!system status",
|
||||||
"rank": 3,
|
"privileges": privileges.ADMIN_MANAGE_SERVERS,
|
||||||
"callback": systemStatus
|
"callback": systemStatus
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!ban",
|
"trigger": "!ban",
|
||||||
"syntax": "<target>",
|
"syntax": "<target>",
|
||||||
"minRank": 3,
|
"privileges": privileges.ADMIN_BAN_USERS,
|
||||||
"callback": ban
|
"callback": ban
|
||||||
}, {
|
}, {
|
||||||
"trigger": "!unban",
|
"trigger": "!unban",
|
||||||
"syntax": "<target>",
|
"syntax": "<target>",
|
||||||
"minRank": 3,
|
"privileges": privileges.ADMIN_BAN_USERS,
|
||||||
"callback": unban
|
"callback": unban
|
||||||
|
}, {
|
||||||
|
"trigger": "!restrict",
|
||||||
|
"syntax": "<target>",
|
||||||
|
"privileges": privileges.ADMIN_BAN_USERS,
|
||||||
|
"callback": restrict
|
||||||
|
}, {
|
||||||
|
"trigger": "!unrestrict",
|
||||||
|
"syntax": "<target>",
|
||||||
|
"privileges": privileges.ADMIN_BAN_USERS,
|
||||||
|
"callback": unrestrict
|
||||||
}, {
|
}, {
|
||||||
"trigger": "\x01ACTION is listening to",
|
"trigger": "\x01ACTION is listening to",
|
||||||
"callback": tillerinoNp
|
"callback": tillerinoNp
|
||||||
|
@ -684,7 +729,6 @@ commands = [
|
||||||
# Commands list default values
|
# Commands list default values
|
||||||
for cmd in commands:
|
for cmd in commands:
|
||||||
cmd.setdefault("syntax", "")
|
cmd.setdefault("syntax", "")
|
||||||
cmd.setdefault("minRank", 1)
|
cmd.setdefault("privileges", None)
|
||||||
cmd.setdefault("rank", None)
|
|
||||||
cmd.setdefault("callback", None)
|
cmd.setdefault("callback", None)
|
||||||
cmd.setdefault("response", "u w0t m8?")
|
cmd.setdefault("response", "u w0t m8?")
|
||||||
|
|
20
constants/privileges.py
Normal file
20
constants/privileges.py
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
USER_PUBLIC = 1
|
||||||
|
USER_NORMAL = 2 << 0
|
||||||
|
USER_DONOR = 2 << 1
|
||||||
|
ADMIN_ACCESS_RAP = 2 << 2
|
||||||
|
ADMIN_MANAGE_USERS = 2 << 3
|
||||||
|
ADMIN_BAN_USERS = 2 << 4
|
||||||
|
ADMIN_SILENCE_USERS = 2 << 5
|
||||||
|
ADMIN_WIPE_USERS = 2 << 6
|
||||||
|
ADMIN_MANAGE_BEATMAPS = 2 << 7
|
||||||
|
ADMIN_MANAGE_SERVERS = 2 << 8
|
||||||
|
ADMIN_MANAGE_SETTINGS = 2 << 9
|
||||||
|
ADMIN_MANAGE_BETAKEYS = 2 << 10
|
||||||
|
ADMIN_MANAGE_REPORTS = 2 << 11
|
||||||
|
ADMIN_MANAGE_DOCS = 2 << 12
|
||||||
|
ADMIN_MANAGE_BADGES = 2 << 13
|
||||||
|
ADMIN_VIEW_RAP_LOGS = 2 << 14
|
||||||
|
ADMIN_MANAGE_PRIVILEGES = 2 << 15
|
||||||
|
ADMIN_SEND_ALERTS = 2 << 16
|
||||||
|
ADMIN_CHAT_MOD = 2 << 17
|
||||||
|
ADMIN_KICK_USERS = 2 << 18
|
|
@ -69,18 +69,15 @@ def friendList(userID):
|
||||||
return packetHelper.buildPacket(packetIDs.server_friendsList, friendsData)
|
return packetHelper.buildPacket(packetIDs.server_friendsList, friendsData)
|
||||||
|
|
||||||
def onlineUsers():
|
def onlineUsers():
|
||||||
onlineUsersData = []
|
userIDs = []
|
||||||
|
|
||||||
users = glob.tokens.tokens
|
users = glob.tokens.tokens
|
||||||
|
|
||||||
# Users number
|
# Create list with all connected (and not restricted) users
|
||||||
onlineUsersData.append([len(users), dataTypes.uInt16])
|
for _, value in users.items():
|
||||||
|
if value.restricted == False:
|
||||||
|
userIDs.append(value.userID)
|
||||||
|
|
||||||
# Add all users user IDs to onlineUsersData
|
return packetHelper.buildPacket(packetIDs.server_userPresenceBundle, [[userIDs, dataTypes.intList]])
|
||||||
for _,value in users.items():
|
|
||||||
onlineUsersData.append([value.userID, dataTypes.sInt32])
|
|
||||||
|
|
||||||
return packetHelper.buildPacket(packetIDs.server_userPresenceBundle, onlineUsersData)
|
|
||||||
|
|
||||||
|
|
||||||
""" Users packets """
|
""" Users packets """
|
||||||
|
@ -88,8 +85,14 @@ def userLogout(userID):
|
||||||
return packetHelper.buildPacket(packetIDs.server_userLogout, [[userID, dataTypes.sInt32], [0, dataTypes.byte]])
|
return packetHelper.buildPacket(packetIDs.server_userLogout, [[userID, dataTypes.sInt32], [0, dataTypes.byte]])
|
||||||
|
|
||||||
def userPanel(userID):
|
def userPanel(userID):
|
||||||
# Get user data
|
# Connected and restricted check
|
||||||
userToken = glob.tokens.getTokenFromUserID(userID)
|
userToken = glob.tokens.getTokenFromUserID(userID)
|
||||||
|
if userToken == None:
|
||||||
|
return bytes()
|
||||||
|
if userToken.restricted == True:
|
||||||
|
return bytes()
|
||||||
|
|
||||||
|
# Get user data
|
||||||
username = userToken.username
|
username = userToken.username
|
||||||
timezone = 24 # TODO: Timezone
|
timezone = 24 # TODO: Timezone
|
||||||
country = userToken.country
|
country = userToken.country
|
||||||
|
@ -99,15 +102,13 @@ def userPanel(userID):
|
||||||
|
|
||||||
# Get username color according to rank
|
# Get username color according to rank
|
||||||
# Only admins and normal users are currently supported
|
# Only admins and normal users are currently supported
|
||||||
#rank = userHelper.getRankPrivileges(userID)
|
|
||||||
rank = userToken.rank
|
|
||||||
if username == "FokaBot":
|
if username == "FokaBot":
|
||||||
userRank = userRanks.MOD
|
userRank = userRanks.MOD
|
||||||
elif rank == 4:
|
elif userHelper.isInPrivilegeGroup(userID, "community manager") == True:
|
||||||
userRank = userRanks.MOD
|
userRank = userRanks.MOD
|
||||||
elif rank == 3:
|
elif userHelper.isInPrivilegeGroup(userID, "developer") == True:
|
||||||
userRank = userRanks.ADMIN
|
userRank = userRanks.ADMIN
|
||||||
elif rank == 2:
|
elif userHelper.isInPrivilegeGroup(userID, "donator") == True:
|
||||||
userRank = userRanks.SUPPORTER
|
userRank = userRanks.SUPPORTER
|
||||||
else:
|
else:
|
||||||
userRank = userRanks.NORMAL
|
userRank = userRanks.NORMAL
|
||||||
|
@ -130,6 +131,8 @@ def userStats(userID):
|
||||||
userToken = glob.tokens.getTokenFromUserID(userID)
|
userToken = glob.tokens.getTokenFromUserID(userID)
|
||||||
if userToken == None:
|
if userToken == None:
|
||||||
return bytes() # NOTE: ???
|
return bytes() # NOTE: ???
|
||||||
|
if userToken.restricted == True:
|
||||||
|
return bytes()
|
||||||
# Stats are cached in token object
|
# Stats are cached in token object
|
||||||
#rankedScore = userHelper.getRankedScore(userID, userToken.gameMode)
|
#rankedScore = userHelper.getRankedScore(userID, userToken.gameMode)
|
||||||
#accuracy = userHelper.getAccuracy(userID, userToken.gameMode)/100
|
#accuracy = userHelper.getAccuracy(userID, userToken.gameMode)/100
|
||||||
|
|
|
@ -11,10 +11,15 @@ def handle(userToken, packetData):
|
||||||
username = userToken.username
|
username = userToken.username
|
||||||
|
|
||||||
# Make sure we are not banned
|
# Make sure we are not banned
|
||||||
if userHelper.getAllowed(userID) == 0:
|
if userHelper.isBanned(userID) == True:
|
||||||
userToken.enqueue(serverPackets.loginBanned())
|
userToken.enqueue(serverPackets.loginBanned())
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# Send restricted message if needed
|
||||||
|
if userToken.restricted == False:
|
||||||
|
if userHelper.isRestricted(userID) == True:
|
||||||
|
userToken.setRestricted()
|
||||||
|
|
||||||
# Change action packet
|
# Change action packet
|
||||||
packetData = clientPackets.userActionChange(packetData)
|
packetData = clientPackets.userActionChange(packetData)
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,6 @@ def joinChannel(userToken, channelName):
|
||||||
# Get usertoken data
|
# Get usertoken data
|
||||||
username = userToken.username
|
username = userToken.username
|
||||||
userID = userToken.userID
|
userID = userToken.userID
|
||||||
userRank = userToken.rank
|
|
||||||
|
|
||||||
# Check spectator channel
|
# Check spectator channel
|
||||||
# If it's spectator channel, skip checks and list stuff
|
# If it's spectator channel, skip checks and list stuff
|
||||||
|
@ -37,7 +36,7 @@ def joinChannel(userToken, channelName):
|
||||||
raise exceptions.channelUnknownException
|
raise exceptions.channelUnknownException
|
||||||
|
|
||||||
# Check channel permissions
|
# Check channel permissions
|
||||||
if glob.channels.channels[channelName].publicRead == False and userRank <= 2:
|
if glob.channels.channels[channelName].publicRead == False and userToken.admin == False:
|
||||||
raise exceptions.channelNoPermissionsException
|
raise exceptions.channelNoPermissionsException
|
||||||
|
|
||||||
# Add our userID to users in that channel
|
# Add our userID to users in that channel
|
||||||
|
|
|
@ -31,7 +31,8 @@ def handle(tornadoRequest):
|
||||||
err = False
|
err = False
|
||||||
|
|
||||||
# Try to get the ID from username
|
# Try to get the ID from username
|
||||||
userID = userHelper.getID(str(loginData[0]))
|
username = str(loginData[0])
|
||||||
|
userID = userHelper.getID(username)
|
||||||
|
|
||||||
if userID == False:
|
if userID == False:
|
||||||
# Invalid username
|
# Invalid username
|
||||||
|
@ -41,9 +42,7 @@ def handle(tornadoRequest):
|
||||||
raise exceptions.loginFailedException()
|
raise exceptions.loginFailedException()
|
||||||
|
|
||||||
# Make sure we are not banned
|
# Make sure we are not banned
|
||||||
userAllowed = userHelper.getAllowed(userID)
|
if userHelper.isBanned(userID) == True:
|
||||||
if userAllowed == 0:
|
|
||||||
# Banned
|
|
||||||
raise exceptions.loginBannedException()
|
raise exceptions.loginBannedException()
|
||||||
|
|
||||||
# 2FA check
|
# 2FA check
|
||||||
|
@ -67,10 +66,9 @@ def handle(tornadoRequest):
|
||||||
silenceSeconds = responseToken.getSilenceSecondsLeft()
|
silenceSeconds = responseToken.getSilenceSecondsLeft()
|
||||||
|
|
||||||
# Get supporter/GMT
|
# Get supporter/GMT
|
||||||
userRank = userHelper.getRankPrivileges(userID)
|
|
||||||
userGMT = False
|
userGMT = False
|
||||||
userSupporter = True
|
userSupporter = True
|
||||||
if userRank >= 3:
|
if responseToken.admin == True:
|
||||||
userGMT = True
|
userGMT = True
|
||||||
|
|
||||||
# Server restarting check
|
# Server restarting check
|
||||||
|
@ -105,9 +103,9 @@ def handle(tornadoRequest):
|
||||||
# TODO: Configurable default channels
|
# TODO: Configurable default channels
|
||||||
channelJoinEvent.joinChannel(responseToken, "#osu")
|
channelJoinEvent.joinChannel(responseToken, "#osu")
|
||||||
channelJoinEvent.joinChannel(responseToken, "#announce")
|
channelJoinEvent.joinChannel(responseToken, "#announce")
|
||||||
if userRank >= 3:
|
|
||||||
# Join admin chanenl if we are mod/admin
|
# Join admin channel if we are an admin
|
||||||
# TODO: Separate channels for mods and admins
|
if responseToken.admin == True:
|
||||||
channelJoinEvent.joinChannel(responseToken, "#admin")
|
channelJoinEvent.joinChannel(responseToken, "#admin")
|
||||||
|
|
||||||
# Output channels info
|
# Output channels info
|
||||||
|
@ -122,12 +120,6 @@ def handle(tornadoRequest):
|
||||||
if glob.banchoConf.config["menuIcon"] != "":
|
if glob.banchoConf.config["menuIcon"] != "":
|
||||||
responseToken.enqueue(serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"]))
|
responseToken.enqueue(serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"]))
|
||||||
|
|
||||||
# Get everyone else userpanel
|
|
||||||
# TODO: Better online users handling
|
|
||||||
#for key, value in glob.tokens.tokens.items():
|
|
||||||
# responseToken.enqueue(serverPackets.userPanel(value.userID))
|
|
||||||
# responseToken.enqueue(serverPackets.userStats(value.userID))
|
|
||||||
|
|
||||||
# Send online users IDs array
|
# Send online users IDs array
|
||||||
responseToken.enqueue(serverPackets.onlineUsers())
|
responseToken.enqueue(serverPackets.onlineUsers())
|
||||||
|
|
||||||
|
@ -151,10 +143,10 @@ def handle(tornadoRequest):
|
||||||
# Set country in db if user has no country (first bancho login)
|
# Set country in db if user has no country (first bancho login)
|
||||||
if userHelper.getCountry(userID) == "XX":
|
if userHelper.getCountry(userID) == "XX":
|
||||||
userHelper.setCountry(userID, countryLetters)
|
userHelper.setCountry(userID, countryLetters)
|
||||||
|
|
||||||
# Send to everyone our userpanel
|
# Send to everyone our userpanel if we are not restricted
|
||||||
glob.tokens.enqueueAll(serverPackets.userPanel(userID))
|
if responseToken.restricted == False:
|
||||||
#glob.tokens.enqueueAll(serverPackets.userStats(userID))
|
glob.tokens.enqueueAll(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
|
||||||
|
|
|
@ -24,6 +24,10 @@ def handle(userToken, packetData):
|
||||||
username = userToken.username
|
username = userToken.username
|
||||||
userID = userToken.userID
|
userID = userToken.userID
|
||||||
|
|
||||||
|
# Make sure the user is not in restricted mode
|
||||||
|
if userToken.restricted == True:
|
||||||
|
raise exceptions.userRestrictedException
|
||||||
|
|
||||||
# Private message packet
|
# Private message packet
|
||||||
packetData = clientPackets.sendPrivateMessage(packetData)
|
packetData = clientPackets.sendPrivateMessage(packetData)
|
||||||
|
|
||||||
|
@ -47,7 +51,7 @@ def handle(userToken, packetData):
|
||||||
raise exceptions.tokenNotFoundException()
|
raise exceptions.tokenNotFoundException()
|
||||||
|
|
||||||
# Check message templates (mods/admins only)
|
# Check message templates (mods/admins only)
|
||||||
if packetData["message"] in messageTemplates.templates and userToken.rank >= 3:
|
if packetData["message"] in messageTemplates.templates and userToken.admin == True:
|
||||||
packetData["message"] = messageTemplates.templates[packetData["message"]]
|
packetData["message"] = messageTemplates.templates[packetData["message"]]
|
||||||
|
|
||||||
# Send message to target
|
# Send message to target
|
||||||
|
@ -71,3 +75,5 @@ def handle(userToken, packetData):
|
||||||
except exceptions.messageTooLongException:
|
except exceptions.messageTooLongException:
|
||||||
# Message > 256 silence
|
# Message > 256 silence
|
||||||
userToken.silence(2*3600, "Sending messages longer than 256 characters")
|
userToken.silence(2*3600, "Sending messages longer than 256 characters")
|
||||||
|
except exceptions.userRestrictedException:
|
||||||
|
pass
|
||||||
|
|
|
@ -20,7 +20,10 @@ def handle(userToken, packetData):
|
||||||
# Get userToken data
|
# Get userToken data
|
||||||
userID = userToken.userID
|
userID = userToken.userID
|
||||||
username = userToken.username
|
username = userToken.username
|
||||||
userRank = userToken.rank
|
|
||||||
|
# Make sure the user is not in restricted mode
|
||||||
|
if userToken.restricted == True:
|
||||||
|
raise exceptions.userRestrictedException
|
||||||
|
|
||||||
# Public chat packet
|
# Public chat packet
|
||||||
packetData = clientPackets.sendPublicMessage(packetData)
|
packetData = clientPackets.sendPublicMessage(packetData)
|
||||||
|
@ -85,11 +88,11 @@ def handle(userToken, packetData):
|
||||||
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[packetData["to"]].moderated == True and userRank <= 2:
|
if glob.channels.channels[packetData["to"]].moderated == True and userToken.admin == False:
|
||||||
raise exceptions.channelModeratedException
|
raise exceptions.channelModeratedException
|
||||||
|
|
||||||
# Make sure we have write permissions
|
# Make sure we have write permissions
|
||||||
if glob.channels.channels[packetData["to"]].publicWrite == False and userRank <= 2:
|
if glob.channels.channels[packetData["to"]].publicWrite == False and userToken.admin == False:
|
||||||
raise exceptions.channelNoPermissionsException
|
raise exceptions.channelNoPermissionsException
|
||||||
|
|
||||||
# Send this packet to everyone in that channel except us
|
# Send this packet to everyone in that channel except us
|
||||||
|
@ -128,3 +131,5 @@ def handle(userToken, packetData):
|
||||||
except exceptions.messageTooLongException:
|
except exceptions.messageTooLongException:
|
||||||
# Message > 256 silence
|
# Message > 256 silence
|
||||||
userToken.silence(2*3600, "Sending messages longer than 256 characters")
|
userToken.silence(2*3600, "Sending messages longer than 256 characters")
|
||||||
|
except exceptions.userRestrictedException:
|
||||||
|
pass
|
||||||
|
|
|
@ -156,9 +156,25 @@ class handler(SentryMixin, requestHelper.asyncRequestHandler):
|
||||||
packetIDs.client_userPanelRequest: handleEvent(userPanelRequestEvent),
|
packetIDs.client_userPanelRequest: handleEvent(userPanelRequestEvent),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Packets processed if in restricted mode.
|
||||||
|
# All other packets will be ignored if the user is in restricted mode
|
||||||
|
packetsRestricted = [
|
||||||
|
packetIDs.client_logout,
|
||||||
|
packetIDs.client_userStatsRequest,
|
||||||
|
packetIDs.client_requestStatusUpdate,
|
||||||
|
packetIDs.client_userPanelRequest,
|
||||||
|
packetIDs.client_changeAction,
|
||||||
|
packetIDs.client_channelJoin,
|
||||||
|
packetIDs.client_channelPart,
|
||||||
|
]
|
||||||
|
|
||||||
|
# Process/ignore packet
|
||||||
if packetID != 4:
|
if packetID != 4:
|
||||||
if packetID in eventHandler:
|
if packetID in eventHandler:
|
||||||
eventHandler[packetID]()
|
if userToken.restricted == False or (userToken.restricted == True and packetID in packetsRestricted):
|
||||||
|
eventHandler[packetID]()
|
||||||
|
else:
|
||||||
|
log.warning("Ignored packet id from {} ({}) (user is restricted)".format(requestTokenString, packetID))
|
||||||
else:
|
else:
|
||||||
log.warning("Unknown packet id from {} ({})".format(requestTokenString, packetID))
|
log.warning("Unknown packet id from {} ({})".format(requestTokenString, packetID))
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import json
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
|
|
||||||
# API URL
|
# API URL
|
||||||
URL = "http://ip.zxq.co/"
|
URL = "http://ipinfo.io/"
|
||||||
|
|
||||||
|
|
||||||
def getCountry(ip):
|
def getCountry(ip):
|
||||||
|
|
|
@ -100,6 +100,14 @@ def packData(__data, __dataType):
|
||||||
# Bytes, do not use pack, do manually
|
# Bytes, do not use pack, do manually
|
||||||
pack = False
|
pack = False
|
||||||
data = __data
|
data = __data
|
||||||
|
elif __dataType == dataTypes.intList:
|
||||||
|
# Pack manually
|
||||||
|
pack = False
|
||||||
|
# Add length
|
||||||
|
data = packData(len(__data), dataTypes.uInt16)
|
||||||
|
# Add all elements
|
||||||
|
for i in __data:
|
||||||
|
data += packData(i, dataTypes.sInt32)
|
||||||
elif __dataType == dataTypes.string:
|
elif __dataType == dataTypes.string:
|
||||||
# String, do not use pack, do manually
|
# String, do not use pack, do manually
|
||||||
pack = False
|
pack = False
|
||||||
|
|
|
@ -4,6 +4,7 @@ from helpers import generalFunctions
|
||||||
from objects import glob
|
from objects import glob
|
||||||
from helpers import logHelper as log
|
from helpers import logHelper as log
|
||||||
import time
|
import time
|
||||||
|
from constants import privileges
|
||||||
|
|
||||||
def getID(username):
|
def getID(username):
|
||||||
"""
|
"""
|
||||||
|
@ -67,27 +68,6 @@ def exists(userID):
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def getAllowed(userID):
|
|
||||||
"""
|
|
||||||
Get allowed status for userID
|
|
||||||
|
|
||||||
db -- database connection
|
|
||||||
userID -- user ID
|
|
||||||
return -- allowed int
|
|
||||||
"""
|
|
||||||
|
|
||||||
return glob.db.fetch("SELECT allowed FROM users WHERE id = %s", [userID])["allowed"]
|
|
||||||
|
|
||||||
|
|
||||||
def getRankPrivileges(userID):
|
|
||||||
"""
|
|
||||||
This returns rank **(PRIVILEGES)**, not game rank (like #1337)
|
|
||||||
If you want to get that rank, user getUserGameRank instead
|
|
||||||
"""
|
|
||||||
|
|
||||||
return glob.db.fetch("SELECT rank FROM users WHERE id = %s", [userID])["rank"]
|
|
||||||
|
|
||||||
|
|
||||||
def getSilenceEnd(userID):
|
def getSilenceEnd(userID):
|
||||||
"""
|
"""
|
||||||
Get userID's **ABSOLUTE** silence end UNIX time
|
Get userID's **ABSOLUTE** silence end UNIX time
|
||||||
|
@ -279,16 +259,6 @@ def getPP(userID, gameMode):
|
||||||
modeForDB = gameModes.getGameModeForDB(gameMode)
|
modeForDB = gameModes.getGameModeForDB(gameMode)
|
||||||
return glob.db.fetch("SELECT pp_{} FROM users_stats WHERE id = %s".format(modeForDB), [userID])["pp_{}".format(modeForDB)]
|
return glob.db.fetch("SELECT pp_{} FROM users_stats WHERE id = %s".format(modeForDB), [userID])["pp_{}".format(modeForDB)]
|
||||||
|
|
||||||
def setAllowed(userID, allowed):
|
|
||||||
"""
|
|
||||||
Set userID's allowed status
|
|
||||||
|
|
||||||
userID -- user
|
|
||||||
allowed -- allowed status. 1: normal, 0: banned
|
|
||||||
"""
|
|
||||||
banDateTime = int(time.time()) if allowed == 0 else 0
|
|
||||||
glob.db.execute("UPDATE users SET allowed = %s, ban_datetime = %s WHERE id = %s", [allowed, banDateTime, userID])
|
|
||||||
|
|
||||||
def setCountry(userID, country):
|
def setCountry(userID, country):
|
||||||
"""
|
"""
|
||||||
Set userID's country (two letters)
|
Set userID's country (two letters)
|
||||||
|
@ -375,3 +345,102 @@ def getUserStats(userID, gameMode):
|
||||||
|
|
||||||
# Return stats + game rank
|
# Return stats + game rank
|
||||||
return stats
|
return stats
|
||||||
|
|
||||||
|
def isAllowed(userID):
|
||||||
|
"""
|
||||||
|
Check if userID is not banned or restricted
|
||||||
|
|
||||||
|
userID -- id of the user
|
||||||
|
return -- True if not banned or restricted, otherwise false.
|
||||||
|
"""
|
||||||
|
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
||||||
|
if result != None:
|
||||||
|
return (result["privileges"] & privileges.USER_NORMAL) and (result["privileges"] & privileges.USER_PUBLIC)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def isRestricted(userID):
|
||||||
|
"""
|
||||||
|
Check if userID is restricted
|
||||||
|
|
||||||
|
userID -- id of the user
|
||||||
|
return -- True if not restricted, otherwise false.
|
||||||
|
"""
|
||||||
|
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
||||||
|
if result != None:
|
||||||
|
return (result["privileges"] & privileges.USER_NORMAL) and not (result["privileges"] & privileges.USER_PUBLIC)
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def isBanned(userID):
|
||||||
|
"""
|
||||||
|
Check if userID is banned
|
||||||
|
|
||||||
|
userID -- id of the user
|
||||||
|
return -- True if not banned, otherwise false.
|
||||||
|
"""
|
||||||
|
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
||||||
|
if result != None:
|
||||||
|
return not (result["privileges"] & privileges.USER_NORMAL) and not (result["privileges"] & privileges.USER_PUBLIC)
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
def ban(userID):
|
||||||
|
"""
|
||||||
|
Ban userID
|
||||||
|
|
||||||
|
userID -- id of user
|
||||||
|
"""
|
||||||
|
banDateTime = int(time.time())
|
||||||
|
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s", [ ~(privileges.USER_NORMAL | privileges.USER_PUBLIC) , banDateTime, userID])
|
||||||
|
|
||||||
|
def unban(userID):
|
||||||
|
"""
|
||||||
|
Unban userID
|
||||||
|
|
||||||
|
userID -- id of user
|
||||||
|
"""
|
||||||
|
glob.db.execute("UPDATE users SET privileges = privileges | %s, ban_datetime = 0 WHERE id = %s", [ (privileges.USER_NORMAL | privileges.USER_PUBLIC) , userID])
|
||||||
|
|
||||||
|
def restrict(userID):
|
||||||
|
"""
|
||||||
|
Put userID in restricted mode
|
||||||
|
|
||||||
|
userID -- id of user
|
||||||
|
"""
|
||||||
|
banDateTime = int(time.time())
|
||||||
|
glob.db.execute("UPDATE users SET privileges = privileges & %s, ban_datetime = %s WHERE id = %s", [~privileges.USER_PUBLIC, banDateTime, userID])
|
||||||
|
|
||||||
|
def unrestrict(userID):
|
||||||
|
"""
|
||||||
|
Remove restricted mode from userID.
|
||||||
|
Same as unban().
|
||||||
|
|
||||||
|
userID -- id of user
|
||||||
|
"""
|
||||||
|
unban(userID)
|
||||||
|
|
||||||
|
def getPrivileges(userID):
|
||||||
|
"""
|
||||||
|
Return privileges for userID
|
||||||
|
|
||||||
|
userID -- id of user
|
||||||
|
return -- privileges number
|
||||||
|
"""
|
||||||
|
result = glob.db.fetch("SELECT privileges FROM users WHERE id = %s", [userID])
|
||||||
|
if result != None:
|
||||||
|
return result["privileges"]
|
||||||
|
else:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
def isInPrivilegeGroup(userID, groupName):
|
||||||
|
groupPrivileges = glob.db.fetch("SELECT privileges FROM privileges_groups WHERE name = %s", [groupName])
|
||||||
|
if groupPrivileges == None:
|
||||||
|
return False
|
||||||
|
groupPrivileges = groupPrivileges["privileges"]
|
||||||
|
userToken = glob.tokens.getTokenFromUserID(userID)
|
||||||
|
if userToken != None:
|
||||||
|
userPrivileges = userToken.privileges
|
||||||
|
else:
|
||||||
|
userPrivileges = getPrivileges(userID)
|
||||||
|
return (userPrivileges == groupPrivileges) or (userPrivileges == (groupPrivileges | privileges.USER_DONOR))
|
||||||
|
|
|
@ -47,16 +47,10 @@ def fokabotResponse(fro, chan, message):
|
||||||
# message has triggered a command
|
# message has triggered a command
|
||||||
|
|
||||||
# Make sure the user has right permissions
|
# Make sure the user has right permissions
|
||||||
if i["rank"] != None:
|
if i["privileges"] != None:
|
||||||
# Rank = x
|
# Rank = x
|
||||||
if userHelper.getRankPrivileges(userHelper.getID(fro)) != i["rank"]:
|
if userHelper.getPrivileges(userHelper.getID(fro)) & i["privileges"] == 0:
|
||||||
return False
|
return False
|
||||||
else:
|
|
||||||
# Rank > x
|
|
||||||
if i["minRank"] > 1:
|
|
||||||
# Get rank from db only if minrank > 1, so we save some CPU
|
|
||||||
if userHelper.getRankPrivileges(userHelper.getID(fro)) < i["minRank"]:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Check argument number
|
# Check argument number
|
||||||
message = message.split(" ")
|
message = message.split(" ")
|
||||||
|
|
|
@ -8,6 +8,7 @@ from objects import glob
|
||||||
import uuid
|
import uuid
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
|
from helpers import logHelper as log
|
||||||
|
|
||||||
class token:
|
class token:
|
||||||
"""
|
"""
|
||||||
|
@ -16,7 +17,6 @@ class token:
|
||||||
token -- token string
|
token -- token string
|
||||||
userID -- userID associated to that token
|
userID -- userID associated to that token
|
||||||
username -- username relative to userID (cache)
|
username -- username relative to userID (cache)
|
||||||
rank -- rank (permissions) relative to userID (cache)
|
|
||||||
actionID -- current user action (see actions.py)
|
actionID -- current user action (see actions.py)
|
||||||
actionText -- current user action text
|
actionText -- current user action text
|
||||||
actionMd5 -- md5 relative to user action
|
actionMd5 -- md5 relative to user action
|
||||||
|
@ -47,7 +47,11 @@ class token:
|
||||||
# Set stuff
|
# Set stuff
|
||||||
self.userID = __userID
|
self.userID = __userID
|
||||||
self.username = userHelper.getUsername(self.userID)
|
self.username = userHelper.getUsername(self.userID)
|
||||||
self.rank = userHelper.getRankPrivileges(self.userID)
|
self.privileges = userHelper.getPrivileges(self.userID)
|
||||||
|
self.admin = userHelper.isInPrivilegeGroup(self.userID, "developer") or userHelper.isInPrivilegeGroup(self.userID, "community manager")
|
||||||
|
self.restricted = userHelper.isRestricted(self.userID)
|
||||||
|
if self.restricted == True:
|
||||||
|
self.setRestricted()
|
||||||
self.loginTime = int(time.time())
|
self.loginTime = int(time.time())
|
||||||
self.pingTime = self.loginTime
|
self.pingTime = self.loginTime
|
||||||
self.lock = threading.Lock() # Sync primitive
|
self.lock = threading.Lock() # Sync primitive
|
||||||
|
@ -69,7 +73,6 @@ class token:
|
||||||
|
|
||||||
# Spam protection
|
# Spam protection
|
||||||
self.spamRate = 0
|
self.spamRate = 0
|
||||||
#self.lastMessagetime = 0
|
|
||||||
|
|
||||||
# Stats cache
|
# Stats cache
|
||||||
self.actionID = actions.idle
|
self.actionID = actions.idle
|
||||||
|
@ -295,3 +298,11 @@ class token:
|
||||||
self.totalScore = stats["totalScore"]
|
self.totalScore = stats["totalScore"]
|
||||||
self.gameRank = stats["gameRank"]
|
self.gameRank = stats["gameRank"]
|
||||||
self.pp = stats["pp"]
|
self.pp = stats["pp"]
|
||||||
|
|
||||||
|
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."))
|
||||||
|
|
Loading…
Reference in New Issue
Block a user