using System.Reflection; using AchiesUtilities.Extensions; using NebulaAuth.LegacyConverter; using Newtonsoft.Json; using SteamLib.Utility.MafileSerialization; try { var mafileSerializer = new MafileSerializer(new MafileSerializerSettings { DeserializationOptions = { AllowDeviceIdGeneration = true, AllowSessionIdGeneration = true } }); var currentPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); if (currentPath != null) Environment.CurrentDirectory = currentPath; const string toStoreFolder = "ConvertedMafiles"; if (Directory.Exists(toStoreFolder) == false) { Directory.CreateDirectory(toStoreFolder); } else { var isEmpty = Directory.GetFiles(toStoreFolder).Length == 0; Console.ForegroundColor = ConsoleColor.Yellow; if (!isEmpty) { Console.WriteLine( "WARNING! 'ConverterdMafiles' folder is not empty. Please backup data from it and then continue."); Console.ResetColor(); Console.WriteLine("Press Y to continue"); while (Console.ReadKey(true).Key != ConsoleKey.Y) { } } } var decryptMode = false; while (true) { Console.WriteLine("Press 'D' to select decrypt mode. Press 'C' to convert mode. Press ESC to exit"); var key = Console.ReadKey(true); switch (key.Key) { case ConsoleKey.D: decryptMode = true; break; case ConsoleKey.C: break; case ConsoleKey.Escape: return; default: continue; } break; } Manifest? manifest = null; string? password = null; if (decryptMode) { var files = Directory.GetFiles(currentPath, "manifest.json"); var manifestPath = files.FirstOrDefault(); if (manifestPath == null) { Console.WriteLine("No manifest.json found in current directory"); return; } var manifestText = File.ReadAllText(manifestPath); try { manifest = JsonConvert.DeserializeObject(manifestText)!; } catch (Exception ex) { Console.WriteLine("Can't read manifest: " + ex); return; } if (manifest.Encrypted == false) { Console.WriteLine("Manifest is not encrypted"); return; } while (true) { Console.WriteLine("Please enter your encryption password: "); password = Console.ReadLine(); if (string.IsNullOrWhiteSpace(password)) continue; break; } } Console.WriteLine(currentPath); foreach (var path in args) { if (Path.Exists(path) == false) { Console.WriteLine($"NOT VALID PATH: '{path}'"); continue; } Console.WriteLine("Reading: " + path); try { var text = File.ReadAllText(path); if (decryptMode) { var fileName = Path.GetFileName(path); text = DecryptMafile(fileName, text); if (text == null) { Console.WriteLine(path + " not found in manifest. Skipped"); continue; } } var data = mafileSerializer.Deserialize(text); var maf = data.Data; var legacy = MafileSerializer.SerializeLegacy(maf, Formatting.Indented); var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path); Write(legacy, fileNameWithoutExtension); Console.WriteLine("DONE: " + fileNameWithoutExtension); } catch (Exception ex) { Console.WriteLine($"ERROR: {ex.Message}"); Console.WriteLine(ex); } finally { Console.WriteLine("-----------------------------------------"); } } //Local Functions void Write(string maf, string name) { var path = Path.Combine(toStoreFolder, name + "_legacy.mafile"); File.WriteAllText(path, maf); } string? DecryptMafile(string fileName, string cipherText) { if (password == null) return null; var entry = manifest?.Entries.FirstOrDefault(x => x.Filename.EqualsIgnoreCase(fileName)); if (entry == null) { return null; } var iv = entry.EncryptionIv; var salt = entry.EncryptionSalt; return SDAEncryptor.DecryptData(password, salt, iv, cipherText); } } finally { Console.WriteLine("Press any key to exit..."); Console.ReadKey(); }