public override bool IsOfType(ArchiveFileStream inputStream, IArchiveDataManager manager, TextureCooked?tex) { UbiArtSettings settings = manager.Context !.GetSettings <UbiArtSettings>(); // TODO: Find better way to check this return(settings.Platform == Platform.Xbox360); }
/// <summary> /// Converts from the format /// </summary> /// <returns>The task</returns> public override async Task ConvertFromAsync() { var attr = GameModeSelection.SelectedValue.GetAttribute <UbiArtGameModeInfoAttribute>(); var settings = UbiArtSettings.GetDefaultSettings(attr.Game, attr.Platform); if (GameModeSelection.SelectedValue == UbiArtGameMode.RaymanFiestaRunPC) { await ConvertFromAsync <FiestaRunLocalizationData>(settings, (data, filePath) => { // Save the data SerializeJSON(data, filePath); }, new FileFilterItem("*.loc", "LOC").ToString(), new[] { ".json" }, Games.RaymanFiestaRun.GetInstallDir(false)); } else { var fileExtension = Equals(settings.StringEncoding, Encoding.UTF8) ? new FileFilterItem("*.loc8", "LOC8") : new FileFilterItem("*.loc", "LOC"); await ConvertFromAsync <UbiArtLocalizationData>(settings, (data, filePath) => { // Save the data SerializeJSON(data, filePath); }, fileExtension.ToString(), new[] { ".json" }, GameModeSelection.SelectedValue.GetGame()?.GetInstallDir(false)); } }
/// <summary> /// Opens the archive explorer /// </summary> /// <returns>The task</returns> public async Task OpenAsync() { var attr = GameMode.GetAttribute <UbiArtGameModeInfoAttribute>(); var settings = UbiArtSettings.GetDefaultSettings(attr.Game, attr.Platform); // Show the archive explorer await RCPServices.UI.ShowArchiveExplorerAsync(new UbiArtIPKArchiveExplorerDataManager(settings), ArchiveFiles.Where(x => x.FileExists)); }
/// <summary> /// Default constructor /// </summary> /// <param name="settings">The settings when serializing the data</param> /// <param name="compressionMode">The compression mode for files and the block</param> public UbiArtIPKArchiveConfigViewModel(UbiArtSettings settings, FileCompressionMode compressionMode) { CompressionMode = compressionMode; Settings = settings; CompressedExtensions = ".dtape.ckd," + ".fx.fxb," + ".m3d.ckd," + ".png.ckd," + ".tga.ckd"; }
/// <summary> /// Converts to the format /// </summary> /// <returns>The task</returns> public override async Task ConvertToAsync() { var settings = UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanOrigins, GameModeSelection.SelectedValue); await ConvertToAsync <OriginsPCSaveData>(settings, (filePath, format) => { // Read the data return(DeserializeJSON <OriginsPCSaveData>(filePath)); }, new FileFilterItem("*.json", "JSON").ToString(), new FileExtension(String.Empty)); }
/// <summary> /// Default constructor /// </summary> /// <param name="fileEntry">The file data</param> /// <param name="settings">The settings when serializing the data</param> /// <param name="baseOffset">The base offset to use when reading the files</param> public UbiArtIPKArchiveFileData(UbiArtIPKFileEntry fileEntry, UbiArtSettings settings, uint baseOffset) { // Get the file properties Directory = fileEntry.Path.DirectoryPath; FileExtension = new FileExtension(fileEntry.Path.GetFileExtensions()); FileName = fileEntry.Path.FileName; FileEntry = fileEntry; BaseOffset = baseOffset; Settings = settings; }
/// <summary> /// Default constructor /// </summary> /// <param name="settings">The settings when serializing the data</param> /// <param name="compressionMode">The file compression mode</param> public UbiArtIPKArchiveDataManager(UbiArtSettings settings, UbiArtIPKArchiveConfigViewModel.FileCompressionMode compressionMode) { Context = new RCPContext(String.Empty, new RCPSerializerSettings() { DefaultEndianness = settings.GetEndian }); Context.AddSettings(settings); Config = new UbiArtIPKArchiveConfigViewModel(settings, compressionMode); }
/// <summary> /// Serializes the data to the localization file /// </summary> /// <param name="file">The localization file</param> /// <param name="data">The data</param> protected override void Serialize(FileSystemPath file, UbiArtLocStringValuePair[] data) { // Read the current data to get the remaining bytes var currentData = BinarySerializableHelpers.ReadFromFile <UbiArtLocalizationData>(file, UbiArtSettings.GetDefaultSettings(UbiArtGame.RaymanOrigins, Platform.PC), RCPServices.App.GetBinarySerializerLogger()); // Replace the string data currentData.Strings = data; // Serialize the data BinarySerializableHelpers.WriteToFile(currentData, file, UbiArtSettings.GetDefaultSettings(UbiArtGame.RaymanOrigins, Platform.PC), RCPServices.App.GetBinarySerializerLogger()); }
/// <summary> /// Converts from the format /// </summary> /// <returns>The task</returns> public override async Task ConvertFromAsync() { var settings = UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanJungleRun, GameModeSelection.SelectedValue); await ConvertFromAsync <JungleRunPCSaveData>(settings, (data, filePath) => { // Save the data SerializeJSON(data, filePath); }, new FileFilterItem("*.dat", "DAT").ToString(), new[] { ".json" }, Environment.SpecialFolder.LocalApplicationData.GetFolderPath() + "Packages" + Games.RaymanJungleRun.GetManager <RCPWinStoreGame>().FullPackageName + "LocalState"); }
/// <summary> /// Converts from the format /// </summary> /// <returns>The task</returns> public override async Task ConvertFromAsync() { var settings = UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanOrigins, GameModeSelection.SelectedValue); await ConvertFromAsync <OriginsPCSaveData>(settings, (data, filePath) => { // Save the data SerializeJSON(data, filePath); }, new FileFilterItem("*", String.Empty).ToString(), new[] { ".json" }, Environment.SpecialFolder.MyDocuments.GetFolderPath() + "My games" + "Rayman origins"); }
/// <summary> /// Imports an exported save slot to the save slot from the specified path /// </summary> /// <param name="inputFilePath">The input file path</param> /// <returns>The task</returns> protected override Task ImportSaveDataAsync(FileSystemPath inputFilePath) { // Get the serialized data var data = BinarySerializableHelpers.ReadFromFile <JungleRunPCSaveData>(SaveSlotFilePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanJungleRun, Platform.PC), RCPServices.App.GetBinarySerializerLogger()); // Deserialize the input data data.Levels = JsonHelpers.DeserializeFromFile <JungleRunPCSaveDataLevel[]>(inputFilePath); // Import the data BinarySerializableHelpers.WriteToFile(data, SaveSlotFilePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanJungleRun, Platform.PC), RCPServices.App.GetBinarySerializerLogger()); return(Task.CompletedTask); }
/// <summary> /// Converts to the format /// </summary> /// <returns>The task</returns> public override async Task ConvertToAsync() { var attr = GameModeSelection.SelectedValue.GetAttribute <UbiArtGameModeInfoAttribute>(); var settings = UbiArtSettings.GetDefaultSettings(attr.Game, attr.Platform); if (GameModeSelection.SelectedValue == UbiArtGameMode.RaymanFiestaRunPC) { await ConvertToAsync <FiestaRunLocalizationData>(settings, (filePath, format) => { // Read the data return(DeserializeJSON <FiestaRunLocalizationData>(filePath)); }, new FileFilterItem("*.json", "JSON").ToString(), new FileExtension(".loc")); } else { var fileExtension = new FileExtension(Equals(settings.StringEncoding, Encoding.UTF8) ? ".loc8" : ".loc"); await ConvertToAsync <UbiArtLocalizationData>(settings, (filePath, format) => { // Read the data return(DeserializeJSON <UbiArtLocalizationData>(filePath)); }, new FileFilterItem("*.json", "JSON").ToString(), fileExtension); } }
/// <summary> /// Default constructor /// </summary> /// <param name="settings">The settings when serializing the data</param> public UbiArtIPKArchiveExplorerDataManager(UbiArtSettings settings) : base(new UbiArtIPKArchiveConfigViewModel(settings, UbiArtIPKArchiveConfigViewModel.FileCompressionMode.WasCompressed)) { }
/// <summary> /// Deserializes the localization file /// </summary> /// <param name="file">The localization file</param> /// <returns>The data</returns> protected override UbiArtLocStringValuePair[] Deserialize(FileSystemPath file) { return(BinarySerializableHelpers.ReadFromFile <UbiArtLocalizationData>(file, UbiArtSettings.GetDefaultSettings(UbiArtGame.RaymanOrigins, Platform.PC), RCPServices.App.GetBinarySerializerLogger()).Strings); }
/// <summary> /// Get the progression slot view model for the save data from the specified file /// </summary> /// <param name="filePath">The slot file path</param> /// <returns>The progression slot view model</returns> protected ProgressionSlotViewModel GetProgressionSlotViewModel(FileSystemPath filePath) { RL.Logger?.LogInformationSource($"Legends slot {filePath.Parent.Name} is being loaded..."); // Make sure the file exists if (!filePath.FileExists) { RL.Logger?.LogInformationSource($"Slot was not loaded due to not being found"); return(null); } // Deserialize and return the data var saveData = BinarySerializableHelpers.ReadFromFile <LegendsPCSaveData>(filePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanLegends, Platform.PC), RCPServices.App.GetBinarySerializerLogger()).SaveData; RL.Logger?.LogInformationSource($"Slot has been deserialized"); // Create the collection with items for each time trial level + general information var progressItems = new List <ProgressionInfoItemViewModel>(); // Create the number format info to use var formatInfo = new NumberFormatInfo() { NumberGroupSeparator = " ", NumberDecimalDigits = 0 }; // Get the total amount of freed teensies var teensies = saveData.Levels.Select(x => x.Value.Object.FreedPrisoners.Length).Sum() + saveData.LuckyTicketRewardList.Count(x => x.Type == 5); // Set general progress info progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Teensy, new LocalizedString(() => $"{teensies}/700"))); progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Lum, new LocalizedString(() => $"{saveData.Score.LocalLumsCount.ToString("n", formatInfo)}"))); // Set rank progressItems.Add(new ProgressionInfoItemViewModel(Enum.Parse(typeof(ProgressionIcons), $"RL_Rank{saveData.Profile.StatusIcon}").CastTo <ProgressionIcons>(), new LocalizedString(() => $"{saveData.Profile.StatusIcon}"))); // Set cups progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Bronze, new LocalizedString(() => $"{saveData.Profile.BronzeMedals.ToString("n", formatInfo)}"))); progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Silver, new LocalizedString(() => $"{saveData.Profile.SilverMedals.ToString("n", formatInfo)}"))); progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Gold, new LocalizedString(() => $"{saveData.Profile.GoldMedals.ToString("n", formatInfo)}"))); progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RL_Diamond, new LocalizedString(() => $"{saveData.Profile.DiamondMedals.ToString("n", formatInfo)}"))); RL.Logger?.LogInformationSource($"General progress info has been set"); // Get the level IDs var lvlIds = GetLevelIDs; // Set invasion times progressItems.AddRange(saveData.Levels. Select(x => x.Value.Object). Where(x => x.BestTime > 0). Select(x => (lvlIds[x.Id.ID], x.BestTime)). Select(x => new ProgressionInfoItemViewModel( Enum.Parse(typeof(ProgressionIcons), $"RL_Inv_{x.Item1.Replace("-", "_")}").CastTo <ProgressionIcons>(), new LocalizedString(() => $"{x.Item1}: {x.BestTime:0.000}"), new LocalizedString(() => Resources.ResourceManager.GetString($"RL_LevelName_{x.Item1.Replace("-", "_")}")))). OrderBy(x => x.Content.Value)); RL.Logger?.LogInformationSource($"Invasion progress info has been set"); // Calculate the percentage var percentage = ((teensies / 700d * 100)).ToString("0.##"); RL.Logger?.LogInformationSource($"Slot percentage is {percentage}%"); // Return the data with the collection return(new LegendsProgressionSlotViewModel(new LocalizedString(() => $"{saveData.Profile.Name} ({percentage}%)"), progressItems.ToArray(), filePath, this)); }
/// <summary> /// Gets the patch infos for each <see cref="Patch"/> /// </summary> /// <param name="ipkStream">The IPK file stream</param> /// <returns>The patch infos</returns> protected IEnumerable <PatchInfo> GetPatchInfos(Stream ipkStream) { // Deserialize the IPK file var ipk = BinarySerializableHelpers.ReadFromStream <UbiArtIpkData>(ipkStream, UbiArtSettings.GetDefaultSettings(UbiArtGame.RaymanLegends, Platform.PC), RCPServices.App.GetBinarySerializerLogger()); // Enumerate every patch foreach (var patchGroup in GetPatches.GroupBy(x => x.FileName)) { // Get the file var file = ipk.Files.FindItem(x => x.Path.FileName == patchGroup.Key); // Make sure we found the file if (file == null) { throw new Exception("Patch file not found"); } // Make sure it's not compressed if (file.IsCompressed) { throw new Exception("The configuration file is compressed and can not be edited"); } // Get the offsets foreach (Patch patch in patchGroup) { // Get the offset of the byte in the file to change yield return(new PatchInfo(patch, (long)(ipk.BaseOffset + file.Offsets.First() + (uint)patch.FileOffset))); } } }
/// <summary> /// Exports the save slot from the specified path /// </summary> /// <param name="outputFilePath">The output file path</param> /// <returns>The task</returns> protected override Task ExportSaveDataAsync(FileSystemPath outputFilePath) { // Get the serialized level data var data = BinarySerializableHelpers.ReadFromFile <JungleRunPCSaveData>(SaveSlotFilePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanJungleRun, Platform.PC), RCPServices.App.GetBinarySerializerLogger()).Levels; // Export the data JsonHelpers.SerializeToFile(data, outputFilePath); return(Task.CompletedTask); }
/// <summary> /// Default constructor /// </summary> /// <param name="settings">The settings when serializing the data</param> public UbiArtIPKArchiveCreatorDataManager(UbiArtSettings settings) : base(new UbiArtIPKArchiveConfigViewModel(settings, UbiArtIPKArchiveConfigViewModel.FileCompressionMode.MatchesSetting)) { }
/// <summary> /// Get the progression slot view model for the save data from the specified file /// </summary> /// <param name="fileName">The slot file name, relative to the save directory</param> /// <param name="slotNamegenerator">The generator for the name of the save slot</param> /// <returns>The progression slot view model</returns> protected ProgressionSlotViewModel GetProgressionSlotViewModel(FileSystemPath fileName, Func <string> slotNamegenerator) { RL.Logger?.LogInformationSource($"Jungle Run slot {fileName.Name} is being loaded..."); // Get the file path var filePath = SaveDir + fileName; // Make sure the file exists if (!filePath.FileExists) { RL.Logger?.LogInformationSource($"Slot was not loaded due to not being found"); return(null); } // Deserialize and return the data var saveData = BinarySerializableHelpers.ReadFromFile <JungleRunPCSaveData>(filePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanJungleRun, Platform.PC), RCPServices.App.GetBinarySerializerLogger()); RL.Logger?.LogInformationSource($"Slot has been deserialized"); // Create the collection with items for each time trial level + general information var progressItems = new ProgressionInfoItemViewModel[(saveData.Levels.Length / 10) + 2]; // Get data values int collectedLums = 0; int availableLums = 0; int collectedTeeth = 0; int availableTeeth = saveData.Levels.Length; RL.Logger?.LogTraceSource($"Levels are being enumerated..."); // Enumerate each level for (int i = 0; i < saveData.Levels.Length; i++) { // Get the level data var levelData = saveData.Levels[i]; // Check if the level is a normal level if ((i + 1) % 10 != 0) { RL.Logger?.LogTraceSource($"Level index {i} is a normal level"); // Get the collected lums collectedLums += levelData.LumsRecord; availableLums += 100; RL.Logger?.LogTraceSource($"{levelData.LumsRecord} Lums have been collected"); // Check if the level is 100% complete if (levelData.LumsRecord >= 100) { collectedTeeth++; } continue; } RL.Logger?.LogTraceSource($"Level index {i} is a time trial level"); // Make sure the level has been completed if (levelData.RecordTime == 0) { RL.Logger?.LogTraceSource($"Level has not been completed"); continue; } RL.Logger?.LogTraceSource($"Level has been completed with the record time {levelData.RecordTime}"); collectedTeeth++; // Get the level number, starting at 10 var fullLevelNumber = (i + 11).ToString(); // Get the world and level numbers var worldNum = fullLevelNumber[0].ToString(); var lvlNum = fullLevelNumber[1].ToString(); // If the level is 0, correct the numbers to be level 10 if (lvlNum == "0") { worldNum = (Int32.Parse(worldNum) - 1).ToString(); lvlNum = "10"; } // Create the view model progressItems[((i + 1) / 10) - 1 + 2] = new ProgressionInfoItemViewModel(ProgressionIcons.RO_Clock, new LocalizedString(() => $"{worldNum}-{lvlNum}: {new TimeSpan(0, 0, 0, 0, (int)levelData.RecordTime):mm\\:ss\\:fff}")); } // Set general progress info progressItems[0] = new ProgressionInfoItemViewModel(ProgressionIcons.RO_Lum, new LocalizedString(() => $"{collectedLums}/{availableLums}")); progressItems[1] = new ProgressionInfoItemViewModel(ProgressionIcons.RO_RedTooth, new LocalizedString(() => $"{collectedTeeth}/{availableTeeth}")); RL.Logger?.LogInformationSource($"General progress info has been set"); // Calculate the percentage var percentage = ((collectedLums / (double)availableLums * 50) + (collectedTeeth / (double)availableTeeth * 50)).ToString("0.##"); RL.Logger?.LogInformationSource($"Slot percentage is {percentage}%"); // Return the data with the collection return(new JungleRunProgressionSlotViewModel(new LocalizedString(() => $"{slotNamegenerator()} ({percentage}%)"), progressItems, filePath, this)); }
/// <summary> /// Get the progression slot view model for the save data from the specified file /// </summary> /// <param name="filePath">The slot file path</param> /// <param name="slotNamegenerator">The generator for the name of the save slot</param> /// <returns>The progression slot view model</returns> protected ProgressionSlotViewModel GetProgressionSlotViewModel(FileSystemPath filePath, Func <string> slotNamegenerator) { RL.Logger?.LogInformationSource($"Origins slot {filePath.Name} is being loaded..."); // Make sure the file exists if (!filePath.FileExists) { RL.Logger?.LogInformationSource($"Slot was not loaded due to not being found"); return(null); } // Deserialize and get the data var saveData = BinarySerializableHelpers.ReadFromFile <OriginsPCSaveData>(filePath, UbiArtSettings.GetSaveSettings(UbiArtGame.RaymanOrigins, Platform.PC), RCPServices.App.GetBinarySerializerLogger()).SaveData; RL.Logger?.LogInformationSource($"Slot has been deserialized"); // Get the level configuration var lvlConfig = JsonConvert.DeserializeObject <ROLevelConfig>(Files.RO_LevelConfig); int completed = 0; int cageMaps = 0; int lumAttack1 = 0; int lumAttack2 = 0; int lumAttack3 = 0; int timeAttack1 = 0; int timeAttack2 = 0; // Get number of levels where each mission has been completed foreach (var lvl in saveData.Levels) { // Get the configuration for the level var level = lvlConfig.GetLevel(lvl.Key.ID); var mission = lvlConfig.GetMission(lvl.Key.ID); // Make sure it's a normal level, i.e. it has a medallion if (level == null || mission == null) { continue; } // Check if the level has been completed if (lvl.Value.Object.LevelState == OriginsPCSaveData.SPOT_STATE.COMPLETED) { completed++; } // Get the number of completed cage maps (between 0-2) cageMaps += lvl.Value.Object.CageMapPassedDoors.Length; // Get the best time attack score var timeAttack = lvl.Value.Object.BestTimeAttack; // Compare the time attack score with the targets if (timeAttack <= level.Time1) { timeAttack1++; } if (timeAttack <= level.Time2) { timeAttack2++; } // Get the best lum attack score var lumAttack = lvl.Value.Object.BestLumAttack; // Compare the lum attack score with the targets if (lumAttack >= mission.LumAttack1) { lumAttack1++; } if (lumAttack >= mission.LumAttack2) { lumAttack2++; } if (lumAttack >= mission.LumAttack3) { lumAttack3++; } } // Create the collection with items for each time trial level + general information var progressItems = new List <ProgressionInfoItemViewModel>(); // Get the number of Electoons var electoons = // Cages cageMaps + // Levels completed completed + // Lum attack 1 lumAttack1 + // Lum attack 2 lumAttack2 + // Time attack 1 timeAttack1; var teeth = saveData.Levels.Select(x => x.Value.Object.ISDs.Select(y => y.Value.Object.TakenTooth.Length)).SelectMany(x => x).Sum(); // Set general progress info progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RO_Electoon, new LocalizedString(() => $"{electoons}/246"))); progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RO_RedTooth, new LocalizedString(() => $"{teeth}/10"))); progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RO_Medal, new LocalizedString(() => $"{lumAttack3}/51"))); progressItems.Add(new ProgressionInfoItemViewModel(ProgressionIcons.RO_Trophy, new LocalizedString(() => $"{timeAttack2}/31"))); RL.Logger?.LogInformationSource($"General progress info has been set"); // Calculate the percentage var percentage = ((electoons / 246d * 25) + (teeth / 10d * 25) + (lumAttack3 / 51d * 25) + (timeAttack2 / 31d * 25)).ToString("0.##"); RL.Logger?.LogInformationSource($"Slot percentage is {percentage}%"); // Return the data with the collection return(new OriginsProgressionSlotViewModel(new LocalizedString(() => $"{slotNamegenerator()} ({percentage}%)"), progressItems.ToArray(), filePath, this)); }
/// <summary> /// Default constructor /// </summary> /// <param name="fileEntry">The file data</param> /// <param name="settings">The settings when serializing the data</param> /// <param name="baseOffset">The base offset to use when reading the files</param> public UbiArtIPKArchiveImageFileData(UbiArtIPKFileEntry fileEntry, UbiArtSettings settings, uint baseOffset) : base(fileEntry, settings, baseOffset) { }