@@ -18,49 +18,131 @@ get_controls
1818
1919# Variables
2020GAMEDIR=" /${directory} /ports/pharos"
21+ GAMEPARENT=" ${GAMEDIR%/* } "
22+ PENDING_ZIP=" ${GAMEDIR} /.pending_update.zip"
2123LOG_DIR=" ${GAMEDIR} /logs"
24+ RUN_LOG=" ${LOG_DIR} /$( date +' %Y-%m-%d' ) .log"
25+
26+ # Find the launcher path
27+ SCRIPT_PATH=" $( readlink -f " $0 " 2> /dev/null) "
28+ [ -z " ${SCRIPT_PATH} " ] && SCRIPT_PATH=" $0 "
29+ SCRIPT_DIR=" $( dirname " ${SCRIPT_PATH} " ) "
30+ SCRIPT_NAME=" $( basename " ${SCRIPT_PATH} " ) "
2231
2332cd " ${GAMEDIR} " || exit 1
2433
34+ mkdir -p " ${LOG_DIR} "
35+
2536# Exports
2637export XDG_DATA_HOME=" ${GAMEDIR} "
27- export LOG_FILE=" ${LOG_DIR} / $( date + ' %Y-%m-%d ' ) .log "
38+ export LOG_FILE=" ${RUN_LOG} "
2839export SDL_GAMECONTROLLERCONFIG=" ${sdl_controllerconfig} "
2940export PYSDL2_DLL_PATH=" /usr/lib"
3041export LD_LIBRARY_PATH=" ${GAMEDIR} /libs:${LD_LIBRARY_PATH} "
3142export controlfolder
3243export DEVICE_ARCH
3344
34- mkdir -p " ${LOG_DIR} "
45+ notify () {
46+ if command -v pm_message > /dev/null 2>&1 ; then
47+ pm_message " $1 "
48+ fi
49+ echo " [Pharos.sh] $( date ' +%H:%M:%S' ) $1 " >> " ${RUN_LOG} "
50+ }
3551
36- # Apply any pending self-update
3752apply_pending_update () {
38- local zip=" ${GAMEDIR} /.pending_update.zip"
39- local parent
40- parent=" $( dirname " ${GAMEDIR} " ) "
41- {
42- echo " [Update] Applying pending update from ${zip} ..."
43- if " $controlfolder /7zzs.${DEVICE_ARCH} " x -y " ${zip} " -o" ${parent} " > /dev/null; then
44- rm -f " ${zip} "
45- chmod +x " /{directory}/ports/Pharos App.sh"
46- echo " [Update] Applied; re-launching."
47- export _PHAROS_UPDATE_APPLIED=1
48- exec " $0 " " $@ "
53+ seven_zip=" ${controlfolder} /7zzs.${DEVICE_ARCH} "
54+ tmpdir=" "
55+
56+ if [ ! -x " ${seven_zip} " ]; then
57+ notify " Update apply: 7zzs not found at ${seven_zip} ."
58+ rm -f " ${PENDING_ZIP} "
59+ return 1
60+ fi
61+
62+ if ! " ${seven_zip} " t " ${PENDING_ZIP} " >> " ${RUN_LOG} " 2>&1 ; then
63+ notify " Update apply: pending zip is corrupt; deleted."
64+ rm -f " ${PENDING_ZIP} "
65+ return 1
66+ fi
67+
68+ tmpdir=" $( mktemp -d 2> /dev/null) "
69+ [ -z " ${tmpdir} " ] && tmpdir=" ${LOG_DIR} /.update_tmp.$$ "
70+ mkdir -p " ${tmpdir} " 2> /dev/null
71+
72+ notify " Applying Pharos update..."
73+ if ! " ${seven_zip} " x -y " ${PENDING_ZIP} " -o" ${tmpdir} " >> " ${RUN_LOG} " 2>&1 ; then
74+ notify " Update apply: extraction failed; see ${RUN_LOG} ."
75+ rm -rf " ${tmpdir} "
76+ rm -f " ${PENDING_ZIP} "
77+ return 1
78+ fi
79+
80+ # --- Data dir ---
81+ if [ ! -d " ${tmpdir} /pharos" ]; then
82+ notify " Update apply: zip is missing pharos/ directory; aborting."
83+ rm -rf " ${tmpdir} "
84+ rm -f " ${PENDING_ZIP} "
85+ return 1
86+ fi
87+ if ! cp -rf " ${tmpdir} /pharos/." " ${GAMEDIR} /" >> " ${RUN_LOG} " 2>&1 ; then
88+ notify " Update apply: data copy failed; see ${RUN_LOG} ."
89+ rm -rf " ${tmpdir} "
90+ rm -f " ${PENDING_ZIP} "
91+ return 1
92+ fi
93+
94+ # --- Launcher ---
95+ launcher_in_zip=" $( ls " ${tmpdir} " /* .sh 2> /dev/null | head -n1) "
96+ launcher_name=" ${SCRIPT_NAME} "
97+ if [ -n " ${launcher_in_zip} " ] && [ -f " ${launcher_in_zip} " ]; then
98+ launcher_name=" $( basename " ${launcher_in_zip} " ) "
99+ # Stage to a sibling .new then rename — atomic on the same FS,
100+ # so the in-flight `exec` below never sees a half-written script.
101+ if cp -f " ${launcher_in_zip} " " ${SCRIPT_DIR} /${launcher_name} .new" >> " ${RUN_LOG} " 2>&1 \
102+ && chmod +x " ${SCRIPT_DIR} /${launcher_name} .new" >> " ${RUN_LOG} " 2>&1 \
103+ && mv -f " ${SCRIPT_DIR} /${launcher_name} .new" " ${SCRIPT_DIR} /${launcher_name} " >> " ${RUN_LOG} " 2>&1 ; then
104+ :
49105 else
50- echo " [Update] Extraction failed; deleting partial zip."
51- rm -f " ${zip} "
106+ notify " Update apply: launcher swap failed at ${SCRIPT_DIR} ; old launcher kept."
107+ rm -f " ${SCRIPT_DIR} /${launcher_name} .new"
108+ launcher_name=" ${SCRIPT_NAME} "
109+ fi
110+ # If the launcher was renamed across versions, drop the old one.
111+ if [ " ${launcher_name} " != " ${SCRIPT_NAME} " ] && [ -f " ${SCRIPT_DIR} /${SCRIPT_NAME} " ]; then
112+ rm -f " ${SCRIPT_DIR} /${SCRIPT_NAME} "
113+ fi
114+ # Mirror into ${GAMEPARENT} too if that's a separate location
115+ # and a launcher already exists there.
116+ if [ " ${SCRIPT_DIR} " != " ${GAMEPARENT} " ] && [ -f " ${GAMEPARENT} /${launcher_name} " ]; then
117+ cp -f " ${SCRIPT_DIR} /${launcher_name} " " ${GAMEPARENT} /${launcher_name} " >> " ${RUN_LOG} " 2>&1
118+ chmod +x " ${GAMEPARENT} /${launcher_name} " >> " ${RUN_LOG} " 2>&1
52119 fi
53- } >> " ${LOG_FILE} " 2>&1
120+ fi
121+
122+ rm -rf " ${tmpdir} "
123+ rm -f " ${PENDING_ZIP} "
124+ chmod +x " ${GAMEDIR} /Pharos" 2>> " ${RUN_LOG} "
125+ export _PHAROS_UPDATE_APPLIED=1
126+ exec " ${SCRIPT_DIR} /${launcher_name} " " $@ "
54127}
55128
56- if [ -f " ${GAMEDIR} /.pending_update.zip" ] && [ -z " ${_PHAROS_UPDATE_APPLIED} " ]; then
129+ # Pre-launch apply: catches the path where the user came back to the menu
130+ # and re-launched manually after a previous download.
131+ if [ -f " ${PENDING_ZIP} " ] && [ -z " ${_PHAROS_UPDATE_APPLIED} " ]; then
57132 apply_pending_update " $@ "
58133fi
59134
60- # Permissions
135+ # Defensive +x on the binary.
61136chmod +x " ${GAMEDIR} /Pharos"
62137
63- pm_platform_helper " ${GAMEDIR} /Pharos" > /dev/null
64- " ${GAMEDIR} /Pharos" " ${GAMEDIR} /.sources" > " ${LOG_FILE} " 2>&1 || true
138+ # Run
139+ pm_platform_helper " ${GAMEDIR} /Pharos" >> " ${RUN_LOG} " 2>&1
140+ " ${GAMEDIR} /Pharos" " ${GAMEDIR} /.sources" >> " ${RUN_LOG} " 2>&1
141+
142+ # Post-exit apply
143+ if [ -f " ${PENDING_ZIP} " ]; then
144+ apply_pending_update " $@ "
145+ fi
65146
147+ # Cleanup
66148pm_finish
0 commit comments