public void TestLoadBeatmap() { using (Apk apk = new Apk(baseAPKPath)) { byte[] data = apk.ReadEntireEntry(apk.MainAssetsFile()); if (apk.version >= Apk.Version.V1_1_0) { return; } SerializedAssets assets = SerializedAssets.FromBytes(data, apk.version); SerializedAssets.AssetObject obj = assets.objects[62]; MonoBehaviorAssetData monob = (MonoBehaviorAssetData)obj.data; BeatmapDataBehaviorData beatmap = (BeatmapDataBehaviorData)monob.data; using (Stream fileStream = new FileStream(repoPath("testoutput/beatmap_deflated.bin"), FileMode.Create)) { using (MemoryStream memoryStream = new MemoryStream(beatmap.projectedData)) { using (DeflateStream ds = new DeflateStream(memoryStream, CompressionMode.Decompress)) { ds.CopyTo(fileStream); } } } BeatmapSaveData saveData = BeatmapSaveData.DeserializeFromBinary(beatmap.projectedData); Assert.NotEmpty(saveData._notes); byte[] outData = saveData.SerializeToBinary(false); File.WriteAllBytes(repoPath("testoutput/beatmap_roundtrip.bin"), outData); BeatmapSaveData saveData2 = BeatmapSaveData.DeserializeFromBinary(outData, false); Assert.NotEmpty(saveData._notes); byte[] outData2 = saveData.SerializeToBinary(false); File.WriteAllBytes(repoPath("testoutput/beatmap_roundtrip2.bin"), outData); } }
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); }
public void TestBigFile() { using (Apk apk = new Apk(baseAPKPath)) { byte[] data = apk.ReadEntireEntry(apk.MainAssetsFile()); var assets = TestRoundTrips(data, "big", apk.version); var existing = assets.ExistingLevelIDs(); Assert.NotEmpty(existing); Assert.False(existing.Contains("BUBBLETEA"), "Run tests on a non-patched APK"); JsonLevel level = JsonLevel.LoadFromFolder(repoPath("testdata/bubble_tea_song/")); var assetsTxn = new SerializedAssets.Transaction(assets); var apkTxn = new Apk.Transaction(); AssetPtr levelPtr = level.AddToAssets(assetsTxn, apkTxn, level.GenerateBasicLevelID()); assetsTxn.ApplyTo(assets); // don't apply apkTxn so our tests don't modify the APK LevelCollectionBehaviorData extrasCollection = assets.FindExtrasLevelCollection(); extrasCollection.levels.Add(levelPtr); byte[] outData = assets.ToBytes(); File.WriteAllBytes($"../../../../testoutput/bubble_tea_mod.asset", outData); } }
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); }