.BANCHO. pep.py modules
This commit is contained in:
21
events/cantSpectateEvent.py
Normal file
21
events/cantSpectateEvent.py
Normal file
@@ -0,0 +1,21 @@
|
||||
from objects import glob
|
||||
from constants import serverPackets
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from constants import exceptions
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# get usertoken data
|
||||
userID = userToken.userID
|
||||
|
||||
try:
|
||||
# We don't have the beatmap, we can't spectate
|
||||
target = userToken.spectating
|
||||
targetToken = glob.tokens.getTokenFromUserID(target)
|
||||
|
||||
# Send the packet to host
|
||||
targetToken.enqueue(serverPackets.noSongSpectator(userID))
|
||||
except exceptions.tokenNotFoundException:
|
||||
# Stop spectating if token not found
|
||||
consoleHelper.printColored("[!] Spectator can't spectate: token not found", bcolors.RED)
|
||||
userToken.stopSpectating()
|
32
events/changeActionEvent.py
Normal file
32
events/changeActionEvent.py
Normal file
@@ -0,0 +1,32 @@
|
||||
from objects import glob
|
||||
from constants import clientPackets
|
||||
from constants import serverPackets
|
||||
from constants import actions
|
||||
from helpers import userHelper
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Get usertoken data
|
||||
userID = userToken.userID
|
||||
username = userToken.username
|
||||
|
||||
# Make sure we are not banned
|
||||
if userHelper.getAllowed(userID) == 0:
|
||||
userToken.enqueue(serverPackets.loginBanned())
|
||||
return
|
||||
|
||||
# Change action packet
|
||||
packetData = clientPackets.userActionChange(packetData)
|
||||
|
||||
# Update our action id, text and md5
|
||||
userToken.actionID = packetData["actionID"]
|
||||
userToken.actionText = packetData["actionText"]
|
||||
userToken.actionMd5 = packetData["actionMd5"]
|
||||
userToken.actionMods = packetData["actionMods"]
|
||||
userToken.gameMode = packetData["gameMode"]
|
||||
|
||||
# Enqueue our new user panel and stats to everyone
|
||||
glob.tokens.enqueueAll(serverPackets.userPanel(userID))
|
||||
glob.tokens.enqueueAll(serverPackets.userStats(userID))
|
||||
|
||||
# Console output
|
||||
print("> {} changed action: {} [{}][{}]".format(username, str(userToken.actionID), userToken.actionText, userToken.actionMd5))
|
43
events/changeMatchModsEvent.py
Normal file
43
events/changeMatchModsEvent.py
Normal file
@@ -0,0 +1,43 @@
|
||||
from objects import glob
|
||||
from constants import clientPackets
|
||||
from constants import matchModModes
|
||||
from constants import mods
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Get token data
|
||||
userID = userToken.userID
|
||||
|
||||
# Get packet data
|
||||
packetData = clientPackets.changeMods(packetData)
|
||||
|
||||
# Make sure the match exists
|
||||
matchID = userToken.matchID
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Set slot or match mods according to modType
|
||||
if match.matchModMode == matchModModes.freeMod:
|
||||
# Freemod
|
||||
|
||||
# Host can set global DT/HT
|
||||
if userID == match.hostUserID:
|
||||
# If host has selected DT/HT and Freemod is enabled, set DT/HT as match mod
|
||||
if (packetData["mods"] & mods.DoubleTime) > 0:
|
||||
match.changeMatchMods(mods.DoubleTime)
|
||||
# Nighcore
|
||||
if (packetData["mods"] & mods.Nightcore) > 0:
|
||||
match.changeMatchMods(match.mods+mods.Nightcore)
|
||||
elif (packetData["mods"] & mods.HalfTime) > 0:
|
||||
match.changeMatchMods(mods.HalfTime)
|
||||
else:
|
||||
# No DT/HT, set global mods to 0 (we are in freemod mode)
|
||||
match.changeMatchMods(0)
|
||||
|
||||
# Set slot mods
|
||||
slotID = match.getUserSlotID(userID)
|
||||
if slotID != None:
|
||||
match.setSlotMods(slotID, packetData["mods"])
|
||||
else:
|
||||
# Not freemod, set match mods
|
||||
match.changeMatchMods(packetData["mods"])
|
17
events/changeMatchPasswordEvent.py
Normal file
17
events/changeMatchPasswordEvent.py
Normal file
@@ -0,0 +1,17 @@
|
||||
from constants import clientPackets
|
||||
from objects import glob
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Read packet data. Same structure as changeMatchSettings
|
||||
packetData = clientPackets.changeMatchSettings(packetData)
|
||||
|
||||
# Make sure the match exists
|
||||
matchID = userToken.matchID
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# Get our match
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Update match password
|
||||
match.changePassword(packetData["matchPassword"])
|
109
events/changeMatchSettingsEvent.py
Normal file
109
events/changeMatchSettingsEvent.py
Normal file
@@ -0,0 +1,109 @@
|
||||
from objects import glob
|
||||
from constants import clientPackets
|
||||
from constants import matchModModes
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
import random
|
||||
from constants import matchTeamTypes
|
||||
from constants import matchTeams
|
||||
from constants import slotStatuses
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Read new settings
|
||||
packetData = clientPackets.changeMatchSettings(packetData)
|
||||
|
||||
# Get match ID
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# Get match object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Some dank memes easter egg
|
||||
memeTitles = [
|
||||
"RWC 2020",
|
||||
"Fokabot is a duck",
|
||||
"Dank memes",
|
||||
"1337ms Ping",
|
||||
"Iscriviti a Xenotoze",
|
||||
"...e i marò?",
|
||||
"Superman dies",
|
||||
"The brace is on fire",
|
||||
"print_foot()",
|
||||
"#FREEZEBARKEZ",
|
||||
"Ripple devs are actually cats",
|
||||
"Thank Mr Shaural",
|
||||
"NEVER GIVE UP",
|
||||
"T I E D W I T H U N I T E D",
|
||||
"HIGHEST HDHR LOBBY OF ALL TIME",
|
||||
"This is gasoline and I set myself on fire",
|
||||
"Everyone is cheating apparently",
|
||||
"Kurwa mac",
|
||||
"TATOE",
|
||||
"This is not your drama landfill.",
|
||||
"I like cheese",
|
||||
"NYO IS NOT A CAT HE IS A DO(N)G",
|
||||
"Datingu startuato"
|
||||
]
|
||||
|
||||
# Set match name
|
||||
match.matchName = packetData["matchName"] if packetData["matchName"] != "meme" else random.choice(memeTitles)
|
||||
|
||||
# Update match settings
|
||||
match.inProgress = packetData["inProgress"]
|
||||
match.matchPassword = packetData["matchPassword"]
|
||||
match.beatmapName = packetData["beatmapName"]
|
||||
match.beatmapID = packetData["beatmapID"]
|
||||
match.hostUserID = packetData["hostUserID"]
|
||||
match.gameMode = packetData["gameMode"]
|
||||
|
||||
oldBeatmapMD5 = match.beatmapMD5
|
||||
oldMods = match.mods
|
||||
|
||||
match.mods = packetData["mods"]
|
||||
match.beatmapMD5 = packetData["beatmapMD5"]
|
||||
match.matchScoringType = packetData["scoringType"]
|
||||
match.matchTeamType = packetData["teamType"]
|
||||
match.matchModMode = packetData["freeMods"]
|
||||
|
||||
# Reset ready if needed
|
||||
if oldMods != match.mods or oldBeatmapMD5 != match.beatmapMD5:
|
||||
for i in range(0,16):
|
||||
if match.slots[i]["status"] == slotStatuses.ready:
|
||||
match.slots[i]["status"] = slotStatuses.notReady
|
||||
|
||||
# Reset mods if needed
|
||||
if match.matchModMode == matchModModes.normal:
|
||||
# Reset slot mods if not freeMods
|
||||
for i in range(0,16):
|
||||
match.slots[i]["mods"] = 0
|
||||
else:
|
||||
# Reset match mods if freemod
|
||||
match.mods = 0
|
||||
|
||||
# Set/reset teams
|
||||
if match.matchTeamType == matchTeamTypes.teamVs or match.matchTeamType == matchTeamTypes.tagTeamVs:
|
||||
# Set teams
|
||||
c=0
|
||||
for i in range(0,16):
|
||||
if match.slots[i]["team"] == matchTeams.noTeam:
|
||||
match.slots[i]["team"] = matchTeams.red if c % 2 == 0 else matchTeams.blue
|
||||
c+=1
|
||||
else:
|
||||
# Reset teams
|
||||
for i in range(0,16):
|
||||
match.slots[i]["team"] = matchTeams.noTeam
|
||||
|
||||
# Force no freemods if tag coop
|
||||
if match.matchTeamType == matchTeamTypes.tagCoop or match.matchTeamType == matchTeamTypes.tagTeamVs:
|
||||
match.matchModMode = matchModModes.normal
|
||||
|
||||
# Send updated settings
|
||||
match.sendUpdate()
|
||||
|
||||
# Console output
|
||||
consoleHelper.printColored("> MPROOM{}: Updated room settings".format(match.matchID), bcolors.BLUE)
|
||||
#consoleHelper.printColored("> MPROOM{}: DEBUG: Host is {}".format(match.matchID, match.hostUserID), bcolors.PINK)
|
18
events/changeSlotEvent.py
Normal file
18
events/changeSlotEvent.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from constants import clientPackets
|
||||
from objects import glob
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Get usertoken data
|
||||
userID = userToken.userID
|
||||
username = userToken.username
|
||||
|
||||
# Read packet data
|
||||
packetData = clientPackets.changeSlot(packetData)
|
||||
|
||||
# Get match
|
||||
match = glob.matches.matches[userToken.matchID]
|
||||
|
||||
# Change slot
|
||||
match.userChangeSlot(userID, packetData["slotID"])
|
56
events/channelJoinEvent.py
Normal file
56
events/channelJoinEvent.py
Normal file
@@ -0,0 +1,56 @@
|
||||
"""
|
||||
Event called when someone joins a channel
|
||||
"""
|
||||
|
||||
from constants import clientPackets
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from constants import serverPackets
|
||||
from objects import glob
|
||||
from constants import exceptions
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Channel join packet
|
||||
packetData = clientPackets.channelJoin(packetData)
|
||||
joinChannel(userToken, packetData["channel"])
|
||||
|
||||
def joinChannel(userToken, channelName):
|
||||
'''
|
||||
Join a channel
|
||||
|
||||
userToken -- user token object of user that joins the chanlle
|
||||
channelName -- name of channel
|
||||
'''
|
||||
try:
|
||||
# Get usertoken data
|
||||
username = userToken.username
|
||||
userID = userToken.userID
|
||||
userRank = userToken.rank
|
||||
|
||||
# Check spectator channel
|
||||
# If it's spectator channel, skip checks and list stuff
|
||||
if channelName != "#spectator" and channelName != "#multiplayer":
|
||||
# Normal channel, do check stuff
|
||||
# Make sure the channel exists
|
||||
if channelName not in glob.channels.channels:
|
||||
raise exceptions.channelUnknownException
|
||||
|
||||
# Check channel permissions
|
||||
if glob.channels.channels[channelName].publicRead == False and userRank <= 2:
|
||||
raise exceptions.channelNoPermissionsException
|
||||
|
||||
# Add our userID to users in that channel
|
||||
glob.channels.channels[channelName].userJoin(userID)
|
||||
|
||||
# Add the channel to our joined channel
|
||||
userToken.joinChannel(channelName)
|
||||
|
||||
# Send channel joined
|
||||
userToken.enqueue(serverPackets.channelJoinSuccess(userID, channelName))
|
||||
|
||||
# Console output
|
||||
consoleHelper.printColored("> {} joined channel {}".format(username, channelName), bcolors.GREEN)
|
||||
except exceptions.channelNoPermissionsException:
|
||||
consoleHelper.printColored("[!] {} attempted to join channel {}, but they have no read permissions".format(username, channelName), bcolors.RED)
|
||||
except exceptions.channelUnknownException:
|
||||
consoleHelper.printColored("[!] {} attempted to join an unknown channel ({})".format(username, channelName), bcolors.RED)
|
36
events/channelPartEvent.py
Normal file
36
events/channelPartEvent.py
Normal file
@@ -0,0 +1,36 @@
|
||||
"""
|
||||
Event called when someone parts a channel
|
||||
"""
|
||||
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from objects import glob
|
||||
from constants import clientPackets
|
||||
from constants import serverPackets
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Channel part packet
|
||||
packetData = clientPackets.channelPart(packetData)
|
||||
partChannel(userToken, packetData["channel"])
|
||||
|
||||
def partChannel(userToken, channelName, kick = False):
|
||||
# Get usertoken data
|
||||
username = userToken.username
|
||||
userID = userToken.userID
|
||||
|
||||
# Remove us from joined users and joined channels
|
||||
if channelName in glob.channels.channels:
|
||||
# Check that user is in channel
|
||||
if channelName in userToken.joinedChannels:
|
||||
userToken.partChannel(channelName)
|
||||
|
||||
# Check if user is in channel
|
||||
if userID in glob.channels.channels[channelName].connectedUsers:
|
||||
glob.channels.channels[channelName].userPart(userID)
|
||||
|
||||
# Force close tab if needed
|
||||
if kick == True:
|
||||
userToken.enqueue(serverPackets.channelKicked(channelName))
|
||||
|
||||
# Console output
|
||||
consoleHelper.printColored("> {} parted channel {}".format(username, channelName), bcolors.YELLOW)
|
44
events/createMatchEvent.py
Normal file
44
events/createMatchEvent.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from constants import serverPackets
|
||||
from constants import clientPackets
|
||||
from objects import glob
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from events import joinMatchEvent
|
||||
from constants import exceptions
|
||||
|
||||
def handle(userToken, packetData):
|
||||
try:
|
||||
# get usertoken data
|
||||
userID = userToken.userID
|
||||
|
||||
# Read packet data
|
||||
packetData = clientPackets.createMatch(packetData)
|
||||
|
||||
# Create a match object
|
||||
# TODO: Player number check
|
||||
matchID = glob.matches.createMatch(packetData["matchName"], packetData["matchPassword"], packetData["beatmapID"], packetData["beatmapName"], packetData["beatmapMD5"], packetData["gameMode"], userID)
|
||||
|
||||
# Make sure the match has been created
|
||||
if matchID not in glob.matches.matches:
|
||||
raise exceptions.matchCreateError
|
||||
|
||||
# Get match object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Join that match
|
||||
joinMatchEvent.joinMatch(userToken, matchID, packetData["matchPassword"])
|
||||
|
||||
# Give host to match creator
|
||||
match.setHost(userID)
|
||||
|
||||
# Send match create packet to everyone in lobby
|
||||
for i in glob.matches.usersInLobby:
|
||||
# Make sure this user is still connected
|
||||
token = glob.tokens.getTokenFromUserID(i)
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.createMatch(matchID))
|
||||
|
||||
# Console output
|
||||
consoleHelper.printColored("> MPROOM{}: Room created!".format(matchID), bcolors.BLUE)
|
||||
except exceptions.matchCreateError:
|
||||
consoleHelper.printColored("[!] Error while creating match!", bcolors.RED)
|
10
events/friendAddEvent.py
Normal file
10
events/friendAddEvent.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from helpers import userHelper
|
||||
from constants import clientPackets
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Friend add packet
|
||||
packetData = clientPackets.addRemoveFriend(packetData)
|
||||
userHelper.addFriend(userToken.userID, packetData["friendID"])
|
||||
|
||||
# Console output
|
||||
print("> {} have added {} to their friends".format(userToken.username, str(packetData["friendID"])))
|
10
events/friendRemoveEvent.py
Normal file
10
events/friendRemoveEvent.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from helpers import userHelper
|
||||
from constants import clientPackets
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Friend remove packet
|
||||
packetData = clientPackets.addRemoveFriend(packetData)
|
||||
userHelper.removeFriend(userToken.userID, packetData["friendID"])
|
||||
|
||||
# Console output
|
||||
print("> {} have removed {} from their friends".format(userToken.username, str(packetData["friendID"])))
|
19
events/joinLobbyEvent.py
Normal file
19
events/joinLobbyEvent.py
Normal file
@@ -0,0 +1,19 @@
|
||||
from constants import serverPackets
|
||||
from objects import glob
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
|
||||
def handle(userToken, _):
|
||||
# Get userToken data
|
||||
username = userToken.username
|
||||
userID = userToken.userID
|
||||
|
||||
# Add user to users in lobby
|
||||
glob.matches.lobbyUserJoin(userID)
|
||||
|
||||
# Send matches data
|
||||
for key, _ in glob.matches.matches.items():
|
||||
userToken.enqueue(serverPackets.createMatch(key))
|
||||
|
||||
# Console output
|
||||
consoleHelper.printColored("> {} has joined multiplayer lobby".format(username), bcolors.BLUE)
|
60
events/joinMatchEvent.py
Normal file
60
events/joinMatchEvent.py
Normal file
@@ -0,0 +1,60 @@
|
||||
from constants import clientPackets
|
||||
from constants import serverPackets
|
||||
from objects import glob
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from constants import exceptions
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# read packet data
|
||||
packetData = clientPackets.joinMatch(packetData)
|
||||
|
||||
# Get match from ID
|
||||
joinMatch(userToken, packetData["matchID"], packetData["password"])
|
||||
|
||||
|
||||
def joinMatch(userToken, matchID, password):
|
||||
try:
|
||||
# TODO: leave other matches
|
||||
# TODO: Stop spectating
|
||||
|
||||
# get usertoken data
|
||||
userID = userToken.userID
|
||||
username = userToken.username
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
raise exceptions.matchNotFoundException
|
||||
|
||||
# Match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Check password
|
||||
# TODO: Admins can enter every match
|
||||
if match.matchPassword != "":
|
||||
if match.matchPassword != password:
|
||||
raise exceptions.matchWrongPasswordException
|
||||
|
||||
# Password is correct, join match
|
||||
result = match.userJoin(userID)
|
||||
|
||||
# Check if we've joined the match successfully
|
||||
if result == False:
|
||||
raise exceptions.matchJoinErrorException
|
||||
|
||||
# Match joined, set matchID for usertoken
|
||||
userToken.joinMatch(matchID)
|
||||
|
||||
# Send packets
|
||||
userToken.enqueue(serverPackets.matchJoinSuccess(matchID))
|
||||
userToken.enqueue(serverPackets.channelJoinSuccess(userID, "#multiplayer"))
|
||||
#userToken.enqueue(serverPackets.sendMessage("FokaBot", "#multiplayer", "Hi {}, and welcome to Ripple's multiplayer mode! This feature is still WIP and might have some issues. If you find any bugs, please report them (by clicking here)[https://ripple.moe/index.php?p=22].".format(username)))
|
||||
except exceptions.matchNotFoundException:
|
||||
userToken.enqueue(serverPackets.matchJoinFail())
|
||||
consoleHelper.printColored("[!] {} has tried to join a mp room, but it doesn't exist".format(userToken.username), bcolors.RED)
|
||||
except exceptions.matchWrongPasswordException:
|
||||
userToken.enqueue(serverPackets.matchJoinFail())
|
||||
consoleHelper.printColored("[!] {} has tried to join a mp room, but he typed the wrong password".format(userToken.username), bcolors.RED)
|
||||
except exceptions.matchJoinErrorException:
|
||||
userToken.enqueue(serverPackets.matchJoinFail())
|
||||
consoleHelper.printColored("[!] {} has tried to join a mp room, but an error has occured".format(userToken.username), bcolors.RED)
|
184
events/loginEvent.py
Normal file
184
events/loginEvent.py
Normal file
@@ -0,0 +1,184 @@
|
||||
from helpers import userHelper
|
||||
from constants import serverPackets
|
||||
from constants import exceptions
|
||||
from objects import glob
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from helpers import locationHelper
|
||||
from helpers import countryHelper
|
||||
import time
|
||||
from helpers import generalFunctions
|
||||
from events import channelJoinEvent
|
||||
import sys
|
||||
import traceback
|
||||
|
||||
def handle(flaskRequest):
|
||||
# Data to return
|
||||
responseTokenString = "ayy"
|
||||
responseData = bytes()
|
||||
|
||||
# Get IP from flask request
|
||||
requestIP = flaskRequest.headers.get('X-Real-IP')
|
||||
if requestIP == None:
|
||||
requestIP = flaskRequest.remote_addr
|
||||
|
||||
# Console output
|
||||
print("> Accepting connection from {}...".format(requestIP))
|
||||
|
||||
# Split POST body so we can get username/password/hardware data
|
||||
# 2:-3 thing is because requestData has some escape stuff that we don't need
|
||||
loginData = str(flaskRequest.data)[2:-3].split("\\n")
|
||||
|
||||
# Process login
|
||||
print("> Processing login request for {}...".format(loginData[0]))
|
||||
try:
|
||||
# If true, print error to console
|
||||
err = False
|
||||
|
||||
# Try to get the ID from username
|
||||
userID = userHelper.getID(str(loginData[0]))
|
||||
|
||||
if userID == False:
|
||||
# Invalid username
|
||||
raise exceptions.loginFailedException()
|
||||
if userHelper.checkLogin(userID, loginData[1]) == False:
|
||||
# Invalid password
|
||||
raise exceptions.loginFailedException()
|
||||
|
||||
# Make sure we are not banned
|
||||
userAllowed = userHelper.getAllowed(userID)
|
||||
if userAllowed == 0:
|
||||
# Banned
|
||||
raise exceptions.loginBannedException()
|
||||
|
||||
# No login errors!
|
||||
# Delete old tokens for that user and generate a new one
|
||||
glob.tokens.deleteOldTokens(userID)
|
||||
responseToken = glob.tokens.addToken(userID)
|
||||
responseTokenString = responseToken.token
|
||||
|
||||
# Get silence end
|
||||
userSilenceEnd = max(0, userHelper.getSilenceEnd(userID)-int(time.time()))
|
||||
|
||||
# Get supporter/GMT
|
||||
userRank = userHelper.getRankPrivileges(userID)
|
||||
userGMT = False
|
||||
userSupporter = True
|
||||
if userRank >= 3:
|
||||
userGMT = True
|
||||
|
||||
# Server restarting check
|
||||
if glob.restarting == True:
|
||||
raise exceptions.banchoRestartingException()
|
||||
|
||||
# Maintenance check
|
||||
if glob.banchoConf.config["banchoMaintenance"] == True:
|
||||
if userGMT == False:
|
||||
# We are not mod/admin, delete token, send notification and logout
|
||||
glob.tokens.deleteToken(responseTokenString)
|
||||
raise exceptions.banchoMaintenanceException()
|
||||
else:
|
||||
# We are mod/admin, send warning notification and continue
|
||||
responseToken.enqueue(serverPackets.notification("Bancho is in maintenance mode. Only mods/admins have full access to the server.\nType !system maintenance off in chat to turn off maintenance mode."))
|
||||
|
||||
# Send all needed login packets
|
||||
responseToken.enqueue(serverPackets.silenceEndTime(userSilenceEnd))
|
||||
responseToken.enqueue(serverPackets.userID(userID))
|
||||
responseToken.enqueue(serverPackets.protocolVersion())
|
||||
responseToken.enqueue(serverPackets.userSupporterGMT(userSupporter, userGMT))
|
||||
responseToken.enqueue(serverPackets.userPanel(userID))
|
||||
responseToken.enqueue(serverPackets.userStats(userID))
|
||||
|
||||
# Channel info end (before starting!?! wtf bancho?)
|
||||
responseToken.enqueue(serverPackets.channelInfoEnd())
|
||||
|
||||
# Default opened channels
|
||||
# TODO: Configurable default channels
|
||||
channelJoinEvent.joinChannel(responseToken, "#osu")
|
||||
channelJoinEvent.joinChannel(responseToken, "#announce")
|
||||
if userRank >= 3:
|
||||
# Join admin chanenl if we are mod/admin
|
||||
# TODO: Separate channels for mods and admins
|
||||
channelJoinEvent.joinChannel(responseToken, "#admin")
|
||||
|
||||
# Output channels info
|
||||
for key, value in glob.channels.channels.items():
|
||||
if value.publicRead == True:
|
||||
responseToken.enqueue(serverPackets.channelInfo(key))
|
||||
|
||||
responseToken.enqueue(serverPackets.friendList(userID))
|
||||
|
||||
# Send main menu icon and login notification if needed
|
||||
if glob.banchoConf.config["menuIcon"] != "":
|
||||
responseToken.enqueue(serverPackets.mainMenuIcon(glob.banchoConf.config["menuIcon"]))
|
||||
|
||||
if glob.banchoConf.config["loginNotification"] != "":
|
||||
responseToken.enqueue(serverPackets.notification(glob.banchoConf.config["loginNotification"]))
|
||||
|
||||
# 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
|
||||
responseToken.enqueue(serverPackets.onlineUsers())
|
||||
|
||||
# Get location and country from ip.zxq.co or database
|
||||
if generalFunctions.stringToBool(glob.conf.config["server"]["localizeusers"]):
|
||||
# Get location and country from IP
|
||||
location = locationHelper.getLocation(requestIP)
|
||||
countryLetters = locationHelper.getCountry(requestIP)
|
||||
country = countryHelper.getCountryID(countryLetters)
|
||||
else:
|
||||
# Set location to 0,0 and get country from db
|
||||
print("[!] Location skipped")
|
||||
location = [0,0]
|
||||
countryLetters = "XX"
|
||||
country = countryHelper.getCountryID(userHelper.getCountry(userID))
|
||||
|
||||
# Set location and country
|
||||
responseToken.setLocation(location)
|
||||
responseToken.setCountry(country)
|
||||
|
||||
# Set country in db if user has no country (first bancho login)
|
||||
if userHelper.getCountry(userID) == "XX":
|
||||
userHelper.setCountry(userID, countryLetters)
|
||||
|
||||
# Send to everyone our userpanel and userStats (so they now we have logged in)
|
||||
glob.tokens.enqueueAll(serverPackets.userPanel(userID))
|
||||
glob.tokens.enqueueAll(serverPackets.userStats(userID))
|
||||
|
||||
# Set reponse data to right value and reset our queue
|
||||
responseData = responseToken.queue
|
||||
responseToken.resetQueue()
|
||||
|
||||
# Print logged in message
|
||||
consoleHelper.printColored("> {} logged in ({})".format(loginData[0], responseToken.token), bcolors.GREEN)
|
||||
except exceptions.loginFailedException:
|
||||
# Login failed error packet
|
||||
# (we don't use enqueue because we don't have a token since login has failed)
|
||||
err = True
|
||||
responseData += serverPackets.loginFailed()
|
||||
except exceptions.loginBannedException:
|
||||
# Login banned error packet
|
||||
err = True
|
||||
responseData += serverPackets.loginBanned()
|
||||
except exceptions.banchoMaintenanceException:
|
||||
# Bancho is in maintenance mode
|
||||
responseData += serverPackets.notification("Our bancho server is in maintenance mode. Please try to login again later.")
|
||||
responseData += serverPackets.loginError()
|
||||
except exceptions.banchoRestartingException:
|
||||
# Bancho is restarting
|
||||
responseData += serverPackets.notification("Bancho is restarting. Try again in a few minutes.")
|
||||
responseData += serverPackets.loginError()
|
||||
except:
|
||||
# Unknown exception
|
||||
msg = "UNKNOWN ERROR IN LOGIN!!!\n{}\n{}".format(sys.exc_info(), traceback.format_exc())
|
||||
consoleHelper.printColored("[!] {}".format(msg), bcolors.RED)
|
||||
finally:
|
||||
# Print login failed message to console if needed
|
||||
if err == True:
|
||||
consoleHelper.printColored("> {}'s login failed".format(loginData[0]), bcolors.YELLOW)
|
||||
|
||||
return (responseTokenString, responseData)
|
39
events/logoutEvent.py
Normal file
39
events/logoutEvent.py
Normal file
@@ -0,0 +1,39 @@
|
||||
from objects import glob
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from constants import serverPackets
|
||||
import time
|
||||
|
||||
def handle(userToken, _):
|
||||
# get usertoken data
|
||||
userID = userToken.userID
|
||||
username = userToken.username
|
||||
requestToken = userToken.token
|
||||
|
||||
# Big client meme here. If someone logs out and logs in right after,
|
||||
# the old logout packet will still be in the queue and will be sent to
|
||||
# the server, so we accept logout packets sent at least 5 seconds after login
|
||||
# if the user logs out before 5 seconds, he will be disconnected later with timeout check
|
||||
if int(time.time()-userToken.loginTime) >= 5:
|
||||
# Stop spectating if needed
|
||||
if userToken.spectating != 0:
|
||||
# The user was spectating someone
|
||||
spectatorHostToken = glob.tokens.getTokenFromUserID(userToken.spectating)
|
||||
if spectatorHostToken != None:
|
||||
# The host is still online, send removeSpectator to him
|
||||
spectatorHostToken.enqueue(serverPackets.removeSpectator(userID))
|
||||
|
||||
# Part all joined channels
|
||||
for i in userToken.joinedChannels:
|
||||
glob.channels.channels[i].userPart(userID)
|
||||
|
||||
# TODO: Lobby left if joined
|
||||
|
||||
# Enqueue our disconnection to everyone else
|
||||
glob.tokens.enqueueAll(serverPackets.userLogout(userID))
|
||||
|
||||
# Delete token
|
||||
glob.tokens.deleteToken(requestToken)
|
||||
|
||||
# Console output
|
||||
consoleHelper.printColored("> {} have been disconnected.".format(username), bcolors.YELLOW)
|
22
events/matchBeatmapEvent.py
Normal file
22
events/matchBeatmapEvent.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from objects import glob
|
||||
|
||||
def handle(userToken, packetData, has):
|
||||
# Get usertoken data
|
||||
userID = userToken.userID
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# The match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Set has beatmap/no beatmap
|
||||
match.userHasBeatmap(userID, has)
|
22
events/matchChangeTeamEvent.py
Normal file
22
events/matchChangeTeamEvent.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from objects import glob
|
||||
|
||||
def handle(userToken, _):
|
||||
# Read token data
|
||||
userID = userToken.userID
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# Get match object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Change team
|
||||
match.changeTeam(userID)
|
22
events/matchCompleteEvent.py
Normal file
22
events/matchCompleteEvent.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from objects import glob
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Get usertoken data
|
||||
userID = userToken.userID
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# The match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Set our match complete
|
||||
match.playerCompleted(userID)
|
22
events/matchFailedEvent.py
Normal file
22
events/matchFailedEvent.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from objects import glob
|
||||
|
||||
def handle(userToken, _):
|
||||
# Get usertoken data
|
||||
userID = userToken.userID
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# Match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Fail user
|
||||
match.playerFailed(userID)
|
35
events/matchFramesEvent.py
Normal file
35
events/matchFramesEvent.py
Normal file
@@ -0,0 +1,35 @@
|
||||
from objects import glob
|
||||
from constants import slotStatuses
|
||||
from constants import serverPackets
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Get usertoken data
|
||||
userID = userToken.userID
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# The match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Change slot id in packetData
|
||||
slotID = match.getUserSlotID(userID)
|
||||
'''opd = packetData[4]
|
||||
packetData = bytearray(packetData)
|
||||
packetData[4] = slotID
|
||||
print("User: {}, slot {}, oldPackData: {}, packData {}".format(userID, slotID, opd, packetData[4]))'''
|
||||
|
||||
# Enqueue frames to who's playing
|
||||
for i in range(0,16):
|
||||
if match.slots[i]["userID"] > -1 and match.slots[i]["status"] == slotStatuses.playing:
|
||||
token = glob.tokens.getTokenFromUserID(match.slots[i]["userID"])
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.matchFrames(slotID, packetData))
|
3
events/matchHasBeatmapEvent.py
Normal file
3
events/matchHasBeatmapEvent.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from events import matchBeatmapEvent
|
||||
def handle(userToken, packetData):
|
||||
matchBeatmapEvent.handle(userToken, packetData, True)
|
24
events/matchInviteEvent.py
Normal file
24
events/matchInviteEvent.py
Normal file
@@ -0,0 +1,24 @@
|
||||
from constants import clientPackets
|
||||
from objects import glob
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Read token and packet data
|
||||
userID = userToken.userID
|
||||
packetData = clientPackets.matchInvite(packetData)
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# Get match object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Send invite
|
||||
match.invite(userID, packetData["userID"])
|
23
events/matchLockEvent.py
Normal file
23
events/matchLockEvent.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from objects import glob
|
||||
from constants import clientPackets
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Get token data
|
||||
userID = userToken.userID
|
||||
|
||||
# Get packet data
|
||||
packetData = clientPackets.lockSlot(packetData)
|
||||
|
||||
# Make sure the match exists
|
||||
matchID = userToken.matchID
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Make sure we aren't locking our slot
|
||||
ourSlot = match.getUserSlotID(userID)
|
||||
if packetData["slotID"] == ourSlot:
|
||||
return
|
||||
|
||||
# Lock/Unlock slot
|
||||
match.toggleSlotLock(packetData["slotID"])
|
3
events/matchNoBeatmapEvent.py
Normal file
3
events/matchNoBeatmapEvent.py
Normal file
@@ -0,0 +1,3 @@
|
||||
from events import matchBeatmapEvent
|
||||
def handle(userToken, packetData):
|
||||
matchBeatmapEvent.handle(userToken, packetData, False)
|
22
events/matchPlayerLoadEvent.py
Normal file
22
events/matchPlayerLoadEvent.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from objects import glob
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Get userToken data
|
||||
userID = userToken.userID
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# The match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Set our load status
|
||||
match.playerLoaded(userID)
|
16
events/matchReadyEvent.py
Normal file
16
events/matchReadyEvent.py
Normal file
@@ -0,0 +1,16 @@
|
||||
from objects import glob
|
||||
|
||||
def handle(userToken, _):
|
||||
# Get usertoken data
|
||||
userID = userToken.userID
|
||||
|
||||
# Make sure the match exists
|
||||
matchID = userToken.matchID
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Get our slotID and change ready status
|
||||
slotID = match.getUserSlotID(userID)
|
||||
if slotID != None:
|
||||
match.toggleSlotReady(slotID)
|
22
events/matchSkipEvent.py
Normal file
22
events/matchSkipEvent.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from objects import glob
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Get userToken data
|
||||
userID = userToken.userID
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# The match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Skip
|
||||
match.playerSkip(userID)
|
47
events/matchStartEvent.py
Normal file
47
events/matchStartEvent.py
Normal file
@@ -0,0 +1,47 @@
|
||||
from objects import glob
|
||||
from constants import slotStatuses
|
||||
from constants import serverPackets
|
||||
|
||||
def handle(userToken, _):
|
||||
# TODO: Host check
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# The match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
force = False # TODO: Force thing
|
||||
|
||||
# Make sure we have enough players
|
||||
if (match.countUsers() < 2 or not match.checkTeams()) and not force:
|
||||
return
|
||||
|
||||
# Change inProgress value
|
||||
match.inProgress = True
|
||||
|
||||
# Set playing to ready players and set load, skip and complete to False
|
||||
for i in range(0,16):
|
||||
if (match.slots[i]["status"] & slotStatuses.ready) > 0:
|
||||
match.slots[i]["status"] = slotStatuses.playing
|
||||
match.slots[i]["loaded"] = False
|
||||
match.slots[i]["skip"] = False
|
||||
match.slots[i]["complete"] = False
|
||||
|
||||
# Send match start packet
|
||||
for i in range(0,16):
|
||||
if (match.slots[i]["status"] & slotStatuses.playing) > 0 and match.slots[i]["userID"] != -1:
|
||||
token = glob.tokens.getTokenFromUserID(match.slots[i]["userID"])
|
||||
if token != None:
|
||||
token.enqueue(serverPackets.matchStart(matchID))
|
||||
|
||||
# Send updates
|
||||
match.sendUpdate()
|
23
events/matchTransferHostEvent.py
Normal file
23
events/matchTransferHostEvent.py
Normal file
@@ -0,0 +1,23 @@
|
||||
from objects import glob
|
||||
from constants import clientPackets
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# Get packet data
|
||||
packetData = clientPackets.transferHost(packetData)
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# Match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Transfer host
|
||||
match.transferHost(packetData["slotID"])
|
18
events/partLobbyEvent.py
Normal file
18
events/partLobbyEvent.py
Normal file
@@ -0,0 +1,18 @@
|
||||
from objects import glob
|
||||
from events import channelPartEvent
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
|
||||
def handle(userToken, _):
|
||||
# Get usertoken data
|
||||
userID = userToken.userID
|
||||
username = userToken.username
|
||||
|
||||
# Remove user from users in lobby
|
||||
glob.matches.lobbyUserPart(userID)
|
||||
|
||||
# Part lobby channel
|
||||
channelPartEvent.partChannel(userToken, "#lobby", True)
|
||||
|
||||
# Console output
|
||||
consoleHelper.printColored("> {} has left multiplayer lobby".format(username), bcolors.BLUE)
|
27
events/partMatchEvent.py
Normal file
27
events/partMatchEvent.py
Normal file
@@ -0,0 +1,27 @@
|
||||
from objects import glob
|
||||
from constants import serverPackets
|
||||
|
||||
def handle(userToken, _):
|
||||
# get data from usertoken
|
||||
userID = userToken.userID
|
||||
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# The match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Set slot to free
|
||||
match.userLeft(userID)
|
||||
|
||||
# Set usertoken match to -1
|
||||
userToken.partMatch()
|
||||
userToken.enqueue(serverPackets.channelKicked("#multiplayer"))
|
52
events/sendPrivateMessageEvent.py
Normal file
52
events/sendPrivateMessageEvent.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from constants import clientPackets
|
||||
from constants import serverPackets
|
||||
from objects import glob
|
||||
from objects import fokabot
|
||||
from constants import exceptions
|
||||
from constants import messageTemplates
|
||||
|
||||
def handle(userToken, packetData):
|
||||
"""
|
||||
Event called when someone sends a private message
|
||||
|
||||
userToken -- request user token
|
||||
packetData -- request data bytes
|
||||
"""
|
||||
|
||||
try:
|
||||
# Get usertoken username
|
||||
username = userToken.username
|
||||
|
||||
# Private message packet
|
||||
packetData = clientPackets.sendPrivateMessage(packetData)
|
||||
|
||||
if packetData["to"] == "FokaBot":
|
||||
# FokaBot command check
|
||||
fokaMessage = fokabot.fokabotResponse(username, packetData["to"], packetData["message"])
|
||||
if fokaMessage != False:
|
||||
userToken.enqueue(serverPackets.sendMessage("FokaBot", username, fokaMessage))
|
||||
consoleHelper.printColored("> FokaBot>{}: {}".format(packetData["to"], str(fokaMessage.encode("UTF-8"))), bcolors.PINK)
|
||||
else:
|
||||
# Send packet message to target if it exists
|
||||
token = glob.tokens.getTokenFromUsername(packetData["to"])
|
||||
if token == None:
|
||||
raise exceptions.tokenNotFoundException()
|
||||
|
||||
# Check message templates (mods/admins only)
|
||||
if packetData["message"] in messageTemplates.templates and userToken.rank >= 3:
|
||||
packetData["message"] = messageTemplates.templates[packetData["message"]]
|
||||
|
||||
# Send message to target
|
||||
token.enqueue(serverPackets.sendMessage(username, packetData["to"], packetData["message"]))
|
||||
|
||||
# Send away message to sender if needed
|
||||
if token.awayMessage != "":
|
||||
userToken.enqueue(serverPackets.sendMessage(packetData["to"], username, "This user is away: {}".format(token.awayMessage)))
|
||||
|
||||
# Console output
|
||||
consoleHelper.printColored("> {}>{}: {}".format(username, packetData["to"], packetData["message"]), bcolors.PINK)
|
||||
except exceptions.tokenNotFoundException:
|
||||
# Token not found, user disconnected
|
||||
consoleHelper.printColored("[!] {} tried to send a message to {}, but their token couldn't be found".format(username, packetData["to"]), bcolors.RED)
|
108
events/sendPublicMessageEvent.py
Normal file
108
events/sendPublicMessageEvent.py
Normal file
@@ -0,0 +1,108 @@
|
||||
from constants import exceptions
|
||||
from constants import clientPackets
|
||||
from objects import glob
|
||||
from objects import fokabot
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from constants import serverPackets
|
||||
|
||||
def handle(userToken, packetData):
|
||||
"""
|
||||
Event called when someone sends a public message
|
||||
|
||||
userToken -- request user token
|
||||
packetData -- request data bytes
|
||||
"""
|
||||
|
||||
try:
|
||||
# Get uesrToken data
|
||||
userID = userToken.userID
|
||||
username = userToken.username
|
||||
userRank = userToken.rank
|
||||
|
||||
# Public chat packet
|
||||
packetData = clientPackets.sendPublicMessage(packetData)
|
||||
|
||||
# Receivers
|
||||
who = []
|
||||
|
||||
# Check #spectator
|
||||
if packetData["to"] == "#spectator":
|
||||
# Spectator channel
|
||||
# Send this packet to every spectator and host
|
||||
if userToken.spectating == 0:
|
||||
# We have sent to send a message to our #spectator channel
|
||||
targetToken = userToken
|
||||
who = targetToken.spectators[:]
|
||||
# No need to remove us because we are the host so we are not in spectators list
|
||||
else:
|
||||
# We have sent a message to someone else's #spectator
|
||||
targetToken = glob.tokens.getTokenFromUserID(userToken.spectating)
|
||||
who = targetToken.spectators[:]
|
||||
|
||||
# Remove us
|
||||
if userID in who:
|
||||
who.remove(userID)
|
||||
|
||||
# Add host
|
||||
who.append(targetToken.userID)
|
||||
elif packetData["to"] == "#multiplayer":
|
||||
# Multiplayer Channel
|
||||
# Get match ID and match object
|
||||
matchID = userToken.matchID
|
||||
|
||||
# Make sure we are in a match
|
||||
if matchID == -1:
|
||||
return
|
||||
|
||||
# Make sure the match exists
|
||||
if matchID not in glob.matches.matches:
|
||||
return
|
||||
|
||||
# The match exists, get object
|
||||
match = glob.matches.matches[matchID]
|
||||
|
||||
# Create targets list
|
||||
who = []
|
||||
for i in range(0,16):
|
||||
uid = match.slots[i]["userID"]
|
||||
if uid > -1 and uid != userID:
|
||||
who.append(uid)
|
||||
else:
|
||||
# Standard channel
|
||||
# Make sure the channel exists
|
||||
if packetData["to"] not in glob.channels.channels:
|
||||
raise exceptions.channelUnknownException
|
||||
|
||||
# Make sure the channel is not in moderated mode
|
||||
if glob.channels.channels[packetData["to"]].moderated == True and userRank <= 2:
|
||||
raise exceptions.channelModeratedException
|
||||
|
||||
# Make sure we have write permissions
|
||||
if glob.channels.channels[packetData["to"]].publicWrite == False and userRank <= 2:
|
||||
raise exceptions.channelNoPermissionsException
|
||||
|
||||
# Send this packet to everyone in that channel except us
|
||||
who = glob.channels.channels[packetData["to"]].getConnectedUsers()[:]
|
||||
if userID in who:
|
||||
who.remove(userID)
|
||||
|
||||
|
||||
# Send packet to required users
|
||||
glob.tokens.multipleEnqueue(serverPackets.sendMessage(username, packetData["to"], packetData["message"]), who, False)
|
||||
|
||||
# Fokabot command check
|
||||
fokaMessage = fokabot.fokabotResponse(username, packetData["to"], packetData["message"])
|
||||
if fokaMessage != False:
|
||||
who.append(userID)
|
||||
glob.tokens.multipleEnqueue(serverPackets.sendMessage("FokaBot", packetData["to"], fokaMessage), who, False)
|
||||
consoleHelper.printColored("> FokaBot@{}: {}".format(packetData["to"], str(fokaMessage.encode("UTF-8"))), bcolors.PINK)
|
||||
|
||||
# Console output
|
||||
consoleHelper.printColored("> {}@{}: {}".format(username, packetData["to"], str(packetData["message"].encode("UTF-8"))), bcolors.PINK)
|
||||
except exceptions.channelModeratedException:
|
||||
consoleHelper.printColored("[!] {} tried to send a message to a channel that is in moderated mode ({})".format(username, packetData["to"]), bcolors.RED)
|
||||
except exceptions.channelUnknownException:
|
||||
consoleHelper.printColored("[!] {} tried to send a message to an unknown channel ({})".format(username, packetData["to"]), bcolors.RED)
|
||||
except exceptions.channelNoPermissionsException:
|
||||
consoleHelper.printColored("[!] {} tried to send a message to channel {}, but they have no write permissions".format(username, packetData["to"]), bcolors.RED)
|
20
events/setAwayMessageEvent.py
Normal file
20
events/setAwayMessageEvent.py
Normal file
@@ -0,0 +1,20 @@
|
||||
from constants import clientPackets
|
||||
from constants import serverPackets
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# get token data
|
||||
username = userToken.username
|
||||
|
||||
# Read packet data
|
||||
packetData = clientPackets.setAwayMessage(packetData)
|
||||
|
||||
# Set token away message
|
||||
userToken.setAwayMessage(packetData["awayMessage"])
|
||||
|
||||
# Send private message from fokabot
|
||||
if packetData["awayMessage"] == "":
|
||||
fokaMessage = "Your away message has been reset"
|
||||
else:
|
||||
fokaMessage = "Your away message is now: {}".format(packetData["awayMessage"])
|
||||
userToken.enqueue(serverPackets.sendMessage("FokaBot", username, fokaMessage))
|
||||
print("{} has changed their away message to: {}".format(username, packetData["awayMessage"]))
|
33
events/spectateFramesEvent.py
Normal file
33
events/spectateFramesEvent.py
Normal file
@@ -0,0 +1,33 @@
|
||||
from objects import glob
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from constants import serverPackets
|
||||
from constants import exceptions
|
||||
|
||||
def handle(userToken, packetData):
|
||||
# get token data
|
||||
userID = userToken.userID
|
||||
|
||||
# Send spectator frames to every spectator
|
||||
consoleHelper.printColored("> {}'s spectators: {}".format(str(userID), str(userToken.spectators)), bcolors.BLUE)
|
||||
for i in userToken.spectators:
|
||||
# Send to every user but host
|
||||
if i != userID:
|
||||
try:
|
||||
# Get spectator token object
|
||||
spectatorToken = glob.tokens.getTokenFromUserID(i)
|
||||
|
||||
# Make sure the token exists
|
||||
if spectatorToken == None:
|
||||
raise exceptions.stopSpectating
|
||||
|
||||
# Make sure this user is spectating us
|
||||
if spectatorToken.spectating != userID:
|
||||
raise exceptions.stopSpectating
|
||||
|
||||
# Everything seems fine, send spectator frames to this spectator
|
||||
spectatorToken.enqueue(serverPackets.spectatorFrames(packetData[7:]))
|
||||
except exceptions.stopSpectating:
|
||||
# Remove this user from spectators
|
||||
userToken.removeSpectator(i)
|
||||
userToken.enqueue(serverPackets.removeSpectator(i))
|
51
events/startSpectatingEvent.py
Normal file
51
events/startSpectatingEvent.py
Normal file
@@ -0,0 +1,51 @@
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from constants import clientPackets
|
||||
from constants import serverPackets
|
||||
from constants import exceptions
|
||||
from objects import glob
|
||||
from helpers import userHelper
|
||||
|
||||
def handle(userToken, packetData):
|
||||
try:
|
||||
# Get usertoken data
|
||||
userID = userToken.userID
|
||||
username = userToken.username
|
||||
|
||||
# Start spectating packet
|
||||
packetData = clientPackets.startSpectating(packetData)
|
||||
|
||||
# Stop spectating old user if needed
|
||||
if userToken.spectating != 0:
|
||||
oldTargetToken = glob.tokens.getTokenFromUserID(userToken.spectating)
|
||||
oldTargetToken.enqueue(serverPackets.removeSpectator(userID))
|
||||
userToken.stopSpectating()
|
||||
|
||||
# Start spectating new user
|
||||
userToken.startSpectating(packetData["userID"])
|
||||
|
||||
# Get host token
|
||||
targetToken = glob.tokens.getTokenFromUserID(packetData["userID"])
|
||||
if targetToken == None:
|
||||
raise exceptions.tokenNotFoundException
|
||||
|
||||
# Add us to host's spectators
|
||||
targetToken.addSpectator(userID)
|
||||
|
||||
# Send spectator join packet to host
|
||||
targetToken.enqueue(serverPackets.addSpectator(userID))
|
||||
|
||||
# Join #spectator channel
|
||||
userToken.enqueue(serverPackets.channelJoinSuccess(userID, "#spectator"))
|
||||
|
||||
if len(targetToken.spectators) == 1:
|
||||
# First spectator, send #spectator join to host too
|
||||
targetToken.enqueue(serverPackets.channelJoinSuccess(userID, "#spectator"))
|
||||
|
||||
# Console output
|
||||
consoleHelper.printColored("> {} are spectating {}".format(username, userHelper.getUsername(packetData["userID"])), bcolors.PINK)
|
||||
consoleHelper.printColored("> {}'s spectators: {}".format(str(packetData["userID"]), str(targetToken.spectators)), bcolors.BLUE)
|
||||
except exceptions.tokenNotFoundException:
|
||||
# Stop spectating if token not found
|
||||
consoleHelper.printColored("[!] Spectator start: token not found", bcolors.RED)
|
||||
userToken.stopSpectating()
|
31
events/stopSpectatingEvent.py
Normal file
31
events/stopSpectatingEvent.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from helpers import consoleHelper
|
||||
from constants import bcolors
|
||||
from objects import glob
|
||||
from constants import serverPackets
|
||||
from constants import exceptions
|
||||
|
||||
def handle(userToken, _):
|
||||
try:
|
||||
# get user token data
|
||||
userID = userToken.userID
|
||||
username = userToken.username
|
||||
|
||||
# Remove our userID from host's spectators
|
||||
target = userToken.spectating
|
||||
targetToken = glob.tokens.getTokenFromUserID(target)
|
||||
if targetToken == None:
|
||||
raise exceptions.tokenNotFoundException
|
||||
targetToken.removeSpectator(userID)
|
||||
|
||||
# Send the spectator left packet to host
|
||||
targetToken.enqueue(serverPackets.removeSpectator(userID))
|
||||
|
||||
# Console output
|
||||
# TODO: Move messages in stop spectating
|
||||
consoleHelper.printColored("> {} are no longer spectating whoever they were spectating".format(username), bcolors.PINK)
|
||||
consoleHelper.printColored("> {}'s spectators: {}".format(str(target), str(targetToken.spectators)), bcolors.BLUE)
|
||||
except exceptions.tokenNotFoundException:
|
||||
consoleHelper.printColored("[!] Spectator stop: token not found", bcolors.RED)
|
||||
finally:
|
||||
# Set our spectating user to 0
|
||||
userToken.stopSpectating()
|
Reference in New Issue
Block a user