diff --git a/GeckoLoader.py b/GeckoLoader.py index 0de4f31..9a3afca 100644 --- a/GeckoLoader.py +++ b/GeckoLoader.py @@ -36,7 +36,7 @@ except ImportError: TRED = '' TREDLIT = '' -__version__ = 'v5.3.0' +__version__ = 'v6.0.0' def resource_path(relative_path: str): """ Get absolute path to resource, works for dev and for PyInstaller """ @@ -68,31 +68,31 @@ if __name__ == "__main__": help='Define where geckoloader is injected in hex', metavar='ADDRESS') parser.add_argument('-m', '--movecodes', - help='''Choose if geckoloader moves the codes to OSArenaHi, + help='''["AUTO", "LEGACY", "ARENA"] Choose if geckoloader moves the codes to OSArenaHi, or the legacy space. Default is "AUTO", which auto decides where to insert the codes''', default='AUTO', choices=['AUTO', 'LEGACY', 'ARENA'], metavar='TYPE') parser.add_argument('-tc', '--txtcodes', - help='''What codes get parsed when a txt file is used. + help='''["ACTIVE", "ALL"] What codes get parsed when a txt file is used. "ALL" makes all codes get parsed, - "ACTIVE" makes only activated codes get parsed.''', - default='active', + "ACTIVE" makes only activated codes get parsed. + "ACTIVE" is the default''', + default='ACTIVE', metavar='TYPE') parser.add_argument('--handler', - help='''Which codeHandler gets used. "MINI" uses a smaller codeHandler + help='''["MINI", "FULL"] Which codeHandler gets used. "MINI" uses a smaller codeHandler which only supports (0x, 2x, Cx, and E0 types) and supports up to 600 lines of gecko codes when using the legacy codespace. "FULL" is the standard codeHandler, supporting up to 350 lines of code - in the legacy codespace. - "MINI" should only be considered if using the legacy codespace''', + in the legacy codespace. "FULL" is the default''', default='FULL', choices=['MINI', 'FULL'], metavar='TYPE') parser.add_argument('--hooktype', - help='''The type of hook used for the RAM search. VI or GX are recommended, - although PAD can work just as well. VI is the default hook used''', + help='''["VI", "GX", "PAD"] The type of hook used for the RAM search. "VI" or "GX" are recommended, + although "PAD" can work just as well. "VI" is the default''', default='VI', choices=['VI', 'GX', 'PAD'], metavar='HOOK') @@ -127,14 +127,7 @@ if __name__ == "__main__": if len(sys.argv) == 1: version = __version__.rjust(9, ' ') - - if os.path.normpath(os.path.join(os.path.expanduser('~'), "AppData", "Roaming")) in os.path.dirname(__file__): - helpMessage = 'Try the command: GeckoLoader -h'.center(64, ' ') - else: - if os.path.splitext(__file__)[1].lower() == ".py": - helpMessage = 'Try the command: python GeckoLoader.py -h'.center(64, ' ') - else: - helpMessage = 'Try the command: .\GeckoLoader.exe -h'.center(64, ' ') + helpMessage = 'Try option -h for more info on this program'.center(64, ' ') logo = [' ', ' ╔═══════════════════════════════════════════════════════════╗ ', @@ -229,7 +222,7 @@ if __name__ == "__main__": codeHandler.allocation = _allocation codeHandler.hookAddress = _codehook codeHandler.hookType = args.hooktype - codeHandler.includeAll = args.txtcodes + codeHandler.includeAll = (args.txtcodes.lower() == 'all') with open(resource_path(os.path.join('bin', 'geckoloader.bin')), 'rb') as kernelfile: geckoKernel = KernelLoader(kernelfile) diff --git a/installer.cs b/installer.cs index 12e5a4b..5f2a98e 100644 --- a/installer.cs +++ b/installer.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Linq; +using System.Xml.Serialization; public class Program { @@ -24,6 +25,38 @@ public class Installer overwrite = true; } + void CopyAll (DirectoryInfo source, DirectoryInfo destination, string wildcard, string[] exclude, int maxdepth = 16) + { + if (maxdepth <= 0) return; + + DirectoryInfo[] subdirs = source.GetDirectories(); + + foreach (DirectoryInfo dirPath in source.EnumerateDirectories()) + Directory.CreateDirectory(dirPath.FullName.Replace(source.FullName, destination.FullName)); + + foreach (FileInfo filePath in source.EnumerateFiles(wildcard)) + { + bool include = true; + foreach (string exc in exclude) + { + if (exc.ToLower().Contains(filePath.Name.ToLower())) + { + include = false; + break; + } + } + if (include) File.Copy(filePath.FullName, filePath.FullName.Replace(source.FullName, destination.FullName), true); + } + + foreach (DirectoryInfo dir in subdirs) + { + DirectoryInfo dest = new DirectoryInfo(Path.Combine(destination.FullName, dir.Name)); + DirectoryInfo src = new DirectoryInfo(dir.FullName); + + CopyAll(src, dest, wildcard, exclude, maxdepth - 1); + } + } + private static void ClearConsoleLine(int index, bool moveto) { int currentLineCursor = Console.CursorTop; @@ -104,9 +137,10 @@ public class Installer dir.Delete(true); } + //Copy top level files foreach (FileInfo file in cwd.EnumerateFiles(wildcard, SearchOption.TopDirectoryOnly)) { - string ext = ".exe.py.bin"; + string ext = ".exe.py.bin.dll"; if (ext.Contains(file.Extension.ToLower())) { @@ -115,17 +149,9 @@ public class Installer file.CopyTo(Path.Combine(programspace.FullName, file.Name), true); } } - foreach (DirectoryInfo dir in cwd.EnumerateDirectories()) - { - if (!Directory.Exists(Path.Combine(programspace.FullName, dir.Name))) - { - Directory.CreateDirectory(Path.Combine(programspace.FullName, dir.Name)); - } - foreach (FileInfo subfile in dir.EnumerateFiles(wildcard, SearchOption.TopDirectoryOnly)) - { - subfile.CopyTo(Path.Combine(programspace.FullName, dir.Name, subfile.Name), true); - } - } + //Copy dependancies + string[] exclude = { "installer.exe" }; + this.CopyAll(cwd, programspace, wildcard, exclude); } catch (UnauthorizedAccessException e) { diff --git a/kernel.py b/kernel.py index e95dbd3..f3298af 100644 --- a/kernel.py +++ b/kernel.py @@ -204,7 +204,7 @@ class CodeHandler: f.seek(0) - def gecko_parser(self, geckoText, parseAll=False): + def gecko_parser(self, geckoText): with open(r'{}'.format(geckoText), 'rb') as gecko: result = chardet.detect(gecko.read()) encodeType = result['encoding'] @@ -225,10 +225,8 @@ class CodeHandler: try: if state == 'OcarinaM': - if parseAll.lower() == 'all': + if self.includeAll: geckoLine = re.findall(r'[A-F0-9]{8}[\t\f ][A-F0-9]{8}', line, re.IGNORECASE)[0] - elif parseAll.lower() == 'active': - geckoLine = re.findall(r'(?:\*\s*)([A-F0-9]{8}[\t\f ][A-F0-9]{8})', line, re.IGNORECASE)[0] else: geckoLine = re.findall(r'(?:\*\s*)([A-F0-9]{8}[\t\f ][A-F0-9]{8})', line, re.IGNORECASE)[0] else: @@ -488,7 +486,7 @@ class KernelLoader: if '.' in gctFile: if os.path.splitext(gctFile)[1].lower() == '.txt': with open(os.path.join(tmpdir, 'gct.bin'), 'wb+') as temp: - temp.write(bytes.fromhex('00D0C0DE'*2 + codeHandler.gecko_parser(gctFile, codeHandler.includeAll) + 'F000000000000000')) + temp.write(bytes.fromhex('00D0C0DE'*2 + codeHandler.gecko_parser(gctFile) + 'F000000000000000')) temp.seek(0) codeHandler.geckoCodes = GCT(temp) foundData = True @@ -504,7 +502,7 @@ class KernelLoader: for file in os.listdir(gctFile): if os.path.isfile(os.path.join(gctFile, file)): if os.path.splitext(file)[1].lower() == '.txt': - temp.write(bytes.fromhex(codeHandler.gecko_parser(os.path.join(gctFile, file), codeHandler.includeAll))) + temp.write(bytes.fromhex(codeHandler.gecko_parser(os.path.join(gctFile, file)))) foundData = True elif os.path.splitext(file)[1].lower() == '.gct': with open(os.path.join(gctFile, file), 'rb') as gct: