"""Pos-processa a saida do web_build do Ren'Py (index.html): sem PWA, sem link externo, wasm em .gz, CSP. uso: post-web.py """ import re import sys index = sys.argv[1] + "/index.html" with open(index, encoding="utf-8") as f: html = f.read() # PWA: manifest, icones e service worker saem (a pagina roda dentro de um iframe do site). html, n = re.subn(r'[ \t]*]*>\n', "", html) assert n == 17, n html, n = re.subn(r"\n[ \t]*// Register the service worker\.\n.*?\n \}\n", "\n", html, flags=re.S) assert n == 1, n assert "serviceWorker" not in html # "Powered by Ren'Py" levava ao renpy.org: o credito fica na pagina do jogo. html, n = re.subn(r'[ \t]*\s*Powered by Ren\'Py\s*\n[ \t]*\n', "", html) assert n == 1, n assert not re.search(r"https?://", html), re.findall(r"https?://\S+", html) csp = ( "default-src 'none'; script-src 'self' 'unsafe-inline' 'unsafe-eval' 'wasm-unsafe-eval'; " "style-src 'self' 'unsafe-inline'; img-src 'self' data: blob:; media-src 'self' data: blob:; " "font-src 'self' data: blob:; connect-src 'self' data: blob:; worker-src 'self' blob:; " "form-action 'none'; base-uri 'self'" ) head = ( f' \n' ' \n' ) html = html.replace("\n", "\n" + head, 1) # O wasm vai em renpy.wasm.gz (o CloudFront nao comprime acima de 10 MB): o Emscripten chama este gancho # no lugar de buscar renpy.wasm, e o navegador descomprime com DecompressionStream. hook = """ """ marker = ' ' assert html.count(marker) == 1 html = html.replace(marker, hook + marker) with open(index, "w", encoding="utf-8") as f: f.write(html) # game.zip: datas fixas (os .rpyc e o cache de bytecode nascem com a data do build) e ordem estavel. import zipfile zp = sys.argv[1] + "/game.zip" with zipfile.ZipFile(zp) as zin: items = [(i, zin.read(i.filename)) for i in zin.infolist()] items.sort(key=lambda t: t[0].filename) with zipfile.ZipFile(zp + ".tmp", "w") as zout: for i, data in items: if i.filename == "game/cache/build_info.json": data = re.sub(rb'"time": [0-9.]+', b'"time": 1577836800.0', data) zi = zipfile.ZipInfo(i.filename, (2020, 1, 1, 0, 0, 0)) zi.compress_type = i.compress_type zi.external_attr = i.external_attr zout.writestr(zi, data) import os os.replace(zp + ".tmp", zp) print("post-web ok")