bang bang

This commit is contained in:
bryanthaboi
2026-08-04 16:37:21 -04:00
parent 12b4c93279
commit d18824cfae
9 changed files with 715 additions and 392 deletions
@@ -259,7 +259,19 @@ bool httpDownload(const char *url, const char *destPath, const char *userAgent,
return false;
JNIEnv *env = (JNIEnv*) SDL_AndroidGetJNIEnv();
jclass activity = env->FindClass("org/love2d/android/GameActivity");
// NOT FindClass: this is the one bridge called off the main thread
// (love.thread workers in src/net/fetch_worker.lua and
// src/update/check_worker.lua). A worker is a raw pthread whose JNI
// class loader is the system one, which cannot see app classes, so
// FindClass("org/love2d/android/GameActivity") left a pending
// ClassNotFoundException and the next JNI call aborted the process --
// opening FIND MODS killed the app on the first stats fetch. Resolving
// through the live activity instance works from any attached thread.
jobject activityObj = (jobject) SDL_AndroidGetActivity();
if (activityObj == nullptr)
return false;
jclass activity = env->GetObjectClass(activityObj);
env->DeleteLocalRef(activityObj);
// Old APK / new liblove skew: report "no transport" the same way a
// missing curl does, instead of aborting on a missing method (#597).
+4 -4
View File
@@ -65,10 +65,10 @@ mkdir -p "$CACHE" "$WORK" "$DIST/mac" "$DIST/win" "$DIST/linux"
say "packing game.love"
LOVE_FILE="$WORK/game.love"
rm -f "$LOVE_FILE"
# libs/ carries the vendored FlexLove toolkit the launcher UI is built on
# (src/import/LauncherView.lua); a build without it dies on the first frame.
# The launcher UI kit lives at src/ui/kit (inside src/, packed wholesale);
# the vendored libs/flexlove tree it replaced is gone.
(cd "$ROOT" && zip -q -9 -r "$LOVE_FILE" \
main.lua conf.lua src libs data assets tools/save-editor \
main.lua conf.lua src data assets tools/save-editor \
tools/rom_manifest.json tools/rom_manifest_blue.json \
tools/rom_manifest_yellow.json \
-x '*.DS_Store' 'data/generated/*' 'assets/generated/*')
@@ -88,7 +88,7 @@ fi
# way once).
for required in tools/save-editor/App.lua tools/save-editor/Kit.lua \
tools/save-editor/panels/Party.lua \
libs/flexlove/FlexLove.lua \
src/ui/kit/Kit.lua \
tools/rom_manifest.json tools/rom_manifest_blue.json \
tools/rom_manifest_yellow.json; do
grep -qxF "$required" "$LOVE_LISTING" \
+11 -11
View File
@@ -202,12 +202,10 @@ pack_game_love() {
# APK, so the mod manager's Delete can't remove it and it reappears every
# launch. Pokewalker ships as an importable .zip instead, which gives it
# a real install/upgrade/delete lifecycle.
# libs/ carries the vendored FlexLove toolkit the launcher UI is built on
# (src/import/LauncherView.lua requires it at the top level, and RomImporter
# calls into that view from both update and draw), so an archive without it
# dies on the first frame with nothing left to fall back to.
# The launcher UI kit lives at src/ui/kit (inside src/, packed wholesale);
# the vendored libs/flexlove tree it replaced is gone.
(cd "$ROOT" && zip -q -9 -r "$LOVE_FILE" \
main.lua conf.lua src libs data assets tools/save-editor \
main.lua conf.lua src data assets tools/save-editor \
tools/rom_manifest.json tools/rom_manifest_blue.json \
tools/rom_manifest_yellow.json \
-x '*.DS_Store' -x '*/.git/*' -x '*/.DS_Store' \
@@ -229,12 +227,14 @@ pack_game_love() {
|| fail "game.love is missing the save editor (Edit on a save row would crash)"
grep -qx "$YELLOW_MANIFEST_RELATIVE" <<< "$archive_entries" \
|| fail "game.love is missing the Yellow ROM import manifest"
# This gate exists because libs/ was added to scripts/build.sh's payload and
# to no other packager, so Android and iOS built an APK/IPA whose launcher
# threw on require("libs.flexlove.FlexLove") before drawing anything. Source
# runs read libs/ off the working tree, so only a build can catch it.
grep -qx 'libs/flexlove/FlexLove.lua' <<< "$archive_entries" \
|| fail "game.love is missing the FlexLove UI toolkit (launcher dies on frame 1)"
# This gate exists because the launcher's UI toolkit once lived outside
# src/ (libs/flexlove) and was added to scripts/build.sh's payload and to
# no other packager, so Android and iOS built an APK/IPA whose launcher
# threw before drawing anything. The kit now lives inside src/, but the
# gate stays: source runs read the working tree, so only a build can catch
# a packaging miss.
grep -qx 'src/ui/kit/Kit.lua' <<< "$archive_entries" \
|| fail "game.love is missing the launcher UI kit (launcher dies on frame 1)"
say "game.love: $(du -h "$LOVE_FILE" | cut -f1) -> $LOVE_FILE"
# This script packs its own game.love (it does not reuse build.sh's), so it
+8 -9
View File
@@ -315,13 +315,11 @@ pack_game_love() {
# it reappears every launch. Mods install as .zips at runtime instead
# (launcher -> MODS -> Import mod .zip), the same lifecycle as every
# other platform.
# libs/ carries the vendored FlexLove toolkit the launcher UI is built on
# (src/import/LauncherView.lua requires it at the top level, and RomImporter
# calls into that view from both update and draw), so an archive without it
# dies on the first frame with nothing left to fall back to.
# The launcher UI kit lives at src/ui/kit (inside src/, packed wholesale);
# the vendored libs/flexlove tree it replaced is gone.
# shellcheck disable=SC2086 # MANIFESTS is a deliberate word list
(cd "$ROOT" && zip -q -9 -r "$LOVE_FILE" \
main.lua conf.lua src libs data assets tools/save-editor \
main.lua conf.lua src data assets tools/save-editor \
$MANIFESTS \
-x '*.DS_Store' -x '*/.git/*' -x '*/.DS_Store' \
-x 'data/generated/*' -x 'assets/generated/*')
@@ -337,14 +335,15 @@ pack_game_love() {
# in 0.1.45 through 0.1.47: decodeManifest (src/import/RomImporter.lua) errors
# outright when a version's manifest is absent, so Import ROM on Yellow died
# in the built app while dev, which reads the source tree, stayed green.
# libs/flexlove/FlexLove.lua is on the list for the same reason: it was added
# to build.sh's payload and to no other packager, so the mobile builds shipped
# a launcher that threw before drawing its first frame.
# src/ui/kit/Kit.lua is on the list for the same reason: the launcher's UI
# toolkit once lived outside src/ (libs/flexlove) and shipped missing from
# the mobile packagers, so the launcher threw before drawing its first
# frame. The kit is inside src/ now; the gate stays to catch a repeat.
archive_entries="$(unzip -Z1 "$LOVE_FILE")"
# shellcheck disable=SC2086 # MANIFESTS is a deliberate word list
for required in src/update/Boot.lua tools/save-editor/App.lua \
tools/save-editor/Kit.lua tools/save-editor/panels/Party.lua \
libs/flexlove/FlexLove.lua \
src/ui/kit/Kit.lua \
$MANIFESTS; do
printf '%s\n' "$archive_entries" | grep -qx "$required" \
|| fail "game.love is missing $required"
+4 -4
View File
@@ -44,10 +44,10 @@ mkdir -p "$(dirname "$OUTPUT")" "$(dirname "$LISTING")"
say "packing game.love"
rm -f "$OUTPUT"
# libs/ carries the vendored FlexLove toolkit the launcher UI is built on
# (src/import/LauncherView.lua); a build without it dies on the first frame.
# The launcher UI kit lives at src/ui/kit (inside src/, packed wholesale);
# the vendored libs/flexlove tree it replaced is gone.
(cd "$ROOT" && zip -q -9 -r "$OUTPUT" \
main.lua conf.lua src libs data assets tools/save-editor \
main.lua conf.lua src data assets tools/save-editor \
tools/rom_manifest.json tools/rom_manifest_blue.json \
tools/rom_manifest_yellow.json \
-x '*.DS_Store' 'data/generated/*' 'assets/generated/*')
@@ -88,7 +88,7 @@ for required in tools/save-editor/App.lua tools/save-editor/Kit.lua \
tools/save-editor/panels/Party.lua \
tools/rom_manifest.json tools/rom_manifest_blue.json \
tools/rom_manifest_yellow.json \
libs/flexlove/FlexLove.lua \
src/ui/kit/Kit.lua \
src/import/LauncherView.lua; do
grep -qxF "$required" "$LISTING" \
|| fail "game.love is missing $required"
File diff suppressed because it is too large Load Diff
+4
View File
@@ -3468,6 +3468,10 @@ function RomImporter:_pumpFindStats()
end
self._findStatsCache = self._findStatsCache or {}
self._findStatsCache[id] = cached
-- The FIND list's sort cache is keyed on this revision; without the
-- bump a Popularity/date sort stays frozen in the order of the first
-- frame (no stats yet = name order) even after every fetch lands.
self._findStatsRev = (self._findStatsRev or 0) + 1
end
end
if next(pending) == nil then self._findStatsPending = nil end
+13 -8
View File
@@ -257,16 +257,21 @@ end
-- across all releases - Released 2024-05-31 - Updated 2026-07-01".
-- Each part is optional; nil everywhere means nil, so a row with no data
-- shows no line rather than a wrong "0".
function ModUpdate.downloadsLine(total)
if total == nil then return nil end
return Strings("%s downloads across all releases",
ModUpdate.formatCount(total))
end
function ModUpdate.datesLine(first, latest)
if not (first or latest) then return nil end
return Strings("Released %s - Updated %s", first or "?", latest or "?")
end
function ModUpdate.statsLine(total, first, latest)
local parts = {}
if total ~= nil then
parts[#parts + 1] = Strings("%s downloads across all releases",
ModUpdate.formatCount(total))
end
if first or latest then
parts[#parts + 1] = Strings("Released %s - Updated %s",
first or "?", latest or "?")
end
parts[#parts + 1] = ModUpdate.downloadsLine(total)
parts[#parts + 1] = ModUpdate.datesLine(first, latest)
if #parts == 0 then return nil end
return table.concat(parts, " - ")
end
+8 -1
View File
@@ -368,7 +368,10 @@ Kit._navQueue = nil
Kit._activateId = nil
-- Register a focusable. Returns true when it currently holds the ring.
-- Shielded widgets do not register: while a modal owns the frame the ring
-- must not wander through (or Enter-activate) the controls underneath it.
function Kit.focusable(id, x, y, w, h)
if Kit.blockClicks then return false end
local n = (Kit._navN or 0) + 1
Kit._navN = n
local slot = Kit._nav[n]
@@ -492,6 +495,9 @@ function Kit.hit(x, y, w, h)
end
function Kit.hover(x, y, w, h)
-- Shielded widgets (drawn while a modal owns the frame) must not glow
-- either: a hover highlight under the scrim reads as "still clickable".
if Kit.blockClicks then return false end
return Kit.hit(x, y, w, h)
end
@@ -640,7 +646,8 @@ function Kit.button(x, y, w, h, label, opts)
end
if not enabled then return false end
return Kit.press(x, y, w, h)
or (opts.id ~= nil and Kit._activateId == opts.id)
or (not Kit.blockClicks and opts.id ~= nil
and Kit._activateId == opts.id)
end
-- A small square control: +/- steppers, arrow cyclers, the row X.