diff --git a/MHSEC-G/MHSEC-G/App.xaml.cs b/MHSEC-G/MHSEC-G/App.xaml.cs index dc85ee5..00e9452 100644 --- a/MHSEC-G/MHSEC-G/App.xaml.cs +++ b/MHSEC-G/MHSEC-G/App.xaml.cs @@ -10,15 +10,5 @@ namespace MHSEC_G { public partial class App : Application { - private Model model; - public Model get_model() - { - return model; - } - - public void set_model(Model model) - { - - } } } diff --git a/MHSEC-G/MHSEC-G/Character.cs b/MHSEC-G/MHSEC-G/Character.cs index c7da394..3a58683 100644 --- a/MHSEC-G/MHSEC-G/Character.cs +++ b/MHSEC-G/MHSEC-G/Character.cs @@ -1,4 +1,5 @@ using System.ComponentModel; +using System.Windows; using MHSEC_G.Annotations; namespace MHSEC_G @@ -6,46 +7,88 @@ namespace MHSEC_G public class Character : INotifyPropertyChanged { private const uint OFFSETA_CHAR_NAME = 0x9DA0; - private const uint LENGTH_CHAR_NAME = 6; + private const uint LENGTH_CHAR_NAME = 5; private const uint OFFSETA_CHAR_MONEY = 0x5B404; private const uint OFFSETA_CHAR_EXP = 0x9E68; private const uint OFFSETA_CHAR_LEVEL = 0x9E64; + public const uint LIMIT_LEVEL = 99; + public const uint LIMIT_MONEY = 9999999; + public const uint LIMIT_EXP = 25165822; - private uint _char_level; - public uint char_level + private readonly Model _model; + + public uint level { - get { return _char_level; } - set { _char_level = value; OnPropertyChanged(nameof(char_level)); } + get { return Model.byte_to_uint(_model.save_file[OFFSETA_CHAR_LEVEL]); } + set + { + if (value <= LIMIT_LEVEL) + { + Model.write_byte(_model.save_file, OFFSETA_CHAR_LEVEL, value); + } + else + { + MessageBox.Show("Level must be less than " + LIMIT_LEVEL, "Error", MessageBoxButton.OK, MessageBoxImage.Error); + } + OnPropertyChanged(nameof(level)); + } } - private uint _char_exp; - public uint char_exp + public uint exp { - get { return _char_exp; } - set { _char_exp = value; OnPropertyChanged(nameof(char_exp)); } + get { return Model.byte_to_uint32_le(_model.save_file, OFFSETA_CHAR_EXP); } + set + { + if (value <= LIMIT_EXP) + { + Model.write_uint32_le(_model.save_file, OFFSETA_CHAR_EXP, value); + } + else + { + MessageBox.Show("Exp must be less than " + LIMIT_EXP, "Error", MessageBoxButton.OK, MessageBoxImage.Error); + } + OnPropertyChanged(nameof(exp)); + } } - private uint _char_money; - public uint char_money + public uint money { - get { return _char_money; } - set { _char_money = value; OnPropertyChanged(nameof(char_money)); } + get { return Model.byte_to_uint32_le(_model.save_file, OFFSETA_CHAR_MONEY); } + set + { + if (value <= LIMIT_MONEY) + { + Model.write_uint32_le(_model.save_file, OFFSETA_CHAR_MONEY, value); + } + else + { + MessageBox.Show("Money must be less than " + LIMIT_MONEY, "Error", MessageBoxButton.OK, MessageBoxImage.Error); + } + OnPropertyChanged(nameof(money)); + } } - private string _char_name; - public string char_name + public string name { - get { return _char_name; } - set { _char_name = value; OnPropertyChanged(nameof(char_name)); } + get { return Model.read_unicode_string(_model.save_file, OFFSETA_CHAR_NAME, LENGTH_CHAR_NAME); } + set + { + if (value.Length <= LENGTH_CHAR_NAME && value.Length > 0) + { + Model.write_unicode_string(_model.save_file, OFFSETA_CHAR_NAME, value, LENGTH_CHAR_NAME); + } + else + { + MessageBox.Show("Name must be 1-6 characters.", "Error", MessageBoxButton.OK, MessageBoxImage.Error); + } + OnPropertyChanged(nameof(name)); + } } - public Character(byte[] save_data) + public Character(Model model) { - _char_level = Model.byte_to_uint(save_data[OFFSETA_CHAR_LEVEL]); - _char_exp = Model.byte_to_uint32_le(save_data, OFFSETA_CHAR_EXP); - _char_money = Model.byte_to_uint32_le(save_data, OFFSETA_CHAR_MONEY); - _char_name = Model.read_unicode_string(save_data, OFFSETA_CHAR_NAME, LENGTH_CHAR_NAME); + _model = model; } public event PropertyChangedEventHandler PropertyChanged; diff --git a/MHSEC-G/MHSEC-G/Item.cs b/MHSEC-G/MHSEC-G/Item.cs index 72753fe..4163c26 100644 --- a/MHSEC-G/MHSEC-G/Item.cs +++ b/MHSEC-G/MHSEC-G/Item.cs @@ -1,11 +1,132 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; -using System.Text; +using System.Windows; +using MHSEC_G.Annotations; namespace MHSEC_G { - class Item + public class Item : INotifyPropertyChanged { + private static readonly uint OFFSETA_ITEM_BOX = 0x10; + private static readonly uint SIZE_ITEM = 0x8; + private static readonly uint OFFSETR_ITEM_ID = 0x0; + private static readonly uint OFFSETR_ITEM_COUNT = 0x2; + private static readonly uint OFFSETA_ITEM_BOX_END = 0x2EE7; + + private static readonly string ID_MAPPING_FILE_NAME = "C:\\Users\\hyper\\Desktop\\idmap.txt"; + private static readonly Dictionary OFFSET_ID_MAPPING = new Dictionary(); + private static readonly Dictionary OFFSET_NAME_MAPPING = new Dictionary(); + + private readonly uint _offset; + private readonly Model _model; + + public string name + { + get { + string name = "Unknown"; + if (OFFSET_NAME_MAPPING.ContainsKey(_offset)) + { + name = OFFSET_NAME_MAPPING[_offset]; + } + return name; + } + } + + + public uint count + { + get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_ITEM_COUNT); } + set + { + if (value <= 999) + { + Model.write_uint16_le(_model.save_file, _offset + OFFSETR_ITEM_COUNT, value); + } + else + { + MessageBox.Show("Quantity must be less than 999.","Error",MessageBoxButton.OK, MessageBoxImage.Error); + } + OnPropertyChanged(nameof(count)); + } + } + + public uint id + { + get { return Model.byte_to_uint16_le(_model.save_file, _offset + OFFSETR_ITEM_ID); } + } + + public Item(uint offset, Model model) + { + _offset = offset; + _model = model; + } + + public static List read_all_items(Model model) + { + byte[] buffer = model.save_file; + List ret = new List(); + for (uint offset = OFFSETA_ITEM_BOX; offset < OFFSETA_ITEM_BOX_END; offset += SIZE_ITEM) + { + string name = "Unknown"; + uint item_id = Model.byte_to_uint16_le(buffer, offset + OFFSETR_ITEM_ID); + + if (item_id == 0) + { + // if not obtained yet + if (!OFFSET_ID_MAPPING.ContainsKey(offset)) + { + // well we dont know the id to this offset either. just ignore! + // continue + continue; + } + + } + else + { + // already obtained + // validate + if (OFFSET_ID_MAPPING.ContainsKey(offset)) + { + if (item_id != OFFSET_ID_MAPPING[offset]) + { + throw new SystemException("Item offset and ID do not correspond."); + } + } + } + // valid offset + ret.Add(new Item(offset, model)); + } + return ret; + } + + public static void read_item_mappings() + { + string line; + System.IO.StreamReader file = new System.IO.StreamReader(ID_MAPPING_FILE_NAME); + while ((line = file.ReadLine()) != null) + { + if (line.Length == 0) + continue; + + string[] eachline = line.Split('\t'); + if (eachline.Length != 3) + throw new SystemException("Item mapping file is corrupted."); + + OFFSET_ID_MAPPING.Add(UInt32.Parse(eachline[0], System.Globalization.NumberStyles.HexNumber), UInt32.Parse(eachline[1], System.Globalization.NumberStyles.HexNumber)); + OFFSET_NAME_MAPPING.Add(UInt32.Parse(eachline[0], System.Globalization.NumberStyles.HexNumber), eachline[2]); + } + + file.Close(); + } + + public event PropertyChangedEventHandler PropertyChanged; + + [NotifyPropertyChangedInvocator] + protected virtual void OnPropertyChanged(string propertyName) + { + PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); + } } } diff --git a/MHSEC-G/MHSEC-G/MHSEC-G.csproj b/MHSEC-G/MHSEC-G/MHSEC-G.csproj index d5d11c7..75bc4dd 100644 --- a/MHSEC-G/MHSEC-G/MHSEC-G.csproj +++ b/MHSEC-G/MHSEC-G/MHSEC-G.csproj @@ -98,6 +98,9 @@ + + +