using Microsoft.AspNetCore.RateLimiting; using Microsoft.AspNetCore.SignalR; using Newtonsoft.Json; using QuestShare.Common.API.Share; using QuestShare.Server.Hubs; using QuestShare.Server.Managers; using QuestShare.Server.Models; namespace QuestShare.Server.Hubs { public partial class ShareHub : Hub { [EnableRateLimiting("ClientPolicy")] [HubMethodName(nameof(Register))] public async Task Server_Register(Register.Request request) { if (BanManager.IsBanned(Context)) { Log.Warning($"[REGISTER] Client {Context.ConnectionId} is banned."); Context.Abort(); return; } var error = Error.None; if (request.CharacterId == 0) error = Error.InvalidCharacterId; if (request.Version != Common.Constants.Version) error = Error.InvalidVersion; var client = ClientManager.GetClient(Context.ConnectionId); if (client == null || client.Token != request.Token) { error = Error.Unauthorized; if (BanManager.CheckBadRequests(Context, nameof(Register))) { error = Error.BannedTooManyBadRequests; } } if (error != Error.None) { Log.Warning($"[REGISTER] Client {Context.ConnectionId} failed registration with error {error}."); await Clients.Caller.SendAsync(nameof(Register), new Register.Response { Success = false, Error = error, ShareCode = "", }); return; } if (request.BroadcastParty && request.PartyMembers.Count > 0) { foreach (var partyMember in request.PartyMembers) { ShareManager.AddBroadcastPartyMember(request.CharacterId, partyMember); } } if (ShareManager.GetShare(client!) != null) { Log.Warning($"[REGISTER] Client {Context.ConnectionId} already registered."); await Clients.Caller.SendAsync(nameof(Register), new Register.Response { Success = false, Error = Error.AlreadyRegistered, ShareCode = "" }); return; } var share = new Share { ShareCode = ShareManager.GenerateShareCode(), ShareHost = client!, BroadcastParty = request.BroadcastParty, SharedQuestId = request.SharedQuestId, SharedQuestStep = request.SharedQuestStep, }; var newShare = await ShareManager.AddShare(share); Log.Information($"[REGISTER] Client {Context.ConnectionId} registered share {share.ShareCode}."); await Clients.Caller.SendAsync(nameof(Register), new Register.Response { Success = true, Error = Error.None, ShareCode = share.ShareCode, }); } } }