58 lines
2.4 KiB
C#

using System.Collections.Generic;
namespace ET.Server
{
[MessageSessionHandler(SceneType.Gate)]
[FriendOf(typeof(GachaComponent))]
public class C2G_GachaDrawHandler : RpcMessageHandler<C2G_GachaDraw, R2C_GachaDraw>
{
protected override async ETTask OnRun(Session session, C2G_GachaDraw request, R2C_GachaDraw response)
{
SessionPlayerComponent sessionPlayer = session.GetComponent<SessionPlayerComponent>();
Player player = sessionPlayer?.Player;
if (player == null)
{
response.Error = ErrorCode.ERR_RpcFail;
response.Message = "Player not found";
return;
}
GachaComponent gacha = player.GetComponent<GachaComponent>() ?? player.AddComponent<GachaComponent>();
if (!gacha.PoolStats.TryGetValue(request.poolId, out GachaPoolState state))
{
state = new GachaPoolState();
gacha.PoolStats[request.poolId] = state;
}
long now = TimeInfo.Instance.ServerNow();
if (now - state.LastDrawMs < 100)
{
response.Error = ErrorCode.ERR_GACHA_RATE_LIMIT;
response.Message = "Rate limited";
Log.Error($"[L3][Gacha] player={player.Id} poolId={request.poolId} rate-limit");
return;
}
BagComponent bag = player.GetComponent<BagComponent>() ?? player.AddComponent<BagComponent>();
List<RewardEntry> rewards = gacha.Draw(request.poolId, (GachaDrawType)request.drawType, bag);
response.rewards.AddRange(rewards);
foreach (RewardEntry reward in rewards)
{
response.isNewHero.Add(reward.ItemId >= 10000);
}
Gacha_GachaInfo info = Gacha_GachaInfo.Create();
foreach (var kv in gacha.PoolStats)
{
GachaPoolStats stat = GachaPoolStats.Create();
stat.poolId = kv.Key;
stat.totalCount = kv.Value.TotalCount;
stat.guaranteeRemain = kv.Value.GuaranteeRemain;
info.stats.Add(stat);
}
session.Send(info);
LogExtensions.Audit("Gacha", "DrawHandler", $"{{\"playerId\":{player.Id},\"poolId\":{request.poolId},\"count\":{rewards.Count}}}");
await ETTask.CompletedTask;
}
}
}