static InvocationResult RunInvocation(Invocation inv) { InvocationResult res = new InvocationResult(); try { using (Apk apk = new Apk(inv.apkPath)) { if (inv.patchSignatureCheck) { apk.PatchSignatureCheck(); res.didSignatureCheckPatch = true; } SerializedAssets mainAssets = SerializedAssets.FromBytes( apk.ReadEntireEntry(apk.MainAssetsFile()), apk.version ); SyncLevels(apk, mainAssets, inv, res); apk.ReplaceAssetsFile(apk.MainAssetsFile(), mainAssets.ToBytes()); if (inv.colors != null) { UpdateColors(apk, inv.colors, res); } if (inv.replaceText != null) { UpdateText(apk, inv.replaceText, res); } apk.Save(); } if (inv.sign) { Signer.Sign(inv.apkPath); res.didSign = true; } } catch (Exception e) { res.error = e.ToString(); } return(res); }
static InvocationResult RunInvocation(Invocation inv) { InvocationResult res = new InvocationResult(); try { using (Apk apk = new Apk(inv.apkPath)) { if (inv.patchSignatureCheck) { apk.PatchSignatureCheck(); res.didSignatureCheckPatch = true; } byte[] data = apk.ReadEntireEntry(apk.MainAssetsFile()); SerializedAssets assets = SerializedAssets.FromBytes(data, apk.version); HashSet <string> existingLevels = assets.ExistingLevelIDs(); if (inv.ensureInstalled.Count > 0) { Program.EnsureInstalled(apk, assets, existingLevels, res, inv.ensureInstalled); byte[] outData = assets.ToBytes(); apk.ReplaceAssetsFile(apk.MainAssetsFile(), outData); } res.presentLevels = existingLevels.ToList(); apk.Save(); } if (inv.sign) { Signer.Sign(inv.apkPath); res.didSign = true; } } catch (Exception e) { res.error = e.ToString(); } return(res); }
static void Main(string[] args) { if (args.Length < 1) { Console.WriteLine("arguments: pathToAPKFileToModify levelFolders..."); return; } string apkPath = args[0]; using (Apk apk = new Apk(apkPath)) { apk.PatchSignatureCheck(); byte[] data = apk.ReadEntireEntry(apk.MainAssetsFile()); SerializedAssets assets = SerializedAssets.FromBytes(data, apk.version); HashSet <string> existingLevels = assets.ExistingLevelIDs(); LevelCollectionBehaviorData extrasCollection = assets.FindExtrasLevelCollection(); for (int i = 1; i < args.Length; i++) { Utils.FindLevels(args[i], levelFolder => { try { JsonLevel level = JsonLevel.LoadFromFolder(levelFolder); string levelID = level.GenerateBasicLevelID(); if (existingLevels.Contains(levelID)) { Console.WriteLine($"Present: {level._songName}"); } else { Console.WriteLine($"Adding: {level._songName}"); // We use transactions here so if these throw // an exception, which happens when levels are // invalid, then it doesn't modify the APK in // any way that might screw things up later. var assetsTxn = new SerializedAssets.Transaction(assets); var apkTxn = new Apk.Transaction(); AssetPtr levelPtr = level.AddToAssets(assetsTxn, apkTxn, levelID); // Danger should be over, nothing here should fail assetsTxn.ApplyTo(assets); extrasCollection.levels.Add(levelPtr); existingLevels.Add(levelID); apkTxn.ApplyTo(apk); } } catch (FileNotFoundException e) { Console.WriteLine("[SKIPPING] Missing file referenced by level: {0}", e.FileName); } catch (JsonReaderException e) { Console.WriteLine("[SKIPPING] Invalid level JSON: {0}", e.Message); } }); } byte[] outData = assets.ToBytes(); apk.ReplaceAssetsFile(apk.MainAssetsFile(), outData); apk.Save(); } Console.WriteLine("Signing APK..."); Signer.Sign(apkPath); }