Fix gameupdate and minimize bug

This commit is contained in:
DazedAnon 2026-07-11 09:26:20 -05:00
parent 300953a04d
commit 836280e00d
3 changed files with 187 additions and 68 deletions

View file

@ -3,12 +3,44 @@
# Enable error handling
set -e
# Same layout as GameUpdate.bat: patch assets live under ./gameupdate/ next to this file.
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
GAME_ROOT="$SCRIPT_DIR"
PATCH_DIR="$SCRIPT_DIR/gameupdate"
# Re-exec from a temp copy so applying the patch zip cannot overwrite/truncate
# this launcher while bash is still reading it (same idea as patch.sh -> patch2.sh).
if [ -z "${GAMEUPDATE_LINUX_REEXEC:-}" ]; then
SELF="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/$(basename "${BASH_SOURCE[0]}")"
GAME_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TMP_SELF="$(mktemp)"
cp -f "$SELF" "$TMP_SELF"
chmod +x "$TMP_SELF"
export GAMEUPDATE_LINUX_REEXEC=1
# shellcheck disable=SC2093
exec bash "$TMP_SELF" "$GAME_ROOT"
fi
GAME_ROOT="$1"
PATCH_DIR="$GAME_ROOT/gameupdate"
REEXEC_PATH="$0"
cleanup_reexec() {
rm -f "$REEXEC_PATH"
}
trap cleanup_reexec EXIT
cd "$GAME_ROOT"
cp "$PATCH_DIR/patch.sh" "$PATCH_DIR/patch2.sh"
set +e
bash "$PATCH_DIR/patch2.sh"
rm "$PATCH_DIR/patch2.sh"
patch_exit=$?
set -e
rm -f "$PATCH_DIR/patch2.sh"
if [ "$patch_exit" -ne 0 ]; then
echo "GameUpdate failed (exit $patch_exit)."
fi
# Match Windows patch.ps1 pause when launched interactively (double-click / terminal).
if [ -t 0 ] && [ -t 1 ]; then
echo
read -r -p "Press Enter to close..."
fi
exit "$patch_exit"

View file

