//Buttons private void buttonDecryptSave_Click(object sender, EventArgs e) { SetDefaultValues(false); ClearFormControls(true); ToggleMainControlsAccess(false); SavefilePath = Globals.SavesHex[comboBoxSaves.SelectedIndex]; string SiiSavePath = SavefilePath + @"\game.sii"; string[] file = NewDecodeFile(SiiSavePath); if (file != null) { LogWriter("Backing up file to: " + SavefilePath + @"\game_backup.sii"); File.Copy(SiiSavePath, SavefilePath + @"\game_backup.sii", true); File.WriteAllLines(SiiSavePath, file); UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Clear); } else { UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Error, "error_could_not_decode_file"); } ToggleMainControlsAccess(true); buttonMainDecryptSave.Enabled = false; ToggleGame(GameType); //GC GC.Collect(); //GC.WaitForPendingFinalizers(); }
public unsafe string[] NewDecodeFile(string _savefile_path, bool _verbose) { UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Info, "message_loading_save_file"); if (_verbose) { LogWriter("Loading file into memory: " + _savefile_path); } //string FileData = ""; byte[] FileDataB = new byte[10]; try { FileDataB = File.ReadAllBytes(_savefile_path); } catch { LogWriter("Could not find file in: " + _savefile_path); UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Error, "error_could_not_find_file"); FileDecoded = false; return(null); } int MemFileFrm = -1; UInt32 buff = (UInt32)FileDataB.Length; fixed(byte *ptr = FileDataB) { MemFileFrm = SIIGetMemoryFormat(ptr, buff); } switch (MemFileFrm) { case 1: // "SIIDEC_RESULT_FORMAT_PLAINTEXT"; { FileDecoded = true; string BigS = Encoding.UTF8.GetString(FileDataB); return(BigS.Split(new string[] { "\r\n" }, StringSplitOptions.None)); } case 2: // "SIIDEC_RESULT_FORMAT_ENCRYPTED"; { UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Info, "message_decoding_save_file"); if (_verbose) { LogWriter("Decoding file: " + _savefile_path); } int result = -1; uint newbuff = 0; uint *newbuffP = &newbuff; fixed(byte *ptr = FileDataB) { result = SIIDecryptAndDecodeMemory(ptr, buff, null, newbuffP); } if (result == 0) { byte[] newFileData = new byte[(int)newbuff]; fixed(byte *ptr = FileDataB) { fixed(byte *ptr2 = newFileData) result = SIIDecryptAndDecodeMemory(ptr, buff, ptr2, newbuffP); } UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Clear); FileDecoded = true; string BigS = Encoding.UTF8.GetString(newFileData); return(BigS.Split(new string[] { "\r\n" }, StringSplitOptions.None)); } return(null); } case 3: // "SIIDEC_RESULT_FORMAT_BINARY"; case 4: // "SIIDEC_RESULT_FORMAT_3NK"; { UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Info, "message_decoding_save_file"); if (_verbose) { LogWriter("Decoding file: " + _savefile_path); } int result = -1; uint newbuff = 0; uint *newbuffP = &newbuff; fixed(byte *ptr = FileDataB) { result = SIIDecodeMemory(ptr, buff, null, newbuffP); } if (result == 0) { byte[] newFileData = new byte[(int)newbuff]; fixed(byte *ptr = FileDataB) { fixed(byte *ptr2 = newFileData) result = SIIDecodeMemory(ptr, buff, ptr2, newbuffP); } UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Clear); FileDecoded = true; string BigS = Encoding.UTF8.GetString(newFileData); return(BigS.Split(new string[] { "\r\n" }, StringSplitOptions.None)); } return(null); } case -1: // "SIIDEC_RESULT_GENERIC_ERROR"; case 10: // "SIIDEC_RESULT_FORMAT_UNKNOWN"; case 11: // "SIIDEC_RESULT_TOO_FEW_DATA"; default: // "UNEXPECTED_ERROR"; return(null); } }
public void FillProfileSaves() { if (!Directory.Exists(Globals.ProfilesHex[comboBoxProfiles.SelectedIndex])) { FillProfiles(); return; } string SelectedFolder = Globals.ProfilesHex[comboBoxProfiles.SelectedIndex]; List <string> includedFiles = new List <string>(); string[] t1 = Directory.GetFiles(SelectedFolder); List <string> t2 = t1.Select(Path.GetFileName).ToList(); includedFiles = Directory.GetFiles(SelectedFolder).Select(Path.GetFileName).ToList(); if (includedFiles.Contains("game.sii")) { Globals.SavesHex = new string[1]; Globals.SavesHex[0] = SelectedFolder; } else { SelectedFolder = Globals.ProfilesHex[comboBoxProfiles.SelectedIndex] + @"\save"; Globals.SavesHex = Directory.GetDirectories(SelectedFolder).OrderByDescending(f => new FileInfo(f).LastWriteTime).ToArray(); } if (Globals.SavesHex.Length > 0) { DataTable combDT = new DataTable(); DataColumn dc = new DataColumn("savePath", typeof(string)); combDT.Columns.Add(dc); dc = new DataColumn("saveName", typeof(string)); combDT.Columns.Add(dc); bool NotANumber = false; foreach (string profile in Globals.SavesHex) { if (!File.Exists(profile + @"\game.sii") || !File.Exists(profile + @"\info.sii")) { continue; } string[] fold = profile.Split(new string[] { "\\" }, StringSplitOptions.None); foreach (char c in fold[fold.Length - 1]) { if (c < '0' || c > '9') { NotANumber = true; break; } } if (NotANumber) { string[] namearr = fold[fold.Length - 1].Split(new char[] { '_' }); string ProfileName = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(namearr[0]); for (int i = 1; i < namearr.Length; i++) { ProfileName += " " + namearr[i]; } combDT.Rows.Add(profile, "- " + ProfileName + " -"); } else { combDT.Rows.Add(profile, GetCustomSaveFilename(profile)); } NotANumber = false; } comboBoxSaves.ValueMember = "savePath"; comboBoxSaves.DisplayMember = "saveName"; comboBoxSaves.DataSource = combDT; if (comboBoxSaves.Items.Count > 0) { comboBoxSaves.Enabled = true; //comboBoxSaves.SelectedIndex = 0; buttonProfilesAndSavesOpenSaveFolder.Enabled = true; buttonMainDecryptSave.Enabled = true; buttonMainLoadSave.Enabled = true; UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Clear); } else { comboBoxSaves.Enabled = false; comboBoxSaves.DataSource = null; comboBoxSaves.SelectedIndex = -1; buttonProfilesAndSavesOpenSaveFolder.Enabled = false; buttonMainDecryptSave.Enabled = false; buttonMainLoadSave.Enabled = false; UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Error, "error_No valid Saves was found"); } } else { comboBoxSaves.Enabled = false; buttonProfilesAndSavesOpenSaveFolder.Enabled = false; buttonMainDecryptSave.Enabled = false; buttonMainLoadSave.Enabled = false; MessageBox.Show("No save file folders found"); } }
public void FillProfiles() { if (!Directory.Exists(Globals.ProfilesPaths[comboBoxPrevProfiles.SelectedIndex])) { FillAllProfilesPaths(); return; } string Profile = ""; string SelectedFolder = ""; SelectedFolder = comboBoxPrevProfiles.SelectedValue.ToString(); List <string> includedFiles = new List <string>(); includedFiles = Directory.GetFiles(SelectedFolder).Select(Path.GetFileName).ToList(); if (includedFiles.Contains("profile.sii") || includedFiles.Contains("game.sii")) { Globals.ProfilesHex.Clear(); Globals.ProfilesHex.Add(SelectedFolder); } else { Globals.ProfilesHex = Directory.GetDirectories(SelectedFolder).OrderByDescending(f => new FileInfo(f).LastWriteTime).ToList(); } if (Globals.ProfilesHex.Count > 0) { DataTable combDT = new DataTable(); DataColumn dc = new DataColumn("ProfilePath", typeof(string)); combDT.Columns.Add(dc); dc = new DataColumn("ProfileName", typeof(string)); combDT.Columns.Add(dc); List <string> NewProfileHex = new List <string>(); if (!includedFiles.Contains("game.sii")) { foreach (string profile in Globals.ProfilesHex) { Profile = Utilities.TextUtilities.FromHexToString(Path.GetFileName(profile)); if (Profile != null && Directory.Exists(profile + @"\save")) { combDT.Rows.Add(profile, Profile); NewProfileHex.Add(profile); } } } else { NewProfileHex.Add(SelectedFolder); combDT.Rows.Add(SelectedFolder, "[C] Custom profile"); } Globals.ProfilesHex = NewProfileHex; comboBoxProfiles.ValueMember = "ProfilePath"; comboBoxProfiles.DisplayMember = "ProfileName"; comboBoxProfiles.DataSource = combDT; if (comboBoxProfiles.Items.Count > 0) { //comboBoxProfiles.SelectedIndex = 0; comboBoxProfiles.Enabled = true; //comboBoxSaves.Enabled = true; buttonProfilesAndSavesOpenSaveFolder.Enabled = true; buttonMainDecryptSave.Enabled = true; buttonMainLoadSave.Enabled = true; } else { comboBoxProfiles.Enabled = false; comboBoxProfiles.DataSource = null; comboBoxProfiles.SelectedIndex = -1; comboBoxSaves.Enabled = false; comboBoxSaves.DataSource = null; buttonProfilesAndSavesOpenSaveFolder.Enabled = false; buttonMainDecryptSave.Enabled = false; buttonMainLoadSave.Enabled = false; UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Error, "error_No valid Profiles was found"); } } else { comboBoxProfiles.Enabled = false; comboBoxSaves.Enabled = false; buttonProfilesAndSavesOpenSaveFolder.Enabled = false; buttonMainDecryptSave.Enabled = false; buttonMainLoadSave.Enabled = false; MessageBox.Show("Please select another folder", "No valid profiles found"); } }
//Buttons private void buttonSave_Click(object sender, EventArgs e) { if (listBox1.SelectionMode == SelectionMode.None || listBox1.SelectedIndex == -1) { listBox1.SelectionMode = SelectionMode.One; MessageBox.Show("Please select Base save file for New saves."); listBox1.SelectedValue = Globals.SelectedSavePath; } else { //Check if selected existing and valid save files 0,1 not 2,4 DataRowView sI = (DataRowView)listBox1.SelectedItem; BaseSave = (string)sI.Row["savePath"]; if ((byte)sI.Row[2] == 0 || (byte)sI.Row[2] == 1) { string SiiSavePath = (string)sI.Row[0] + "\\game.sii"; //bool FileDecoded = false; string[] tempSavefileInMemory = null; //Load Base save file if (!File.Exists(SiiSavePath)) { MessageBox.Show("File does not exist in " + SiiSavePath); UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Error, "error_could_not_find_file"); } else { MainForm.FileDecoded = false; try { int decodeAttempt = 0; while (decodeAttempt < 5) { tempSavefileInMemory = MainForm.NewDecodeFile(SiiSavePath); if (MainForm.FileDecoded) { break; } decodeAttempt++; } if (decodeAttempt == 5) { MessageBox.Show("Could not decrypt after 5 attempts"); UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Error, "error_could_not_find_file"); } } catch { MessageBox.Show("Could not read: " + SiiSavePath); } if ((tempSavefileInMemory == null) || (tempSavefileInMemory[0] != "SiiNunit")) { MessageBox.Show("Wrongly decoded Save file or wrong file format"); UpdateStatusBarMessage.ShowStatusMessage(SMStatus.Error, "error_could_not_find_file"); } else { //Delete overwritten savefiles foreach (KeyValuePair <string, string> ftd in FoldersToClear) { Directory.Delete(ftd.Key, true); } Globals.SavesHex = Directory.GetDirectories(Globals.SelectedProfilePath + @"\save").OrderByDescending(f => new FileInfo(f).LastWriteTime).ToArray(); List <byte> CustomFolders = new List <byte>(); //Find all custom folders foreach (string saveF in Globals.SavesHex) { string saveFname = Path.GetFileName(saveF); bool result = byte.TryParse(saveFname, out byte number); if (result) { CustomFolders.Add(number); } } List <byte> NewCustomFolders = new List <byte>(); byte CustomFoldersCount = 1; while (true) { if (CustomFolders.Exists(x => x == CustomFoldersCount)) { } else { NewCustomFolders.Add(CustomFoldersCount); } if (NewCustomFolders.Count() == NewSave.Count) { break; } CustomFoldersCount++; } //Create new numbered folder and new save files int iSave = 0; foreach (KeyValuePair <int, string[]> entry in NewSave) { //Create folder string fp = Directory.GetParent(Globals.SavesHex[0]).FullName + "\\" + NewCustomFolders[iSave].ToString(); Directory.CreateDirectory(fp); //Copy info file string[] infoSii = MainForm.NewDecodeFile(BaseSave + @"\info.sii"); //Prepare data uint tDT = Utilities.DateTimeUtilities.DateTimeToUnixTimeStamp(DateTime.UtcNow.ToLocalTime()); SaveFileInfoData infoData = new SaveFileInfoData(); infoData.Prepare(infoSii); infoData.Name = entry.Value[0]; //Save name infoData.FileTime = tDT; //File time //Write info file using (StreamWriter writer = new StreamWriter(fp + "\\info.sii", false)) { infoData.WriteToStream(writer); } //Create thumbnail files //mat Encoding utf8WithoutBom = new UTF8Encoding(false); using (StreamWriter writer = new StreamWriter(fp + "\\preview.mat", false, utf8WithoutBom)) { writer.WriteLine(preview_mat); } //tobj using (BinaryWriter binWriter = new BinaryWriter(File.Open(fp + "\\preview.tobj", FileMode.Create))) { binWriter.Write(preview_tobj); string pathToTGA = "/home/profiles/" + Globals.SelectedProfile + "/save/" + NewCustomFolders[iSave] + "/preview.tga"; byte filePathLength = (byte)pathToTGA.Length; binWriter.Write(filePathLength); binWriter.Write(new byte[] { 0, 0, 0, 0, 0, 0, 0 }); binWriter.Write(Encoding.UTF8.GetBytes(pathToTGA)); } //image tga //Default thumbnail TGA tgaImg; Bitmap newbmp = null; int custThumbCount = 0; if (!checkBoxCustomThumbnail.Checked) { string[] imgpaths = new string[] { "img\\" + MainForm.GameType + "\\autosave.dds" }; newbmp = new Bitmap(MainForm.ExtImgLoader(imgpaths, 256, 128, 0, 0)[0]); } else if (checkBoxCustomThumbnail.Checked && Thumbnails.Length != 0) { if (custThumbCount < Thumbnails.Length) { newbmp = new Bitmap(Thumbnails[custThumbCount]); custThumbCount++; } else { custThumbCount = 0; newbmp = new Bitmap(Thumbnails[custThumbCount]); } } tgaImg = (TGA)newbmp; tgaImg.Save(fp + "\\preview.tga"); //Create game save file using (StreamWriter writer = new StreamWriter(fp + "\\game.sii", true)) { writer.Write(tempSavefileInMemory[0]); for (int line = 1; line < tempSavefileInMemory.Length; line++) { string SaveInMemLine = tempSavefileInMemory[line]; if (SaveInMemLine.StartsWith(" truck_placement:")) { writer.Write("\r\n" + " truck_placement: " + entry.Value[1]); line++; writer.Write("\r\n" + " trailer_placement: (0, 0, 0) (1; 0, 0, 0)"); line++; int slave_trailers = int.Parse(tempSavefileInMemory[line].Split(new char[] { ' ' })[2]); writer.Write("\r\n" + tempSavefileInMemory[line]); if (slave_trailers > 0) { for (int i = 0; i < slave_trailers; i++) { writer.Write("\r\n" + " slave_trailer_placements[" + i + "]: (0, 0, 0) (1; 0, 0, 0)"); line++; } } continue; } //EndWrite: writer.Write("\r\n" + SaveInMemLine); } } iSave++; } // buttonSave.Enabled = false; GC.Collect(); MessageBox.Show("Saves are created.\nNow you can close this window."); } } } else { MessageBox.Show("Not a valid save file for base file.\nPlease select existing save file not marked for deleting."); //return; } } }