Compare commits

...

6 Commits

Author SHA1 Message Date
ZeroSkill1
cf1cb1cfc5 fix a few cases of improper varg usage in luaL_error 2025-04-26 14:38:59 +02:00
ihaveahax
9ae4351bce
Lua documentation fixes (#910)
* lua-doc: Fix fs.find_all documentation

It returns an array, not a string. Also document return information.

* lua-doc: Remove TODO for fs.verify_with_sha_file

No reason to add fs.read_file errors here as that function gets
pcall-ed. If it fails, nil gets returned.

* lua-doc: Consistently refer to tables/arrays as tables

That's what they're called within Lua all the time.

* lua-doc: fix incorrect references to util module
2025-04-26 14:38:25 +02:00
ihaveahax
99f1abd7a4 lua io: fix incorrect mode detection
string.find has pattern matching by default, so it was incorrectly
reading "r+" when the mode was supposed to be "r". So this disables the
pattern matching and does a plain substring search.
2025-04-26 14:37:46 +02:00
ihaveahax
15eb3b1ebe
GM9Megascript: remove "Un-install Hax" (#916)
This option is confusing because despite it saying "will completely
remove CFW", it is not sufficient to actually fully remove custom
firmware. It doesn't, and can't, detect everything like region changes,
modified system titles, and other things that could brick a stock
console.

There have been numerous cases of bricked consoles because someone saw
this, thinking it would do everything needed to restore a console back
to an unmodified state, and getting a bricked console that needs a
flashcart purchase to fix.

(There is also a issue where, even if everything else was in order, it
can still brick a console due to a bad SD card. For some reason it
copies the FIRM to the SD card, where it can potentially get corrupted
if a counterfeit card was used.)

A proper uninstall guide is required, and we have one here:
https://3ds.hacks.guide/uninstall-cfw
2025-04-26 14:36:36 +02:00
ihaveahax
4424c37a89
Fix fs.list_dir not closing directory (#902)
I forgot fvx_closedir oops!
2025-03-24 17:11:46 +01:00
TophattedWasTaken
bc84780036
Lua examples: Small error corrections (#898)
* HelloScript.lua: Correct typos

* Lua docs: fget corresponds to fs.read_file
2025-03-24 17:08:53 +01:00
6 changed files with 22 additions and 115 deletions

View File

@ -122,7 +122,7 @@ static int internalfs_mkdir(lua_State* L) {
FRESULT res = fvx_rmkdir(path);
if (res != FR_OK) {
return luaL_error(L, "could not mkdir (%d)", path, res);
return luaL_error(L, "could not mkdir %s (%d)", path, res);
}
return 0;
@ -145,6 +145,7 @@ static int internalfs_list_dir(lua_State* L) {
for (int i = 1; true; i++) {
res = fvx_readdir(&dir, &fno);
if (res != FR_OK) {
fvx_closedir(&dir);
lua_pop(L, 1); // remove final table from stack
return luaL_error(L, "could not readdir %s (%d)", path, res);
}
@ -152,6 +153,7 @@ static int internalfs_list_dir(lua_State* L) {
CreateStatTable(L, &fno);
lua_seti(L, -2, i); // add nested table to final table
}
fvx_closedir(&dir);
return 1;
}
@ -465,7 +467,7 @@ static int internalfs_make_dummy_file(lua_State* L) {
CheckWritePermissionsLuaError(L, path);
if (!(FileCreateDummy(path, NULL, size))) {
return luaL_error(L, "FileCreateDummy failed on %s");
return luaL_error(L, "FileCreateDummy failed on %s", path);
}
return 0;

View File

@ -35,7 +35,7 @@ static inline void CheckLuaArgCount(lua_State* L, int argcount, const char* cmd)
static inline bool CheckLuaArgCountPlusExtra(lua_State* L, int argcount, const char* cmd) {
int args = lua_gettop(L);
if (args != argcount && args != argcount + 1) {
luaL_error(L, "bad number of arguments passed to '%s' (expected %d, got %d or %d)", cmd, argcount, args);
luaL_error(L, "bad number of arguments passed to '%s' (expected %d or %d, got %d)", cmd, argcount, argcount + 1, args);
}
return args == argcount + 1;
}

View File

@ -35,7 +35,7 @@ function file.new(filename, mode)
end
debugf("opening", filename, mode)
of = setmetatable({_filename=filename, _mode=mode, _seek=0, _open=true, _readable=false, _writable=false, _append_only=false}, file)
if string.find(mode, "w") then
if string.find(mode, "w", 1, true) then
debugf("opening", filename, "for writing")
-- preemptively allow writing instead of having that prompt at file:write
allowed = fs.allow(filename)
@ -48,7 +48,7 @@ function file.new(filename, mode)
of._size = 0
of._readable = false
of._writable = true
elseif string.find(mode, "r+") then
elseif string.find(mode, "r+", 1, true) then
debugf("opening", filename, "for updating")
allowed = fs.allow(filename)
debugf("allowed:", allowed)
@ -64,7 +64,7 @@ function file.new(filename, mode)
of._stat = {}
of._size = 0
end
elseif string.find(mode, "a") then
elseif string.find(mode, "a", 1, true) then
debugf("opening", filename, "for appending")
allowed = fs.allow(filename)
debugf("allowed:", allowed)
@ -82,7 +82,7 @@ function file.new(filename, mode)
of._stat = {}
of._size = 0
end
if string.find(mode, "+") then
if string.find(mode, "+", 1, true) then
debugf("append update mode")
of._readable = true
else

View File

@ -409,100 +409,6 @@ else
end
goto Hax_Options_Install_Boot9Strap
###################Hax Uninstall##################
@Hax_Options_Un-install_Hax
set PREVIEW_MODE "GODMODE9 ALL-IN-ONE MEGASCRIPT\nby annson24\n \nHax Options\n>Hax Un-install"
if not ask "!!WARNING!!\nThis will completely remove CFW and\nrevert your system to stock.\n \nProceed anyway?"
goto MainMenu_Hax_Options
end
if not chk -u $[HAX] "ntrboot"
if not ask "!!WARNING!!\nntrboot not detected!\nYou should at least have ntrboot or a hardmod\nwith you before proceeding in case of brick.\n \nProceed anyway?"
goto MainMenu_Restore_Options
end
end
if chk -u $[ONTYPE] "N3DS"
goto Unhax_Old
end
if not sha S:/sector0x96.bin 82F2730D2C2DA3F30165F987FDCCAC5CBAB24B4E5F65C981CD7BE6F438E6D9D3
if not find 0:/boot9strap/secret_sector.bin SECRET
if not find $[GM9IN]/boot9strap/secret_sector.bin SECRET
echo "Sector 0x96 is not genuine.\nYou must have the secret_sector.bin file in the\nboot9strap folder first then try again.\n \nAborting."
goto Hax_Options_Install_Boot9Strap
end
end
if not allow -a S:
echo "Permissions denied. Aborting."
goto MainMenu_Hax_Options
end
cp -n -w S:/sector0x96.bin $[SECRET].bak
cp -n -w $[SECRET] S:/sector0x96.bin
end
if not find 1:/title/00040138/20000002/content/????????.app NATIVE_NCCH
echo "NATIVE_FIRM not found.\nIs this a N3DS?"
goto MainMenu_Hax_Options
end
imgmount $[NATIVE_NCCH]
verify G:/exefs/.firm
set NATIVE_FIRM $[GM9OUT]/NATIVE_FIRM.firm
cp -w G:/exefs/.firm $[NATIVE_FIRM]
imgumount
if allow -a S:
allow -a 1:
rm -o -s 1:/boot.firm
rm -o -s 1:/rw/luma
cp -n $[NATIVE_FIRM] S:/firm0.bin
cp -n $[NATIVE_FIRM] S:/firm1.bin
shaget S:/nand.bin@57FFE00:200 PRE_STAGE2_HASH
if not sha S:/nand.bin@B800000:200 $[PRE_STAGE2_HASH]
fget S:/nand.bin@57FFE00:1 PRE_STAGE2
fill S:/nand.bin@B7FFE00:89C00 $[PRE_STAGE2]
end
echo "CFW uninstalled successfully"
else
echo "Permissions denied. Aborting."
end
goto MainMenu_Hax_Options
@Unhax_Old
if not find 1:/title/00040138/00000002/content/????????.app NATIVE_NCCH
echo "NATIVE_FIRM not found.\nIs this an O3DS?"
goto MainMenu_Hax_Options
end
imgmount $[NATIVE_NCCH]
verify G:/exefs/.firm
set NATIVE_FIRM $[GM9OUT]/NATIVE_FIRM.firm
cp -w G:/exefs/.firm $[NATIVE_FIRM]
imgumount
if allow -a S:
allow -a 1:
rm -o -s 1:/boot.firm
rm -o -s 1:/rw/luma
cp -n $[NATIVE_FIRM] S:/firm0.bin
cp -n $[NATIVE_FIRM] S:/firm1.bin
shaget S:/nand.bin@57FFE00:200 PRE_STAGE2_HASH
if not sha S:/nand.bin@B800000:200 $[PRE_STAGE2_HASH]
fget S:/nand.bin@57FFE00:1 PRE_STAGE2
fill S:/nand.bin@B7FFE00:89C00 $[PRE_STAGE2]
end
echo "CFW uninstalled successfully"
else
echo "Permissions denied. Aborting."
end
goto MainMenu_Hax_Options
################FBI to H&S Options################
@MainMenu_FBI_to_H&S_Options

View File

@ -60,7 +60,7 @@ mount | fs.img_mount |  
umount | fs.img_umount |  
find | fs.find |  
findnot | fs.find_not |  
fget | fs.write_file |  
fget | fs.read_file |  
fset | fs.write_file |  
sha | fs.hash_file OR fs.verify_with_sha_file | hash_file simply returns a hash, verify_with_sha_file compares it with a corresponding .sha file
shaget | fs.hash_file |  
@ -111,9 +111,9 @@ EMUID0 | sys.emu_id0 |  
EMUBASE | sys.emu_base |  
SERIAL | sys.serial |  
REGION | sys.region |  
SDSIZE | fs.stat_fs("0:/").total | int instead of string (use util.format_bytes to format it)
SDFREE | fs.stat_fs("0:/").free | int instead of string (use util.format_bytes to format it)
NANDSIZE | NANDSIZE | int instead of string (use util.format_bytes to format it)
SDSIZE | fs.stat_fs("0:/").total | int instead of string (use ui.format_bytes to format it)
SDFREE | fs.stat_fs("0:/").free | int instead of string (use ui.format_bytes to format it)
NANDSIZE | NANDSIZE | int instead of string (use ui.format_bytes to format it)
GM9OUT | GM9OUT |  
CURRDIR | CURRDIR | nil instead of “(null)" if it cant be found
ONTYPE | CONSOLE_TYPE | “O3DS" or “N3DS"
@ -251,7 +251,7 @@ Ask the user to input text.
#### ui.ask_selection
* `int ui.ask_selection(string prompt, array options)`
* `int ui.ask_selection(string prompt, table options)`
Ask the user to choose an option from a list. A maximum of 256 options are allowed.
@ -437,7 +437,7 @@ Create a directory. This creates intermediate directories as required, so `fs.mk
#### fs.stat
* `array fs.stat(string path)`
* `table fs.stat(string path)`
Get information about a file or directory. The result is a stat table with these keys:
@ -453,7 +453,7 @@ Get information about a file or directory. The result is a stat table with these
#### fs.list_dir
* `array fs.list_dir(string path)`
* `table fs.list_dir(string path)`
Get the contents of a directory. The result is a list of stat tables with these keys:
* `name` (string)
@ -474,7 +474,7 @@ Get the contents of a directory. The result is a list of stat tables with these
#### fs.stat_fs
* `array fs.stat_fs(string path)`
* `table fs.stat_fs(string path)`
Get information about a filesystem.
@ -490,7 +490,7 @@ Get information about a filesystem.
#### fs.dir_info
* `array fs.dir_info(string path)`
* `table fs.dir_info(string path)`
Get information about a directory.
@ -570,7 +570,7 @@ Pattern can use `?` for search values, for example `nand_??.bin` will check to s
#### fs.find_all
* `string fs.find_all(string dir, string pattern[, table opts {bool recursive}])`
* `table fs.find_all(string dir, string pattern[, table opts {bool recursive}])`
Search for all files that match a pattern.
* **Arguments**
@ -578,6 +578,7 @@ Search for all files that match a pattern.
* `pattern` - Filename pattern
* `opts` (optional) - Option flags
* `recursive` - Remove directories recursively
* **Returns:** table of found files
* **Throws**
* `"could not open directory"` - failed to open directory
@ -679,8 +680,6 @@ Calculate the hash of a file and compare it with a corresponding `.sha` file.
> [!IMPORTANT]
> This currently assumes SHA-256. In the future this may automatically use SHA-1 when appropriate, based on the `.sha` file size.
TODO: add errors for fs.read_file here
* **Argumens**
* `path` - File to hash
* **Returns:** `true` if successful, `false` if failed, `nil` if `.sha` file could not be read

View File

@ -61,7 +61,7 @@ fs.copy("M:/otp.mem", "9:/otp_copied_by_lua.mem", {overwrite=true})
-- SCRIPT - the executed script, such as "0:/gm9/luascripts/HelloScript.lua"
-- CURRDIR - the directory of the executed script, such as "0:/gm9/luascripts"
-- GM9OUT - the standard output path "0:/gm9/out"
-- HAX - the hax the system is currently running from, whihc can be "ntrboot", "sighax", or an empty string
-- HAX - the hax the system is currently running from, which can be "ntrboot", "sighax", or an empty string
-- NANDSIZE - total size of SysNAND in bytes
-- CONSOLE_TYPE - the string "O3DS" or "N3DS"
-- IS_DEVKIT - true if the console is a developer unit
@ -82,7 +82,7 @@ end
ui.echo("Your GodMode9 version is "..GM9VER..
"\nYour region is "..sys.region..
"\nYour serial number is "..sys.serial..
"\nYour std out oath is "..GM9OUT..
"\nYour std out path is "..GM9OUT..
"\nCurrent dir is "..CURRDIR..
"\nCurrent hax is "..HAX..
"\nYour system is a "..retail_or_devkit..