@ -15,6 +15,25 @@ check_dependency() {
fi
}
# Run a Windows .exe. On Linux always go through wine (never rely on binfmt,
# which can hang waiting on wineserver / GUI). On Windows / Git Bash, exec directly.
run_windows_exe() {
local exe="$1"
shift
case "$(uname -s)" in
Linux*)
if ! command -v wine > /dev/null 2>&1; then
echo "ERROR: wine is required to run $(basename "$exe") on Linux."
return 1
fi
( cd "$ROOT_DIR" && WINEDEBUG=-all wine "$exe" "$@" )
;;
*)
( cd "$ROOT_DIR" && "$exe" "$@" )
;;
esac
}
# Check for jq, unzip, and curl
check_dependency jq
check_dependency unzip
@ -263,12 +282,7 @@ invoke_wolf_pre_setup() {
fi
echo "[Pre-Setup] Unpacking Data.wolf with UberWolfCli (one-time)..."
# Native .exe works under Windows / Git Bash; wine covers Linux hosts.
if ( cd "$ROOT_DIR" && "$cli" -o "$data_wolf" ); then
:
elif command -v wine > /dev/null 2>&1 && ( cd "$ROOT_DIR" && wine "$cli" -o "$data_wolf" ); then
:
else
if ! run_windows_exe "$cli" -o "$data_wolf"; then
echo "[Pre-Setup] ERROR: UberWolfCli unpack failed."
return 0
fi
@ -315,7 +329,7 @@ if [ -f "$ROOT_DIR/data.dts" ]; then
if [ ! -d "$ROOT_DIR/data" ] || [ ! -f "$ROOT_DIR/data/project.dat" ]; then
if [ -f "$ROOT_DIR/data.dts" ]; then
echo "[Pre-Setup] Step 1: Unpacking data.dts -> data"
( cd "$ROOT_DIR" && "$UNPACKER" -o data data.dts ) || echo "[Pre-Setup] ERROR: Unpack failed."
run_windows_exe "$UNPACKER" -o data data.dts || echo "[Pre-Setup] ERROR: Unpack failed."
else
echo "[Pre-Setup] Step 1: Skipping unpack (no data folder and no data.dts found)."
fi
@ -327,7 +341,7 @@ if [ -f "$ROOT_DIR/data.dts" ]; then
if [ ! -d "$ROOT_DIR/patch" ]; then
if [ -f "$ROOT_DIR/data/project.dat" ]; then
echo "[Pre-Setup] Step 2: Creating patch from data/project.dat"
( cd "$ROOT_DIR" && "$UNPACKER" ./data/project.dat -c ) || echo "[Pre-Setup] ERROR: Create Patch failed."
run_windows_exe "$UNPACKER" ./data/project.dat -c || echo "[Pre-Setup] ERROR: Create Patch failed."
else
echo "[Pre-Setup] Step 2: Skipping create patch (data/project.dat not found)."
fi
@ -385,20 +399,17 @@ download_extract() {
invoke_wolf_pre_setup
echo "Applying patch..."
if ! cp -r "$inner"/* "$ROOT_DIR/"; then
if ! cp -rf "$inner"/* "$ROOT_DIR/"; then
echo "Patch application failed!"
rm -rf "$TMP_EX"
rm -f "$ROOT_DIR/repo.zip"
return 1
fi
rm -rf "$TMP_EX"
echo "Cleaning up..."
rm -f "$ROOT_DIR/repo.zip"
# --------------------------------------------------------
# POST-APPLY: Run Steps 3 and 4 after patch files are merged
# (Must finish before "Cleaning up" so a slow wine/SRPG step is not
# mistaken for a hung cleanup - matches patch.ps1 order.)
# --------------------------------------------------------
UNPACKER="$ROOT_DIR/SRPG_Unpacker.exe"
if [ -f "$ROOT_DIR/data.dts" ]; then
@ -407,14 +418,14 @@ download_extract() {
if [ -f "$ROOT_DIR/data/project.dat" ]; then
echo "Step 3: Applying patch to data/project.dat"
( cd "$ROOT_DIR" && "$UNPACKER" ./data/project.dat -a ) || echo "ERROR: Apply Patch failed."
run_windows_exe "$UNPACKER" ./data/project.dat -a || echo "ERROR: Apply Patch failed."
else
echo "ERROR: data/project.dat not found; cannot apply patch."
fi
if [ -d "$ROOT_DIR/data" ]; then
echo "Step 4: Packing data -> data.dts"
( cd "$ROOT_DIR" && "$UNPACKER" -o data.dts data ) || echo "WARNING: Pack failed."
run_windows_exe "$UNPACKER" -o data.dts data || echo "WARNING: Pack failed."
else
echo "Step 4: Skipping pack (data folder not found)."
fi
@ -426,7 +437,19 @@ download_extract() {
# Retire Data.wolf if loose Data/ is ready after the patch copy.
invoke_wolf_pre_setup
echo "Cleaning up..."
rm -rf "$TMP_EX"
rm -f "$ROOT_DIR/repo.zip"
# Legacy / accidental leftovers from older patchers.
rm -rf "$ROOT_DIR/_patch_extract_tmp"
shopt -s nullglob
for stale in "$ROOT_DIR"/dazedmtl_patch_*.zip; do
rm -f "$stale"
done
shopt -u nullglob
echo "$latest_patch_sha" > "$STATE_FILE"
echo "Done."
}
# Check if previous_patch_sha.txt exists in gameupdate

View file

@ -74,6 +74,89 @@ BATCH_COLLECT_LIVE_CHARGE_NOTE = (
)
class _ShimLabel:
"""Plain stand-in for QLabel used by Files-tab row helpers (no real Qt widget)."""
def __init__(self, text=""):
self._text = text
self._style = ""
self._visible = False
self._tooltip = ""
def setText(self, text):
self._text = text or ""
def text(self):
return self._text
def setStyleSheet(self, style):
self._style = style or ""
def setVisible(self, visible):
self._visible = bool(visible)
def setToolTip(self, tip):
self._tooltip = tip or ""
def toolTip(self):
return self._tooltip
class _ShimCheckBox:
def __init__(self):
self._checked = False
self._enabled = False
self._visible = False
def setChecked(self, checked):
self._checked = bool(checked)
def isChecked(self):
return self._checked
def setEnabled(self, enabled):
self._enabled = bool(enabled)
def setVisible(self, visible):
self._visible = bool(visible)
class _ShimProgressBar:
def __init__(self):
self._value = 0
self._maximum = 100
self._visible = False
self._text_visible = True
self._style = ""
def setValue(self, value):
self._value = int(value)
def setMaximum(self, maximum):
self._maximum = int(maximum)
def setVisible(self, visible):
self._visible = bool(visible)
def setTextVisible(self, visible):
self._text_visible = bool(visible)
def setStyleSheet(self, style):
self._style = style or ""
class _ShimWidget:
def __init__(self):
self._visible = False
self._tooltip = ""
def setVisible(self, visible):
self._visible = bool(visible)
def setToolTip(self, tip):
self._tooltip = tip or ""
class TranslationWorker(QThread):
"""Worker thread for running translations without blocking the UI."""
@ -1162,31 +1245,12 @@ class TranslationTab(QWidget):
self.batch_pipeline_stack.setStyleSheet("background: transparent;")
self.batch_pipeline_stack.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.progress_list = QListWidget()
self.progress_list.setMinimumHeight(120)
self.progress_list.setSelectionMode(QListWidget.NoSelection)
self.progress_list.setFocusPolicy(Qt.NoFocus)
self.progress_list.setSpacing(1) # Minimal spacing between items
self.progress_list.setStyleSheet("""
QListWidget {
outline: none;
border: 1px solid #555555;
border-radius: 3px;
background-color: #1e1e1e;
color: white;
font-size: 13px;
}
QListWidget::item {
padding: 0px;
border-bottom: 1px solid #333333;
}
QListWidget::item:last {
border-bottom: none;
}
""")
# Prefer a Batch-history-style table for per-file status; keep the list
# widget as a non-visible compatibility shim for any leftover references.
# Prefer a Batch-history-style table for per-file status. Keep a hidden,
# parented list as a compatibility shim so clear()/legacy refs stay safe
# without creating an orphan top-level window (minimize/restore glitches).
self.progress_list = QListWidget(self)
self.progress_list.setVisible(False)
self.progress_list.setMaximumSize(0, 0)
self.progress_files_summary = QLabel("No files in this run.")
self.progress_files_summary.setStyleSheet("color:#9d9d9d;font-size:12px;padding:2px 0;")
@ -1785,6 +1849,16 @@ class TranslationTab(QWidget):
self.files_tab_btn.setText("Files")
self._batch_tab_index = -1
self.progress_content_stack.setCurrentIndex(1)
# Per-file Time is useful for live translate; for batch, Anthropic owns
# the wait and local write time is negligible.
table = getattr(self, "progress_table", None)
if table is not None and table.columnCount() > 5:
table.setColumnHidden(5, bool(batch_mode))
try:
if hasattr(self, "totals_time_label"):
self.totals_time_label.setVisible(not batch_mode)
except Exception:
pass
def _on_batch_submit_yes(self):
if hasattr(self, "translation_worker") and self.translation_worker:
@ -2456,11 +2530,10 @@ class TranslationTab(QWidget):
self._refresh_files_summary()
def create_progress_item(self, filename):
"""Add a Files-tab table row for a file and return a placeholder widget."""
"""Add a Files-tab table row for a file and return a placeholder shim."""
table = getattr(self, "progress_table", None)
if table is None:
# Fallback empty widget if table is unavailable
return QWidget()
return _ShimWidget()
row = table.rowCount()
table.insertRow(row)
@ -2473,25 +2546,16 @@ class TranslationTab(QWidget):
item.setData(Qt.UserRole, filename)
table.setItem(row, col, item)
# Keep a small compatibility widget so older helpers that expect
# checkbox/label/progress_bar keys do not crash.
checkbox = QCheckBox()
# Non-Qt shims keep older helpers working without spawning orphan windows.
checkbox = _ShimCheckBox()
checkbox.setEnabled(False)
checkbox.setVisible(False)
progress_label = QLabel("Waiting...")
progress_label.setVisible(False)
progress_bar = QProgressBar()
progress_bar.setVisible(False)
tokens_label = QLabel("")
tokens_label.setVisible(False)
cost_label = QLabel("")
cost_label.setVisible(False)
time_label = QLabel("")
time_label.setVisible(False)
status_label = QLabel("")
status_label.setVisible(False)
shim = QWidget()
shim.setVisible(False)
progress_label = _ShimLabel("Waiting...")
progress_bar = _ShimProgressBar()
tokens_label = _ShimLabel("")
cost_label = _ShimLabel("")
time_label = _ShimLabel("")
status_label = _ShimLabel("")
shim = _ShimWidget()
self.file_progress_items[filename] = {
"row": row,
@ -2650,7 +2714,7 @@ class TranslationTab(QWidget):
filename,
tokens=tokens or None,
cost=cost or None,
time_s=time_s or None,
time_s=None if getattr(self, "_batch_active", False) else (time_s or None),
)
def reset_to_file_view(self):
@ -3083,7 +3147,7 @@ class TranslationTab(QWidget):
filename,
tokens=tokens_text,
cost=cost_text,
time_s=time_text,
time_s=None if getattr(self, "_batch_active", False) else time_text,
)
except Exception:
pass