diff --git a/AscNet.Common/Database/Inventory.cs b/AscNet.Common/Database/Inventory.cs new file mode 100644 index 0000000..c2ff2c5 --- /dev/null +++ b/AscNet.Common/Database/Inventory.cs @@ -0,0 +1,69 @@ +using AscNet.Common.MsgPack; +using MongoDB.Bson; +using MongoDB.Bson.Serialization.Attributes; +using MongoDB.Driver; +using Newtonsoft.Json; + +namespace AscNet.Common.Database +{ + #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + public class Inventory + { + public static readonly IMongoCollection collection = Common.db.GetCollection("inventory"); + + public static Inventory FromUid(long uid) + { + return collection.AsQueryable().FirstOrDefault(x => x.Uid == uid) ?? Create(uid); + } + + private static Inventory Create(long uid) + { + Inventory inventory = new() + { + Uid = uid, + Items = new() + }; + + List? defaultItems = JsonConvert.DeserializeObject>(File.ReadAllText("./Configs/default_items.json")); + if (defaultItems is not null) + { + inventory.Items.AddRange(defaultItems.Select(item => new Item() + { + Id = item.Id, + Count = item.Count, + RefreshTime = DateTimeOffset.Now.ToUnixTimeSeconds(), + CreateTime = DateTimeOffset.Now.ToUnixTimeSeconds() + })); + } + + collection.InsertOne(inventory); + + return inventory; + } + + public void Save() + { + collection.ReplaceOne(Builders.Filter.Eq(x => x.Id, Id), this); + } + + [BsonId] + public ObjectId Id { get; set; } + + [BsonElement("uid")] + [BsonRequired] + public long Uid { get; set; } + + [BsonElement("items")] + [BsonRequired] + public List Items { get; set; } + } + + public partial class ItemConfig + { + [JsonProperty("Id")] + public int Id { get; set; } + + [JsonProperty("Count")] + public long Count { get; set; } + } +} diff --git a/AscNet.Common/MsgPack/Types.cs b/AscNet.Common/MsgPack/Types.cs index 3c1e8ea..79ca454 100644 --- a/AscNet.Common/MsgPack/Types.cs +++ b/AscNet.Common/MsgPack/Types.cs @@ -212,7 +212,7 @@ namespace AscNet.Common.MsgPack } [MessagePackObject(true)] - public partial class ItemList + public partial class Item { public int Id { get; set; } public long Count { get; set; } @@ -319,7 +319,7 @@ namespace AscNet.Common.MsgPack public PlayerData PlayerData { get; set; } public List TimeLimitCtrlConfigList { get; set; } = new(); public List SharePlatformConfigList { get; set; } = new(); - public List ItemList { get; set; } = new(); + public List ItemList { get; set; } = new(); public Dictionary> ItemRecycleDict { get; set; } = new(); public List CharacterList { get; set; } = new(); public List EquipList { get; set; } = new(); diff --git a/AscNet.Common/Util/Miscs.cs b/AscNet.Common/Util/Miscs.cs index 0f56c87..8f1ab1e 100644 --- a/AscNet.Common/Util/Miscs.cs +++ b/AscNet.Common/Util/Miscs.cs @@ -2,7 +2,7 @@ { public static class Miscs { - public static int ParseIntOr(string? s, int d) + public static int ParseIntOr(string? s, int d = 0) { if (int.TryParse(s, out var parsed)) { diff --git a/AscNet.GameServer/Handlers/AccountModule.cs b/AscNet.GameServer/Handlers/AccountModule.cs index 3c98a80..b272a6c 100644 --- a/AscNet.GameServer/Handlers/AccountModule.cs +++ b/AscNet.GameServer/Handlers/AccountModule.cs @@ -1,6 +1,8 @@ using AscNet.Common.Database; using AscNet.Common.MsgPack; +using AscNet.Common.Util; using AscNet.Table.share.guide; +using AscNet.Table.share.item; using MessagePack; namespace AscNet.GameServer.Handlers @@ -64,6 +66,8 @@ namespace AscNet.GameServer.Handlers session.player = player; session.character = Character.FromUid(player.PlayerData.Id); session.stage = Stage.FromUid(player.PlayerData.Id); + session.inventory = Inventory.FromUid(player.PlayerData.Id); + session.SendResponse(new LoginResponse { Code = 0, @@ -85,10 +89,11 @@ namespace AscNet.GameServer.Handlers else { player = Player.FromToken(request.Token); - if (player is not null && (session.character is null || session.stage is null)) + if (player is not null && (session.character is null || session.stage is null || session.inventory is null)) { session.character = Character.FromUid(player.PlayerData.Id); session.stage = Stage.FromUid(player.PlayerData.Id); + session.inventory = Inventory.FromUid(player.PlayerData.Id); } } @@ -131,7 +136,7 @@ namespace AscNet.GameServer.Handlers FubenMainLineData = new(), FubenChapterExtraLoginData = new(), FubenUrgentEventData = new(), - // ItemList = ItemTableReader.Instance.All.Select(x => new ItemList() { Id = x.Id, Count = 6969696969 }).ToList(), + ItemList = session.inventory.Items, UseBackgroundId = 14000001 // main ui theme, table still failed to dump }; if (notifyLogin.PlayerData.DisplayCharIdList.Count < 1) diff --git a/AscNet.GameServer/Session.cs b/AscNet.GameServer/Session.cs index 279a2ff..78d76d9 100644 --- a/AscNet.GameServer/Session.cs +++ b/AscNet.GameServer/Session.cs @@ -17,6 +17,7 @@ namespace AscNet.GameServer public Player player = default!; public Character character = default!; public Stage stage = default!; + public Inventory inventory = default!; public readonly Logger log; private long lastPacketTime = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds(); private ushort packetNo = 0; @@ -222,6 +223,7 @@ namespace AscNet.GameServer player?.Save(); character?.Save(); stage?.Save(); + inventory?.Save(); log.Warn($"{id} disconnected"); client.Close(); diff --git a/AscNet/Program.cs b/AscNet/Program.cs index bf59147..8e12ac1 100644 --- a/AscNet/Program.cs +++ b/AscNet/Program.cs @@ -29,6 +29,8 @@ namespace AscNet static void KillProtocol(object? sender, EventArgs e) { + LoggerFactory.Logger.Info("Shutting down..."); + foreach (var session in Server.Instance.Sessions) { session.Value.SendPush(new ShutdownNotify()); diff --git a/Resources/Configs/default_items.json b/Resources/Configs/default_items.json new file mode 100644 index 0000000..1030e1c --- /dev/null +++ b/Resources/Configs/default_items.json @@ -0,0 +1,26 @@ +[ + { + "Id": 1, + "Count": 30000 + }, + { + "Id": 4, + "Count": 70 + }, + { + "Id": 12, + "Count": 10 + }, + { + "Id": 17, + "Count": 21 + }, + { + "Id": 21, + "Count": 99 + }, + { + "Id": 22, + "Count": 21 + } +] \ No newline at end of file