2016-05-18 17:12:46 +00:00
from helpers import userHelper
from constants import serverPackets
from constants import exceptions
from objects import glob
2016-05-17 21:40:34 +00:00
from helpers import consoleHelper
from constants import bcolors
2016-05-18 17:12:46 +00:00
from helpers import locationHelper
from helpers import countryHelper
2016-04-19 17:40:59 +00:00
import time
2016-05-18 17:12:46 +00:00
from helpers import generalFunctions
from events import channelJoinEvent
2016-05-17 21:40:34 +00:00
import sys
import traceback
2016-04-19 17:40:59 +00:00
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. \n Type !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
2016-05-17 21:40:34 +00:00
if generalFunctions . stringToBool ( glob . conf . config [ " server " ] [ " localizeusers " ] ) :
2016-05-12 17:22:13 +00:00
# Get location and country from IP
location = locationHelper . getLocation ( requestIP )
countryLetters = locationHelper . getCountry ( requestIP )
country = countryHelper . getCountryID ( countryLetters )
2016-04-19 17:40:59 +00:00
else :
# Set location to 0,0 and get country from db
print ( " [!] Location skipped " )
location = [ 0 , 0 ]
2016-05-01 18:39:01 +00:00
countryLetters = " XX "
2016-04-19 17:40:59 +00:00
country = countryHelper . getCountryID ( userHelper . getCountry ( userID ) )
# Set location and country
responseToken . setLocation ( location )
responseToken . setCountry ( country )
2016-05-01 16:09:35 +00:00
# Set country in db if user has no country (first bancho login)
if userHelper . getCountry ( userID ) == " XX " :
userHelper . setCountry ( userID , countryLetters )
2016-04-19 17:40:59 +00:00
# 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 ( )
2016-05-17 21:40:34 +00:00
except :
# Unknown exception
msg = " UNKNOWN ERROR IN LOGIN!!! \n {} \n {} " . format ( sys . exc_info ( ) , traceback . format_exc ( ) )
consoleHelper . printColored ( " [!] {} " . format ( msg ) , bcolors . RED )
2016-04-19 17:40:59 +00:00
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 )