#!/usr/bin/env bash # Exporta para a web, com o Ren'Py 8.5.3 oficial (MIT, com partes LGPL), tres visual novels pequenas: # # the-question o demo do proprio Ren'Py (the_question/ do tarball do codigo, MIT) # starseed Starseed (CloneDeath), do zip do itch.io (Ren'Py 7.2.1), portado para o 8.5.3 # three-drunk-pissed-off-frogs Three Drunk, Pissed-Off Frogs (Froge), do zip do itch.io (Ren'Py 7.x), portado # # src/FredGames.Bundler/Builds/build-renpy-vn.sh # # O SDK e o modulo web vem do site do Ren'Py e sao conferidos pelo SHA-256 (artifacts/tools/renpy-8.5.3, o mesmo do # build-learn-to-code-rpg.sh). Os jogos do itch.io sao baixados com o itch-fetch.sh (o itch so entrega por links # temporarios) e conferidos pelo SHA-256 do zip; so entram game/*.rpy, imagens, audio e fonte (sem os .rpyc/cache da # versao antiga, sem os arquivos de edicao .pdn/.mqn/.aseprite e sem o motor Ren'Py 7 que vem no zip). Mudancas em # cada jogo: renpy-vn/.patch (o texto do que mudou fica no patch e no LICENSE.txt do jogo). # # Depois do export (igual ao do Learn to Code RPG): sem PWA, sem o link "Powered by Ren'Py", wasm em .gz (a pagina # descomprime com DecompressionStream) e CSP que so permite esta origem. A tela de abertura da pagina e a arte do jogo. # # Saida: artifacts/build/renpy-vn//{-web.tar.gz,SHA256SUMS} e, comum aos tres, # artifacts/build/renpy-vn/renpy-8.5.3-lgpl-source.tar.gz (fonte do Ren'Py, FFmpeg e FriBidi: o mesmo arquivo do # Learn to Code RPG, mesmo sha256). ATENCAO: o game.zip pode nao sair igual byte a byte entre duas execucoes (os # .rpyc/.rpyb que o Ren'Py gera mudam de bytes): o bundle.yaml pina o sha256 da execucao publicada. set -euo pipefail slug="${1:-}" case "$slug" in the-question|starseed|three-drunk-pissed-off-frogs) ;; *) echo "uso: $0 the-question|starseed|three-drunk-pissed-off-frogs" >&2; exit 1 ;; esac RENPY=8.5.3 RENPY_URL=https://www.renpy.org/dl/$RENPY RENPY_SDK_SHA256=eb0a9be7f0fb13632fe25ceade9a8bed5a1b4d6b6e83bd19eeeb29e1a1bb4a45 RENPY_WEB_SHA256=954db897e65f51ea63cb2fb7b203d02be0447f4e22069514020bbe6c6691fdfc RENPY_SRC_SHA256=4fd3d7bca7349b0d182830d3cdcf65940fa32e66be1aea0b3690e048be6282a5 RB_TAG=renpy-8.5.3.26051504 RB_SHA256=cee7b853c82b28f3d69586cda1aaf3bfb55cec723171b5cec06784c8e3bc5ce6 STARSEED_SHA256=c55c254019f8511a6b3a70343e3273b979e76d990b1dfe66266b750bb848ec56 FROGS_SHA256=cb97eeb879ba0593e2673865a4db29118e09e03f7cface038de690134912e73e here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$here" rev-parse --show-toplevel 2>/dev/null || pwd)" base="$root/artifacts/build/renpy-vn" out="$base/$slug" cache="$root/artifacts/build/cache" tools="$root/artifacts/tools" sdk="$tools/renpy-$RENPY/renpy-$RENPY-sdk" mkdir -p "$cache" "$base" fetch() { if [ ! -f "$cache/$2" ]; then curl -fsSL --retry 4 "$1" -o "$cache/$2.partial" && mv "$cache/$2.partial" "$cache/$2" fi echo "$3 $cache/$2" | shasum -a 256 -c - } install_renpy() { [ -d "$sdk/web" ] && return 0 fetch "$RENPY_URL/renpy-$RENPY-sdk.tar.bz2" "renpy-$RENPY-sdk.tar.bz2" "$RENPY_SDK_SHA256" fetch "$RENPY_URL/renpy-$RENPY-web.zip" "renpy-$RENPY-web.zip" "$RENPY_WEB_SHA256" rm -rf "$tools/renpy-$RENPY.tmp" mkdir -p "$tools/renpy-$RENPY.tmp" tar -xjf "$cache/renpy-$RENPY-sdk.tar.bz2" -C "$tools/renpy-$RENPY.tmp" unzip -q "$cache/renpy-$RENPY-web.zip" -d "$tools/renpy-$RENPY.tmp/renpy-$RENPY-sdk" rm -rf "$tools/renpy-$RENPY" mv "$tools/renpy-$RENPY.tmp" "$tools/renpy-$RENPY" } if [ "${1:-}" = "--install" ]; then install_renpy; exit 0; fi cwebp -version | head -1 | grep -q "^1.5.0" || { echo "cwebp 1.5.0 necessario" >&2; exit 1; } fetch "$RENPY_URL/renpy-$RENPY-source.tar.bz2" "renpy-$RENPY-source.tar.bz2" "$RENPY_SRC_SHA256" fetch "https://github.com/renpy/renpy-build/archive/refs/tags/$RB_TAG.tar.gz" "renpy-build-$RB_TAG.tar.gz" "$RB_SHA256" if [ ! -d "$sdk/web" ]; then lockf -k "$root/artifacts/renpy-$RENPY.lock" bash "${BASH_SOURCE[0]}" --install fi rm -rf "$out" mkdir -p "$out/project" "$out/web" "$out/tmp" proj="$out/project" # --- o jogo --- presplash="" # imagem (relativa a game/) usada na tela de abertura da pagina case "$slug" in the-question) tar -xjf "$cache/renpy-$RENPY-source.tar.bz2" -C "$out/tmp" "renpy-$RENPY-source/the_question" cp -R "$out/tmp/renpy-$RENPY-source/the_question/game" "$proj/game" cp "$out/tmp/renpy-$RENPY-source/the_question/progressive_download.txt" "$proj/" # sem os testes do Ren'Py, o cache/os .rpyc de quem empacotou, as traducoes (o seletor de idioma sai por patch) e saves rm -rf "$proj/game/testcases.rpy" "$proj/game/cache" "$proj/game/saves" "$proj/game/tl" find "$proj/game" -name '*.rpyc' -delete presplash="images/bg meadow.jpg" ;; starseed|three-drunk-pissed-off-frogs) if [ "$slug" = starseed ]; then page=https://clonedeath.itch.io/starseed; file=Starseed-1.0-pc.zip; sha=$STARSEED_SHA256 else page=https://froge.itch.io/three-drunk-pissed-off-frogs; file=TDPOF-win.zip; sha=$FROGS_SHA256 fi "$here/itch-fetch.sh" "$page" "$file" "$cache/itch-$slug.zip" "$sha" unzip -q "$cache/itch-$slug.zip" -d "$out/tmp" src="$(find "$out/tmp" -mindepth 2 -maxdepth 2 -type d -name game | head -1)" mkdir -p "$proj/game" ( cd "$src" && find . -type f ! -name '*.rpyc' ! -name '*.rpymc' ! -name '*.rpym' ! -path './cache/*' ! -path './tl/*' \ ! -name '*.pdn' ! -name '*.mqn' ! -name '*.aseprite' ! -name 'script_version.txt' ! -name '.DS_Store' ) | while IFS= read -r f; do mkdir -p "$proj/game/$(dirname "$f")"; cp "$src/$f" "$proj/game/$f"; done # .rpy do zip: sem BOM e com fim de linha Unix (o patch e feito em cima disso) find "$proj/game" -name '*.rpy' -print0 | xargs -0 "$tools/venv/bin/python" -I -c ' import sys for p in sys.argv[1:]: b = open(p, "rb").read() if b.startswith(b"\xef\xbb\xbf"): b = b[3:] open(p, "wb").write(b.replace(b"\r\n", b"\n")) ' [ "$slug" = starseed ] && presplash="gui/main_menu.png" || presplash="images/Sea.png" cat > "$proj/progressive_download.txt" <<'EOF' # RenPyWeb progressive download rules - first match applies - image game/gui/** + image game/images/** + music game/**.mp3 EOF ;; esac if [ -f "$here/renpy-vn/$slug.patch" ]; then ( cd "$proj" && patch -s -p1 < "$here/renpy-vn/$slug.patch" ) fi # Tela de abertura da pagina: a arte do proprio jogo no lugar do logo do Ren'Py. cwebp -quiet -q 80 -resize 1280 720 "$proj/game/$presplash" -o "$proj/web-presplash.webp" # Datas fixas (o game.zip leva a data de cada arquivo). TZ=UTC find "$proj" -exec touch -t 202001010000 {} + export HOME="$out/home" TZ=UTC LC_ALL=C PYTHONHASHSEED=0 mkdir -p "$HOME" if [ -n "${RENPY_LINT:-}" ]; then ( cd "$sdk" && ./renpy.sh "$proj" lint ) 2>&1 | tail -40 exit 0 fi ( cd "$sdk" && ./renpy.sh launcher web_build "$proj" --destination "$out/webbuild" ) > "$out/renpy.log" 2>&1 || { tail -40 "$out/renpy.log" >&2; exit 1; } # --- pos-processamento --- w="$out/webbuild" rm -rf "$w/icons" "$w/manifest.json" "$w/service-worker.js" "$w/pwa_catalog.json" "$w/index.html.symbols" rm -f "$w/web-icon.png" "$tools/venv/bin/python" -I "$here/renpy-vn/post-web.py" "$w" gzip -n -9 -c "$w/renpy.wasm" > "$w/renpy.wasm.gz" rm "$w/renpy.wasm" cp -R "$w/." "$out/web/" TZ=UTC find "$out/web" -exec touch -t 202001010000 {} + ( cd "$out" && find web -type f | LC_ALL=C sort > "$out/web-files.txt" ) ( cd "$out" && COPYFILE_DISABLE=1 tar --format=ustar --uid 0 --gid 0 --uname root --gname root -n \ -cf - -T "$out/web-files.txt" ) | gzip -n -9 > "$out/$slug-web.tar.gz" # --- fonte LGPL: Ren'Py + renpy-build (ffmpeg, fribidi e as receitas de build); igual para os tres jogos --- lgpl="$base/renpy-$RENPY-lgpl-source.tar.gz" if [ ! -f "$lgpl" ]; then lg="$out/lgpl" mkdir -p "$lg/renpy-$RENPY" "$lg/renpy-build" tar -xjf "$cache/renpy-$RENPY-source.tar.bz2" -C "$lg/renpy-$RENPY" --strip-components 1 tar -xzf "$cache/renpy-build-$RB_TAG.tar.gz" -C "$lg/renpy-build" --strip-components 1 ( cd "$lg/renpy-$RENPY" && rm -rf doc sphinx the_question tutorial sdk-fonts ) ( cd "$lg/renpy-build" && rm -rf prebuilt rapt renios steamapi nvlib && cd source && find . -mindepth 1 -maxdepth 1 ! -name 'ffmpeg-4.3.1.tar.gz' ! -name 'fribidi-1.0.7.tar.bz2' -exec rm -rf {} + ) TZ=UTC find "$lg" -exec touch -t 202001010000 {} + ( cd "$lg" && find . -type f | sed 's|^\./||' | LC_ALL=C sort > "$out/lgpl-files.txt" ) ( cd "$lg" && COPYFILE_DISABLE=1 tar --format=ustar --uid 0 --gid 0 --uname root --gname root -n \ -cf - -T "$out/lgpl-files.txt" ) | gzip -n -9 > "$lgpl" rm -rf "$lg" fi rm -rf "$out/tmp" ( cd "$out" && shasum -a 256 "$slug-web.tar.gz" && cd web && find . -type f -print0 | LC_ALL=C sort -z | xargs -0 shasum -a 256 ) > "$out/SHA256SUMS" shasum -a 256 "$lgpl" du -sh "$out/web" "$out/$slug-web.tar.gz" "$lgpl"