├── .gitignore ├── README.md ├── scripts ├── Dump_saves.te ├── SystemRestoreV3.te └── createDirs.te ├── v1 ├── FVI.te ├── ParentalLockRemover.te ├── README.md ├── fwdump.te ├── savedumper.te ├── systemRestore.te └── systemwipe.te └── v2 ├── README.md └── scripts ├── fwDump.te ├── systemRestore.te └── systemwipe.te /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | hidden/* 3 | hidden -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Scripts in this repo 2 | - [SystemRestoreV3](https://suchmememanyskill.github.io/TegraScript/scripts/SystemRestoreV3.te) 3 | - [Dump saves](https://suchmememanyskill.github.io/TegraScript/scripts/Dump_saves.te) 4 | 5 | # Syntax 6 | 7 | ## Variable assignment 8 | Variables in TegraScript do not need explicit type definitions: 9 | ``` 10 | variable = function(arg1, arg2) 11 | ``` 12 | 13 | In TegraScript, user provided functions have no arguments and are written like this: 14 | ``` 15 | helloWorld = { 16 | print("hello world!") 17 | } 18 | 19 | helloWorld() 20 | ``` 21 | 22 | Arrays in TegraScript can be of 4 types: StringArray, ByteArray, IntegerArray and EmptyArray 23 | ``` 24 | strings = ["a", "b", "c"] 25 | numbers = [1,2,3,4,5] 26 | bytes = ["BYTE[]",1,2,3,4,5] 27 | empty = [] # Can be converted to other typed arrays by adding a variable into it 28 | ``` 29 | 30 | ## Variable usage 31 | In TegraScript, all variables are global. This means that any variable declared anywhere can be used anywhere 32 | 33 | You can use variables in place of static numbers or strings 34 | ``` 35 | three = 3 36 | 1 + 2 + three 37 | ``` 38 | 39 | Most variable types have function members. See below for all types of variables 40 | ``` 41 | three = 3 42 | three.print() 43 | ``` 44 | 45 | Arrays can be accessed as follows: 46 | (the [arg] syntax is internally converted to variable.get(arg), which is also valid syntax if you wish to use it) 47 | ``` 48 | numbers = [1,2,3,4,5] 49 | print(numbers[1]) # prints 2 50 | ``` 51 | 52 | When calling a user provided function, everything between the `()` gets evaulated, and the result gets discarded. This means that you can use the `()` to define variables. This used to a TegraScriptv2 bug, but is left in for backwards compatibility 53 | ``` 54 | a = { 55 | b = b + 1 56 | } 57 | 58 | a(b = 5) 59 | ``` 60 | 61 | Although normal assignment will work too 62 | ``` 63 | a = { 64 | b = b + 1 65 | } 66 | b = 5 67 | a() 68 | ``` 69 | 70 | You can also invert integers as follows: 71 | ``` 72 | !1 # becomes 0 73 | !0 # becomes 1 74 | 75 | 1.not() # becomes 0 76 | ``` 77 | 78 | ## Operator precedence 79 | TegraScript has no operator precedence. It runs operators from left to right, always. You can put code inbetween `()` to calculate it before it is used. 80 | ``` 81 | println(2 + 2 * 2) # prints 8 82 | println(2 + (2 * 2)) # prints 6 83 | ``` 84 | 85 | ## Flow control 86 | TegraScript has the following functions for flow control: 87 | - `if(int)` Checks if the integer is non-0, then executes the user provided function behind it. Example: `if (1) { print("Hello world!") }`. 88 | - if returns an elseable class. You can call `.else()` on it to get an else. Example: `if (0) { } .else() { print("hi") }` 89 | - `while(int)` Checks if the integer is non-0, then keeps executing the user provided function behind it until the integer is 0. Example: `i = 0 while (i < 10) { print(i) i = i + 1 }` 90 | - `break()` Raises an exception that is caught by while and foreach loops. Example: `while (1) { break() } # This will end` 91 | - `exit()` Raises an exception to exit the script 92 | 93 | No this is not a sensible language, thanks for asking 94 | 95 | # Comments 96 | Comments in TegraScript are started with `#`, and last until the end of the line. 97 | 98 | There are some special comments to aid in prerequisites. 99 | - `#REQUIRE VER x.x.x` Requires a minimum TegraScript version to run the script. x.x.x should be the minimum version, so like `#REQUIRE VER 4.0.0` 100 | - `#REQUIRE MINERVA` Requires extended memory to run the script. This should be used if you work with large files, saves or if your script is generally very big (20kb+) 101 | - `#REQUIRE KEYS` Requires keys to be dumped to run the script 102 | - `#REQUIRE SD` Requires the sd to be mounted to run the script 103 | 104 | # Classes 105 | 106 | ## Integer Class 107 | Integers in TegraScript are always 8 bytes in length 108 | 109 | Static defenition example: 110 | ``` 111 | 10 # 10 112 | 0x10 # 16 113 | ``` 114 | 115 | | Operator | RVal | Result | Description | 116 | |----------|---------|---------|-----------------------| 117 | | + | Integer | Integer | Addition | 118 | | - | Integer | Integer | Subtraction | 119 | | * | Integer | Integer | Multiplication | 120 | | / | Integer | Integer | Division | 121 | | % | Integer | Integer | Modulo | 122 | | < | Integer | Integer | Smaller than | 123 | | > | Integer | Integer | Bigger than | 124 | | <= | Integer | Integer | Smaller or equal than | 125 | | >= | Integer | Integer | Bigger or equal than | 126 | | == | Integer | Integer | Equal to | 127 | | != | Integer | Integer | Not equal to | 128 | | && | Integer | Integer | Logical AND | 129 | | \|\| | Integer | Integer | Logical OR | 130 | | & | Integer | Integer | And | 131 | | \| | Integer | Integer | Or | 132 | | << | Integer | Integer | Bitshift left | 133 | 134 | | Member | Arguments | Argument descriptions | Result | Description | 135 | |---------|-----------|-----------------------|---------|----------------------------------| 136 | | print() | - | - | None | Prints the integer | 137 | | not() | - | - | Integer | Inverts the integer | 138 | | str() | - | - | String | Converts the integer to a string | 139 | 140 | 141 | ## String Class 142 | Strings in TegraScript are immutable 143 | 144 | Static defenition example: 145 | ``` 146 | "Hello" # Hello as text 147 | "\r\n" # Return to left side of the screen, newline 148 | ``` 149 | 150 | | Operator | RVal | Result | Description | 151 | |----------|---------|--------------|---------------------------------------| 152 | | + | String | String | Adds 2 strings together | 153 | | - | Integer | String | Reduces string size by integer amount | 154 | | == | String | Integer | Checks string equality | 155 | | != | String | Integer | Checks string inequality | 156 | | / | String | String Array | Splits left string every right string | 157 | 158 | | Member | Arguments | Argument descriptions | Result | Description | 159 | |---------|-----------|-----------------------|--------------|--------------------------------------| 160 | | print() | - | - | None | Prints the string | 161 | | len() | - | - | Integer | Gets the length of the string | 162 | | bytes() | - | - | Byte Array | Returns the string as a byte array | 163 | | get() | Integer | 0: Index of character | String | Returns the character at given index | 164 | | split() | String | 0: String to split on | String Array | Splits a string | 165 | 166 | 167 | ## Array class 168 | Array classes can be of 4 types: Integer array, string array, byte array and empty array 169 | 170 | An empty array will be converted into an integer or string array if an integer or string gets added. 171 | 172 | You can add integers to byte arrays, and internally they'll be converted to bytes before being added 173 | 174 | ArrayReference: arrayReference classes contain a .project() function. This returns the array. You can project anytime, but do note the result is not memory safe and not garuanteed to be valid after changing the array. It's best to re-project before every use. 175 | 176 | You can get an index from the array by using `array[index]`, Example: `[1,2,3][0]` 177 | 178 | You can also set an array index by using `array[index] = variable`. Example: `a = [1,2,3].copy() a[0] = 69` 179 | 180 | Arrays that are static `[1,2,3]` are read-only and will need to be .copy()'d before modification, because they are evaluated before runtime. Arrays that are not static (`[a,b,c]`) will be evaluated every time the script runs past it, and thus do not need to be copied to be modified 181 | 182 | | Operator | RVal | Result | Description | 183 | |----------|-------------------------|---------|-----------------------------------| 184 | | + | (Dependant on type) | None | Adds type to array | 185 | | - | Integer | None | Removes integer length from array | 186 | | == | ByteArray, IntegerArray | Integer | Compares 2 number arrays | 187 | 188 | | Member | Arguments | Argument descriptions | Result | Description | 189 | |--------------|----------------------------|------------------------------|----------------------------|------------------------------------------------------------------------------------------------------------------------| 190 | | get() | Integer | 0: index of array | String or Integer | Gets a variable at index. You can also use array[index] | 191 | | len() | - | - | Integer | Get the length of an array | 192 | | slice() | Integer, Integer | 0: skip, 1: take | ArrayReference (see above) | Gets a read-only slice of the array | 193 | | foreach() | String | 0: Name of variable | None | Foreaches trough the array using the `{}` behind the foreach. Sets the variable in the string to the iterated variable | 194 | | copy() | - | - | Array | Copy's the array. Required to edit read-only arrays | 195 | | set() | Integer, String or Integer | 0: index, 1: variable to set | None | Sets the variable at array index. You can also use array[index] = var | 196 | | add() | (Dependant on type) | 0: to add | None | Adds type to array | 197 | | contains() | (Dependant on type) | 0: to check if contains | Integer | Checks if array contains item. 0 if false, 1 if true | 198 | | bytestostr() | - | - | String | Converts a byte array to string | 199 | | find() | (Same as type) | 0: needle | Integer | Searches needle in haystack. Returns offset, or -1 if not found | 200 | 201 | ## Dictionary class 202 | You can initiate a dictionary by using `dict()`. This will create an empty dictionary. You can assign to a dictionary by doing the following: `a = dict() a.b = 1` After this, you can access the variables you put in by doing the following: `print(a.b)` This class is used as returns in some functions in the standard library 203 | 204 | ## Save class 205 | You can initiate a save class by using `readsave("path/to/save")`. This uses a lot of memory. 206 | 207 | | Member | Arguments | Argument descriptions | Result | Description | 208 | |----------|-------------------|--------------------------------|-----------|---------------------------------------------------------------------------| 209 | | read() | String | 0: Path | ByteArray | Reads a file inside the save | 210 | | write() | String, ByteArray | 0: Path, 1: ByteArray to write | Integer | Writes to a file inside the save. Returns 0 on success, non zero on error | 211 | | commit() | - | - | None | Flushes the writes made to save and signs the save | 212 | 213 | 214 | # Standard library 215 | 216 | | Function | Arguments | Argument descriptions | Result | Description | Example | 217 | |---|---|---|---|---|---| 218 | | if | Integer | 0: Execute if not 0 | Elseable (.else(){}) | Executes function behind if, if the integer is non 0 | if (1) { print("Hello world!") } | 219 | | while | Integer | 0: Execute if not 0 | None | Executes function behind while as long as integer is non 0 | i = 0 while (i < 10) { println(i) i = i + 1 } | 220 | | exit | - | - | None | Exits the script | exit() | 221 | | break | - | - | None | Exits a loop, or the script if not in a loop | while (1) { break() } println("The loop broke") | 222 | | readsave | String | 0: Path to save | Save | Opens a save. Causes a fatal error if the save failed to open | mountsys("SYSTEM") readsave("bis:/save/8000000000000120").commit() | 223 | | dict | - | - | Dictionary | Creates an empty dictionary | a = dict() | 224 | | print | Any arg count of (Integer, String) | any: To be printed | None | Calls .print() on every argument. Puts spaces inbetween each argument | print("Hello world!") | 225 | | println | Any arg count of (Integer, String) | any: To be printed | None | Calls print, then prints a newline | println("Hello world") | 226 | | printpos | Integer, Integer | 0: X position, range 0-78, 1: Y position, range 0-42 | None | Sets the print position | printpos(20,20) | 227 | | setpixel | Integer, Integer, Integer | 0: X position, range 0-1279, 1: Y position, range 0-719, 2: Hex color (0xRRGGBB) | None | Sets a pixel on the screen to the desired color | setpixel(0,0,0xFFFFFF) | 228 | | setpixels | Integer, Integer, Integer, Integer, Integer | 0: X0 position, 1: Y0 position, 2: X1 position, 3: Y1 position, 4: Hex color | None | Sets a bunch of pixels on the screen to the desired color in the user provided ranges | setpixels(0,0,1279,719,0xFF0000) | 229 | | emu | - | - | Integer | Returns if an emummc is enabled. returns 1 if enabled | print(emu()) | 230 | | cwd | - | - | String | Returns the current working directory. Returns 'sd:/' if ran from builtin script | print(cwd()) | 231 | | clear | - | - | None | Clears the screen and resets the cursor to the top left | clear() | 232 | | timer | - | - | Integer | Get the current system time in ms | a = timer() println("Very intensive operation") print("Time taken:", timer() - a) | 233 | | pause | - | - | Dictionary (a, b, x, y, down, up, right, left, power, volplus, volminus, raw) | Waits for user input, then returns a dictionary of what was pressed | p = pause() if (p.a) { println("A was pressed!") } | 234 | | pause | Integer | 0: Bitmask | Dictionary (a, b, x, y, down, up, right, left, power, volplus, volminus, raw) | Same as argless pause() but you can provide your own bitmask. See source/hid/hid.h | pause(0xC) # Waits until either A or B is pressed | 235 | | color | Integer | 0: Hex color (0xRRGGBB) | None | Sets the text color | color(0x00FF00) print("Green text!") | 236 | | menu | StringArray, Interger | 0: Menu options, 1: Starting position | Integer | Makes a menu of the strings in the array. Returns the index of what was pressed. Pressing b always returns 0 | idx = menu(["1", "2", "3"], 0) println(idx, "was pressed!") | 237 | | menu | StringArray, Integer, IntegerArray | 0: Menu options, 1: Starting position, 2: Color/Options array | Integer | Makes a menu. The lower 3 bytes of the 3rd argument is RGB (0xRRGGBB). The upper byte is a bitfield with: 0x1: skip, 0x2: hide, 0x4: fileIcon, 0x8: folderIcon | menu(["1", "2"], 0, [0xFF0000, 0x00FF00]) | 238 | | power | Integer | 0: https://github.com/suchmememanyskill/TegraExplorer/blob/master/bdk/utils/util.h#L26 | None | Sets the power state. This is an advanced function. | power(3) # Powers off and resets regulators | 239 | | mountsys | String | 0: Mount target | Integer | Mounts a partition on sys/internal storage. Returns 0 on success, 1 on failure | mountsys("SYSTEM") | 240 | | mountemu | String | 0: Mount target | Integer | Same as mountsys, but on emummc instead. | mountemu("SYSTEM") | 241 | | ncatype | String | 0: Path to nca | Integer | Returns the nca type. Returns -1 on error. See | - | 242 | | emmcread | String, String | 0: File destination, 1: Partition on sys | Integer | Dumps the provided partition to a file. Returns 0 on success, non zero on failure | emmcread("sd:/PRODINFO", "PRODINFO") | 243 | | emmcwrite | String, String | 0: File source, 1: Partition on sys | Integer | Restores the file to the provided partition. Returns 0 on success, non zero on failure | emmcwrite("sd:/PRODINFO", "PRODINFO") | 244 | | emummcread | String, String | 0: File destination, 1: Partition on emu | Integer | Same as emmcread() | emummcread("sd:/PRODINFO", "PRODINFO") | 245 | | emummcwrite | String, String | 0: File source, 1: Partition on emu | Integer | Same as emmcwrite() | emummcwrite("sd:/PRODINFO", "PRODINFO") | 246 | | readdir | String | 0: Path to dir | Dictionary (result, files, folders, fileSizes) | Reads a directory. Puts all files in files (StringArray), folders in folders (StringArray), and file sizes in fileSizes (IntegerArray). .result is an Integer, and 0 on success | a = readdir("sd:/") if (a.result) { exit() } a.files.foreach("x") { println(x) } | 247 | | deldir | String | 0: Path to dir | Integer | Deletes a directory. Prints whatever it's deleting. Returns 0 on success | deldir("sd:/sxos") | 248 | | mkdir | String | 0: Path to new dir | Integer | Creates a new directory. Returns 0 on success | mkdir("sd:/tegraexplorer") | 249 | | copydir | String, String | 0: Path to dir, 1: Path to dir where the dir will be copied into | Integer | Copies a folder into another folder. Returns 0 on success | copydir("sd:/tegraexplorer", "sd:/switch") # This will copy sd:/tegraexplorer to sd:/switch/tegraexplorer | 250 | | copyfile | String, String | 0: Path to source file, 1: Path to dest file | Integer | Copies source file to destination. Returns 0 on success | copyfile("sd:/hbmenu.nro", "sd:/hbmenu_2.nro") | 251 | | movefile | String, String | 0: Source Path, 1: Destination path | Integer | Renames or moves the file (or folder) to destination. Returns 0 on success | movefile("sd:/hbmenu.nro", "sd:/lol.nro") | 252 | | delfile | String | 0: Path to file | Integer | Deletes a file. Returns 0 on success | delfile("sd:/boot.dat") | 253 | | readfile | String | 0: Path to file | ByteArray | Reads a file and returns a byte array. This could be a memory intensive operation. Raises a fatal error if there was an error reading the file | a = readfile("sd:/hbmenu.nro") | 254 | | writefile | String, ByteArray | 0: Path to file, 1: Bytes to write | Integer | Writes bytes to a file. Returns 0 on success | writefile("sd:/yeet", ["BYTE[]", 1,2,3]) | 255 | | fsexists | String | 0: Path | Integer | Checks if a file or folder exists. Returns 1 when it exists, 0 if it does not | fsexists("sd:/hbmenu.nro") | 256 | | payload | String | 0: Path to payload | Integer | Boots to a payload. Returns an integer on failure | payload("sd:/atmosphere/reboot_payload.bin") | 257 | | combinepath | Any arg count of (String) | any: String to be combined | String | Combines path parts together into a path | combinepath("sd:/", "tegraexplorer", "firmware") # Returns "sd:/tegraexplorer/firmware" | 258 | | escapepath | String | 0: String to escape a folder | String | Escapes a folder path (to go 1 folder back). See example | escapepath("sd:/tegraexplorer/firmware") # Returns "sd:/tegraexplorer" | 259 | -------------------------------------------------------------------------------- /scripts/Dump_saves.te: -------------------------------------------------------------------------------- 1 | #REQUIRE SD 2 | #REQUIRE KEYS 3 | #REQUIRE VER 4.0.0 4 | 5 | partNames = ["SYSTEM", "USER"] 6 | menuOptions = ["Exit"].copy() 7 | 8 | partNames.foreach("x"){ 9 | menuOptions.add("Sysmmc " + x) 10 | } 11 | 12 | if (emu()){ 13 | partNames.foreach("x"){ 14 | menuOptions.add("Emummc " + x) 15 | } 16 | } 17 | 18 | res = menu(menuOptions, 0) 19 | 20 | if (!res){ 21 | exit() 22 | } 23 | 24 | clear() 25 | 26 | if (res % 2) { 27 | mountStr = "SYSTEM" 28 | }.else() { 29 | mountStr = "USER" 30 | } 31 | 32 | if (res > 2) { 33 | mount = mountemu 34 | }.else() { 35 | mount = mountsys 36 | } 37 | 38 | if (mount(mountStr)){ 39 | println("Mounting failed!") 40 | pause() 41 | exit() 42 | } 43 | 44 | cpSaveFolder = menuOptions[res] 45 | cpSavePath = combinepath("sd:/tegraexplorer/", cpSaveFolder) 46 | mkdir("sd:/tegraexplorer") 47 | mkdir(cpSavePath) 48 | 49 | res = copydir("bis:/save", cpSavePath) 50 | if (res) { 51 | println("Copy failed! Errcode: ", res) 52 | }.else() { 53 | println("Done!") 54 | } 55 | pause() -------------------------------------------------------------------------------- /scripts/SystemRestoreV3.te: -------------------------------------------------------------------------------- 1 | #REQUIRE VER 4.0.0 2 | #REQUIRE MINERVA 3 | #REQUIRE KEYS 4 | #REQUIRE SD 5 | 6 | wait={t=timer()while(timer()<(t+tw)){print("Wait for",(t+tw-timer()/1000),"seconds \r")}} 7 | p = println 8 | 9 | getInt = { 10 | resInt = (buff[0] << 24) | (buff[1] << 16) | (buff[2] << 8) | (buff[3]) 11 | } 12 | bisFileOffset = 0 13 | 14 | getBisBytes = { 15 | buff = bisFileDump.slice(bisFileOffset, bisGetLen).project() 16 | bisFileOffset = bisFileOffset + bisGetLen 17 | } 18 | 19 | getNextInt = { 20 | getBisBytes(bisGetLen = 4) 21 | getInt() 22 | } 23 | 24 | fatal = { 25 | color(0xFF0000) 26 | p("\n[FATAL]", fatalMsg) 27 | pause() 28 | exit() 29 | } 30 | 31 | readBisAttrs = { 32 | path = combinepath(cwd(), "boot.bis") 33 | bisFileRes = 1 34 | if (fsexists(path)){ 35 | bisFileDump = readfile(path) 36 | getBisBytes(bisGetLen = 0x10) 37 | bisName = buff.bytestostr() 38 | getBisBytes(bisGetLen = 1) 39 | 40 | sizes = [0,1,2,3].copy() 41 | 42 | sizes.foreach("x"){ 43 | getNextInt() 44 | sizes[x] = resInt 45 | } 46 | 47 | bisFileRes = 0 48 | } 49 | } 50 | 51 | extractBis = { 52 | color(0xFF0000) 53 | p("Extracting boot.bis...") 54 | color(0xFFFFFF) 55 | i = 0 56 | files = ["BOOT0.bin", "BOOT1.bin", "BCPKG2-1-Normal-Main", "BCPKG2-3-SafeMode-Main"] 57 | 58 | sizes.foreach("x"){ 59 | getBisBytes(bisGetLen = x) 60 | p("Extracting", files[i]) 61 | if (writefile(combinepath(cwd(), files[i]), buff)){ 62 | fatal(fatalMsg = "Extracting boot.bis failed!") 63 | } 64 | 65 | i = i + 1 66 | } 67 | 68 | res = copyfile(combinepath(cwd(), "BCPKG2-1-Normal-Main"), combinepath(cwd(), "BCPKG2-2-Normal-Sub")) 69 | if (!res){ 70 | res = copyfile(combinepath(cwd(), "BCPKG2-3-SafeMode-Main"), combinepath(cwd(), "BCPKG2-4-SafeMode-Sub")) 71 | } 72 | 73 | if (res) { 74 | fatal(fatalMsg = "Extracting boot.bis failed!") 75 | } 76 | 77 | p("\n") 78 | } 79 | 80 | bisFiles = ["BOOT0.bin", "BOOT1.bin", "BCPKG2-1-Normal-Main", "BCPKG2-2-Normal-Sub", "BCPKG2-3-SafeMode-Main", "BCPKG2-4-SafeMode-Sub", "PRODINFO"] 81 | 82 | backupBis = { 83 | color(0xFF0000) 84 | p("Backing up BIS...") 85 | color(0xFFFFFF) 86 | 87 | mkdir(combinepath(cwd(), "backup")) 88 | path = combinepath(cwd(), "backup", "bis") 89 | mkdir(path) 90 | bisFiles.foreach("x"){ 91 | print("Backing up", x, "") 92 | if (mmcread(combinepath(path, x), x)){ 93 | fatal(fatalMsg = "Failed backing up BIS") 94 | } 95 | p() 96 | } 97 | p() 98 | } 99 | 100 | backupSys = { 101 | color(0xFF0000) 102 | p("Backing up SYSTEM...") 103 | color(0xFFFFFF) 104 | 105 | mkdir(combinepath(cwd(), "backup")) 106 | path = combinepath(cwd(), "backup", "system") 107 | mkdir(path) 108 | 109 | if (mount("SYSTEM")){ 110 | fatal(fatalMsg = "Failed to mount SYSTEM") 111 | } 112 | 113 | if (copydir("bis:/Contents/registered", path)){ 114 | fatal(fatalMsg = "Failed to copy registered") 115 | } 116 | 117 | if (copyfile("bis:/save/8000000000000120", combinepath(path, "8000000000000120"))){ 118 | fatal(fatalMsg = "Failed to copy 120 save") 119 | } 120 | 121 | p("\n") 122 | } 123 | 124 | signSave = { 125 | color(0xFF0000) 126 | p("Signing save...") 127 | color(0xFFFFFF) 128 | if (mount("SYSTEM")){ 129 | fatal(fatalMsg = "Failed to mount SYSTEM") 130 | } 131 | sav = readsave("bis:/save/8000000000000120") 132 | if (sav.commit()){ 133 | fatal(fatalMsg = "Failed to sign save!") 134 | } 135 | sav = 0 # Free sav 136 | } 137 | 138 | writeBis = { 139 | color(0xFF0000) 140 | p("Writing BIS...") 141 | color(0xFFFFFF) 142 | toRestore = bisFiles.copy() 143 | toRestore - 1 144 | toRestore.foreach("x"){ 145 | print("Restoring", x + "... ") 146 | if (mmcwrite(combinepath(cwd(), x), x)){ 147 | fatal(fatalMsg = "BIS write failed!!!") 148 | } 149 | p() 150 | } 151 | p() 152 | } 153 | 154 | writeSys = { 155 | if (mount("SYSTEM")){ 156 | fatal(fatalMsg = "Failed to mount SYSTEM") 157 | } 158 | 159 | color(0xFF0000) 160 | print("Deleting SYSTEM contents... ") 161 | color(0xFFFFFF) 162 | if (deldir("bis:/Contents/registered")){ 163 | fatal(fatalMsg = "An error occured during SYSTEM deletion!") 164 | } 165 | p() 166 | 167 | color(0xFF0000) 168 | print("Copying registered... ") 169 | color(0xFFFFFF) 170 | if (copydir(combinepath(cwd(), "SYSTEM/Contents/registered"), "bis:/Contents")) { 171 | fatal(fatalMsg = "An error occured during SYSTEM copying!") 172 | } 173 | p() 174 | 175 | color(0xFF0000) 176 | print("Copying 120 save... ") 177 | color(0xFFFFFF) 178 | if (copyfile(combinepath(cwd(), "SYSTEM/save/8000000000000120"), "bis:/save/8000000000000120")) { 179 | fatal(fatalMsg = "Failed to copy system save") 180 | } 181 | 182 | if (!fsexists("bis:/save/8000000000000000")) 183 | { 184 | p("\nWarning: 8000000000000000 does not exist. This save won't be signed! Copying") 185 | if (copyfile(combinepath(cwd(), "SYSTEM/save/8000000000000000"), "bis:/save/8000000000000000")) { 186 | fatal(fatalMsg = "Failed to copy fs save index save") 187 | } 188 | } 189 | 190 | p("\n") 191 | } 192 | 193 | actionRestoreBis = { 194 | extractBis() 195 | backupBis() 196 | writeBis() 197 | } 198 | 199 | actionRestoreSys = { 200 | backupSys() 201 | writeSys() 202 | signSave() 203 | } 204 | 205 | readBisAttrs() 206 | 207 | bootBisFound = !bisFileRes 208 | systemFolderFound = fsexists(combinepath(cwd(), "SYSTEM")) 209 | 210 | if ((!bootBisFound) && (!systemFolderFound)){ 211 | fatal(fatalMsg = "Nothing to restore found...\nPut a boot.bis and a SYSTEM dir from emmchaccgen next to this script!") 212 | } 213 | 214 | if (!bootBisFound){ 215 | p("Boot.bis not found. Cannot restore bis. Press any key to continue...") 216 | pause() 217 | } 218 | 219 | if (!systemFolderFound){ 220 | p("SYSTEM dir not found. Cannot restore SYSTEM. Press any key to continue...") 221 | pause() 222 | } 223 | 224 | useSys = 1 225 | 226 | if (emu()){ 227 | p("Switch System Restore\n") 228 | res = menu(["Exit", "Apply on Sysmmc", "Apply on Emummc"], 0) 229 | if (res == 0){ 230 | exit() 231 | } 232 | if (res == 2){ 233 | useSys = 0 234 | } 235 | } 236 | 237 | if (useSys){ 238 | mmcread = emmcread 239 | mmcwrite = emmcwrite 240 | mount = mountsys 241 | }.else() { 242 | mmcread = emummcread 243 | mmcwrite = emummcwrite 244 | mount = mountemu 245 | } 246 | 247 | clear() 248 | p("Switch System Restore") 249 | if (bootBisFound){ 250 | p("Target:", bisName) 251 | } 252 | p() 253 | 254 | res = menu(["Exit", "Restore BIS", "Restore SYSTEM", "Restore Both"], 0) 255 | if (res == 0){ 256 | exit() 257 | } 258 | 259 | clear() 260 | 261 | restoreBis = 0 262 | restoreSystem = 0 263 | 264 | if ((res == 1) || (res == 3)){ 265 | if (!bootBisFound){ 266 | fatal(fatalMsg = "Boot.bis not found...") 267 | } 268 | 269 | restoreBis = 1 270 | } 271 | 272 | if ((res == 2) || (res == 3)){ 273 | if (!systemFolderFound){ 274 | fatal(fatalMsg = "SYSTEM dir not found...") 275 | } 276 | 277 | restoreSystem = 1 278 | } 279 | 280 | clear() 281 | p("Switch System Restore") 282 | color(0xFF00) 283 | 284 | if (useSys){ 285 | mmcStr = "Sysmmc" 286 | }.else() { 287 | mmcStr = "Emummc" 288 | } 289 | 290 | p("Restore BIS:", restoreBis) 291 | p("Restore SYSTEM:", restoreSystem) 292 | p("Restoring onto:", mmcStr) 293 | color(0xFFFFFF) 294 | p("Ready!") 295 | color(0xE70000) 296 | print("WARNING!!!\nIf you do not know exactly what this does. STOP!!!\nThis will fuck with your system!\nOnly do this as a last ditch recovery effort!\n") 297 | color(0x40FF00) 298 | p("For help go here: https://discord.gg/C29hYvh\n") 299 | color(0xFFFFFF) 300 | wait(tw = 10000) 301 | p("Press Power to start the restore, any other key to exit") 302 | if (!pause().power){ 303 | exit() 304 | } 305 | clear() 306 | 307 | startMs = timer() 308 | 309 | if (restoreBis){ 310 | actionRestoreBis() 311 | } 312 | 313 | if (restoreSystem){ 314 | actionRestoreSys() 315 | } 316 | 317 | p("\n\nFully done in", (timer() - startMs) / 1000 ,"seconds!\nPress any key to exit") 318 | pause() -------------------------------------------------------------------------------- /scripts/createDirs.te: -------------------------------------------------------------------------------- 1 | #REQUIRE KEYS 2 | 3 | system = ["Contents", "Contents/placehld", "Contents/registered", "save"] 4 | 5 | if(mountsys("SYSTEM")) { 6 | print("SYSTEM mount failed!") 7 | pause() 8 | exit() 9 | } 10 | 11 | system.foreach("x") { 12 | println("Creating", x, "in SYSTEM") 13 | mkdir("bis:/" + x) 14 | } 15 | 16 | user = ["Album","Contents","Contents/placehld","Contents/registered","save","saveMeta","temp"] 17 | 18 | if(mountsys("USER")) { 19 | print("USER mount failed!") 20 | pause() 21 | exit() 22 | } 23 | 24 | user.foreach("x") { 25 | println("Creating", x, "in USER") 26 | mkdir("bis:/" + x) 27 | } 28 | 29 | println("All done!") 30 | pause() -------------------------------------------------------------------------------- /v1/FVI.te: -------------------------------------------------------------------------------- 1 | setString("a1b287e07f8455e8192f13d0e45a2aaf.nca", $100_chk) 2 | setString("3b7cd379e18e2ee7e1c6d0449d540841.nca", $100_exfat) 3 | setString("1.0.0", $100_version) 4 | setString("7a1f79f8184d4b9bae1755090278f52c.nca", $200_chk) 5 | setString("f55a04978465ebf5666ca93e21b26dd2.nca", $200_exfat) 6 | setString("2.0.0", $200_version) 7 | setString("e9b3e75fce00e52fe646156634d229b4.nca", $210_chk) 8 | setString("4a94289d2400b301cbe393e64831f84c.nca", $210_exfat) 9 | setString("2.1.0", $210_version) 10 | setString("7f90353dff2d7ce69e19e07ebc0d5489.nca", $220_chk) 11 | setString("4a94289d2400b301cbe393e64831f84c.nca", $220_exfat) 12 | setString("2.2.0", $220_version) 13 | setString("d1c991c53a8a9038f8c3157a553d876d.nca", $230_chk) 14 | setString("4a94289d2400b301cbe393e64831f84c.nca", $230_exfat) 15 | setString("2.3.0", $230_version) 16 | setString("7bef244b45bf63efb4bf47a236975ec6.nca", $300_chk) 17 | setString("9e5c73ec938f3e1e904a4031aa4240ed.nca", $300_exfat) 18 | setString("3.0.0", $300_version) 19 | setString("9a78e13d48ca44b1987412352a1183a1.nca", $301_chk) 20 | setString("17f9864ce7fe3a35cbe3e3b9f6185ffb.nca", $301_exfat) 21 | setString("3.0.1", $301_version) 22 | setString("704129fc89e1fcb85c37b3112e51b0fc.nca", $302_chk) 23 | setString("e7dd3c6cf68953e86cce54b69b333256.nca", $302_exfat) 24 | setString("3.0.2", $302_version) 25 | setString("f99ac61b17fdd5ae8e4dda7c0b55132a.nca", $400_chk) 26 | setString("090b012b110973fbdc56a102456dc9c6.nca", $400_exfat) 27 | setString("4.0.0", $400_version) 28 | setString("d0e5d20e3260f3083bcc067483b71274.nca", $401_chk) 29 | setString("090b012b110973fbdc56a102456dc9c6.nca", $401_exfat) 30 | setString("4.0.1", $401_version) 31 | setString("77e1ae7661ad8a718b9b13b70304aeea.nca", $410_chk) 32 | setString("458a54253f9e49ddb044642286ca6485.nca", $410_exfat) 33 | setString("4.1.0", $410_version) 34 | setString("faa857ad6e82f472863e97f810de036a.nca", $500_chk) 35 | setString("432f5cc48e6c1b88de2bc882204f03a1.nca", $500_exfat) 36 | setString("5.0.0", $500_version) 37 | setString("7f5529b7a092b77bf093bdf2f9a3bf96.nca", $501_chk) 38 | setString("432f5cc48e6c1b88de2bc882204f03a1.nca", $501_exfat) 39 | setString("5.0.1", $501_version) 40 | setString("c5758b0cb8c6512e8967e38842d35016.nca", $502_chk) 41 | setString("432f5cc48e6c1b88de2bc882204f03a1.nca", $502_exfat) 42 | setString("5.0.2", $502_version) 43 | setString("fce3b0ea366f9c95fe6498b69274b0e7.nca", $510_chk) 44 | setString("c9e500edc7bb0fde52eab246028ef84c.nca", $510_exfat) 45 | setString("5.1.0", $510_version) 46 | setString("286e30bafd7e4197df6551ad802dd815.nca", $600pre_chk) 47 | setString("711b5fc83a1f07d443dfc36ba606033b.nca", $600pre_exfat) 48 | setString("6.0.0(pre-release)", $600pre_version) 49 | setString("258c1786b0f6844250f34d9c6f66095b.nca", $600_chk) 50 | setString("d5186022d6080577b13f7fd8bcba4dbb.nca", $600_exfat) 51 | setString("6.0.0", $600_version) 52 | setString("663e74e45ffc86fbbaeb98045feea315.nca", $601_chk) 53 | setString("d5186022d6080577b13f7fd8bcba4dbb.nca", $601_exfat) 54 | setString("6.0.1", $601_version) 55 | setString("1d21680af5a034d626693674faf81b02.nca", $610_chk) 56 | setString("d5186022d6080577b13f7fd8bcba4dbb.nca", $610_exfat) 57 | setString("6.1.0", $610_version) 58 | setString("6dfaaf1a3cebda6307aa770d9303d9b6.nca", $620_chk) 59 | setString("97cb7dc89421decc0340aec7abf8e33b.nca", $620_exfat) 60 | setString("6.2.0", $620_version) 61 | setString("c613bd9660478de69bc8d0e2e7ea9949.nca", $700_chk) 62 | setString("58c731cdacb330868057e71327bd343e.nca", $700_exfat) 63 | setString("7.0.0", $700_version) 64 | setString("e6b22c40bb4fa66a151f1dc8db5a7b5c.nca", $701_chk) 65 | setString("02a2cbfd48b2f2f3a6cec378d20a5eff.nca", $701_exfat) 66 | setString("7.0.1", $701_version) 67 | setString("4fe7b4abcea4a0bcc50975c1a926efcb.nca", $800_chk) 68 | setString("b2708136b24bbe206e502578000b1998.nca", $800_exfat) 69 | setString("8.0.0", $800_version) 70 | setString("6c5426d27c40288302ad616307867eba.nca", $801_chk) 71 | setString("b2708136b24bbe206e502578000b1998.nca", $801_exfat) 72 | setString("8.0.1", $801_version) 73 | setString("7eedb7006ad855ec567114be601b2a9d.nca", $810_chk) 74 | setString("96f4b8b729ade072cc661d9700955258.nca", $810_exfat) 75 | setString("8.1.0", $810_version) 76 | setString("a6af05b33f8f903aab90c8b0fcbcc6a4.nca", $900_chk) 77 | setString("3b444768f8a36d0ddd85635199f9676f.nca", $900_exfat) 78 | setString("9.0.0", $900_version) 79 | setString("fd1ffb82dc1da76346343de22edbc97c.nca", $901_chk) 80 | setString("3b444768f8a36d0ddd85635199f9676f.nca", $901_exfat) 81 | setString("9.0.1", $901_version) 82 | setString("c5fbb49f2e3648c8cfca758020c53ecb.nca", $910_chk) 83 | setString("c9bd4eda34c91a676de09951bb8179ae.nca", $910_exfat) 84 | setString("9.1.0", $910_version) 85 | setString("09ef4d92bb47b33861e695ba524a2c17.nca", $920_chk) 86 | setString("2416b3794964b3482c7bc506d12c44df.nca", $920_exfat) 87 | setString("9.2.0", $920_version) 88 | setString("5625cdc21d5f1ca52f6c36ba261505b9.nca", $1000_chk) 89 | setString("d5bc167565842ee61f9670d23759844d.nca", $1000_exfat) 90 | setString("10.0.0", $1000_version) 91 | setString("36ab1acf0c10a2beb9f7d472685f9a89.nca", $1001_chk) 92 | setString("d5bc167565842ee61f9670d23759844d.nca", $1001_exfat) 93 | setString("10.0.1", $1001_version) 94 | setString("e951bc9dedcd54f65ffd83d4d050f9e0.nca", $1002_chk) 95 | setString("d5bc167565842ee61f9670d23759844d.nca", $1002_exfat) 96 | setString("10.0.2", $1002_version) 97 | setString("5b1df84f88c3334335bbb45d8522cbb4.nca", $1003_chk) 98 | setString("d5bc167565842ee61f9670d23759844d.nca", $1003_exfat) 99 | setString("10.0.3", $1003_version) 100 | setString("34728c771299443420820d8ae490ea41.nca", $1004_chk) 101 | setString("d5bc167565842ee61f9670d23759844d.nca", $1004_exfat) 102 | setString("10.0.4", $1004_version) 103 | 104 | printf("FVI script edition") 105 | printf("") 106 | printf("Press A to read from SYSMMC") 107 | if (@EMUMMC){ 108 | printf("Press Y to read from EMUMMC") 109 | } 110 | printf("Press any other button to exit") 111 | printf("") 112 | 113 | pause() 114 | @checkInput = setInt(0); 115 | 116 | if (@BTN_A){ 117 | printf("Mounting SYSMMC...") 118 | mmc_connect("SYSMMC") 119 | @checkInput = setInt(1); 120 | } 121 | if (@BTN_Y){ 122 | if (@EMUMMC, == , 0){ 123 | exit() 124 | } 125 | printf("Mounting EMUMMC...") 126 | mmc_connect("EMUMMC") 127 | @checkInput = setInt(1); 128 | } 129 | 130 | if (@checkInput, == , 0){ 131 | exit() 132 | } 133 | 134 | mmc_mount("SYSTEM") 135 | 136 | printf("") 137 | 138 | @i = setInt(1) 139 | 140 | @loop = getPosition() 141 | if (@i, ">=", 103){ 142 | printf("No firmware found") 143 | printf("Press any button to exit") 144 | pause() 145 | exit() 146 | } 147 | 148 | setStringIndex(@i, $nca) 149 | combineStrings("emmc:/Contents/registered/", $nca, $path) 150 | @check = fs_exists($path) 151 | 152 | if (@check, "==", 0){ 153 | @i = math(@i, "+", 3) 154 | goto(@loop) 155 | } 156 | 157 | @i = math(@i, "+", 1) 158 | setStringIndex(@i, $nca) 159 | combineStrings("emmc:/Contents/registered/", $nca, $path) 160 | @checkexfat = fs_exists($path) 161 | 162 | @i = math(@i, "+", 1) 163 | setStringIndex(@i, $version) 164 | 165 | printf("Firmware found:") 166 | printf($version) 167 | 168 | if (@checkexfat){ 169 | printf("Exfat edition") 170 | } 171 | if (@checkexfat, "==", 0){ 172 | printf("Non-Exfat edition") 173 | } 174 | 175 | printf("") 176 | printf("Press any key to exit") 177 | 178 | pause() 179 | exit() -------------------------------------------------------------------------------- /v1/ParentalLockRemover.te: -------------------------------------------------------------------------------- 1 | printf("Remove Parental Lock -.-") 2 | printf("") 3 | printf("Press A to remove from SYSMMC") 4 | if (@EMUMMC){ 5 | printf("Press Y to remove from EMUMMC") 6 | } 7 | printf("Press power to exit") 8 | printf("") 9 | 10 | pause() 11 | @checkInput = setInt(0); 12 | 13 | if (@BTN_A){ 14 | printf("Mounting SYSMMC...") 15 | mmc_connect("SYSMMC") 16 | @checkInput = setInt(1); 17 | } 18 | if (@BTN_Y){ 19 | if (@EMUMMC, == , 0){ 20 | exit() 21 | } 22 | printf("Mounting EMUMMC...") 23 | mmc_connect("EMUMMC") 24 | @checkInput = setInt(1); 25 | } 26 | 27 | if (@checkInput, == , 0){ 28 | exit() 29 | } 30 | 31 | mmc_mount("SYSTEM") 32 | 33 | if (@RESULT){ 34 | printf("System failed to mount!") 35 | pause() 36 | exit() 37 | } 38 | 39 | 40 | 41 | setColor("RED") 42 | printf("Deleting Parental Lock") 43 | 44 | fs_del("emmc:/save/8000000000000100") 45 | 46 | 47 | setColor("GREEN") 48 | printf("") 49 | printf("") 50 | printf("Done! press any key to exit") 51 | 52 | pause() 53 | exit() 54 | -------------------------------------------------------------------------------- /v1/README.md: -------------------------------------------------------------------------------- 1 | # TegraScript 2 | The scripting language of TegraExplorer 3 | 4 | ## Functions 5 | 6 | Function | Args | Description | Output 7 | |:-|:-|:-|:-| 8 | `printf(...)` | ...: can be any count of args. Stuff like ("This ", "Is", $Pretty, @Neat) works | writes text to the screen | returns 0 9 | `printInt(int arg1)` | arg1: Int variable to print | Displays an int variable to the screen in the format `@var: (number)` | returns 0 10 | `setPrintPos(int arg1, int arg2)` | arg1: sets cursor position x, arg2: sets cursor position y | sets cursor to a position on the screen. Max X is 42, max Y is 78 | returns 0 11 | `clearscreen()` | - | clears the screen | returns 0 12 | `setColor(string arg1)` | arg1: color string. Valid args: `RED`, `ORANGE`, `YELLOW`, `GREEN`, `BLUE`, `VIOLET`, `WHITE` | Changes the color of the text printed | returns 0 13 | `if(int arg1)` | arg1: checks if interger is true or false (not 0 or 0) | Part of flow control. Runs code inside {} | returns 0 14 | `if(int arg1, string arg2, int arg3)` (overload) | See `check()` and the first `if()` | Part of flow control. Runs code inside {}. Accepts statements like `if (1, == , 1) {}` | returns 0 15 | `goto(int location)` | location: interger aquired by `getLocation()` | jumps to the character offset specified. sets @RETURN based on current location | returns 0 16 | `getPosition()` | - | Returns the current script location, for use with `goto()` | returns > 0 17 | `math(int arg1, string arg2, int arg3)` | arg1 "operator arg2" arg3. Valid operators (arg2s): `"+"`, `"-"`, `"*"`, `"/"` | Does a math operation and returns the result | returns the result of the math operation 18 | `check(int arg1, string arg2, int arg3)` | arg1 "operator arg2" arg3. Valid operators (arg2s): `"=="`, `"!="`, `">="`, `"<="`, `">"`, `"<"` | Does a check and returns the result. result is either 0 or 1 | returns 0 or 1 19 | `invert(int arg1)` | - | makes non 0 integers a 0, and vise versa | returns 0 or 1 20 | `setInt(int arg1)` | - | returns arg1, for setting of variables | returns arg1 21 | `setString(string in, $svar out)` | $svar is a string variable, written as `$var` | copies in to out | returns 0 22 | `setStringIndex(int in, $svar out)` | looks up earlier defined strings in order. User defined strings start at index 1. $svar is a string variable | Copies string table index to out | returns 0 23 | `combineStrings(string s1, string s2, $svar out)` | $svar is a string variable | combines s1 and s2 (as s1s2) and copies it into out | returns 0 24 | `compareStrings(string s1, string s2)` | - | compares s1 to s2. If they are the same, the function returns 1, else 0 | returns 0 or 1 25 | `subString(string in, int startoffset, int size, $svar out)` | in: input string. startoffset: starting offset, 0 is the beginning of the string. size: length to copy, -1 copies the rest of the string. out: output var | Copies part of a string into another string | returns 0 26 | `inputString(string startText, int maxlen, $svar out)` | startText: Starting input text. maxlen: Maximum allowed characters to enter. out: output var | Displays an input box for the user to input text. Note, only works with joycons attached! | returns 1 if user cancelled the input, 0 if success 27 | `stringLength(string in)` | - | Gets the length of the input string | returns the length of the input string 28 | `pause()` | - | pauses the script until it recieves user input. result will be copied into `@BTN_POWER`, `@BTN_VOL+`, `@BTN_VOL-`, `@BTN_A`, `@BTN_B`, `@BTN_X`, `@BTN_Y`, `@BTN_UP`, `@BTN_DOWN`, `@BTN_LEFT` and `@BTN_RIGHT` | returns >0 29 | `wait(int arg1)` | arg1: amount that it waits | waits for the given amount of time, then continues running the script | returns 0 30 | `exit()` | - | exits the script | - 31 | `fs_exists(string path)` | path: full path to file | check if a file exists. 1 if it exists, 0 if it doesn't | returns 0 or 1 32 | `fs_move(string src, string dst)` | src/dst: full path to file | move file from src to dst | returns >= 0 33 | `fs_mkdir(string path)` | path: full path to file | creates a directory at the given path (note: returns 8 if the folder already exists | returns >= 0 34 | `fs_del(string path)` | path: full path to file | deletes a file (or empty directory) | returns >= 0 35 | `fs_delRecursive(string path)` | path: full path to folder | deletes a folder with all subitems | returns >= 0 36 | `fs_copy(string src, string dst)` | src/dst: full path to file | copies a file from src to dst | returns >= 0 37 | `fs_copyRecursive(string src, string dst)` | src/dst: full path to file | copies a folder with subitems from src to dst (note that dst is the parent folder, src will be copied to dst/src) | returns >= 0 38 | `fs_openDir(string path)` | path: full path to folder | opens a directory for use with `fs_readDir()` and sets `@ISDIRVALID` to 1 | returns >= 0 39 | `fs_closeDir()` | - | closes current open directory and sets `@ISDIRVALID` to 0 | returns 0 40 | `fs_readDir()` | - | reads entry out of dir. Atomatically calls `fs_closeDir()` if the end of the dir is reached. Saves result to `$FILENAME` and `@ISDIR` | returns 0 41 | `fs_combinePath(string left, string right, $var out)` | - | Will combine paths, like `sd:/` and `folder` to `sd:/folder`, also `sd:/folder` and `folder2` to `sd:/folder/folder2` | returns 0 42 | `fs_extractBisFile(string path, string outfolder)` | - | take .bis and extract it into outfolder | returns >= 0 43 | `mmc_connect(string mmctype)` | mmctype: either `SYSMMC` or `EMUMMC` | connects SYSMMC or EMUMMC to the system. Specify partition with `mmc_mount()` | returns 0 44 | `mmc_mount(string partition)` | partition: either `SYSTEM` or `USER` | mounts partition in previously connected mmc | returns >= 0 45 | `mmc_dumpPart(string type, string out)` | type: Either `BOOT` or a partition on the gpt. out: Out folder: for `BOOT` this needs to be a folder, otherwise a filepath | Dumps a part from the e(mu)mmc. Determined by earlier mmc_connect's | returns >= 0 46 | `mmc_restorePart(string path)` | path: Needs to be `BOOT0`, `BOOT1` or a valid partition on the gpt. FS Partitions are not allowed | Restores a file to the e(mu)mmc. Determined by earlier mmc_connect's | returns >= 0 47 | 48 | 49 | ## Variables 50 | 51 | TegraScript has 2 kinds of variables, @ints and $strings. 52 | - You can define @ints by writing `@variable = setInt(0);` (or any function for that matter). 53 | - You can define $strings with the use of `setString();`, `setStringIndex();` and `combineStrings();`. 54 | 55 | You can use these variables in place of int or string inputs, so for example `@b = setInt(@a)` or `setString($a, $b)` 56 | 57 | Note though that the int variables can't be assigned negative values 58 | 59 | ### Built in variables 60 | There are some built in variables: 61 | - `@EMUMMC`: 1 if an emummc was found, 0 if no emummc was found 62 | - `@RESULT`: result of the last ran function 63 | - `@JOYCONN`: 1 if both joycons are connected, 0 if not 64 | - `$CURRENTPATH`: Represents the current path 65 | 66 | (if `fs_readdir()` got ran) 67 | - `@ISDIRVALID`: Is the open directory valid 68 | - `$FILENAME`: Represents the current filename 69 | - `@ISDIR`: 1 if the last read file is a DIR, otherwise 0 70 | 71 | (if `pause()` got ran) 72 | - `@BTN_POWER`, `@BTN_VOL+`, `@BTN_VOL-`, `@BTN_A`, `@BTN_B`, `@BTN_X`, `@BTN_Y`, `@BTN_UP`, `@BTN_DOWN`, `@BTN_LEFT`: result of the `pause()` function, represents which button got pressed during the `pause()` function 73 | 74 | (if `goto()` got ran) 75 | - `@RETURN`: sets @RETURN based on current location. can be used to go back to (after) the previously ran goto() 76 | 77 | ## Flow control 78 | 79 | You can use `if()`, `goto()` and `math()` functions to control the flow of your program. Example: 80 | ``` 81 | @i = setInt(0) 82 | @LOOP = getLocation() 83 | if (@i, <= , 10){ 84 | @i = math(@i, + , 1) 85 | printInt(@i) 86 | goto (@LOOP) 87 | } 88 | 89 | pause() 90 | ``` 91 | This will print numbers 0 to 10 as `@i: x` 92 | 93 | Another example: 94 | 95 | ``` 96 | printf("Press a button") 97 | 98 | pause() 99 | 100 | if (@BTN_VOL+){ 101 | printf("Vol+ has been pressed") 102 | } 103 | if (@BTN_VOL-){ 104 | printf("Vol- has been pressed") 105 | } 106 | if (@BTN_POWER){ 107 | printf("Power has been pressed") 108 | } 109 | 110 | pause() 111 | ``` 112 | 113 | # Changelog 114 | 115 | #### 29/05/2020 116 | *It's midnight already? i just got started* 117 | 118 | With the release of TegraExplorer v2.0.3, the arg parser has been changed. If you find any bugs, please make an issue in either the TegraExplorer repository, or here. 119 | 120 | 3 new commands have been added 121 | - subString() 122 | - inputString() 123 | - stringLength() 124 | 125 | 2 new built in variables has been added 126 | - @JOYCONN (1 when both joycons are connected, 0 when at least 1 joycon is disconnected) 127 | - @RETURN (Read on for how this works) 128 | 129 | Minus values are now considered valid by the scripting language, but, printing them will not work well (the print function can only print u32's) 130 | 131 | Errors have been significantly improved. There are now 2 types of errors, ERR IN FUNC, which indicates a scripting function failed, and SCRIPT LOOKUP FAIL, which means the function you inserted doesn't exist (can also mean the wrong amount of args were supplied). The Loc value on the error screen now shows the line number it failed at, rather than the character offset 132 | 133 | Goto functions now generate a variable called @RETURN, which, will return to after the goto. This aids in the making of pseudo-functions. Example: 134 | 135 | ``` 136 | @functionsActive = setInt(0) 137 | 138 | @friiFunction = getPosition() 139 | if (@functionsActive) { 140 | printf("Hi this is a function, i think") 141 | goto(@RETURN) 142 | } 143 | 144 | @functionsActive = setInt(1) 145 | goto(@friiFunction) 146 | 147 | pause() 148 | ``` 149 | 150 | #### 03/05/2020 151 | *God fucking dammit it's 2am again* 152 | 153 | With the release of TegraExplorer v2.0.0, the pause() function changed. It adds some buttons from controllers if they are connected. See the pause() section above to see what buttons are mapped. Note that if no joycons are connected, power = a, up = vol+, down = vol-. Also note that the screen dimentions have changed, so your text might not fit anymore. 154 | 155 | #### 26/04/2020 156 | With the release of TegraExplorer v1.5.2, there has been 1 new feature implemented. 157 | 158 | printf() now can print multiple variables. `printf("This ", "Is", $Pretty, @Neat)` is valid syntax now 159 | 160 | #### 12/04/2020 161 | With the release of TegraExplorer v1.5.1, there has been some breaking changes. `?LOOP` and `goto(?LOOP)` is no longer valid syntax. Replace this with `@LOOP = getPosition()` and `goto(@LOOP)`. 162 | 163 | Other than this, `@check = check(1, "==", 1) if (@check) {}` can be simplified to `if (1, == , 1) {}`. For `math()` functions, you don't have to enclose operators in "" anymore (just like check/if), like `@math = math(1, + , 1)` 164 | -------------------------------------------------------------------------------- /v1/fwdump.te: -------------------------------------------------------------------------------- 1 | setString("a1b287e07f8455e8192f13d0e45a2aaf.nca", $100_chk) 2 | setString("3b7cd379e18e2ee7e1c6d0449d540841.nca", $100_exfat) 3 | setString("1.0.0", $100_version) 4 | setString("7a1f79f8184d4b9bae1755090278f52c.nca", $200_chk) 5 | setString("f55a04978465ebf5666ca93e21b26dd2.nca", $200_exfat) 6 | setString("2.0.0", $200_version) 7 | setString("e9b3e75fce00e52fe646156634d229b4.nca", $210_chk) 8 | setString("4a94289d2400b301cbe393e64831f84c.nca", $210_exfat) 9 | setString("2.1.0", $210_version) 10 | setString("7f90353dff2d7ce69e19e07ebc0d5489.nca", $220_chk) 11 | setString("4a94289d2400b301cbe393e64831f84c.nca", $220_exfat) 12 | setString("2.2.0", $220_version) 13 | setString("d1c991c53a8a9038f8c3157a553d876d.nca", $230_chk) 14 | setString("4a94289d2400b301cbe393e64831f84c.nca", $230_exfat) 15 | setString("2.3.0", $230_version) 16 | setString("7bef244b45bf63efb4bf47a236975ec6.nca", $300_chk) 17 | setString("9e5c73ec938f3e1e904a4031aa4240ed.nca", $300_exfat) 18 | setString("3.0.0", $300_version) 19 | setString("9a78e13d48ca44b1987412352a1183a1.nca", $301_chk) 20 | setString("17f9864ce7fe3a35cbe3e3b9f6185ffb.nca", $301_exfat) 21 | setString("3.0.1", $301_version) 22 | setString("704129fc89e1fcb85c37b3112e51b0fc.nca", $302_chk) 23 | setString("e7dd3c6cf68953e86cce54b69b333256.nca", $302_exfat) 24 | setString("3.0.2", $302_version) 25 | setString("f99ac61b17fdd5ae8e4dda7c0b55132a.nca", $400_chk) 26 | setString("090b012b110973fbdc56a102456dc9c6.nca", $400_exfat) 27 | setString("4.0.0", $400_version) 28 | setString("d0e5d20e3260f3083bcc067483b71274.nca", $401_chk) 29 | setString("090b012b110973fbdc56a102456dc9c6.nca", $401_exfat) 30 | setString("4.0.1", $401_version) 31 | setString("77e1ae7661ad8a718b9b13b70304aeea.nca", $410_chk) 32 | setString("458a54253f9e49ddb044642286ca6485.nca", $410_exfat) 33 | setString("4.1.0", $410_version) 34 | setString("faa857ad6e82f472863e97f810de036a.nca", $500_chk) 35 | setString("432f5cc48e6c1b88de2bc882204f03a1.nca", $500_exfat) 36 | setString("5.0.0", $500_version) 37 | setString("7f5529b7a092b77bf093bdf2f9a3bf96.nca", $501_chk) 38 | setString("432f5cc48e6c1b88de2bc882204f03a1.nca", $501_exfat) 39 | setString("5.0.1", $501_version) 40 | setString("c5758b0cb8c6512e8967e38842d35016.nca", $502_chk) 41 | setString("432f5cc48e6c1b88de2bc882204f03a1.nca", $502_exfat) 42 | setString("5.0.2", $502_version) 43 | setString("fce3b0ea366f9c95fe6498b69274b0e7.nca", $510_chk) 44 | setString("c9e500edc7bb0fde52eab246028ef84c.nca", $510_exfat) 45 | setString("5.1.0", $510_version) 46 | setString("286e30bafd7e4197df6551ad802dd815.nca", $600pre_chk) 47 | setString("711b5fc83a1f07d443dfc36ba606033b.nca", $600pre_exfat) 48 | setString("6.0.0(pre-release)", $600pre_version) 49 | setString("258c1786b0f6844250f34d9c6f66095b.nca", $600_chk) 50 | setString("d5186022d6080577b13f7fd8bcba4dbb.nca", $600_exfat) 51 | setString("6.0.0", $600_version) 52 | setString("663e74e45ffc86fbbaeb98045feea315.nca", $601_chk) 53 | setString("d5186022d6080577b13f7fd8bcba4dbb.nca", $601_exfat) 54 | setString("6.0.1", $601_version) 55 | setString("1d21680af5a034d626693674faf81b02.nca", $610_chk) 56 | setString("d5186022d6080577b13f7fd8bcba4dbb.nca", $610_exfat) 57 | setString("6.1.0", $610_version) 58 | setString("6dfaaf1a3cebda6307aa770d9303d9b6.nca", $620_chk) 59 | setString("97cb7dc89421decc0340aec7abf8e33b.nca", $620_exfat) 60 | setString("6.2.0", $620_version) 61 | setString("c613bd9660478de69bc8d0e2e7ea9949.nca", $700_chk) 62 | setString("58c731cdacb330868057e71327bd343e.nca", $700_exfat) 63 | setString("7.0.0", $700_version) 64 | setString("e6b22c40bb4fa66a151f1dc8db5a7b5c.nca", $701_chk) 65 | setString("02a2cbfd48b2f2f3a6cec378d20a5eff.nca", $701_exfat) 66 | setString("7.0.1", $701_version) 67 | setString("4fe7b4abcea4a0bcc50975c1a926efcb.nca", $800_chk) 68 | setString("b2708136b24bbe206e502578000b1998.nca", $800_exfat) 69 | setString("8.0.0", $800_version) 70 | setString("6c5426d27c40288302ad616307867eba.nca", $801_chk) 71 | setString("b2708136b24bbe206e502578000b1998.nca", $801_exfat) 72 | setString("8.0.1", $801_version) 73 | setString("7eedb7006ad855ec567114be601b2a9d.nca", $810_chk) 74 | setString("96f4b8b729ade072cc661d9700955258.nca", $810_exfat) 75 | setString("8.1.0", $810_version) 76 | setString("a6af05b33f8f903aab90c8b0fcbcc6a4.nca", $900_chk) 77 | setString("3b444768f8a36d0ddd85635199f9676f.nca", $900_exfat) 78 | setString("9.0.0", $900_version) 79 | setString("fd1ffb82dc1da76346343de22edbc97c.nca", $901_chk) 80 | setString("3b444768f8a36d0ddd85635199f9676f.nca", $901_exfat) 81 | setString("9.0.1", $901_version) 82 | setString("c5fbb49f2e3648c8cfca758020c53ecb.nca", $910_chk) 83 | setString("c9bd4eda34c91a676de09951bb8179ae.nca", $910_exfat) 84 | setString("9.1.0", $910_version) 85 | setString("09ef4d92bb47b33861e695ba524a2c17.nca", $920_chk) 86 | setString("2416b3794964b3482c7bc506d12c44df.nca", $920_exfat) 87 | setString("9.2.0", $920_version) 88 | setString("5625cdc21d5f1ca52f6c36ba261505b9.nca", $1000_chk) 89 | setString("d5bc167565842ee61f9670d23759844d.nca", $1000_exfat) 90 | setString("10.0.0", $1000_version) 91 | setString("36ab1acf0c10a2beb9f7d472685f9a89.nca", $1001_chk) 92 | setString("d5bc167565842ee61f9670d23759844d.nca", $1001_exfat) 93 | setString("10.0.1", $1001_version) 94 | setString("e951bc9dedcd54f65ffd83d4d050f9e0.nca", $1002_chk) 95 | setString("d5bc167565842ee61f9670d23759844d.nca", $1002_exfat) 96 | setString("10.0.2", $1002_version) 97 | setString("5b1df84f88c3334335bbb45d8522cbb4.nca", $1003_chk) 98 | setString("d5bc167565842ee61f9670d23759844d.nca", $1003_exfat) 99 | setString("10.0.3", $1003_version) 100 | setString("34728c771299443420820d8ae490ea41.nca", $1004_chk) 101 | setString("d5bc167565842ee61f9670d23759844d.nca", $1004_exfat) 102 | setString("10.0.4", $1004_version) 103 | 104 | # check tid = 0100000000000809, type data 105 | # exfat tid = 010000000000081B, type data 106 | 107 | printf("TegraScript firmware dumper") 108 | printf("") 109 | printf("Press A to dump from SYSMMC") 110 | if (@EMUMMC){ 111 | printf("Press Y to dump from EMUMMC") 112 | } 113 | printf("Press any other button to exit") 114 | printf("") 115 | 116 | pause() 117 | @checkInput = setInt(0); 118 | 119 | if (@BTN_A){ 120 | printf("Mounting SYSMMC...") 121 | mmc_connect("SYSMMC") 122 | @checkInput = setInt(1); 123 | } 124 | if (@BTN_Y){ 125 | if (@EMUMMC, == , 0){ 126 | exit() 127 | } 128 | printf("Mounting EMUMMC...") 129 | mmc_connect("EMUMMC") 130 | @checkInput = setInt(1); 131 | } 132 | 133 | if (@checkInput, == , 0){ 134 | exit() 135 | } 136 | 137 | mmc_mount("SYSTEM") 138 | 139 | printf("") 140 | 141 | @i = setInt(1) 142 | setString("emmc:/Contents/registered/", $basePath) 143 | 144 | @LOOP = getPosition() 145 | if (@i, ">=", 103){ 146 | printf("No valid firmware version found") 147 | printf("Press A to dump anyway") 148 | printf("Press any other button to exit") 149 | pause() 150 | 151 | if (@BTN_A, == , 0){ 152 | exit() 153 | } 154 | 155 | setString("Unknown", $version) 156 | } 157 | if (@i, <, 103){ 158 | setStringIndex(@i, $nca) 159 | combineStrings($basePath, $nca, $path) 160 | @exists = fs_exists($path) 161 | 162 | if (@exists, == , 0){ 163 | @i = math(@i, "+", 3) 164 | goto(@LOOP) 165 | } 166 | 167 | @i = math(@i, "+", 1) 168 | setStringIndex(@i, $nca) 169 | combineStrings($basePath, $nca, $path) 170 | @checkexfat = fs_exists($path) 171 | 172 | @i = math(@i, "+", 1) 173 | setStringIndex(@i, $version) 174 | 175 | if (@checkexfat){ 176 | combineStrings($version, "_exFAT", $version) 177 | } 178 | } 179 | 180 | printf("Firmware found:") 181 | printf($version) 182 | 183 | printf("") 184 | printf("Starting dump...") 185 | 186 | fs_mkdir("sd:/tegraexplorer") 187 | fs_mkdir("sd:/tegraexplorer/Firmware") 188 | combineStrings("sd:/tegraexplorer/Firmware/", $version, $sdBasePath) 189 | fs_mkdir($sdBasePath) 190 | combineStrings($sdBasePath, "/", $sdBasePath) 191 | 192 | @count = setInt(0) 193 | 194 | fs_openDir("emmc:/Contents/registered") 195 | setColor("GREEN") 196 | @LOOP = getPosition() 197 | fs_readDir() 198 | if (@ISDIRVALID){ 199 | if (@ISDIR){ 200 | combineStrings($basePath, $FILENAME, $path) 201 | combineStrings($path, "/00", $path) 202 | } 203 | if (@ISDIR, == , 0){ 204 | combineStrings($basePath, $FILENAME, $path) 205 | } 206 | 207 | setPrintPos(0, 16) 208 | @count = math(@count, "+", 1) 209 | printf(@count, ": ", $FILENAME) 210 | 211 | combineStrings($sdBasePath, $FILENAME, $sdPath) 212 | 213 | fs_copy($path, $sdPath) 214 | if (@RESULT){ 215 | printf("") 216 | printf("Copy failed!") 217 | printInt(@RESULT) 218 | pause() 219 | exit() 220 | } 221 | 222 | goto(@LOOP) 223 | } 224 | 225 | setColor("WHITE") 226 | printf("") 227 | printf("") 228 | printf("Dump done! Press any key to exit") 229 | 230 | pause() 231 | exit() -------------------------------------------------------------------------------- /v1/savedumper.te: -------------------------------------------------------------------------------- 1 | printf("TegraScript save dumper") 2 | printf("") 3 | printf("What mmc would you like to dump from") 4 | printf("Press A for sysmmc") 5 | if (@EMUMMC) { 6 | printf("Or press Y for emummc") 7 | } 8 | printf("Press any other button to exit") 9 | pause() 10 | @checkInput = setInt(0); 11 | 12 | if (@BTN_A){ 13 | printf("Mounting SYSMMC...") 14 | mmc_connect("SYSMMC") 15 | @checkInput = setInt(1); 16 | } 17 | if (@BTN_Y){ 18 | if (@EMUMMC, == , 0){ 19 | exit() 20 | } 21 | printf("Mounting EMUMMC...") 22 | mmc_connect("EMUMMC") 23 | @checkInput = setInt(1); 24 | } 25 | 26 | if (@checkInput, == , 0){ 27 | exit() 28 | } 29 | 30 | printf("") 31 | printf("Which partition do you want to dump from? X for SYSTEM, Y for USER") 32 | pause() 33 | 34 | @checkInput = setInt(0); 35 | 36 | if (@BTN_X) { 37 | printf("Mounting SYSTEM...") 38 | mmc_mount("SYSTEM") 39 | setString("systemSaves", $folder) 40 | @checkInput = setInt(1); 41 | } 42 | 43 | if (@BTN_Y) { 44 | printf("Mounting USER....") 45 | mmc_mount("USER") 46 | setString("userSaves", $folder) 47 | @checkInput = setInt(1); 48 | } 49 | 50 | if (@checkInput, == , 0){ 51 | exit() 52 | } 53 | 54 | combineStrings("sd:/tegraexplorer/", $folder, $path) 55 | 56 | fs_mkdir("sd:/tegraexplorer") 57 | fs_mkdir($path) 58 | 59 | printf("") 60 | printf("Copying saves to ", $path) 61 | printf("") 62 | @check = fs_copyRecursive("emmc:/save", $path) 63 | printf("") 64 | if (@check){ 65 | printf("Something went wrong! Errcode: ", @check) 66 | } 67 | if (@check, == , 0){ 68 | printf("Done, press any button to exit") 69 | } 70 | pause() 71 | exit() 72 | -------------------------------------------------------------------------------- /v1/systemRestore.te: -------------------------------------------------------------------------------- 1 | setString("BOOT0.bin", $BOOT0Path) 2 | setString("BOOT1.bin", $BOOT1Path) 3 | setString("BCPKG2-1-Normal-Main", $BCPKG1) 4 | setString("BCPKG2-2-Normal-Sub", $BCPKG2) 5 | setString("BCPKG2-3-SafeMode-Main", $BCPKG3) 6 | setString("BCPKG2-4-SafeMode-Sub", $BCPKG4) 7 | setString("Exit 8 | ", $menuoption1) 9 | setString("BOOT: ", $menuoption2) 10 | setString("SYSTEM: ", $menuoption3) 11 | setString(" 12 | SYSMMC", $menuoption4) 13 | if (@EMUMMC){ 14 | setString("EMUMMC", $menuoption5) 15 | } 16 | 17 | printf("System restore script") 18 | printf("") 19 | printf("Select what to restore") 20 | printf("And where to restore to") 21 | 22 | @selection = setInt(7) 23 | @restoreBOOT = setInt(1) 24 | @restoreSYS = setInt(1) 25 | @maxSelection = setInt(10) 26 | if (@EMUMMC){ 27 | @maxSelection = math(@maxSelection, "+", 1) 28 | } 29 | 30 | @optionLoop = getPosition() 31 | setPrintPos(0, 6) 32 | @current = setInt(7) 33 | 34 | @drawLoop = getPosition() 35 | 36 | setColor("WHITE") 37 | setStringIndex(@current, $toDraw) 38 | 39 | if (@current, "==", 8){ 40 | if (@restoreBOOT){ 41 | combineStrings($toDraw, "ON ", $toDraw) 42 | } 43 | if (@restoreBOOT, "==", 0){ 44 | combineStrings($toDraw, "OFF", $toDraw) 45 | } 46 | } 47 | 48 | if (@current, "==", 9){ 49 | if (@restoreSYS){ 50 | combineStrings($toDraw, "ON " , $toDraw) 51 | } 52 | if (@restoreSYS, "==", 0){ 53 | combineStrings($toDraw, "OFF", $toDraw) 54 | } 55 | } 56 | 57 | if (@selection, "==", @current){ 58 | setColor("VIOLET") 59 | } 60 | 61 | printf($toDraw) 62 | 63 | @current = math(@current, "+", 1) 64 | 65 | if (@current, "<=", @maxSelection){ 66 | goto(@drawLoop) 67 | } 68 | 69 | pause() 70 | 71 | if (@BTN_DOWN){ 72 | if (@selection, "<", @maxSelection){ 73 | @selection = math(@selection, "+", 1) 74 | } 75 | } 76 | 77 | if (@BTN_UP){ 78 | if (@selection, ">", 7){ 79 | @selection = math(@selection, "-", 1) 80 | } 81 | } 82 | 83 | if (@BTN_A, "==", 0){ 84 | goto(@optionLoop) 85 | } 86 | 87 | if (@selection, "==", 7){ 88 | exit() 89 | } 90 | 91 | if (@selection, "==", 8){ 92 | @restoreBOOT = invert(@restoreBOOT) 93 | goto(@optionLoop) 94 | } 95 | 96 | if (@selection, "==", 9){ 97 | @restoreSYS = invert(@restoreSYS) 98 | goto(@optionLoop) 99 | } 100 | 101 | clearscreen() 102 | setColor("WHITE") 103 | printf("System restore script") 104 | printf("") 105 | 106 | if (@restoreBOOT){ 107 | printf("BOOT: ON") 108 | } 109 | if (@restoreBOOT, "==", 0){ 110 | printf("BOOT: OFF") 111 | } 112 | if (@restoreSYS){ 113 | printf("SYSTEM: ON") 114 | } 115 | if (@restoreSYS, "==", 0){ 116 | printf("SYSTEM: OFF") 117 | } 118 | 119 | printf("Checking requirements...") 120 | printf("") 121 | 122 | if (@restoreSYS){ 123 | fs_combinePath($CURRENTPATH, "SYSTEM", $path) 124 | @check = fs_exists($path) 125 | @checkinv = invert(@check) 126 | if (@checkinv){ 127 | printf("System DIR not found!") 128 | printf("Press any button to exit") 129 | pause() 130 | exit() 131 | } 132 | } 133 | 134 | if (@restoreBOOT){ 135 | fs_combinePath($CURRENTPATH, "boot.bis", $path) 136 | @check = fs_exists($path) 137 | if (@check, "==", 0){ 138 | printf("boot.bis not found!") 139 | printf("Press any button to exit") 140 | pause() 141 | exit() 142 | } 143 | 144 | fs_mkdir("sd:/tegraexplorer") 145 | fs_mkdir("sd:/tegraexplorer/bisextract") 146 | fs_extractBisFile($path, "sd:/tegraexplorer/bisextract") 147 | } 148 | 149 | if (@selection, "==", 10){ 150 | printf("Mounting SYSMMC...") 151 | mmc_connect("SYSMMC") 152 | } 153 | if (@selection, "==", 11){ 154 | if (@EMUMMC, "==", 0){ 155 | exit() 156 | } 157 | printf("Mounting EMUMMC...") 158 | mmc_connect("EMUMMC") 159 | } 160 | 161 | printf("Ready!") 162 | 163 | setColor("RED") 164 | printf("") 165 | printf("WARNING!!!") 166 | printf("If you do not know exactly what this does. STOP!!!") 167 | printf("") 168 | printf("This will fuck with your system!") 169 | printf("Only do this as a last ditch recovery effort!") 170 | printf("") 171 | setColor("GREEN") 172 | printf("For help go here: https://discord.gg/C29hYvh") 173 | setColor("WHITE") 174 | printf("") 175 | wait(10) 176 | printf("X to continue") 177 | printf("Any other button to exit") 178 | 179 | pause() 180 | 181 | if (@BTN_X, "==", 0){ 182 | exit() 183 | } 184 | 185 | clearscreen() 186 | 187 | printf("GO!") 188 | if (@restoreBOOT){ 189 | printf("") 190 | printf("Restoring BIS") 191 | 192 | @i = setInt(1) 193 | @loop = getPosition() 194 | setStringIndex(@i, $part) 195 | combineStrings("sd:/tegraexplorer/bisextract/", $part, $path) 196 | mmc_restorePart($path) 197 | if (@RESULT){ 198 | setColor("RED") 199 | printf("Restoring went wrong!") 200 | printf("Part:") 201 | printf($part) 202 | pause() 203 | exit() 204 | } 205 | @i = math(@i, "+", 1) 206 | if (@i, "<", 7){ 207 | goto(@loop) 208 | } 209 | } 210 | 211 | if (@restoreSYS){ 212 | printf("") 213 | printf("Restoring SYSTEM") 214 | mmc_mount("SYSTEM") 215 | 216 | fs_combinePath($CURRENTPATH, "SYSTEM/Contents/registered", $path) 217 | 218 | fs_delRecursive("emmc:/Contents/registered") 219 | fs_copyRecursive($path, "emmc:/Contents") 220 | 221 | fs_combinePath($CURRENTPATH, "SYSTEM/save/8000000000000120", $path) 222 | 223 | fs_copy($path, "emmc:/save/8000000000000120") 224 | } 225 | 226 | printf("") 227 | printf("Done!") 228 | printf("Press any button to exit") 229 | pause() 230 | exit() -------------------------------------------------------------------------------- /v1/systemwipe.te: -------------------------------------------------------------------------------- 1 | printf("TegraScript system wiper") 2 | printf("") 3 | printf("Press A to wipe from SYSMMC") 4 | if (@EMUMMC){ 5 | printf("Press Y to wipe from EMUMMC") 6 | } 7 | printf("Press power to exit") 8 | printf("") 9 | 10 | pause() 11 | @checkInput = setInt(0); 12 | 13 | if (@BTN_A){ 14 | printf("Mounting SYSMMC...") 15 | mmc_connect("SYSMMC") 16 | @checkInput = setInt(1); 17 | } 18 | if (@BTN_Y){ 19 | if (@EMUMMC, == , 0){ 20 | exit() 21 | } 22 | printf("Mounting EMUMMC...") 23 | mmc_connect("EMUMMC") 24 | @checkInput = setInt(1); 25 | } 26 | 27 | if (@checkInput, == , 0){ 28 | exit() 29 | } 30 | 31 | mmc_mount("SYSTEM") 32 | 33 | if (@RESULT){ 34 | printf("System failed to mount!") 35 | pause() 36 | exit() 37 | } 38 | 39 | setString("emmc:/save/", $basePath) 40 | 41 | setColor("RED") 42 | printf("Are you sure you want to wipe everything?") 43 | printf("This includes:") 44 | printf("- Saves") 45 | printf("- Game Data") 46 | printf("- All other data on the system") 47 | printf("") 48 | printf("Use this only as a last resort!") 49 | printf("") 50 | 51 | setColor("YELLOW") 52 | wait(10) 53 | 54 | printf("Press X to continue") 55 | printf("Press any other button to exit") 56 | 57 | pause() 58 | 59 | if (@BTN_X, == , 0){ 60 | exit() 61 | } 62 | 63 | @count = setInt(1) 64 | printf("Deleting SYSTEM saves") 65 | 66 | fs_openDir("emmc:/save") 67 | setColor("RED") 68 | @LOOP = getPosition() 69 | fs_readDir() 70 | if (@ISDIRVALID){ 71 | combineStrings($basePath, $FILENAME, $path) 72 | 73 | setPrintPos(0, 20) 74 | 75 | @check = compareStrings($FILENAME, "8000000000000120") 76 | 77 | if (@check){ 78 | goto(@LOOP) 79 | } 80 | 81 | @check = compareStrings($FILENAME, "80000000000000d1") 82 | 83 | if (@check){ 84 | goto(@LOOP) 85 | } 86 | 87 | @check = compareStrings($FILENAME, "8000000000000047") 88 | 89 | if (@check){ 90 | goto(@LOOP) 91 | } 92 | 93 | @count = math(@count, "+", 1) 94 | printf(@count, ": ", $FILENAME) 95 | fs_del($path) 96 | 97 | goto(@LOOP) 98 | } 99 | 100 | printf("") 101 | printf("") 102 | printf("Deleting USER") 103 | 104 | mmc_mount("USER") 105 | 106 | if (@RESULT){ 107 | printf("User failed to mount!") 108 | pause() 109 | exit() 110 | } 111 | 112 | fs_delRecursive("emmc:/Album") 113 | fs_mkdir("emmc:/Album") 114 | 115 | fs_delRecursive("emmc:/Contents") 116 | fs_mkdir("emmc:/Contents") 117 | fs_mkdir("emmc:/Contents/placehld") 118 | fs_mkdir("emmc:/Contents/registered") 119 | 120 | fs_delRecursive("emmc:/save") 121 | fs_mkdir("emmc:/save") 122 | 123 | fs_delRecursive("emmc:/saveMeta") 124 | fs_mkdir("emmc:/saveMeta") 125 | 126 | fs_delRecursive("emmc:/temp") 127 | fs_mkdir("emmc:/temp") 128 | 129 | setColor("GREEN") 130 | printf("") 131 | printf("") 132 | printf("Done! press any key to exit") 133 | 134 | pause() 135 | exit() -------------------------------------------------------------------------------- /v2/README.md: -------------------------------------------------------------------------------- 1 | # TegraScript 2 | The scripting language of TegraExplorer 3 | 4 | Notice: TegraScript v2 is entirely different than v1. If you still have v1 scripts, you'll have to rewrite them. 5 | 6 | Included in this repository: 7 | - [fwdump.te](https://suchmememanyskill.github.io/TegraScript/scripts/fwDump.te) dumps the firmware with the actual firmware version as it's name 8 | - [systemRestore.te](https://suchmememanyskill.github.io/TegraScript/scripts/systemRestore.te) restores the output of [emmchaccgen](https://github.com/suchmememanyskill/EmmcHaccGen). Place the generated boot.bis and SYSTEM directory next to this script 9 | - [systemwipe.te](https://suchmememanyskill.github.io/TegraScript/scripts/systemwipe.te) is essentially a 'factory reset'. This will wipe everything off the switch and make it boot up like it was fresh out of the box. Error (eprt) reports are kept, so this is not safe to use with sxos. 10 | 11 | Any of this scripts can be ran by putting them on the sd, then inside tegraexplorer navigating to the sd, selecting the file and running it. 12 | 13 | ## General Syntax 14 | 15 | ### Variables 16 | 17 | Variables in TegraScript do not need explicit type definitions: 18 | ``` 19 | variable = function(arg1, arg2) # this calls function with 2 arguments: arg1 and arg2, and stores it in variable 20 | ``` 21 | 22 | Variables can be of the following types: 23 | - Integer 24 | - String 25 | - Integer Array 26 | - String Array 27 | - Byte Array 28 | - Empty Array 29 | 30 | Creating and accessing Array variables goes as follows: 31 | ``` 32 | variable = [1,2,3,4,5] # This creates an integer array and stores it into variable 33 | function(variable[2]) # This calls function with 1 argument, index 2 of variable, which is 3 34 | ``` 35 | 36 | In tegrascript, operations are evaluated from left to right. This is important for math type operations. See the operator section for what type definitions you can put operators against. As a quick primer: 37 | ``` 38 | variable = 2 + 2 * 2 # This puts 8 into variable, as the calculations get evaluated from left to right 39 | variable = 2 + (2 * 2) # But! we can also use brackets to prioritise calculations 40 | variable = "a" + "b" # Adding 2 strings together is also a supported operator 41 | ``` 42 | 43 | Note: Minus integer values are supported this time around 44 | 45 | Another note: You can do !variable to flip the integer inside 46 | 47 | Another another note: Every object in TScript is not a reference type! every time you try to modify an array it re-makes the array. In practise array operations are slow 48 | 49 | Every variable in TegraScript v2 is global, thus you can access any variable in any self-defined function 50 | 51 | ### Built in variables 52 | 53 | TegraScript has 2 built in variables. 54 | - `_CWD`, which is a string, and represents the current working directory, thus the directory the currently running script is in. 55 | - `_EMU`, which is an int, and represents if an emummc is present. 1 for present, 0 for not present 56 | 57 | When running `dirRead()` as a function, besides returning a list of filenames, also sets an integer array called `fileProperties` that holds if the representing index of the filenames is a folder or not. 1 for a folder, 0 for a file 58 | 59 | ### Functions 60 | 61 | TegraScript has support for functions 62 | 63 | Defining and using a function goes as follows: 64 | ``` 65 | function = { # We are defining a function called function here, with the {} 66 | # We put the code we want to run inside the function here 67 | var = 1 + 2 + 3 68 | } 69 | 70 | function() # after running this, variable will be set to 6 71 | ``` 72 | 73 | But you may see an issue: there are no arguments! Fear not, as every variable in TegraScript is global. You can thus solve it with the following syntax: 74 | ``` 75 | function = { 76 | b = a * 2 # We want to multiply a by 2 and put it into b, but how do we define a? 77 | } 78 | 79 | function(a = 10) # Ah! We can just define it in the function args 80 | 81 | a = 20 82 | function() # Or if you prefer, you can define it normally as well 83 | ``` 84 | 85 | ### Flow control 86 | 87 | TegraScript has the following functions for flow control: `if()`, `else()`, `while()`, `return()`, `exit()` 88 | 89 | - `if()` checks it's first arg, if it's 1, it runs the next {}, otherwise it skips over it 90 | - `else()` checks if the last statement was an if, and if that if skipped, we run the next {} 91 | - `while()` checks it's first arg, if it's 1, it runs the next {}, and jumps back to the while 92 | - `return()` exits the current running function, if there is one 93 | - `exit()` exits the script entirely 94 | 95 | Let's try to build a loop that iterates 30 times, and printing even numbers 96 | ``` 97 | i = 0 98 | while (i < 30){ # check if i is below 30, if so, run the code between the brackets 99 | if (i % 2 == 0){ # is i dividable by 2? 100 | println(i) 101 | } 102 | 103 | i = i + 1 # don't forget the + 1 of i! otherwise an infinite loop will haunt you 104 | } 105 | ``` 106 | 107 | ## Operators 108 | 109 | ### Integer, Integer 110 | Operator | Output 111 | |:-|:-| 112 | `+` | sum of both integers 113 | `-` | integer minus integer 114 | `*` | multiplication of both integers 115 | `/` | integer divided by integer 116 | `%` | integer division remainder (modulo) of integer 117 | `<` | 1 if left is smaller, otherwise 0 118 | `>` | 1 if left is bigger, otherwise 0 119 | `<=`| 1 if left is smaller or equal, otherwise 0 120 | `>=`| 1 if left is bigger or equal, otherwise 0 121 | `==`| 1 if left and right are equal, otherwise 0 122 | `!=`| 1 if left and right are not equal, otherwise 0 123 | `&&`| 1 if left and right are non 0, otherwise 0. Also if output is 0, disregards rest of statement 124 | `\|\|`| 1 if left or right are non 0, otherwise 0. Also if output is 1, disregards rest of statement 125 | `&` | Binary operator. ANDs both integers together 126 | `\|` | Binary operator. ORs both integers together 127 | `<<`| Binary operator. Bitshifts the left integer to the left by right integer's amount 128 | `>>`| Binary operator. Bitshifts the left integer to the right by right integer's amount 129 | 130 | ### String, String 131 | Operator | Output 132 | |:-|:-| 133 | `+` | Adds both strings together 134 | `==`| 1 if strings are equal, otherwise 0 135 | `-` | Removes the end of the first string if the second string matches the end of the first. (Example: `"abcdef" - "def"` is `"abc"`) 136 | `/` | Splits the left string based on the right string. Returns a string array 137 | 138 | ### (Integer Array, Byte Array), Integer 139 | Operator | Output 140 | |:-|:-| 141 | `+` | Adds the right integer into the left array 142 | `-` | Removes right integer amount of entries from the left array 143 | `:` | Removes right integer amount of entries from the beginning of the left array 144 | 145 | ### String, Integer 146 | Operator | Output 147 | |:-|:-| 148 | `-` | Removes right integer amount of characters from the left string 149 | `:` | Removes right integer amount of character from the beginning of the left string 150 | 151 | ### StringArray, String 152 | Operator | Output 153 | |:-|:-| 154 | `+` | Adds a string to an array 155 | 156 | ### EmptyArray, (String, Int) 157 | Operator | Output 158 | |:-|:-| 159 | `+` | Creates the array of the right type and puts the given value as the first entry 160 | 161 | ## Functions 162 | 163 | ### Flow control functions 164 | Name | Description | OutType 165 | |:-|:-|:-| 166 | `if(int arg)` | Runs the next {} if arg is non zero | None 167 | `else()` | Runs the next {} if the last statement was an if that skipped their {} | None 168 | `while(int arg)` | Runs the next {} if arg is non zero. Jumps to the if after exiting the {} | None 169 | `return()` | Breaks out of a function | None 170 | `exit()` | Exits the current script | None 171 | 172 | ### Utilities 173 | Name | Description | OutType 174 | |:-|:-|:-| 175 | `print(...)` | Prints all args provided to the screen. Can print Integer, String, IntegerArray. `\r` and `\n` is supported | None 176 | `println(...)` | Same as `print(...)` but puts a newline at the end | None 177 | `color(string color)`| Sets the print color. Supported inputs: `"RED"`, `"ORANGE"`, `"YELLOW"`, `"GREEN"`, `"BLUE"`, `"VIOLET"`, `"WHITE"` | None 178 | `len(var arg1)` | Gets the length of a string or an array | Integer 179 | `byte(IntegerArray arg1)`| Converts an integer array to a byte one | ByteArray 180 | `bytesToStr(ByteArray arg1)`| Converts a byte array to a string | String 181 | `printPos(int x, int y)` | Sets the printing position on screen. X/Y are in whole character sizes (16x16) | None 182 | `clearscreen()` | Clears the screen full of your nonsense | None 183 | `drawBox(int x1, int y1, int x2, int y2, int color)` | Draws a box from x1/y1 to x2/y2 with the color as color (raw: 0x00RRGGBB) | None 184 | `wait(int ms)` | Waits for ms amount | None 185 | `pause()` | Pauses until controller input is detected. Returns the controller input as raw u32 bitfield | Integer 186 | `version()` | Returns an Integer array of the current TE version | IntegerArray 187 | `menu(StringArray options, int startPos)` | Makes a menu with the cursor at startPos, with the provided options. Returns the current pos when a is pressed. B always returns 0 | Integer 188 | `menu(StringArray options, int startPos, StringArray colors)` | Same as above, but the entries now get colors defined by the colors array. Uses the same colors as the `colors()` function | Integer 189 | `menu(StringArray options, int startPos, StringArray colors, IntegerArray modifier)` | Same as above, but entries can be hidden or skipped defined by the modifier array. 0 for normal, 1 for skip, 2 for hide | Integer 190 | 191 | Note about `pause()`. You need to work with raw bitfields. Have an example 192 | ``` 193 | # The most common controls 194 | JoyY = 0x1 195 | JoyX = 0x2 196 | JoyB = 0x4 197 | JoyA = 0x8 198 | 199 | LeftJoyDown = 0x10000 200 | LeftJoyUp = 0x20000 201 | LeftJoyRight = 0x40000 202 | LeftJoyLeft = 0x80000 203 | 204 | if (pause() & JoyX){ 205 | println("X has been pressed!") 206 | } 207 | ``` 208 | 209 | ### FileSystem functions 210 | Name | Description | OutType 211 | |:-|:-|:-| 212 | `fileRead(string path)` | Reads the file at the given path and returns it's contents in a byte array | ByteArray 213 | `fileWrite(string path, ByteArray data)` | Writes data to the given path. Returns non zero on error | Integer 214 | `fileExists(string path)` | Checks if a file or folder exists at the given path. 1 if yes, otherwise 0 | Integer 215 | `fileMove(string src, string dst)` | Moves a file from src to dst. Returns non zero on error | Integer 216 | `fileCopy(string src, string dst)` | Copies a file from src to dst. Returns non zero on error | Integer 217 | `fileDel(string path)` | Deletes the file located at path. Returns non zero on error | Integer 218 | `pathCombine(...)` | Needs 2+ string args as input. Combines them into a path. First entry must be the source folder Example: `pathCombine("sd:/", "tegraexplorer")` -> `"sd:/tegraexplorer"` | String 219 | `pathEscFolder(string path)`| Escapes a folder path. Example: `pathEscFolder("sd:/tegraexplorer")` -> `"sd:/"` | String 220 | `dirRead(string path)` | Reads a folder and returns a StringArray of filenames. Also creates an IntegerArray called `fileProperties` that is the same length as the filenames, and is non zero if the index of the filename is a folder | StringArray 221 | `dirCopy(string src, string dst)`| Copies a folder from src to dst. Dst needs to be the containing folder of where you want src to go (`"sd:/tegraexplorer", "sd:/backup` -> `"sd:/backup/tegraexplorer"`). Returns non zero on error | Integer 222 | `dirDel(string path)` | Deletes the dir located at path. Returns non zero on error | Integer 223 | `mkdir(string path)` | Makes a directory at path | Integer 224 | `launchPayload(string path)`| Launches the payload at the given path. Returns non zero on error | Integer 225 | 226 | ### Storage functions !! Dangerous 227 | Name | Description | OutType 228 | |:-|:-|:-| 229 | `mmcConnect(string loc)` | Loc can be `"SYSMMC"` or `"EMUMMC"`. Returns non zero on error | Integer 230 | `mmcMount(string loc)` | Loc can be `"PRODINFOF"`, `"SAFE"`, `"SYSTEM"` and `"USER"`. Mounts the filesystem to the prefix `bis:/`. Returns non zero on error | Integer 231 | `mmcDump(string path, string target)`| Dumps target to path. target can be anything in the EMMC menu in TE. Returns non zero on error | Integer 232 | `mmcRestore(string path, string target, int force)`| Restores path to target. target can be anything in the EMMC menu in TE. Force forces smaller files to flash anyway. Returns non zero on error | Integer 233 | `ncaGetType(string path)`| Returns the type of nca that is in path. Make sure you provide an nca and nothing else! Useful for differentiating between Meta and Non-Meta Nca's | Integer 234 | `saveSign(string path)` | Signs the (system) save at the given location. Make sure you provide a save and nothing else! Returns non zero on error | Integer 235 | 236 | # Changelog 237 | ### 11/1/2021 @ 22:10 // Wow it isn't 2am for once! 238 | 239 | For the release of TE 3.0.1, the following changes were made: 240 | - A new type was added: Empty array type. You can get this type by running `var = []` 241 | - Operators were added for StringArray, String and EmptyArray, (String, Integer) 242 | - launchPayload was added as a function 243 | - Menu now allows for an additional integer array to define hidden or skip flags 244 | - A bug was fixed with <= and >= registering as < and > 245 | - fileCopy's should not leave an ugly [ anymore 246 | - A script now get executed at TE bootup if a script called `startup.te` is found on the root of the SD 247 | 248 | ### 5/1/2021 @ 1:32am // Sleep is still a lie 249 | 250 | - Initial writeup on TScript v2 251 | -------------------------------------------------------------------------------- /v2/scripts/fwDump.te: -------------------------------------------------------------------------------- 1 | versionNcas = ["9d9d83d68d9517f245f3e8cd7f93c416.nca","a1863a5c0e1cedd442f5e60b0422dc15.nca","63d928b5a3016fe8cc0e76d2f06f4e98.nca","e65114b456f9d0b566a80e53bade2d89.nca","bd4185843550fbba125b20787005d1d2.nca","56211c7a5ed20a5332f5cdda67121e37.nca","594c90bcdbcccad6b062eadba0cd0e7e.nca","4e43d8b63713039fd87b410e7e1422c2.nca","a7b99eb98d2113824d2b87bce12527ba.nca","c07c0ffb0a2c3155a7ecf2f5b3a28bb6.nca","34728c771299443420820d8ae490ea41.nca","5b1df84f88c3334335bbb45d8522cbb4.nca","e951bc9dedcd54f65ffd83d4d050f9e0.nca","36ab1acf0c10a2beb9f7d472685f9a89.nca","5625cdc21d5f1ca52f6c36ba261505b9.nca","09ef4d92bb47b33861e695ba524a2c17.nca","c5fbb49f2e3648c8cfca758020c53ecb.nca","fd1ffb82dc1da76346343de22edbc97c.nca","a6af05b33f8f903aab90c8b0fcbcc6a4.nca","7eedb7006ad855ec567114be601b2a9d.nca","6c5426d27c40288302ad616307867eba.nca","4fe7b4abcea4a0bcc50975c1a926efcb.nca","e6b22c40bb4fa66a151f1dc8db5a7b5c.nca","c613bd9660478de69bc8d0e2e7ea9949.nca","6dfaaf1a3cebda6307aa770d9303d9b6.nca","1d21680af5a034d626693674faf81b02.nca","663e74e45ffc86fbbaeb98045feea315.nca","258c1786b0f6844250f34d9c6f66095b.nca","286e30bafd7e4197df6551ad802dd815.nca","fce3b0ea366f9c95fe6498b69274b0e7.nca","c5758b0cb8c6512e8967e38842d35016.nca","7f5529b7a092b77bf093bdf2f9a3bf96.nca","faa857ad6e82f472863e97f810de036a.nca","77e1ae7661ad8a718b9b13b70304aeea.nca","d0e5d20e3260f3083bcc067483b71274.nca","f99ac61b17fdd5ae8e4dda7c0b55132a.nca","704129fc89e1fcb85c37b3112e51b0fc.nca","9a78e13d48ca44b1987412352a1183a1.nca","7bef244b45bf63efb4bf47a236975ec6.nca","d1c991c53a8a9038f8c3157a553d876d.nca","7f90353dff2d7ce69e19e07ebc0d5489.nca","e9b3e75fce00e52fe646156634d229b4.nca","7a1f79f8184d4b9bae1755090278f52c.nca","a1b287e07f8455e8192f13d0e45a2aaf.nca"] 2 | exfatNcas = ["25bb90ed24664b791d0e2cc1b707ea30.nca","1334ffa781ecd54085931da55339ed84.nca","77bbe586d5b4bfe8fee7a2a10936716f.nca","22f8b6e12000aa530c1d301b5ed4d70a.nca","22f8b6e12000aa530c1d301b5ed4d70a.nca","0fd89afc0d0f1ee7021084df503bcc19.nca","c70785465de83c7feed3ae28139b5063.nca","be8a259f84590c0ad9aa78312ed1e9fe.nca","3df13daa7f553c8fa85bbff79a189d6c.nca","3df13daa7f553c8fa85bbff79a189d6c.nca","d5bc167565842ee61f9670d23759844d.nca","d5bc167565842ee61f9670d23759844d.nca","d5bc167565842ee61f9670d23759844d.nca","d5bc167565842ee61f9670d23759844d.nca","d5bc167565842ee61f9670d23759844d.nca","2416b3794964b3482c7bc506d12c44df.nca","c9bd4eda34c91a676de09951bb8179ae.nca","3b444768f8a36d0ddd85635199f9676f.nca","3b444768f8a36d0ddd85635199f9676f.nca","96f4b8b729ade072cc661d9700955258.nca","b2708136b24bbe206e502578000b1998.nca","b2708136b24bbe206e502578000b1998.nca","02a2cbfd48b2f2f3a6cec378d20a5eff.nca","58c731cdacb330868057e71327bd343e.nca","97cb7dc89421decc0340aec7abf8e33b.nca","d5186022d6080577b13f7fd8bcba4dbb.nca","d5186022d6080577b13f7fd8bcba4dbb.nca","d5186022d6080577b13f7fd8bcba4dbb.nca","711b5fc83a1f07d443dfc36ba606033b.nca","c9e500edc7bb0fde52eab246028ef84c.nca","432f5cc48e6c1b88de2bc882204f03a1.nca","432f5cc48e6c1b88de2bc882204f03a1.nca","432f5cc48e6c1b88de2bc882204f03a1.nca","458a54253f9e49ddb044642286ca6485.nca","090b012b110973fbdc56a102456dc9c6.nca","090b012b110973fbdc56a102456dc9c6.nca","e7dd3c6cf68953e86cce54b69b333256.nca","17f9864ce7fe3a35cbe3e3b9f6185ffb.nca","9e5c73ec938f3e1e904a4031aa4240ed.nca","4a94289d2400b301cbe393e64831f84c.nca","4a94289d2400b301cbe393e64831f84c.nca","4a94289d2400b301cbe393e64831f84c.nca","f55a04978465ebf5666ca93e21b26dd2.nca","3b7cd379e18e2ee7e1c6d0449d540841.nca"] 3 | versionNames = ["12.1.0","12.0.3","12.0.2","12.0.1","12.0.0","11.0.1","11.0.0","10.2.0","10.1.1","10.1.0","10.0.4","10.0.3","10.0.2","10.0.1","10.0.0","9.2.0","9.1.0","9.0.1","9.0.0","8.1.0","8.0.1","8.0.0","7.0.1","7.0.0","6.2.0","6.1.0","6.0.1","6.0.0","6.0.0(pre-release)","5.1.0","5.0.2","5.0.1","5.0.0","4.1.0","4.0.1","4.0.0","3.0.2","3.0.1","3.0.0","2.3.0","2.2.0","2.1.0","2.0.0","1.0.0"] 4 | 5 | # check tid = 0100000000000809, type data 6 | # exfat tid = 010000000000081B, type data 7 | 8 | println("Tegrascript firmware checker/dumper\n") 9 | 10 | if (_EMU) { 11 | menuOptions = ["Exit", "Sysmmc", "Emummc"] 12 | } 13 | else() { 14 | menuOptions = ["Exit", "Sysmmc"] 15 | } 16 | 17 | print("Check on: ") 18 | res = menu(menuOptions, 0) 19 | 20 | clearscreen() 21 | 22 | if (res == 0){ 23 | exit() 24 | } 25 | 26 | if (res == 1){ 27 | println("Mounting Sysmmc") 28 | mount = mmcConnect("SYSMMC") 29 | } 30 | 31 | if (res == 2){ 32 | println("Mounting Emummc") 33 | mount = mmcConnect("EMUMMC") 34 | } 35 | 36 | if (mount){ 37 | println("Error connecting mmc!") 38 | pause() 39 | exit() 40 | } 41 | 42 | if (mmcMount("SYSTEM")) { 43 | println("Failed to mount SYSTEM") 44 | pause() 45 | exit() 46 | } 47 | 48 | i = 0 49 | found = 0 50 | while (!found && (i < len(versionNcas))){ 51 | if (fileExists(pathCombine("bis:/Contents/registered", versionNcas[i]))){ 52 | found = 1 53 | } 54 | 55 | i = i + 1 56 | } 57 | 58 | i = i - 1 59 | 60 | if (!found){ 61 | println("Firmware not found. Exiting!") 62 | pause() 63 | exit() 64 | } 65 | 66 | exfat = fileExists(pathCombine("bis:/Contents/registered", exfatNcas[i])) 67 | fwName = versionNames[i] 68 | if (exfat){ 69 | fwName = fwName + "_exFAT" 70 | } 71 | 72 | println("\nFirmware found!\nRunning ", fwName) 73 | println("\nPress X to dump the current firmware, any other key to exit") 74 | button = pause() & 0x2 75 | if (!button){ 76 | exit() 77 | } 78 | 79 | start = timerMs() 80 | println("Starting dump...\n") 81 | color("GREEN") 82 | 83 | baseSdPath = pathCombine("sd:/tegraexplorer/Firmware", fwName) 84 | mkdir("sd:/tegraexplorer") 85 | mkdir("sd:/tegraexplorer/Firmware") 86 | mkdir(baseSdPath) 87 | files = dirRead("bis:/Contents/registered") 88 | 89 | i = 0 90 | filesLen = len(files) 91 | while (i < filesLen){ 92 | path = pathCombine("bis:/Contents/registered", files[i]) 93 | if (fileProperties[i]){ 94 | path = pathCombine(path, "00") 95 | } 96 | 97 | sdPath = pathCombine(baseSdPath, files[i]) 98 | 99 | if (ncaGetType(path) == 1){ 100 | sdPath = sdPath - ".nca" + ".cnmt.nca" 101 | } 102 | 103 | print("\r[", i + 1, " / ", filesLen, "] ", files[i]) 104 | 105 | if (fileCopy(path, sdPath)) { 106 | color("RED") 107 | println("\nError during copy. Exiting!") 108 | pause() 109 | exit() 110 | } 111 | 112 | i = i + 1 113 | } 114 | 115 | color("WHITE") 116 | println("\n\nDone! took ", (timerMs() - start) / 1000, "s") 117 | pause() 118 | -------------------------------------------------------------------------------- /v2/scripts/systemRestore.te: -------------------------------------------------------------------------------- 1 | readNext = { 2 | next = all - (len(all) - readAmount) 3 | all = all : readAmount 4 | } 5 | 6 | getInt = { 7 | resInt = (next[0] << 24) | (next[1] << 16) | (next[2] << 8) | (next[3]) 8 | } 9 | 10 | getNextInt = { 11 | readAmount = 4 12 | readNext() 13 | getInt() 14 | } 15 | 16 | extractBis = { 17 | path = pathCombine(_CWD, "boot.bis") 18 | all = fileRead(path) 19 | readAmount = 0x10 20 | readNext() 21 | 22 | bisver = bytesToStr(next) 23 | 24 | readAmount = 1 25 | readNext() 26 | # println(next[0]) 27 | 28 | sizes = [0, 0, 0, 0] 29 | files = ["BOOT0.bin", "BOOT1.bin", "BCPKG2-1-Normal-Main", "BCPKG2-3-SafeMode-Main"] 30 | 31 | i = 0 32 | while (i < 4) { 33 | getNextInt() 34 | sizes[i] = resInt 35 | i = i + 1 36 | } 37 | 38 | # println(sizes) 39 | 40 | i = 0 41 | while (i < 4) { 42 | readAmount = sizes[i] 43 | readNext() 44 | res = fileWrite(pathCombine(_CWD, files[i]), next)) 45 | if (res){ 46 | return() 47 | } 48 | i = i + 1 49 | } 50 | 51 | res = fileCopy(pathCombine(_CWD, "BCPKG2-1-Normal-Main"), pathCombine(_CWD, "BCPKG2-2-Normal-Sub")) 52 | if (!res){ 53 | res = fileCopy(pathCombine(_CWD, "BCPKG2-3-SafeMode-Main"), pathCombine(_CWD, "BCPKG2-4-SafeMode-Sub")) 54 | } 55 | } 56 | 57 | restoreBis = { 58 | toRestoreFiles = ["BOOT0.bin", "BOOT1.bin", "BCPKG2-1-Normal-Main", "BCPKG2-2-Normal-Sub", "BCPKG2-3-SafeMode-Main", "BCPKG2-4-SafeMode-Sub"] 59 | i = 0 60 | color("GREEN") 61 | while (i < len(toRestoreFiles)){ 62 | print("Restoring ", toRestoreFiles[i], "... ") 63 | res = mmcRestore(pathCombine(_CWD, toRestoreFiles[i]), toRestoreFiles[i], 1) 64 | if (res){ 65 | color("RED") 66 | print("An error occured! ", res) 67 | return() 68 | } 69 | println() 70 | i = i + 1 71 | } 72 | color("WHITE") 73 | } 74 | 75 | restoreSystem = { 76 | color("RED") 77 | print("Deleting SYSTEM contents... ") 78 | if (dirDel("bis:/Contents/registered")){ 79 | println("\nAn error occured during deletion!") 80 | return() 81 | } 82 | println() 83 | 84 | color("GREEN") 85 | print("Copying registered... ") 86 | if (dirCopy(pathCombine(_CWD, "SYSTEM/Contents/registered"), "bis:/Contents")) { 87 | println("\nAn error occured during copying!") 88 | return() 89 | } 90 | println() 91 | 92 | color("BLUE") 93 | print("Copying 120 save...") 94 | if (fileCopy(pathCombine(_CWD, "SYSTEM/save/8000000000000120"), "bis:/save/8000000000000120")) { 95 | println("\nFailed to copy system save") 96 | } 97 | println() 98 | 99 | color("WHITE") 100 | } 101 | 102 | signSave = { 103 | print("Signing 120 save... ") 104 | if (saveSign("bis:/save/8000000000000120")){ 105 | println("\nSave sign failed!") 106 | pause() 107 | exit() 108 | } 109 | else(){ 110 | println("Done!") 111 | } 112 | } 113 | 114 | 115 | 116 | origOptions = ["Boot", "System", "Save Sign"] 117 | SystemRestore = 1 118 | BisRestore = 1 119 | SaveSign = 0 120 | 121 | menuOptions = ["Exit", "\n-- Options: --", "Boot.bis not found...", "SYSTEM dir not found...", "", "\n-- Restore to --", "SYSMMC", "EMUMMC"] 122 | menuColors = ["WHITE", "VIOLET", "BLUE", "BLUE", "BLUE", "VIOLET", "YELLOW", "YELLOW"] 123 | menuBits = [0, 1, 1, 1, 0, 1, 0, 0] 124 | 125 | setMenuOptions = { 126 | if (!menuBits[2]) { 127 | if (BisRestore){ 128 | menuOptions[2] = origOptions[0] + ": ON" 129 | } 130 | else() { 131 | menuOptions[2] = origOptions[0] + ": OFF" 132 | } 133 | } 134 | 135 | if (!menuBits[3]) { 136 | if (SystemRestore){ 137 | menuOptions[3] = origOptions[1] + ": ON" 138 | } 139 | else() { 140 | menuOptions[3] = origOptions[1] + ": OFF" 141 | } 142 | } 143 | 144 | if (SaveSign){ 145 | menuOptions[4] = origOptions[2] + ": ON" 146 | } 147 | else() { 148 | menuOptions[4] = origOptions[2] + ": OFF" 149 | } 150 | } 151 | 152 | if (!fileExists(pathCombine(_CWD, "boot.bis"))) { 153 | println("[WARN] boot.bis not found!") 154 | BisRestore = 0 155 | } 156 | else() { 157 | menuBits[2] = 0 158 | } 159 | 160 | if (!fileExists(pathCombine(_CWD, "SYSTEM"))) { 161 | println("[WARN] SYSTEM dir not found!") 162 | SystemRestore = 0 163 | } 164 | else() { 165 | menuBits[3] = 0 166 | } 167 | 168 | if (_EMU){ 169 | menuBits[7] = 0 170 | } 171 | else() { 172 | menuBits[7] = 2 173 | } 174 | 175 | 176 | println("\n-- System Restore Script --\n\n") 177 | 178 | res = 0 179 | while (res < 6){ 180 | printPos(0, 5) 181 | setMenuOptions() 182 | res = menu(menuOptions, res, menuColors, menuBits) 183 | 184 | if (res == 0){ 185 | exit() 186 | } 187 | 188 | if (res == 2){ 189 | BisRestore = !BisRestore 190 | } 191 | 192 | if (res == 3){ 193 | SystemRestore = !SystemRestore 194 | } 195 | 196 | if (res == 4){ 197 | SaveSign = !SaveSign 198 | } 199 | } 200 | 201 | clearscreen() 202 | 203 | if (res == 6){ 204 | println("Mounting SYS") 205 | if (mmcConnect("SYSMMC")){ 206 | println("An error occured during mmc connect!") 207 | pause() 208 | exit() 209 | } 210 | } 211 | 212 | if (res == 7){ 213 | println("Mounting EMU") 214 | if (mmcConnect("EMUMMC")){ 215 | println("An error occured during mmc connect!") 216 | pause() 217 | exit() 218 | } 219 | } 220 | 221 | if (BisRestore){ 222 | print("Extracting bis... ") 223 | extractBis() 224 | if (res){ 225 | println("\nError while extracting bis...") 226 | pause() 227 | exit() 228 | } 229 | else(){ 230 | println(" Done!\nExtracted version: ", bisver) 231 | } 232 | } 233 | 234 | 235 | println("\n\nReady!\n") 236 | 237 | color("RED") 238 | print("WARNING!!!\nIf you do not know exactly what this does. STOP!!!\nThis will fuck with your system!\nOnly do this as a last ditch recovery effort!\n") 239 | color("GREEN") 240 | println("For help go here: https://discord.gg/C29hYvh\n") 241 | color("WHITE") 242 | wait(10000) 243 | println("X to continue \nAny other button to exit") 244 | 245 | if (!(pause() & 0x2)){ 246 | exit() 247 | } 248 | 249 | clearscreen() 250 | println("GO!\n") 251 | 252 | if (BisRestore){ 253 | restoreBis() 254 | } 255 | 256 | println() 257 | 258 | if (mmcMount("SYSTEM")){ 259 | println("Failed to mount system!") 260 | pause() 261 | exit() 262 | } 263 | 264 | if (SystemRestore){ 265 | restoreSystem() 266 | } 267 | 268 | if (SaveSign) { 269 | signSave() 270 | } 271 | 272 | println("\n\nDone!\nPress any button to exit") 273 | pause() -------------------------------------------------------------------------------- /v2/scripts/systemwipe.te: -------------------------------------------------------------------------------- 1 | checkIfImportantSave = { 2 | importantSaves = ["8000000000000120", "80000000000000d1", "8000000000000047"] 3 | j = 0 4 | important = 0 5 | while (j < len(importantSaves)){ 6 | if (importantSaves[j] == save){ 7 | important = 1 8 | } 9 | 10 | j = j + 1 11 | } 12 | } 13 | 14 | ver = version() 15 | 16 | println("Tegrascript system wiper") 17 | println("Running on TE ", ver) 18 | println() 19 | 20 | BTN_X = 0x2 21 | 22 | if (_EMU) { 23 | menuOptions = ["Exit", "Sysmmc", "Emummc"] 24 | } 25 | else() { 26 | menuOptions = ["Exit", "Sysmmc"] 27 | } 28 | 29 | print("Wipe from: ") 30 | res = menu(menuOptions, 0) 31 | 32 | clearscreen() 33 | 34 | if (res == 0){ 35 | exit() 36 | } 37 | 38 | if (res == 1){ 39 | println("Mounting Sysmmc") 40 | mount = mmcConnect("SYSMMC") 41 | } 42 | 43 | if (res == 2){ 44 | println("Mounting Emummc") 45 | mount = mmcConnect("EMUMMC") 46 | } 47 | 48 | if (mount){ 49 | println("Error connecting mmc!") 50 | pause() 51 | exit() 52 | } 53 | 54 | if (mmcMount("SYSTEM")) { 55 | println("Failed to mount SYSTEM") 56 | pause() 57 | exit() 58 | } 59 | 60 | color("RED") 61 | println("Are you sure you want to wipe everything?\nThis includes:\n- Saves\n- Game Data\n- All other data on the system\n\nUse this only as a last resort!") 62 | color("YELLOW") 63 | wait(10000) 64 | 65 | println("Press X to continue\nPress any other button to exit") 66 | 67 | start = pause() & BTN_X 68 | if (!start){ 69 | color("WHITE") 70 | exit() 71 | } 72 | 73 | color("WHITE") 74 | println("Deleting SYSTEM saves") 75 | files = dirRead("bis:/save") 76 | 77 | i = 0 78 | color("RED") 79 | while (i < len(files)) { 80 | if (!fileProperties[i]){ # checks if it's not a file 81 | save = files[i] 82 | checkIfImportantSave() 83 | if (!important){ 84 | print("\rDeleting ", save) 85 | res = fileDel(pathCombine("bis:/save", save)) 86 | if (res) { 87 | println("\nFile deletion failed!") 88 | pause() 89 | exit() 90 | } 91 | } 92 | } 93 | 94 | i = i + 1 95 | } 96 | 97 | color("WHITE") 98 | println("\n\nDeleting USER\n") 99 | color("RED") 100 | 101 | if (mmcMount("USER")){ 102 | println("Failed to mount USER") 103 | pause() 104 | exit() 105 | } 106 | 107 | toDel = ["Album", "Contents", "save", "saveMeta", "temp"] 108 | 109 | i = 0 110 | while (i < len(toDel)){ 111 | dirDel(pathCombine("bis:/", toDel[i])) 112 | mkdir(pathCombine("bis:/", toDel[i])) 113 | 114 | i = i + 1 115 | } 116 | 117 | mkdir("bis:/Contents/placehld") 118 | mkdir("bis:/Contents/registered") 119 | 120 | color("GREEN") 121 | println("\n\nDone!") 122 | pause() --------------------------------------------------------------------------------