Homebrew Official [Release] GodMode9 - All Access File Browser for the 3DS

  • Thread starter d0k3
  • Start date
  • Views 307,088
  • Replies 1,143
  • Likes 105

Kazuma77

Well-Known Member
Member
Joined
May 11, 2008
Messages
1,035
Trophies
1
XP
900
Country
United States
Thanks for pointing that messup out :).

Anyways - you'd be better served with a way to run a script from inside a script, correct? Or, some way you could have a menu that jumps to a label. I can think about ways to support this.

You pretty much read my mind there. Launching a script from a script would probably work well for the most uses. Though my "Options" script already IS a "menu that jumps to labels" so, I've kind-of already jumped the gun on that angle of approach. The only issue is that entries have to use underscores instead of spaces, for obvious reasons. Full paths make for some strange looking labels, but they work as long as there are no spaces. Just one of many reasons being able to get the individual path, filename, and extension from filesel, find, and findnot would be useful. Like I said, though, I may find a use for multi-script yet, given some time to mess with it. More options is never a bad thing.

EDIT: Maybe I should just show you what I've come up with so far. For the moment, my multi-script header looks like this:

Code:
set PREVIEW_MODE off
@options_main
set ERRORMSG ""
set OPTIONMAIN ""
filesel -o -s "InScripted Options" 0:/gm9/zeroes/Options/* OPTIONMAIN
if chk $[OPTIONMAIN] ""
goto options_main
else
goto $[OPTIONMAIN]
end

So, to add a script, you first create a zero byte file for the menu entry (with no spaces), then add the full path to that file near the top of the script as a label (@0:/gm9/zeroes/Options/<filename>), and make sure there's a reboot, poweroff, or "goto options_main" at the end to ensure isolation from the other scripts you will be adding. Make sure the header's filename starts with a 0 (I name mine "0 - Options Header.gm9" for example) so it will be at the top, and that there's an empty line at the end of every script you're adding, and then just "copy *.gm9 autorun.gm9" and there you go, instant multi-menu. Note that an extra character will be added to the end of the file for some reason. I'd suggest deleting it before compiling the SSR.

It works, but there's definitely room for improvement. Hopefully this will give you some ideas for new features.
 
Last edited by Kazuma77,

Taffy

jdfiehgvrhfvhfjkvgrjhfejvgrjkbjvr
Member
Joined
Mar 3, 2017
Messages
621
Trophies
0
Age
21
Location
Student
XP
1,130
Country
United States
I'd love it if you could make something where you can change the default colors of the status bar by checking a file at the root of the SD or something.

also I use this a lot and I like it :D
 

MrMcTiller

GBATemp's Tiller
Member
Joined
Mar 7, 2017
Messages
1,185
Trophies
0
Age
20
Location
Iowa
XP
1,555
Country
United States
@d0k3 , Is there a good tutorial on making .gm9 scripts? I would like to find out if it is possible to make a merger for USUM ips patches. There is already a .py script for it, but I can't use python.


EDIT: Here is where the ips patches are located.
 
Last edited by MrMcTiller,

windows_server_2003

Well-Known Member
Newcomer
Joined
Jul 13, 2017
Messages
84
Trophies
0
Age
44
XP
379
Country
Japan
@d0k3
I fixed most of the bugs.I simplified the goto jumping code and it takes less than 0.3 sec to jump 20000 lines(255KB).

By the way, I think the write permissions in the explorer and in scripts should be separated.
For example, unlocking the blue permissions in explorer and editting the memory area manually are not so dangerous. (may lead to crash, but probably not brick it)
But allowing scripts to edit there automatically is very dangerous.
I understand it is bother to unlock the yellow ones each time.

: So at least, the red one and the blue one should be asked to the users each time the scripts using them executed, like UAC.
 

Kazuma77

Well-Known Member
Member
Joined
May 11, 2008
Messages
1,035
Trophies
1
XP
900
Country
United States
@d0k3
I fixed most of the bugs.I simplified the goto jumping code and it takes less than 0.3 sec to jump 20000 lines(255KB).

By the way, I think the write permissions in the explorer and in scripts should be separated.
For example, unlocking the blue permissions in explorer and editting the memory area manually are not so dangerous. (may lead to crash, but probably not brick it)
But allowing scripts to edit there automatically is very dangerous.
I understand it is bother to unlock the yellow ones each time.

: So at least, the red one and the blue one should be asked to the users each time the scripts using them executed, like UAC.

While that wasn't directed at me, thanks for the update all the same. It will be fun testing the improvements you've made. Thanks again for all your efforts to bring branching commands to GM9. They're a real game changer.

As for your security changes suggestion, I can agree with you on the blue, but not on the red. That would turn an automated exploit installer like "One & Done" into nag city, with it copying up to 3 files to the S: drive. And I wouldn't exactly use UAC as a positive example. Need I remind you what most of us techs do within 5 minutes of a Windows install completing (myself included)? That's right, we disable that obnoxious thing, so that we can double click the Ninite installer and check back in an hour or two.

Or did you mean that after the script ends, the user should not be given the option to keep the unlock? In that case, I'm fine with it. Though for better or worse, such a thing would not affect my SSRs. Most of them loop back to the main menu until you choose to reboot or power off. For "Options" or "NAND Manager" to ask again on subsequent selections, something like a "relock" command would be needed.
 
Last edited by Kazuma77,

windows_server_2003

Well-Known Member
Newcomer
Joined
Jul 13, 2017
Messages
84
Trophies
0
Age
44
XP
379
Country
Japan
While that wasn't directed at me, thanks for the update all the same. It will be fun testing the improvements you've made. Thanks again for all your efforts to bring branching commands to GM9. They're a real game changer.

As for your security changes suggestion, I can agree with you on the blue, but not on the red. That would turn an automated exploit installer like "One & Done" into nag city, with it copying up to 3 files to the S: drive. And I wouldn't exactly use UAC as a positive example. Need I remind you what most of us techs do within 5 minutes of a Windows install completing (myself included)? That's right, we disable that obnoxious thing, so that we can double click the Ninite installer and check back in an hour or two.

Yes, I meant the second one. Once you reject to relock a permission, never asked to relock anymore so if users unlocked the blue one in the explorer and pressed B at the relock confirmation and if they run a script like RedUnlocker, ...Dangerous. Especially the blue one, Users don't feel enough danger even the key combo became longer, but unlocking it in scripts is more dangerous than unlocking the red one.
: The blue one in explorer is not so dangerous so users unlock it without enough thinking but the permission will be also applied to scripts and that's more dangerous.
 

d0k3

3DS Homebrew Legend
OP
Member
Joined
Dec 3, 2004
Messages
2,786
Trophies
1
XP
3,896
Country
Germany
Okay, tl;dr for everyone else: I messed up Github yesterday and accidentially closed @windows_server_2003's pr. Not really a problem, cause his commits are still in his and my repo. Continuing the discussion from Github:
windows_server_2003 said:
About global vars

u32 ifcnt
Count of if nesting. increases at 'if's and decreases at 'end's unless you're jumping to a label from 'goto'

u32 ifcnt_skipped
increases at skipped 'if's and decreases at skipped 'end's and reset to 0 on finishing skipping/starting skipping(for safety, double-reset it)
example :
Code:
if chk test test1 # fail
 ## 0
 if chk test test
  ## 1
 end
 ##0
end # stop skipping
It won't be used if we aren't skipping. On 'end' and else', if skipping and it is 0, it will stop skipping.

u8 skip
0 -> not skipping
1 -> 'if' with failed condition command. From 'if' to 'else' or 'end'
2 -> 'if' with succeed one. From 'else' to 'end'
3 -> searching a label. Set in run_cmd() by 'goto' and used to decide to run search_label() in ExecuteGM9Script(). Reset if found the label.

bool syntax_error
One to know that a syntax error occurred in run_cmd() and should disable -o and -s in ExecuteGM9Script().
I know this way is not good. so If you have any better ideas to disable -o & -s teach me!

bool running_cond
True if running a command as a condition of 'if'.
This is to prevent infinite recursive 'if' condition running. infinite recursive("if if if...") makes no sense and may lead to a bug or crash cause memory overflow.

bool if_cond_res
The result of a command as a condition of 'if'.
set in run_line()(at calling itself) and used in run_cmd()

char findlabel[513]
The name of finding label.
findlabel[0] == '\000' means not jumping now.



Any opinion to this ?

Alright, I'll dive into this now. On first glance...

512 is too much for the label max length. No one will ever use that much

As for running_cond - you really don't need to be protective of script authors. If someone messes up, let them. A script author using:
if if if ask "Continue?"
... is basically asking for trouble.

Other than that I *think* (not sure) we can go with a few globals less. More later.
 

windows_server_2003

Well-Known Member
Newcomer
Joined
Jul 13, 2017
Messages
84
Trophies
0
Age
44
XP
379
Country
Japan
Okay, tl;dr for everyone else: I messed up Github yesterday and accidentially closed @windows_server_2003's pr. Not really a problem, cause his commits are still in his and my repo. Continuing the discussion from Github:


Alright, I'll dive into this now. On first glance...

512 is too much for the label max length. No one will ever use that much

As for running_cond - you really don't need to be protective of script authors. If someone messes up, let them. A script author using:
if if if ask "Continue?"
... is basically asking for trouble.

Other than that I *think* (not sure) we can go with a few globals less. More later.

Okay. The max label length should be 64 ? or 256 for FAT path.
 

d0k3

3DS Homebrew Legend
OP
Member
Joined
Dec 3, 2004
Messages
2,786
Trophies
1
XP
3,896
Country
Germany
Okay. The max label length should be 64 ? or 256 for FAT path.
Unsure yet, but no one will ever use 512 :).

I already did some minor edits, and I noticed - I should have handled syntax errors differently from the start - that's a global var we definitely need.

EDIT: I suggest we go this way now - I introduce changes in small commits, and we discuss them afterwards. I'll have to stop for today, but I will continue tomorrow.
 
Last edited by d0k3,

zoogie

playing around in the end of life
Developer
Joined
Nov 30, 2014
Messages
8,560
Trophies
2
XP
15,000
Country
Micronesia, Federated States of
Unsure yet, but no one will ever use 512 :).

I already did some minor edits, and I noticed - I should have handled syntax errors differently from the start - that's a global var we definitely need.

EDIT: I suggest we go this way now - I introduce changes in small commits, and we discuss them afterwards. I'll have to stop for today, but I will continue tomorrow.
I know that most gm9 discussion has centered around script branching lately but I couldn't help but notice this. :D thanx btw
I don't know if you ever planned on TAD rebuild support (with content mods), but if signing the footer is/was an issue, this little app by yellows8 fits the bill -- if that helps any.
 
Last edited by zoogie,

Kazuma77

Well-Known Member
Member
Joined
May 11, 2008
Messages
1,035
Trophies
1
XP
900
Country
United States
Okay, tl;dr for everyone else: I messed up Github yesterday and accidentially closed @windows_server_2003's pr. Not really a problem, cause his commits are still in his and my repo. Continuing the discussion from Github:


Alright, I'll dive into this now. On first glance...

512 is too much for the label max length. No one will ever use that much

As for running_cond - you really don't need to be protective of script authors. If someone messes up, let them. A script author using:
if if if ask "Continue?"
... is basically asking for trouble.

Other than that I *think* (not sure) we can go with a few globals less. More later.

Well as long as the code's not gone (just phrasing it that way has me thinking of a PotC spoof -- "but why is the code gone?" ;) ).

Yeah, I think most of us know better than to put 3 ifs on the same line (though forgetting to put a $ and brackets around a variable, done that). So, I can agree as long as the following will still work:

Code:
@start
set NUMBER ""
if filesel "Pick a number." V:/zeroes/test/* NUMBER
if chk -u $[NUMBER] "V:/zeroes/test/1"
if chk -u $[NUMBER] "V:/zeroes/test/2"
echo "You picked 3 or 4"
else
echo "You picked 2"
end
else
echo "You picked 1"
end
else
echo "I said pick a number, jackass!"
goto start
end

Okay. The max label length should be 64 ? or 256 for FAT path.

64 might be cutting it a little close, especially since we can't discard the path from a "filesel" choice (my "Options" example from a few posts back is using full paths as labels). I can see myself maybe hitting 64 at some point, but not 96.

Unsure yet, but no one will ever use 512 :).

I already did some minor edits, and I noticed - I should have handled syntax errors differently from the start - that's a global var we definitely need.

EDIT: I suggest we go this way now - I introduce changes in small commits, and we discuss them afterwards. I'll have to stop for today, but I will continue tomorrow.

Works for me. I have to stop for a while too. I'm just too angry to sit here testing code after what just happened. I don't want to derail the thread by getting into the subject, but, let's just say I need to kill virtual things to let off steam. And if anyone knows of any IT openings in New Zealand, please forward them to me, because I'd like to leave the US before the 2018 campaign season starts (especially having seen what's coming).
 
Last edited by Kazuma77,

d0k3

3DS Homebrew Legend
OP
Member
Joined
Dec 3, 2004
Messages
2,786
Trophies
1
XP
3,896
Country
Germany
64 might be cutting it a little close, especially since we can't discard the path from a "filesel" choice (my "Options" example from a few posts back is using full paths as labels). I can see myself maybe hitting 64 at some point, but not 96.

I do have something planned about this. I'll let you in on it, I I guess:
  • labelsel [string] [lpattern]: Searches for all labels matching lpattern, provides a selection menu to jump to them. Will be limited to a certain number of labels. '_' will be replaced with spaces. Example: 'labelsel "Select something" somelabel_' will find somelabel_Option_1, somelabel_Option_2, etc... and display as "Option 1", Option 2", ....
  • fname [var] [pathstring]: Will extract fname from drv:/path1/path2/fname.ext
  • fext [var] [pathstring]: Will extract ext from drv:/path1/path2/fname.ext
  • fdir [var] [pathstring]: Will extract drv:/path1/path2 from drv:/path1/path2/fname.ext
  • for [pattern] in [path]...[next]: Allows to traverse through a directory, matching filenames. Nesting will not be allowed here, the current path will go to a fixed variable. Still considering if I want to allow recursion, for now I guess rather not.
Unsure if we'll need fname, fext, fdir anymore then. Ideas?
 
Last edited by d0k3,

windows_server_2003

Well-Known Member
Newcomer
Joined
Jul 13, 2017
Messages
84
Trophies
0
Age
44
XP
379
Country
Japan
I do have something planned about this. I'll let you in on it, I I guess:
  • labelsel [string] [lpattern]: Searches for all labels matching lpattern, provides a selection menu to jump to them. Will be limited to a certain number of labels. '_' will be replaced with spaces. Example: 'labelsel "Select something" somelabel_' will find somelabel_Option_1, somelabel_Option_2, etc... and display as "Option 1", Option 2", ....
  • fname [var] [pathstring]: Will extract fname from drv:/path1/path2/fname.ext
  • fext [var] [pathstring]: Will extract ext from drv:/path1/path2/fname.ext
  • fdir [var] [pathstring]: Will extract drv:/path1/path2 from drv:/path1/path2/fname.ext
  • for [pattern] in [path]...[next]: Allows to traverse through a directory, matching filenames. Nesting will not be allowed here, the current path will go to a fixed variable. Still considering if I want to allow recursion, for now I guess rather not.
Unsure if we'll need fname, fext, fdir anymore then. Ideas?
About 'for' :
Are you thinking about the security problem ? Already scripts can be dangerous.
Code:
allow -a 1:
rm 1:/title
rm 1:/ro
rm 1:/rw
rm 1:/data
...

About fname, fdir, fext
Instead, why don't we make a command to cut string at a given char ? like this :

ssplit [-f | --first] [-b | --before] VAR str char

Store the string after(before if -b) the last(first if -f) given char in given string.
If given char is not found in given string, store empty string.
The three command is replaceable with this.
Code:
fname VAR pathstr
ssplit VAR pathstr "/"

fext VAR pathstr
ssplit VAR pathstr "."

fdir VAR pathstr
ssplit -b VAR pathstr "/"
About fext, doesn't work if pathstr is like this
0:/path.1/path2/fname
It will store "1/path2/fname" as ext, but scripts can catch it.
Code:
ssplit EXT "0:/path.1/path2/fname" "." # EXT will be "1/path2/fname"(doesn't work)
ssplit TMP $[EXT] "/"
if chk -u $[TMP] ""
 set EXT "" # ext not found
end

Edit :
Thank you for decreasing number of global vars and cleaning up.

Edit1 :
Question
You said CURRDIR will be edited in "for". Will CURRDIR be a file name ?
 
Last edited by windows_server_2003,

Kazuma77

Well-Known Member
Member
Joined
May 11, 2008
Messages
1,035
Trophies
1
XP
900
Country
United States
I do have something planned about this. I'll let you in on it, I I guess:
  • labelsel [string] [lpattern]: Searches for all labels matching lpattern, provides a selection menu to jump to them. Will be limited to a certain number of labels. '_' will be replaced with spaces. Example: 'labelsel "Select something" somelabel_' will find somelabel_Option_1, somelabel_Option_2, etc... and display as "Option 1", Option 2", ....
  • fname [var] [pathstring]: Will extract fname from drv:/path1/path2/fname.ext
  • fext [var] [pathstring]: Will extract ext from drv:/path1/path2/fname.ext
  • fdir [var] [pathstring]: Will extract drv:/path1/path2 from drv:/path1/path2/fname.ext
  • for [pattern] in [path]...[next]: Allows to traverse through a directory, matching filenames. Nesting will not be allowed here, the current path will go to a fixed variable. Still considering if I want to allow recursion, for now I guess rather not.
Unsure if we'll need fname, fext, fdir anymore then. Ideas?

Good ideas. I can already see two situations where "labelsel" won't replace "filesel" though -- the option to switch chainloaders in my "Settings" SSR, and the main menu in my "Options" SSR. Both of them change depending on what you pick. Actually, I might be able to simulate how that part of "Settings" works by having 5 copies of each theoretical label to be used. It might be more trouble than it's worth though (and it's always going to need to set a token file on the SD card to remember which chainloader is active). But "Options" is pretty much stuck using "filesel" I think. I've got two options that change to something else when selected, and one that's meant to be used once and delete itself. Unless "lpattern" can contain multiple entries (semicolon delimited would be good), "labelsel" just will not be able to handle a changing list of options like that.

I think "fext" is probably going to be something we already know 99.9% of the time. But "fname" would have many uses. Associated files not needing the ".ext1.ext2" structure to be used. Having a selection associated with the contents of a folder, without that folder having to be in the same folder the file is located in (and with said folder also not having to follow the ".ext1.ext2" naming convention). If I use it for "Options" (what I think will probably work best at this point), it will also be needing a formatting flag to convert spaces to underscores. I have no immediate use for "fdir" but it could make for a nice shortcut if you need a different file from the same folder as a file you just used a "find" to locate.

I'm not sure this will be universally better. Many of my merges are not simple ones where every individual script that's functionality was added still has it's own separate section. If two or more options do many of the same things, I'll process the others first or "chk -u" for the other option(s), so I've got a virtual "or" gate for my similar functions. So then I can just check for an individual choice where I actually need one of them to do something extra. No duplicated commands. I can still make "labelsel" work with these scripts, but will trading "else, if" chains for "label, set, goto" blocks be an improvement? One way to find out I guess. Try it both ways.

As for "for" without recurse... "you're breakin' my balls" as Eric Cartman would say. As windows_server_2003 has pointed out, "rm" could already do a decent amount of damage if you don't get your scripts from a trustworthy source. With recurse, we could clean out those obnoxious indexing files that OS-bundled file managers create (granted, this could be done while the card is still in the device that's making the mess, via a batch file or script that OS can run).

About 'for' :
Are you thinking about the security problem ? Already scripts can be dangerous.
Code:
allow -a 1:
rm 1:/title
rm 1:/ro
rm 1:/rw
rm 1:/data
...

About fname, fdir, fext
Instead, why don't we make a command to cut string at a given char ? like this :

ssplit [-f | --first] [-b | --before] VAR str char

Store the string after(before if -b) the last(first if -f) given char in given string.
If given char is not found in given string, store empty string.
The three command is replaceable with this.
Code:
fname VAR pathstr
ssplit VAR pathstr "/"

fext VAR pathstr
ssplit VAR pathstr "."

fdir VAR pathstr
ssplit -b VAR pathstr "/"
About fext, doesn't work if pathstr is like this
0:/path.1/path2/fname
It will store "1/path2/fname" as ext, but scripts can catch it.
Code:
ssplit EXT "0:/path.1/path2/fname" "." # EXT will be "1/path2/fname"(doesn't work)
ssplit TMP $[EXT] "/"
if chk -u $[TMP] ""
 set EXT "" # ext not found
end

Edit :
Thank you for decreasing number of global vars and cleaning up.

Edit1 :
Question
You said CURRDIR will be edited in "for". Will CURRDIR be a file name ?

Also not a bad idea. We could always just split for "/" then split for "." to eliminate the issue you brought up with it. It needs an option to convert spaces to underscores though, so we can choose files with spaces and still have a matching label that works (doing a goto using the filename eliminates the need to "chk" for every possible file that could have been selected, after all, but labels can't have spaces of course).
 

SirNapkin1334

Renound Aritst
Member
Joined
Aug 20, 2017
Messages
1,665
Trophies
1
XP
975
Country
United States
@d0k3 is it possible to undo the bootloader installation? I can't update my EmuNand and I think it's because I installed it to firm0 & firm1 (or, rather the fact that I installed it at all). If you can tell me a way to undo it or I figure it out, I'll report back if I'm able to update.
 

windows_server_2003

Well-Known Member
Newcomer
Joined
Jul 13, 2017
Messages
84
Trophies
0
Age
44
XP
379
Country
Japan
@d0k3 is it possible to undo the bootloader installation? I can't update my EmuNand and I think it's because I installed it to firm0 & firm1 (or, rather the fact that I installed it at all). If you can tell me a way to undo it or I figure it out, I'll report back if I'm able to update.
You can install b9s via GodMode9 or SafeB9SInstaller to undo it.
Put boot9strap.firm and .sha to /boot9strap.
Then launch SafeB9SInstaller.
By the way, I think the bootloader is not the cause of the issue.
 
Last edited by windows_server_2003,
  • Like
Reactions: SirNapkin1334

Kazuma77

Well-Known Member
Member
Joined
May 11, 2008
Messages
1,035
Trophies
1
XP
900
Country
United States
@d0k3 is it possible to undo the bootloader installation? I can't update my EmuNand and I think it's because I installed it to firm0 & firm1 (or, rather the fact that I installed it at all). If you can tell me a way to undo it or I figure it out, I'll report back if I'm able to update.

If you're using my AIO, the included "Sighax Updater" allows you to switch between B9S and GM9 at the drop of a hat. That's actually why I created it. Though I quickly compiled it into an SSR when I realized Safe B9S Installer couldn't install GM9, and started referring to it as a replacement for it. I will also be genuinely surprised if it's GM9 that's causing the issue, though.
 
  • Like
Reactions: SirNapkin1334

d0k3

3DS Homebrew Legend
OP
Member
Joined
Dec 3, 2004
Messages
2,786
Trophies
1
XP
3,896
Country
Germany
@SirNapkin1334 - nope, that's not caused by the bootloader. Otherwise you couldn't update your SysNAND either. You won't have more luck with b9s.

@Kazuma77 - labelsel will be first. I'll be thinking about allowing multiple wildcard patterns, but apparently that doesn't solve the problem. Can you think about other ways to do it? As for for recursion - that's pretty hard to do, near impossible without wasting a lot of memory. I'll think about it.

@windows_server_2003 - just to make this clear, your code is good. I just want to reduce the number of global vars first to make stuff easier to follow and less error prone. You can help me by following my commits and pointing out stuff you note!
 
  • Like
Reactions: SirNapkin1334

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    K3Nv2 @ K3Nv2: https://youtu.be/MddR6PTmGKg?si=mU2EO5hoE7XXSbSr