diff --git a/Common/Data/Custom/BannersConfig.cs b/Common/Data/Custom/BannersConfig.cs index 301ee196..301140a3 100644 --- a/Common/Data/Custom/BannersConfig.cs +++ b/Common/Data/Custom/BannersConfig.cs @@ -114,7 +114,7 @@ public class BannerConfig return gold[random.Next(0, gold.Count)]; } - public GachaInfo ToInfo(List goldAvatar) + public GachaInfo ToInfo(List decideOrder, List goldAvatar) { var info = new GachaInfo { @@ -127,6 +127,17 @@ public class BannerConfig { info.BeginTime = BeginTime; info.EndTime = EndTime; + info.DecideItemInfo = new DecideItemInfo(); + } + + if (GachaType == GachaTypeEnum.AvatarUp) + { + info.DecideItemInfo = new DecideItemInfo + { + DecideItemOrder = { decideOrder.Select(x => (uint)x) }, + CHDOIBFEHLP = 1, + JIGONEALCPC = { 11 } + }; } if (GachaId == 1001) diff --git a/Common/Data/Excel/DecideAvatarOrderExcel.cs b/Common/Data/Excel/DecideAvatarOrderExcel.cs new file mode 100644 index 00000000..00a48adb --- /dev/null +++ b/Common/Data/Excel/DecideAvatarOrderExcel.cs @@ -0,0 +1,18 @@ +namespace EggLink.DanhengServer.Data.Excel; + +[ResourceEntity("DecideAvatarOrder.json")] +public class DecideAvatarOrderExcel : ExcelResource +{ + public int ItemID { get; set; } = 0; + public int Order { get; set; } = 0; + + public override int GetId() + { + return ItemID; + } + + public override void Loaded() + { + GameData.DecideAvatarOrderData.Add(ItemID, this); + } +} \ No newline at end of file diff --git a/Common/Data/Excel/RechargeConfigExcel.cs b/Common/Data/Excel/RechargeConfigExcel.cs new file mode 100644 index 00000000..2de4a85a --- /dev/null +++ b/Common/Data/Excel/RechargeConfigExcel.cs @@ -0,0 +1,20 @@ +namespace EggLink.DanhengServer.Data.Excel; + +[ResourceEntity("RechargeConfig.json")] +public class RechargeConfigExcel : ExcelResource +{ + public string TierID { get; set; } = ""; + public string ProductID { get; set; } = ""; + public int GiftType { get; set; } + public int ListOrder { get; set; } + + public override int GetId() + { + return TierID.GetHashCode(); + } + + public override void Loaded() + { + GameData.RechargeConfigData[ProductID] = this; + } +} \ No newline at end of file diff --git a/Common/Data/Excel/RechargeGiftConfigExcel.cs b/Common/Data/Excel/RechargeGiftConfigExcel.cs new file mode 100644 index 00000000..c816b57d --- /dev/null +++ b/Common/Data/Excel/RechargeGiftConfigExcel.cs @@ -0,0 +1,18 @@ +namespace EggLink.DanhengServer.Data.Excel; + +[ResourceEntity("RechargeGiftConfig.json")] +public class RechargeGiftConfigExcel : ExcelResource +{ + public int GiftType { get; set; } + public List GiftIDList { get; set; } = []; + + public override int GetId() + { + return GiftType; + } + + public override void Loaded() + { + GameData.RechargeGiftConfigData.Add(GiftType, this); + } +} \ No newline at end of file diff --git a/Common/Data/GameData.cs b/Common/Data/GameData.cs index c9d380b2..0d8ae977 100644 --- a/Common/Data/GameData.cs +++ b/Common/Data/GameData.cs @@ -51,6 +51,7 @@ public static class GameData public static Dictionary AdventurePlayerData { get; private set; } = []; public static Dictionary SummonUnitDataData { get; private set; } = []; + public static Dictionary DecideAvatarOrderData { get; private set; } = []; #endregion @@ -112,6 +113,8 @@ public static class GameData public static Dictionary PlayerLevelConfigData { get; private set; } = []; public static Dictionary BackGroundMusicData { get; private set; } = []; public static Dictionary ChatBubbleConfigData { get; private set; } = []; + public static Dictionary RechargeConfigData { get; private set; } = []; + public static Dictionary RechargeGiftConfigData { get; private set; } = []; #endregion diff --git a/Common/Database/Gacha/GachaData.cs b/Common/Database/Gacha/GachaData.cs index 8c8b4d5d..bb34b750 100644 --- a/Common/Database/Gacha/GachaData.cs +++ b/Common/Database/Gacha/GachaData.cs @@ -11,6 +11,7 @@ public class GachaData : BaseDatabaseDataHelper public bool LastWeaponGachaFailed { get; set; } = false; public int LastGachaFailedCount { get; set; } = 0; public int LastGachaPurpleFailedCount { get; set; } = 0; + [SugarColumn(IsJson = true)] public List GachaDecideOrder { get; set; } = []; } public class GachaInfo diff --git a/Common/Database/Player/ServerPrefsData.cs b/Common/Database/Player/ServerPrefsData.cs index 314cc730..b8cd38c5 100644 --- a/Common/Database/Player/ServerPrefsData.cs +++ b/Common/Database/Player/ServerPrefsData.cs @@ -9,7 +9,7 @@ public class ServerPrefsData : BaseDatabaseDataHelper { [SugarColumn(IsJson = true)] public Dictionary ServerPrefsDict { get; set; } = []; - public double Version { get; set; } = 2.4; + public double Version { get; set; } = 3.2; public void SetData(int prefsId, string b64Data) { diff --git a/Common/Util/GameConstants.cs b/Common/Util/GameConstants.cs index 5f18cdc0..13bdc32c 100644 --- a/Common/Util/GameConstants.cs +++ b/Common/Util/GameConstants.cs @@ -3,6 +3,7 @@ public static class GameConstants { public const string GAME_VERSION = "3.2.0"; + public const int GameVersionInt = 3200; public const int MAX_STAMINA = 300; public const int MAX_STAMINA_RESERVE = 2400; public const int STAMINA_RECOVERY_TIME = 360; // 6 minutes diff --git a/GameServer/Game/Gacha/GachaManager.cs b/GameServer/Game/Gacha/GachaManager.cs index 4936eb07..75196583 100644 --- a/GameServer/Game/Gacha/GachaManager.cs +++ b/GameServer/Game/Gacha/GachaManager.cs @@ -11,9 +11,23 @@ using GachaInfo = EggLink.DanhengServer.Database.Gacha.GachaInfo; namespace EggLink.DanhengServer.GameServer.Game.Gacha; -public class GachaManager(PlayerInstance player) : BasePlayerManager(player) +public class GachaManager : BasePlayerManager { - public GachaData GachaData { get; } = DatabaseHelper.Instance!.GetInstanceOrCreateNew(player.Uid); + public GachaData GachaData { get; } + + public GachaManager(PlayerInstance player) : base(player) + { + GachaData = DatabaseHelper.Instance!.GetInstanceOrCreateNew(player.Uid); + + if (GachaData.GachaHistory.Count >= 50) + GachaData.GachaHistory.RemoveRange(0, GachaData.GachaHistory.Count - 50); + + foreach (var order in GameData.DecideAvatarOrderData.Values.ToList().OrderBy(x => -x.Order)) + { + if (GachaData.GachaDecideOrder.Contains(order.ItemID)) continue; + GachaData.GachaDecideOrder.Add(order.ItemID); + } + } public List GetPurpleAvatars() { @@ -21,7 +35,7 @@ public class GachaManager(PlayerInstance player) : BasePlayerManager(player) foreach (var avatar in GameData.AvatarConfigData.Values) if (avatar.Rarity == RarityEnum.CombatPowerAvatarRarityType4 && !(GameData.MultiplePathAvatarConfigData.ContainsKey(avatar.AvatarID) && - GameData.MultiplePathAvatarConfigData[avatar.AvatarID].BaseAvatarID != avatar.AvatarID)) + GameData.MultiplePathAvatarConfigData[avatar.AvatarID].BaseAvatarID != avatar.AvatarID) && avatar.MaxRank > 0) purpleAvatars.Add(avatar.AvatarID); return purpleAvatars; } @@ -98,11 +112,11 @@ public class GachaManager(PlayerInstance player) : BasePlayerManager(player) var banner = GameData.BannersConfig.Banners.Find(x => x.GachaId == bannerId); if (banner == null) return null; Player.InventoryManager?.RemoveItem(banner.GachaType.GetCostItemId(), times); - + var decideItem = GachaData.GachaDecideOrder.GetRange(0, 7); var items = new List(); for (var i = 0; i < times; i++) { - var item = banner.DoGacha(GetGoldAvatars(), GetPurpleAvatars(), GetPurpleWeapons(), GetGoldWeapons(), + var item = banner.DoGacha(decideItem, GetPurpleAvatars(), GetPurpleWeapons(), GetGoldWeapons(), GetBlueWeapons(), GachaData); items.Add(item); } @@ -284,7 +298,8 @@ public class GachaManager(PlayerInstance player) : BasePlayerManager(player) { GachaRandom = (uint)Random.Shared.Next(1000, 1999) }; - foreach (var banner in GameData.BannersConfig.Banners) proto.GachaInfoList.Add(banner.ToInfo(GetGoldAvatars())); + foreach (var banner in GameData.BannersConfig.Banners) proto.GachaInfoList.Add(banner.ToInfo(GachaData.GachaDecideOrder, GetGoldAvatars())); + return proto; } } \ No newline at end of file diff --git a/GameServer/Server/Packet/Recv/Gacha/HandlerSetGachaDecideItemCsReq.cs b/GameServer/Server/Packet/Recv/Gacha/HandlerSetGachaDecideItemCsReq.cs new file mode 100644 index 00000000..70b1bd17 --- /dev/null +++ b/GameServer/Server/Packet/Recv/Gacha/HandlerSetGachaDecideItemCsReq.cs @@ -0,0 +1,18 @@ +using EggLink.DanhengServer.GameServer.Server.Packet.Send.Gacha; +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.Gacha; + +[Opcode(CmdIds.SetGachaDecideItemCsReq)] +public class HandlerSetGachaDecideItemCsReq : Handler +{ + public override async Task OnHandle(Connection connection, byte[] header, byte[] data) + { + var req = SetGachaDecideItemCsReq.Parser.ParseFrom(data); + + connection.Player!.GachaManager!.GachaData.GachaDecideOrder = req.DecideItemOrder.Select(x => (int)x).ToList(); + + await connection.SendPacket(new PacketSetGachaDecideItemScRsp(req.GachaId, req.DecideItemOrder.ToList())); + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Recv/RechargeGift/HandlerGetRechargeGiftInfoCsReq.cs b/GameServer/Server/Packet/Recv/RechargeGift/HandlerGetRechargeGiftInfoCsReq.cs new file mode 100644 index 00000000..f6f21f6b --- /dev/null +++ b/GameServer/Server/Packet/Recv/RechargeGift/HandlerGetRechargeGiftInfoCsReq.cs @@ -0,0 +1,13 @@ +using EggLink.DanhengServer.GameServer.Server.Packet.Send.RechargeGift; +using EggLink.DanhengServer.Kcp; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Recv.RechargeGift; + +[Opcode(CmdIds.GetRechargeGiftInfoCsReq)] +public class HandlerGetRechargeGiftInfoCsReq : Handler +{ + public override async Task OnHandle(Connection connection, byte[] header, byte[] data) + { + await connection.SendPacket(new PacketGetRechargeGiftInfoScRsp()); + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/Gacha/PacketSetGachaDecideItemScRsp.cs b/GameServer/Server/Packet/Send/Gacha/PacketSetGachaDecideItemScRsp.cs new file mode 100644 index 00000000..d7f04f3a --- /dev/null +++ b/GameServer/Server/Packet/Send/Gacha/PacketSetGachaDecideItemScRsp.cs @@ -0,0 +1,21 @@ +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.Gacha; + +public class PacketSetGachaDecideItemScRsp : BasePacket +{ + public PacketSetGachaDecideItemScRsp(uint gachaId, List order) : base(CmdIds.SetGachaDecideItemScRsp) + { + var proto = new SetGachaDecideItemScRsp + { + GachaId = gachaId, + DecideItemInfo = new DecideItemInfo + { + DecideItemOrder = { order }, + CHDOIBFEHLP = 1, + JIGONEALCPC = { 11 } + } + }; + } +} \ No newline at end of file diff --git a/GameServer/Server/Packet/Send/Player/PacketQueryProductInfoScRsp.cs b/GameServer/Server/Packet/Send/Player/PacketQueryProductInfoScRsp.cs index 66c24035..f2949c96 100644 --- a/GameServer/Server/Packet/Send/Player/PacketQueryProductInfoScRsp.cs +++ b/GameServer/Server/Packet/Send/Player/PacketQueryProductInfoScRsp.cs @@ -1,4 +1,5 @@ -using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Data; +using EggLink.DanhengServer.Kcp; using EggLink.DanhengServer.Proto; namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.Player; @@ -10,6 +11,13 @@ public class PacketQueryProductInfoScRsp : BasePacket var proto = new QueryProductInfoScRsp { //PEKJLBINDGG = (ulong)Extensions.GetUnixSec() + 8640000, // 100 day + ProductList = { GameData.RechargeConfigData.Values.Where(x => x.GiftType != 1).Select(x => new Product + { + EndTime = uint.MaxValue, + GiftType = (ProductGiftType)x.GiftType, + PriceTier = x.TierID, + ProductId = x.ProductID + }) } }; SetData(proto); diff --git a/GameServer/Server/Packet/Send/RechargeGift/PacketGetRechargeGiftInfoScRsp.cs b/GameServer/Server/Packet/Send/RechargeGift/PacketGetRechargeGiftInfoScRsp.cs new file mode 100644 index 00000000..58e54608 --- /dev/null +++ b/GameServer/Server/Packet/Send/RechargeGift/PacketGetRechargeGiftInfoScRsp.cs @@ -0,0 +1,33 @@ +using EggLink.DanhengServer.Data; +using EggLink.DanhengServer.Kcp; +using EggLink.DanhengServer.Proto; + +namespace EggLink.DanhengServer.GameServer.Server.Packet.Send.RechargeGift; + +public class PacketGetRechargeGiftInfoScRsp : BasePacket +{ + public PacketGetRechargeGiftInfoScRsp() : base(CmdIds.GetRechargeGiftInfoScRsp) + { + var proto = new GetRechargeGiftInfoScRsp + { + RechargeBenefitList = + { + GameData.RechargeGiftConfigData.Values.Select(x => new RechargeGiftInfo + { + GiftType = (uint)x.GiftType, + EndTime = uint.MaxValue, + GiftDataList = + { + x.GiftIDList.Select(h => new RechargeGiftData + { + Status = RechargeGiftStatus.Received, + Index = (uint)x.GiftIDList.IndexOf(h), + }) + } + }) + } + }; + + SetData(proto); + } +} \ No newline at end of file