using Newtonsoft.Json; using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Runtime.InteropServices; using System.Windows.Forms; namespace SaveWizard { public partial class MainForm: Form { private readonly string config_file_name = "update.cfg"; [DllImport("SII_Decrypt.dll")] public static extern int GetFileFormat(string FileName); [DllImport("SII_Decrypt.dll")] public static extern int DecryptAndDecodeFile(string InputFile, string OutputFile); private Dictionary items = null; private string opened_file_path, selected_game; private Dictionary owns = null; public MainForm() { InitializeComponent(); // Test stuff //string path = Path.Combine(Environment.CurrentDirectory, "configs"); //if (Directory.Exists(path)) // Directory.Delete(path, true); //path = Path.Combine(Environment.CurrentDirectory, "update.cfg"); //if (File.Exists(path)) // File.Delete(path); } private class WindowItem { private readonly CheckBox Check; private readonly string Str; public WindowItem(CheckBox _check, string _str) { Check = _check; Str = _str; } public CheckBox GetCheck() { return Check; } public string GetString() { return Str; } } private void boxTextChanged(object sender, EventArgs e) { TextBox _sender = sender as TextBox; if (_sender != txt_adr) items[_sender].GetCheck().Checked = false; else chk_adr.Checked = false; } private void ValidateBasic(object sender, KeyPressEventArgs e) { //if (!(e.KeyChar >= '0' && e.KeyChar <= '9') && !char.IsControl(e.KeyChar)) if (!(e.KeyChar >= '0' && e.KeyChar <= '9') && e.KeyChar != (char)Keys.Back) e.Handled = true; } private void ValidateSkills(object sender, KeyPressEventArgs e) { //if (!(e.KeyChar >= '0' && e.KeyChar <= '6') && !char.IsControl(e.KeyChar)) if (!(e.KeyChar >= '0' && e.KeyChar <= '6') && e.KeyChar != (char)Keys.Back) e.Handled = true; } private List GetADR(string value) { string binaryCode = Convert.ToString(int.Parse(value), 2); binaryCode = new string('0', 6 - binaryCode.Length) + binaryCode; List result = new List(); foreach (char character in binaryCode) result.Add(character.ToString()); return result; } private void GetFileData(string filename) { RegexHandler.FillLines(File.ReadAllLines(filename).ToList()); foreach (KeyValuePair item in items) { item.Key.Text = RegexHandler.GetValue(RegexHandler.SearchLine(item.Value.GetString())); item.Value.GetCheck().Checked = true; } txt_adr.Text = string.Join(",", GetADR(RegexHandler.GetValue(RegexHandler.SearchLine("adr:")))); chk_adr.Checked = true; if (RegexHandler.SearchLine("company.volatile.stokes.calais") != 0) selected_game = "ets2"; else if (RegexHandler.SearchLine("company.volatile.ed_mkt.elko") != 0) selected_game = "ats"; else selected_game = null; if (selected_game != null) { string config_path = $"configs/{selected_game}/dlc.json"; if (File.Exists(config_path)) { Dictionary dlc = JsonConvert.DeserializeObject>(File.ReadAllText(config_path)); owns = new Dictionary { { "base", true } }; List companies = RegexHandler.GetArrayItems("companies:"); foreach (string company in companies) foreach (KeyValuePair item in dlc) if (company.Contains(item.Value)) owns[item.Key] = true; } else Utils.ShowError($"'dlc.json' from '{selected_game}' have errors or not found, functionality has been limited"); } btn_unlock_garages.Enabled = true; btn_recover_backup.Enabled = true; btn_apply_changes.Enabled = true; } private void ClearData() { opened_file_path = null; RegexHandler.FillLines(null); selected_game = null; owns = null; foreach (KeyValuePair item in items) { item.Key.Text = ""; item.Value.GetCheck().Checked = true; } txt_adr.Text = ""; chk_adr.Checked = true; btn_unlock_garages.Enabled = false; btn_recover_backup.Enabled = false; btn_apply_changes.Enabled = false; } private void MainForm_FormClosed(object sender, FormClosedEventArgs e) { Application.Exit(); } private void MainForm_Load(object sender, EventArgs e) { if (!File.Exists("SII_Decrypt.dll")) { Utils.ShowError("SII_Decrypt.dll not found! Place dll file near this executable."); Close(); } items = new Dictionary { { txt_money, new WindowItem(chk_money, "money_account:") }, { txt_experience, new WindowItem(chk_experience, "experience_points:") }, { txt_loan_limit, new WindowItem(chk_loan_limit, "loan_limit:") }, { txt_long_distance, new WindowItem(chk_long_distance, "long_dist:") }, { txt_high_value_cargo, new WindowItem(chk_high_value_cargo, "heavy:") }, { txt_fragile_cargo, new WindowItem(chk_fragile_cargo, "fragile:") }, { txt_urgent_delivery, new WindowItem(chk_urgent_delivery, "urgent:") }, { txt_ecodriving, new WindowItem(chk_ecodriving, "mechanical:") }, }; KeyPressEventHandler basic = new KeyPressEventHandler(ValidateBasic); txt_money.KeyPress += basic; txt_experience.KeyPress += basic; txt_loan_limit.KeyPress += basic; //txt_adr.KeyPress += new KeyPressEventHandler(ValidateADR); KeyPressEventHandler skills = new KeyPressEventHandler(ValidateSkills); txt_long_distance.KeyPress += skills; txt_high_value_cargo.KeyPress += skills; txt_fragile_cargo.KeyPress += skills; txt_urgent_delivery.KeyPress += skills; txt_ecodriving.KeyPress += skills; foreach (TextBox txtbox in items.Keys) txtbox.TextChanged += boxTextChanged; txt_adr.TextChanged += boxTextChanged; Dictionary update_conf = new Dictionary { { "update_on_start", false } }; string path = Path.Combine(Environment.CurrentDirectory, config_file_name); if (File.Exists(path)) update_conf = JsonConvert.DeserializeObject>(File.ReadAllText(path)); if (update_conf["update_on_start"]) { chk_update_on_start.Checked = true; UpdateForm window = new UpdateForm(); window.ShowDialog(); window.Focus(); } } private void chk_update_on_start_CheckedChanged(object sender, EventArgs e) { File.WriteAllText( Path.Combine(Environment.CurrentDirectory, config_file_name), JsonConvert.SerializeObject(new Dictionary { { "update_on_start", chk_update_on_start.Checked } }) ); } private void btn_open_save_Click(object sender, EventArgs e) { ClearData(); OpenFileDialog ofd = new OpenFileDialog() { Title = "Выберите файл сохранения", Filter = "Сохранение в формате SII|game.sii", Multiselect = false, }; if (ofd.ShowDialog() == DialogResult.OK) { if (GetFileFormat(ofd.FileName) == 2) { if (DecryptAndDecodeFile(ofd.FileName, ofd.FileName) != 0) { Utils.ShowError("Something went wrong with decrypting file. Try again."); return; } } GetFileData(ofd.FileName); opened_file_path = ofd.FileName; } } private void btn_unlock_garages_Click(object sender, EventArgs e) { SecondForm dlg = new SecondForm(selected_game, owns); dlg.ShowDialog(); dlg.Focus(); } private void btn_recover_backup_Click(object sender, EventArgs e) { string backup_path = opened_file_path + ".swbak"; if (!File.Exists(backup_path)) { Utils.ShowError("Backup not found."); return; } File.WriteAllLines(opened_file_path, File.ReadAllLines(backup_path)); File.Delete(backup_path); Utils.ShowInfo("Backup successfully recovered."); GetFileData(opened_file_path); } private void btn_apply_changes_Click(object sender, EventArgs e) { if (!chk_adr.Checked) { List adrList = txt_adr.Text.ToList(); adrList.RemoveAll(i => i == ' ' || i == ',' || i == '.'); if (adrList.Count < 6) { Utils.ShowError("ADR can't have less than 6 elements."); } else if (adrList.Count > 6) { Utils.ShowError("ADR can't have more than 6 elements."); } else { int adrNew = Convert.ToInt32(string.Join("", adrList), 2); RegexHandler.SetValue(RegexHandler.SearchLine("adr:"), adrNew.ToString()); } } foreach (KeyValuePair item in items) if (!item.Value.GetCheck().Checked) RegexHandler.SetValue(RegexHandler.SearchLine(item.Value.GetString()), item.Key.Text); File.WriteAllLines(opened_file_path + ".swbak", RegexHandler.GetBackup()); File.WriteAllLines(opened_file_path, RegexHandler.GetAllLines()); Utils.ShowInfo("Changes successfully applied."); GetFileData(opened_file_path); } } }