Skip to content

Instantly share code, notes, and snippets.

@vwrs
Created March 12, 2023 07:48
Show Gist options
  • Save vwrs/68d47c974c7b772f342ebfe9a1f88d70 to your computer and use it in GitHub Desktop.
Save vwrs/68d47c974c7b772f342ebfe9a1f88d70 to your computer and use it in GitHub Desktop.
A simple python server for a Unity WebGL build
import sys
from http.server import SimpleHTTPRequestHandler, HTTPServer
class GzipRequestHandler(SimpleHTTPRequestHandler):
'''HTTPRequestHandler for gzip files'''
def end_headers(self):
'''Set Content-Encoding: gzip for gzipped files'''
if self.path.endswith('.gz'):
self.send_header('Content-Encoding', 'gzip')
super().end_headers()
def do_GET(self):
'''Set Content-Encoding and Content-Type to gzipped files'''
path = self.translate_path(self.path)
if path.endswith('.js.gz'):
with open(path, 'rb') as f:
content = f.read()
self.send_response(200)
self.send_header('Content-Type', 'application/javascript')
self.end_headers()
self.wfile.write(content)
elif path.endswith('.wasm.gz'):
with open(path, 'rb') as f:
content = f.read()
self.send_response(200)
self.send_header('Content-Type', 'application/wasm')
self.end_headers()
self.wfile.write(content)
elif path.endswith('.gz'):
with open(path, 'rb') as f:
content = f.read()
self.send_response(200)
self.send_header('Content-Type',self.guess_type(path))
self.end_headers()
self.wfile.write(content)
else:
super().do_GET()
def serve(port: int):
'''Run a local HTTP server'''
httpd = HTTPServer(('localhost', port), GzipRequestHandler)
print(f"Serving at http://localhost:{port}")
httpd.serve_forever()
if __name__ == "__main__":
try:
if len(sys.argv) != 2:
print(f'usage: {sys.argv[0]} [PORT]')
port = int(sys.argv[1])
serve(port)
except Exception as e:
print('Error:', e)
@parkerlreed
Copy link

parkerlreed commented Oct 21, 2024

@mfbru Same! python -m http.server was fine but ran into the occasional issue with the game not packaging correctly. This version is great for that.

I'll share what I created with this

itch.io auto downloader just pass in the URL to the game. If you pass in the same URL/name and it has already been downloaded it will just launch it directly.

I got the auth token from looking at the existing itch.io client traffic

#!/usr/bin/env bash

# Configuration
AUTH_TOKEN="my_token"
USER_AGENT="butler/v15.21.0 itch/26.1.9 (linux)"
API_BASE_URL="https://api.itch.io"
GAME_URL="$1"
GAME_ID="$(curl -s "$GAME_URL" | grep -oP '"id":\K\d+')"
GAME_NAME="$(basename "$GAME_URL")"

# Functions
get_download_id() {
  curl -s \
    -H "User-Agent: $USER_AGENT" \
    -H 'Accept: application/vnd.itch.v2' \
    -H 'Accept-Language: *' \
    -H "Authorization: $AUTH_TOKEN" \
    --compressed \
    "$API_BASE_URL/games/$GAME_ID/uploads" |
    jq '.uploads[] | select(.type == "html") | .id'
}

get_download_token() {
  curl -s \
    -H "User-Agent: $USER_AGENT" \
    -H 'Accept: application/vnd.itch.v2' \
    -H 'Accept-Language: *' \
    -H "Authorization: $AUTH_TOKEN" \
    -H 'Content-Type: application/x-www-form-urlencoded' \
    --compressed \
    -X POST "$API_BASE_URL/games/$GAME_ID/download-sessions" |
    jq -r '.uuid'
}

get_download_url() {
  curl -s \
    -H "User-Agent: $USER_AGENT" \
    -H 'Range: bytes=0-' \
    "$API_BASE_URL/uploads/$(get_download_id)/download?api_key=$AUTH_TOKEN&uuid=$(get_download_token)" \
    -w "%{redirect_url}"
}

download_file() {
  curl -OJ \
    -w '%{filename_effective}' \
    -H "User-Agent: $USER_AGENT" \
    -H 'Range: bytes=0-' \
    "$(get_download_url)"
}

run_in_firefox() {
  cd ~/Games/itch-webgl/"$GAME_NAME" || exit

  # Start the Python HTTP server in the background
  python ~/Games/itch-webgl/server.py 8666 &
  SERVER_PID=$!

  # Start Firefox and wait for it to exit
  /home/parker/Games/itch-webgl/firefox/firefox --kiosk http://127.0.0.1:8666/
  
  # When Firefox exits, kill the Python server
  kill $SERVER_PID
}

# Main script
if [[ -z "$1" ]]; then
  cd /home/parker/Games/itch-webgl/
  python ~/Games/itch-webgl/server.py 8666 &
  SERVER_PID=$!

  # Start Electron and wait for it to exit
  /home/parker/Games/itch-webgl/firefox/firefox --kiosk http://127.0.0.1:8666/
  exit
elif [[ -d "/home/parker/Games/itch-webgl/$GAME_NAME" ]]; then
  run_in_firefox
  exit
fi
mkdir -p ~/Games/itch-webgl/"$GAME_NAME"
cd ~/Games/itch-webgl/"$GAME_NAME" || exit

FILENAME="$(download_file)"
unzip "$FILENAME"

run_in_firefox

@mfbru
Copy link

mfbru commented Oct 22, 2024

Cool! I see you made the URL an argument to the script, it's a good idea because OP's script only works locally as it serves the website at localhost, so you can't access it from another client on the network.

@parkerlreed
Copy link

My script is just using OPs script to serve it. So it works all the same.

@mfbru
Copy link

mfbru commented Oct 25, 2024

Hello @vwrs, if you change "localhost" --> "0.0.0.0", the webserver can run from other network clients (e.g., smartphones) 😃

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment