diff --git a/AscNet.GameServer/Game/DrawManager.cs b/AscNet.GameServer/Game/DrawManager.cs index cd79e5f8..b17a9e13 100644 --- a/AscNet.GameServer/Game/DrawManager.cs +++ b/AscNet.GameServer/Game/DrawManager.cs @@ -1,8 +1,11 @@ using AscNet.Common.Database; +using AscNet.Common.MsgPack; using AscNet.Common.Util; using AscNet.GameServer.Handlers; +using AscNet.Logging; using AscNet.Table.V2.client.draw; using AscNet.Table.V2.share.character; +using AscNet.Table.V2.share.character.quality; namespace AscNet.GameServer.Game { @@ -10,6 +13,8 @@ namespace AscNet.GameServer.Game { public static readonly List drawSceneTables = TableReaderV2.Parse(); public static readonly List charactersTables = TableReaderV2.Parse(); + public static readonly List characterQualitiesTables = TableReaderV2.Parse(); + static readonly Logger log = new(typeof(DrawManager), LogLevel.DEBUG, LogLevel.DEBUG); #region DrawTags public const int TagBase = 1; @@ -61,12 +66,35 @@ namespace AscNet.GameServer.Game { case GroupArrivalConstruct: // Querying every character scene that is omniframe. - infos.AddRange(drawSceneTables.Where(x => x.Type == 1 && charactersTables.Any(y => y.Type == 1 && y.Id == x.ModelId)).DistinctBy(x => x.ModelId).Select(x => new DrawInfo() + infos.AddRange(drawSceneTables.Where(x => x.Type == 1 && charactersTables.Any(y => + { + // only get the S chars since this is Arrival Construct + int firstQuality = characterQualitiesTables.Where(x => x.CharacterId == y.Id).OrderBy(x => x.Quality).FirstOrDefault()?.Quality ?? 0; + return y.Type == 1 && y.Id == x.ModelId && firstQuality == 3; + })).DistinctBy(x => x.ModelId).Select(x => new DrawInfo() { Id = x.Id, UseItemId = Inventory.FreeGem, UseItemCount = 1, - GroupId = 12, + GroupId = GroupArrivalConstruct, + BtnDrawCount = { 1, 10 }, + Banner = "Assets/Product/Ui/Scene3DPrefab/UiMain3dXiahuo.prefab", + EndTime = DateTimeOffset.Now.ToUnixTimeSeconds() * 2 + })); + break; + case GroupMemberTarget: + // Querying every character scene that is omniframe. + infos.AddRange(drawSceneTables.Where(x => x.Type == 1 && charactersTables.Any(y => + { + // only get the A chars since this is member target + int firstQuality = characterQualitiesTables.Where(x => x.CharacterId == y.Id).OrderBy(x => x.Quality).FirstOrDefault()?.Quality ?? 0; + return y.Type == 1 && y.Id == x.ModelId && firstQuality == 2; + })).DistinctBy(x => x.ModelId).Select(x => new DrawInfo() + { + Id = x.Id, + UseItemId = Inventory.FreeGem, + UseItemCount = 1, + GroupId = GroupMemberTarget, BtnDrawCount = { 1, 10 }, Banner = "Assets/Product/Ui/Scene3DPrefab/UiMain3dXiahuo.prefab", EndTime = DateTimeOffset.Now.ToUnixTimeSeconds() * 2 @@ -76,5 +104,66 @@ namespace AscNet.GameServer.Game return infos; } + + public static int GetGroupByDrawId(int draw) + { + foreach (var groupId in new int[] { GroupMemberTarget, GroupWeaponResearch, GroupTargetWeaponResearch, GroupDormitoryResearch, GroupThemedTargetWeapon, GroupThemedEventConstruct, GroupArrivalConstruct, GroupFateArrivalConstruct, GroupArrivalEventConstruct, GroupFateThemedConstruct, GroupTargetUniframe, GroupAnniversary, GroupFateAnniversaryLimited, GroupCollabTarget, GroupFateCollabTarget, GroupCollabWeaponTarget, GroupCUBTarget, GroupWishingTarget, GroupFateWishingTarget}) + { + if (GetDrawInfosByGroup(groupId).Any(x => x.Id == draw)) + { + return groupId; + } + } + + log.Error($"Get group not found for draw {draw}"); + return 0; + } + + public static List DrawDraw(int drawId) + { + List rewards = new(); + var drawScene = drawSceneTables.Find(x => x.Id == drawId); + var drawPool = TableReaderV2.Parse().Find(x => x.Id == drawId); + if (drawScene is null || drawPool is null) + { + log.Error($"Invalid draw id {drawId}"); + return rewards; + } + + switch (drawScene.Type) + { + case 1: + // Character + if (drawPool.UpGoodsId.Count > 0 && Random.Shared.NextDouble() >= 0.7) + { + rewards.Add(new() + { + RewardType = (int)RewardType.Character, + Level = 1, + Id = drawPool.UpGoodsId[Random.Shared.Next(drawPool.UpGoodsId.Count)] + }); + } + else + { + rewards.Add(new() + { + RewardType = (int)RewardType.Character, + Level = 1, + Id = drawPool.GoodsId[Random.Shared.Next(drawPool.GoodsId.Count)] + }); + } + break; + case 2: + // Weapon + break; + case 3: + // CUB + break; + default: + break; + } + + return rewards; + } } } diff --git a/AscNet.GameServer/AutoFightModule.cs b/AscNet.GameServer/Handlers/AutoFightModule.cs similarity index 96% rename from AscNet.GameServer/AutoFightModule.cs rename to AscNet.GameServer/Handlers/AutoFightModule.cs index 69076668..9ab22d59 100644 --- a/AscNet.GameServer/AutoFightModule.cs +++ b/AscNet.GameServer/Handlers/AutoFightModule.cs @@ -1,6 +1,6 @@ using MessagePack; -namespace AscNet.GameServer +namespace AscNet.GameServer.Handlers { #region MsgPackScheme diff --git a/AscNet.GameServer/Handlers/DrawModule.cs b/AscNet.GameServer/Handlers/DrawModule.cs index 36adda66..42d45db9 100644 --- a/AscNet.GameServer/Handlers/DrawModule.cs +++ b/AscNet.GameServer/Handlers/DrawModule.cs @@ -1,14 +1,41 @@ -using AscNet.Common.Database; -using AscNet.Common.Util; +using AscNet.Common.MsgPack; using AscNet.GameServer.Game; -using AscNet.Table.V2.client.draw; using MessagePack; -using static AscNet.GameServer.Packet; namespace AscNet.GameServer.Handlers { #region MsgPackScheme #pragma warning disable CS8618 // Non-nullable field must contain a non-null value when exiting constructor. Consider declaring as nullable. + [MessagePackObject(true)] + public class DrawDrawCardRequest + { + public int DrawId { get; set; } + public int Count { get; set; } + public int UseDrawTicketId { get; set; } + } + + [MessagePackObject(true)] + public class DrawDrawCardResponse + { + public int Code { get; set; } + public List RewardGoodsList { get; set; } = new(); + public List ExtraRewardList { get; set; } = new(); + public DrawInfo ClientDrawInfo { get; set; } + } + + [MessagePackObject(true)] + public class DrawSetUseDrawIdRequest + { + public int DrawId { get; set; } + } + + [MessagePackObject(true)] + public class DrawSetUseDrawIdResponse + { + public int Code { get; set; } + public int SwitchDrawIdCount { get; set; } + } + [MessagePackObject(true)] public class DrawGetDrawInfoListResponse { @@ -84,6 +111,18 @@ namespace AscNet.GameServer.Handlers BannerEndTime = DateTimeOffset.Now.ToUnixTimeSeconds() * 2 }); } + { + var drawInfos = DrawManager.GetDrawInfosByGroup(DrawManager.GroupMemberTarget); + rsp.DrawGroupInfoList.Add(new() + { + Id = DrawManager.GroupMemberTarget, + UseDrawId = drawInfos.Count > 0 ? drawInfos.First().Id : 0, + Order = 1, + Tag = DrawManager.TagBase, + EndTime = DateTimeOffset.Now.ToUnixTimeSeconds() * 2, + BannerEndTime = DateTimeOffset.Now.ToUnixTimeSeconds() * 2 + }); + } session.SendResponse(rsp, packet.Id); } @@ -98,5 +137,31 @@ namespace AscNet.GameServer.Handlers session.SendResponse(rsp, packet.Id); } + + [RequestPacketHandler("DrawSetUseDrawIdRequest")] + public static void DrawSetUseDrawIdRequestHandler(Session session, Packet.Request packet) + { + DrawSetUseDrawIdRequest request = packet.Deserialize(); + + session.SendResponse(new DrawSetUseDrawIdResponse(), packet.Id); + } + + [RequestPacketHandler("DrawDrawCardRequest")] + public static void DrawDrawCardRequestHandler(Session session, Packet.Request packet) + { + DrawDrawCardRequest request = packet.Deserialize(); + DrawDrawCardResponse rsp = new(); + + for (int i = 0; i < request.Count; i++) + { + rsp.RewardGoodsList.AddRange(DrawManager.DrawDraw(request.DrawId)); + } + + DrawInfo? drawInfo = DrawManager.GetDrawInfosByGroup(DrawManager.GetGroupByDrawId(request.DrawId)).Find(x => x.Id == request.DrawId); + if (drawInfo is not null) + rsp.ClientDrawInfo = drawInfo; + + session.SendResponse(rsp, packet.Id); + } } }