# Peças comuns dos jogos Java (libGDX -> navegador por TeaVM/gdx-teavm ou GWT). Uso, num build-.sh: # # source "$here/java-web/env.sh" # # Define: root, cache (artifacts/build/cache), JAVA_HOME (Temurin de artifacts/tools, sem JDK do sistema), # GRADLE_USER_HOME (artifacts/build/cache/gradle-, nunca ~/.gradle) e as funções jw_fetch e jw_gradle. # O cache do Gradle é apagado à mão quando o jogo for publicado (rm -rf artifacts/build/cache/gradle-). _jw_here="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" root="$(git -C "$_jw_here" rev-parse --show-toplevel 2>/dev/null || pwd)" cache="$root/artifacts/build/cache" mkdir -p "$cache" case "${2:?jdk 17 ou 21}" in 17) export JAVA_HOME="$root/artifacts/tools/jdk-jdk-17.0.21+9/Contents/Home" ;; 21) export JAVA_HOME="$root/artifacts/tools/jdk-jdk-21.0.13+9/Contents/Home" ;; *) echo "jdk desconhecido: $2" >&2; exit 1 ;; esac [ -x "$JAVA_HOME/bin/java" ] || { echo "JDK ausente: $JAVA_HOME" >&2; exit 1; } export PATH="$JAVA_HOME/bin:$PATH" export GRADLE_USER_HOME="$cache/gradle-${1:?slug}" mkdir -p "$GRADLE_USER_HOME" export TZ=UTC LC_ALL=C # jw_fetch : baixa uma vez e confere sempre. jw_fetch() { if [ ! -f "$cache/$3" ]; then curl -fsSL --retry 4 "$1" -o "$cache/$3.partial" && mv "$cache/$3.partial" "$cache/$3" fi echo "$2 $cache/$3" | shasum -a 256 -c - >/dev/null || { echo "sha256 divergente: $3" >&2; exit 1; } } # jw_gradle : o wrapper do projeto (o gradle-wrapper.jar dele, que baixa o Gradle pinado em # gradle-wrapper.properties e confere o distributionSha256Sum), sem daemon. Chama o GradleWrapperMain direto: o # script gradlew de alguns projetos é mais antigo que o jar (o jar do Gradle 9 não tem Main-Class) e nem sempre # vem executável do tarball. jw_gradle() { java -Xmx512m -classpath gradle/wrapper/gradle-wrapper.jar org.gradle.wrapper.GradleWrapperMain \ --no-daemon --console=plain -q -Dorg.gradle.jvmargs="-Xmx2g ${JW_JVMARGS:-}" "$@" } # jw_det_hash: faz a JVM numerar os objetos em sequencia (-XX:hashCode=3) em vez de ao acaso. Compiladores que iteram # HashMap/HashSet de objetos sem hashCode proprio (o GWT) geram saidas diferentes a cada execucao sem isso. Vale para # todas as JVMs filhas (JAVA_TOOL_OPTIONS). Nao resolveu o TeaVM (lá a saida so fica igual com optimization NONE). jw_det_hash() { export JAVA_TOOL_OPTIONS="-XX:+UnlockExperimentalVMOptions -XX:hashCode=3" } # jw_pack : tar determinístico (ustar, ordem fixa, sem dono, gzip sem data). jw_pack() { ( cd "$1/.." && find "$(basename "$1")" -type f | sort > "$1.list" \ && COPYFILE_DISABLE=1 tar --format=ustar --uid 0 --gid 0 --uname root --gname root -n -cf - -T "$1.list" ) | gzip -n -9 > "$2" rm -f "$1.list" } # jw_post [script do app, padrão teavm/app.js] [teavm|gwt]: # deixa só o necessário (index.html nosso com CSP que só permite esta origem, o app.js/wasm e os assets; # sem WEB-INF e com o logo de carregamento do libGDX trocado por um PNG vazio), isola o localStorage por jogo e zera as datas. jw_post() { local src="$1" dst="$2" id="$3" title="$4" bg="$5" fg="$6" app="${7:-teavm/app.js}" kind="${8:-teavm}" rm -rf "$dst"; mkdir -p "$dst" cp -R "$src/." "$dst/" rm -rf "$dst/WEB-INF" "$dst/index.html" # o app.js do gdx-teavm pede assets/startup-logo.png (logo do libGDX): vira um PNG transparente de 1x1 [ ! -f "$dst/assets/startup-logo.png" ] || printf 'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR4nGNgYGD4DwABBAEAHnOcQAAAAABJRU5ErkJggg==' | base64 -d > "$dst/assets/startup-logo.png" local tpl="$_jw_here/index.html.in" cp "$_jw_here/fredygames-storage.js" "$dst/" if [ "$kind" = gwt ]; then tpl="$_jw_here/index-gwt.html.in"; else cp "$_jw_here/fredygames-start.js" "$dst/"; fi sed -e "s|@ID@|$id|g" -e "s|@TITLE@|$title|g" -e "s|@BG@|$bg|g" -e "s|@FG@|$fg|g" -e "s|@APP@|$app|g" "$tpl" > "$dst/index.html" # gdx-teavm 1.6 (plugin) nao usa a barra de carregamento do index.html: JW_NO_PROGRESS=1 a tira [ -z "${JW_NO_PROGRESS:-}" ] || sed -i.bak '/
/d' "$dst/index.html" && rm -f "$dst/index.html.bak" rm -f "$dst/assets/.gitkeep" find "$dst" -exec touch -t 202001010000 {} + }