diff --git a/Api/Utility/Factory.cs b/Api/Utility/Factory.cs index ff08525..4a9ad5d 100644 --- a/Api/Utility/Factory.cs +++ b/Api/Utility/Factory.cs @@ -131,7 +131,17 @@ namespace Milimoe.FunGame.Core.Api.Utility TXTHelper.AppendErrorLog(e.GetErrorInfo()); } } - return (T)(object)new OpenSkill(id, name, args); + + Skill openSkill = new OpenSkill(id, name, args); + if (args.TryGetValue("values", out object? value) && value is Dictionary dict) + { + foreach (string key in dict.Keys) + { + openSkill.Values[key] = dict[key]; + } + } + + return (T)(object)openSkill; } if (typeof(T) == typeof(Effect)) { @@ -167,7 +177,7 @@ namespace Milimoe.FunGame.Core.Api.Utility TXTHelper.AppendErrorLog(e.GetErrorInfo()); } } - return (T)(object)GetItem(); + return (T)(object)new OpenItem(id, name, args); } if (typeof(T) == typeof(Room)) { diff --git a/Api/Utility/JsonTool.cs b/Api/Utility/JsonTool.cs index 36ac012..399b7e3 100644 --- a/Api/Utility/JsonTool.cs +++ b/Api/Utility/JsonTool.cs @@ -15,17 +15,15 @@ namespace Milimoe.FunGame.Core.Api.Utility public class JsonTool { /// - /// 序列化选项 - /// 已经默认添加了下列转换器: - /// , , + /// 序列化选项 /// - public JsonSerializerOptions JsonSerializerOptions => options; + public static JsonSerializerOptions JsonSerializerOptions => JsonManager.GeneralOptions; /// /// 注册一个自定义转换器,支持 /// /// - public void AddConverter(JsonConverter converter) + public static void AddConverter(JsonConverter converter) { if (!JsonSerializerOptions.Converters.Contains(converter)) JsonSerializerOptions.Converters.Add(converter); @@ -49,7 +47,7 @@ namespace Milimoe.FunGame.Core.Api.Utility /// /// /// - public string GetString(T obj) => JsonManager.GetString(obj, options); + public string GetString(T obj) => JsonManager.GetString(obj, JsonSerializerOptions); /// /// 反序列化Json对象 @@ -57,14 +55,14 @@ namespace Milimoe.FunGame.Core.Api.Utility /// /// /// - public T? GetObject(string json) => JsonManager.GetObject(json, options); + public T? GetObject(string json) => JsonManager.GetObject(json, JsonSerializerOptions); /// /// 反序列化Json对象,此方法可能无法返回正确的类型,请注意辨别 /// /// /// - public object? GetObject(string json) => JsonManager.GetObject(json, options); + public object? GetObject(string json) => JsonManager.GetObject(json, JsonSerializerOptions); /// /// 反序列化Hashtable中Key对应的Json对象 @@ -73,7 +71,7 @@ namespace Milimoe.FunGame.Core.Api.Utility /// /// /// - public T? GetObject(Hashtable table, string key) => JsonManager.GetObject(table, key, options); + public T? GetObject(Hashtable table, string key) => JsonManager.GetObject(table, key, JsonSerializerOptions); /// /// 反序列化Dictionary中Key对应的Json对象 @@ -82,7 +80,7 @@ namespace Milimoe.FunGame.Core.Api.Utility /// /// /// - public T? GetObject(Dictionary dict, string key) => JsonManager.GetObject(dict, key, options); + public T? GetObject(Dictionary dict, string key) => JsonManager.GetObject(dict, key, JsonSerializerOptions); /// /// 反序列化IEnumerable中的Json对象 可指定反序列化选项 @@ -91,7 +89,7 @@ namespace Milimoe.FunGame.Core.Api.Utility /// /// /// - public T? JsonDeserializeFromIEnumerable(IEnumerable e, int index) => JsonManager.GetObject(e, index, options); + public T? JsonDeserializeFromIEnumerable(IEnumerable e, int index) => JsonManager.GetObject(e, index, JsonSerializerOptions); /// /// 反序列化多个Json对象 @@ -100,18 +98,6 @@ namespace Milimoe.FunGame.Core.Api.Utility /// /// /// - public List GetObjects(string json) => JsonManager.GetObjects(json, options); - - /// - /// Private JsonSerializerOptions - /// - private readonly JsonSerializerOptions options = new() - { - WriteIndented = true, - PropertyNameCaseInsensitive = true, - ReferenceHandler = ReferenceHandler.IgnoreCycles, - Converters = { new DateTimeConverter(), new DataTableConverter(), new DataSetConverter(), new UserConverter(), new RoomConverter(), - new CharacterConverter(), new MagicResistanceConverter(), new EquipSlotConverter(), new SkillConverter(), new EffectConverter(), new ItemConverter() } - }; + public List GetObjects(string json) => JsonManager.GetObjects(json, JsonSerializerOptions); } } diff --git a/Entity/Character/Character.cs b/Entity/Character/Character.cs index 5d919c1..01c773b 100644 --- a/Entity/Character/Character.cs +++ b/Entity/Character/Character.cs @@ -1306,6 +1306,7 @@ namespace Milimoe.FunGame.Core.Entity { Id = Id, Name = Name, + Guid = Guid, FirstName = FirstName, NickName = NickName, Profile = Profile.Copy(), @@ -1394,7 +1395,7 @@ namespace Milimoe.FunGame.Core.Entity Skills.Clear(); Items.Clear(); Id = c.Id; - Guid = original.Guid; + Guid = c.Guid; Name = c.Name; FirstName = c.FirstName; NickName = c.NickName; diff --git a/Entity/Character/CharacterBuilder.cs b/Entity/Character/CharacterBuilder.cs new file mode 100644 index 0000000..d2f72aa --- /dev/null +++ b/Entity/Character/CharacterBuilder.cs @@ -0,0 +1,82 @@ +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Library.Constant; + +namespace Milimoe.FunGame.Core.Entity +{ + public class CharacterBuilder(long id, string name, string firstName, string nickName, PrimaryAttribute primaryAttribute, double initialATK, double initialHP, double initialMP, double initialSTR, double strGrowth, double initialAGI, double agiGrowth, double initialINT, double intGrowth, double initialSPD, double initialHR, double initialMR) + { + public long Id { get; set; } = id; + public string Name { get; set; } = name; + public string FirstName { get; set; } = firstName; + public string NickName { get; set; } = nickName; + public PrimaryAttribute PrimaryAttribute { get; set; } = primaryAttribute; + public double InitialATK { get; set; } = initialATK; + public double InitialHP { get; set; } = initialHP; + public double InitialMP { get; set; } = initialMP; + public double InitialSTR { get; set; } = initialSTR; + public double STRGrowth { get; set; } = strGrowth; + public double InitialAGI { get; set; } = initialAGI; + public double AGIGrowth { get; set; } = agiGrowth; + public double InitialINT { get; set; } = initialINT; + public double INTGrowth { get; set; } = intGrowth; + public double InitialSPD { get; set; } = initialSPD; + public double InitialHR { get; set; } = initialHR; + public double InitialMR { get; set; } = initialMR; + + public Character Build(int level, IEnumerable skills, IEnumerable items, EquipSlot? equips = null) + { + Character character = Factory.GetCharacter(); + character.Id = Id; + character.Name = Name; + character.FirstName = FirstName; + character.NickName = NickName; + character.PrimaryAttribute = PrimaryAttribute; + character.InitialATK = InitialATK; + character.InitialHP = InitialHP; + character.InitialMP = InitialMP; + character.InitialSTR = InitialSTR; + character.STRGrowth = STRGrowth; + character.InitialAGI = InitialAGI; + character.AGIGrowth = AGIGrowth; + character.InitialINT = InitialINT; + character.INTGrowth = INTGrowth; + character.InitialSPD = InitialSPD; + character.InitialHR = InitialHR; + character.InitialMR = InitialMR; + if (level > 1) + { + character.Level = level; + } + foreach (Skill skill in skills) + { + Skill newskill = skill.Copy(); + newskill.Character = character; + newskill.Level = skill.Level; + newskill.CurrentCD = 0; + character.Skills.Add(newskill); + } + foreach (Item item in items) + { + Item newitem = item.Copy(true); + newitem.Character = character; + character.Items.Add(newitem); + } + if (equips != null) + { + Item? mcp = equips.MagicCardPack; + Item? w = equips.Weapon; + Item? a = equips.Armor; + Item? s = equips.Shoes; + Item? ac1 = equips.Accessory1; + Item? ac2 = equips.Accessory2; + if (mcp != null) character.Equip(mcp); + if (w != null) character.Equip(w); + if (a != null) character.Equip(a); + if (s != null) character.Equip(s); + if (ac1 != null) character.Equip(ac1); + if (ac2 != null) character.Equip(ac2); + } + return character; + } + } +} diff --git a/Entity/Item/Item.cs b/Entity/Item/Item.cs index fa15a08..6b9e57d 100644 --- a/Entity/Item/Item.cs +++ b/Entity/Item/Item.cs @@ -11,6 +11,11 @@ namespace Milimoe.FunGame.Core.Entity /// public class Item : BaseEntity, IItem { + /// + /// 唯一标识符 + /// + public override Guid Guid { get; set; } = Guid.NewGuid(); + /// /// 物品的描述 /// @@ -499,6 +504,7 @@ namespace Milimoe.FunGame.Core.Entity SetPropertyToItemModuleNew(item); item.Id = Id; item.Name = Name; + item.Guid = Guid; item.Description = Description; item.GeneralDescription = GeneralDescription; item.BackgroundStory = BackgroundStory; @@ -519,24 +525,27 @@ namespace Milimoe.FunGame.Core.Entity item.IsTradable = IsTradable; item.NextTradableTime = NextTradableTime; item.RemainUseTimes = RemainUseTimes; - item.Skills.Active = Skills.Active?.Copy(); - if (item.Skills.Active != null) + if (item is OpenItem) { - item.Skills.Active.Level = copyLevel ? (Skills.Active?.Level ?? 1) : 1; - } - foreach (Skill skill in Skills.Passives) - { - Skill newskill = skill.Copy(); - newskill.Item = item; - newskill.Level = copyLevel ? skill.Level : 1; - item.Skills.Passives.Add(newskill); - } - foreach (Skill skill in Skills.Magics) - { - Skill newskill = skill.Copy(); - newskill.Item = item; - newskill.Level = copyLevel ? skill.Level : 1; - item.Skills.Magics.Add(newskill); + item.Skills.Active = Skills.Active?.Copy(); + if (item.Skills.Active != null) + { + item.Skills.Active.Level = copyLevel ? (Skills.Active?.Level ?? 1) : 1; + } + foreach (Skill skill in Skills.Passives) + { + Skill newskill = skill.Copy(); + newskill.Item = item; + newskill.Level = copyLevel ? skill.Level : 1; + item.Skills.Passives.Add(newskill); + } + foreach (Skill skill in Skills.Magics) + { + Skill newskill = skill.Copy(); + newskill.Item = item; + newskill.Level = copyLevel ? skill.Level : 1; + item.Skills.Magics.Add(newskill); + } } return item; } diff --git a/Entity/Item/OpenItem.cs b/Entity/Item/OpenItem.cs new file mode 100644 index 0000000..74757e8 --- /dev/null +++ b/Entity/Item/OpenItem.cs @@ -0,0 +1,21 @@ +namespace Milimoe.FunGame.Core.Entity +{ + /// + /// 用于动态扩展物品 + /// + public class OpenItem : Item + { + public override long Id { get; set; } + public override string Name { get; set; } + + public OpenItem(long id, string name, Dictionary args) + { + Id = id; + Name = name; + foreach (string key in args.Keys) + { + Others[key] = args[key]; + } + } + } +} diff --git a/Entity/System/Inventory.cs b/Entity/System/Inventory.cs index 0e2bff9..00c6d7a 100644 --- a/Entity/System/Inventory.cs +++ b/Entity/System/Inventory.cs @@ -5,12 +5,13 @@ public long Id => User.Id; public string Name { get; set; } = ""; public User User { get; } - public Dictionary Characters { get; set; } = new(); - public Dictionary Items { get; set; } = new(); + public Dictionary Characters { get; } = []; + public Dictionary Items { get; } = []; internal Inventory(User user) { User = user; + Name = user.Username + "的库存"; } } } diff --git a/Library/Common/JsonConverter/InventoryConverter.cs b/Library/Common/JsonConverter/InventoryConverter.cs new file mode 100644 index 0000000..6d96a6f --- /dev/null +++ b/Library/Common/JsonConverter/InventoryConverter.cs @@ -0,0 +1,52 @@ +using System.Text.Json; +using Milimoe.FunGame.Core.Api.Utility; +using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Library.Common.Architecture; + +namespace Milimoe.FunGame.Core.Library.Common.JsonConverter +{ + public class InventoryConverter : BaseEntityConverter + { + public override Inventory NewInstance() + { + return Factory.GetInventory(); + } + + public override void ReadPropertyName(ref Utf8JsonReader reader, string propertyName, JsonSerializerOptions options, ref Inventory result) + { + switch (propertyName) + { + case nameof(Inventory.Name): + result.Name = reader.GetString() ?? ""; + break; + case nameof(Inventory.Characters): + Dictionary characters = NetworkUtility.JsonDeserialize>(ref reader, options) ?? []; + foreach (string key in characters.Keys) + { + result.Characters[key] = characters[key]; + } + break; + case nameof(Inventory.Items): + Dictionary items = NetworkUtility.JsonDeserialize>(ref reader, options) ?? []; + foreach (string key in items.Keys) + { + result.Items[key] = items[key]; + } + break; + } + } + + public override void Write(Utf8JsonWriter writer, Inventory value, JsonSerializerOptions options) + { + writer.WriteStartObject(); + + writer.WriteString(nameof(Inventory.Name), value.Name); + writer.WritePropertyName(nameof(Inventory.Characters)); + JsonSerializer.Serialize(writer, value.Characters, options); + writer.WritePropertyName(nameof(Inventory.Items)); + JsonSerializer.Serialize(writer, value.Items, options); + + writer.WriteEndObject(); + } + } +} diff --git a/Library/Common/JsonConverter/ItemConverter.cs b/Library/Common/JsonConverter/ItemConverter.cs index b3bc088..7097412 100644 --- a/Library/Common/JsonConverter/ItemConverter.cs +++ b/Library/Common/JsonConverter/ItemConverter.cs @@ -23,6 +23,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter case nameof(Item.Name): result.Name = reader.GetString() ?? ""; break; + case nameof(Item.Guid): + result.Guid = reader.GetGuid(); + break; case nameof(Item.Description): result.Description = reader.GetString() ?? ""; break; @@ -112,6 +115,8 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter writer.WriteNumber(nameof(Item.Id), (int)value.Id); writer.WriteString(nameof(Item.Name), value.Name); + writer.WritePropertyName(nameof(Item.Guid)); + JsonSerializer.Serialize(writer, value.Guid, options); writer.WriteString(nameof(Item.Description), value.Description); writer.WriteString(nameof(Item.GeneralDescription), value.GeneralDescription); writer.WriteString(nameof(Item.BackgroundStory), value.BackgroundStory); diff --git a/Library/Common/JsonConverter/UserConverter.cs b/Library/Common/JsonConverter/UserConverter.cs index 99b3de5..d8ef325 100644 --- a/Library/Common/JsonConverter/UserConverter.cs +++ b/Library/Common/JsonConverter/UserConverter.cs @@ -1,6 +1,7 @@ using System.Text.Json; using Milimoe.FunGame.Core.Api.Utility; using Milimoe.FunGame.Core.Entity; +using Milimoe.FunGame.Core.Interface.Entity; using Milimoe.FunGame.Core.Library.Common.Architecture; using Milimoe.FunGame.Core.Library.Constant; using Milimoe.FunGame.Core.Library.SQLScript.Entity; @@ -67,12 +68,25 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter case UserQuery.Column_AutoKey: result.AutoKey = reader.GetString() ?? ""; break; + case nameof(Inventory): + Inventory inventory = NetworkUtility.JsonDeserialize(ref reader, options) ?? Factory.GetInventory(); + result.Inventory.Name = inventory.Name; + foreach (string key in inventory.Characters.Keys) + { + result.Inventory.Characters[key] = inventory.Characters[key]; + } + foreach (string key in inventory.Items.Keys) + { + result.Inventory.Items[key] = inventory.Items[key]; + } + break; } } public override void Write(Utf8JsonWriter writer, User value, JsonSerializerOptions options) { writer.WriteStartObject(); + writer.WriteNumber(UserQuery.Column_UID, value.Id); writer.WriteString(UserQuery.Column_Username, value.Username); writer.WriteString(UserQuery.Column_RegTime, value.RegTime.ToString(General.GeneralDateTimeFormat)); @@ -86,6 +100,9 @@ namespace Milimoe.FunGame.Core.Library.Common.JsonConverter writer.WriteNumber(UserQuery.Column_Materials, value.Materials); writer.WriteNumber(UserQuery.Column_GameTime, value.GameTime); writer.WriteString(UserQuery.Column_AutoKey, value.AutoKey); + writer.WritePropertyName(nameof(Inventory)); + JsonSerializer.Serialize(writer, value.Inventory, options); + writer.WriteEndObject(); } } diff --git a/Service/JsonManager.cs b/Service/JsonManager.cs index 429f5a4..f00452b 100644 --- a/Service/JsonManager.cs +++ b/Service/JsonManager.cs @@ -13,14 +13,16 @@ namespace Milimoe.FunGame.Core.Service /// /// 默认的序列化选项 /// - private readonly static JsonSerializerOptions GeneralOptions = new() + internal static JsonSerializerOptions GeneralOptions { get; } = new() { WriteIndented = true, PropertyNameCaseInsensitive = true, Encoder = JavaScriptEncoder.Create(UnicodeRanges.All), ReferenceHandler = ReferenceHandler.IgnoreCycles, Converters = { new DateTimeConverter(), new DataTableConverter(), new DataSetConverter(), new UserConverter(), new RoomConverter(), - new CharacterConverter(), new MagicResistanceConverter(), new EquipSlotConverter(), new SkillConverter(), new EffectConverter(), new ItemConverter() } + new CharacterConverter(), new MagicResistanceConverter(), new EquipSlotConverter(), new SkillConverter(), new EffectConverter(), new ItemConverter(), + new InventoryConverter() + } }; ///