2021-11-08 00:25:27 +02:00
import sys
from asyncio import wait_for , TimeoutError
from base64 import b64encode
2021-10-28 03:54:04 +03:00
from sanic import Sanic
2022-01-25 17:10:35 +02:00
from sanic . response import file , redirect , empty
2021-10-28 03:54:04 +03:00
2021-11-04 02:41:34 +02:00
from InputController import InputController
2021-11-08 00:25:27 +02:00
from MessageParser import MessageParser
2021-10-28 03:54:04 +03:00
2021-11-08 00:25:27 +02:00
app = Sanic (
" capybara " ,
2022-01-25 17:10:35 +02:00
env_prefix = " CAPYBARA_ "
2021-11-08 00:25:27 +02:00
)
input_controller = InputController ( )
control_message_parser = MessageParser ( )
# auth packet
control_message_parser . add_handler ( " 0 " , {
" auth_string " : " str "
} )
2021-10-28 03:54:04 +03:00
2021-11-03 04:21:58 +02:00
app . static ( " app " , " frontend/dist/ " , resource_type = " dir " )
2021-10-28 03:54:04 +03:00
2021-11-08 00:25:27 +02:00
@app.get ( " / " )
async def home ( req ) :
return redirect ( " /app/app.html " )
@app.get ( " /app " )
async def app_route ( req ) :
return redirect ( " /app/app.html " )
2021-11-04 02:41:34 +02:00
2021-10-28 03:54:04 +03:00
@app.websocket ( " /gateway " )
async def gateway ( req , ws ) :
2021-11-08 00:25:27 +02:00
# Before the client is able to send any data, we must await an authorization packet
try :
auth_payload = await wait_for ( ws . recv ( ) , timeout = 5 )
except TimeoutError :
await ws . close ( code = 4001 , reason = " Invalid auth packet " )
return
code , args = control_message_parser . parse ( auth_payload )
2022-01-25 17:10:35 +02:00
if (
not code or
2021-11-08 00:25:27 +02:00
code != " 0 " or
2022-01-25 17:10:35 +02:00
args [ " auth_string " ] != app . ctx . EXPECTED_AUTH_STRING
) : # 0 is the code for the initial auth packet
2021-11-08 00:25:27 +02:00
await ws . close ( code = 4001 , reason = " Invalid auth packet " )
return
2022-01-25 17:10:35 +02:00
await ws . send ( " 1 " ) # send a single `1` to let the client know the server is accepting input packets
2021-11-08 00:25:27 +02:00
2021-10-28 03:54:04 +03:00
while True :
2021-11-08 00:25:27 +02:00
input_controller . process_message ( await ws . recv ( ) )
2021-10-28 03:54:04 +03:00
2021-11-04 02:41:34 +02:00
2021-10-28 03:54:04 +03:00
def main ( ) :
2021-11-08 00:25:27 +02:00
if not app . config . get ( " AUTH_PASSWORD " ) :
print (
" capybara: FATAL ERROR: Capybara is expecting the `CAPYBARA_AUTH_PASSWORD` environment variable to be set (to a password of your choice). \n Your users will use this password to authenticate to your server. \n EXITING... " ,
file = sys . stderr
)
exit ( 1 )
return
app . ctx . EXPECTED_AUTH_STRING = " %a uth % " + str ( b64encode ( app . config . AUTH_PASSWORD . encode ( " utf-8 " ) ) , " utf-8 " )
2021-10-28 03:54:04 +03:00
app . run ( host = ' 0.0.0.0 ' , port = 4003 , access_log = False )
if __name__ == " __main__ " :
main ( )