This repository has been archived on 2024-12-22. You can view files and clone it, but cannot push or open issues or pull requests.
elliebot/src/EllieBot/Services/GrpcApi/WarnSvc.cs

224 lines
No EOL
6.8 KiB
C#

using Grpc.Core;
using EllieBot.Db.Models;
using EllieBot.Modules.Administration.Services;
using Enum = System.Enum;
namespace EllieBot.GrpcApi;
public sealed class WarnSvc : GrpcWarn.GrpcWarnBase, IGrpcSvc, IEService
{
private readonly UserPunishService _ups;
private readonly DiscordSocketClient _client;
public WarnSvc(UserPunishService ups, DiscordSocketClient client)
{
_ups = ups;
_client = client;
}
public ServerServiceDefinition Bind()
=> GrpcWarn.BindService(this);
public override async Task<WarnSettingsReply> GetWarnSettings(
WarnSettingsRequest request,
ServerCallContext context)
{
var list = await _ups.WarnPunishList(request.GuildId);
var wsr = new WarnSettingsReply();
(wsr.ExpiryDays, wsr.DeleteOnExpire) = await _ups.GetWarnExpire(request.GuildId);
wsr.Punishments.AddRange(list.Select(x => new WarnPunishment()
{
Action = x.Punishment.ToString(),
Duration = x.Time,
Threshold = x.Count,
Role = x.RoleId is ulong rid
? _client.GetGuild(request.GuildId)?.GetRole(rid)?.Name ?? x.RoleId?.ToString() ?? string.Empty
: string.Empty
}));
return wsr;
}
public override async Task<SetWarnExpiryReply> SetWarnExpiry(
SetWarnExpiryRequest request,
ServerCallContext context)
{
if (request.ExpiryDays > 366)
{
return new SetWarnExpiryReply()
{
Success = false
};
}
await _ups.WarnExpireAsync(request.GuildId, request.ExpiryDays, request.DeleteOnExpire);
return new SetWarnExpiryReply()
{
Success = true
};
}
public override async Task<DeleteWarnpReply> DeleteWarnp(DeleteWarnpRequest request, ServerCallContext context)
{
var succ = await _ups.WarnPunishRemove(request.GuildId, request.Threshold);
return new DeleteWarnpReply
{
Success = succ
};
}
public override async Task<AddWarnpReply> AddWarnp(AddWarnpRequest request, ServerCallContext context)
{
if (request.Punishment.Threshold <= 0)
throw new RpcException(new Status(StatusCode.InvalidArgument, "Threshold must be greater than 0"));
var g = _client.GetGuild(request.GuildId);
if (g is null)
throw new RpcException(new Status(StatusCode.NotFound, "Guild not found"));
if (!Enum.TryParse<PunishmentAction>(request.Punishment.Action, out var action))
throw new RpcException(new Status(StatusCode.InvalidArgument, "Invalid action"));
IRole? role = null;
if (action == PunishmentAction.AddRole && ulong.TryParse(request.Punishment.Role, out var roleId))
{
role = g.GetRole(roleId);
if (role is null)
return new AddWarnpReply()
{
Success = false
};
if (!ulong.TryParse(context.RequestHeaders.GetValue("userid"), out var userId))
return new AddWarnpReply()
{
Success = false
};
var user = await ((IGuild)g).GetUserAsync(userId);
if (user is null)
throw new RpcException(new Status(StatusCode.NotFound, "User not found"));
var userMaxRole = user.GetRoles().MaxBy(x => x.Position)?.Position ?? 0;
if (g.OwnerId != user.Id && userMaxRole <= role.Position)
{
return new AddWarnpReply()
{
Success = false
};
}
}
var duration = TimeSpan.FromMinutes(request.Punishment.Duration);
var succ = await _ups.WarnPunish(request.GuildId,
request.Punishment.Threshold,
action,
duration,
role
);
return new AddWarnpReply()
{
Success = succ
};
}
public override async Task<GetLatestWarningsReply> GetLatestWarnings(
GetLatestWarningsRequest request,
ServerCallContext context)
{
var (latest, count) = await _ups.GetLatestWarnings(request.GuildId, request.Page);
var reply = new GetLatestWarningsReply()
{
TotalCount = count
};
reply.Warnings.AddRange(latest.Select(MapWarningToGrpcWarning));
return reply;
}
public override async Task<GetUserWarningsReply> GetUserWarnings(
GetUserWarningsRequest request,
ServerCallContext context)
{
IReadOnlyCollection<Db.Models.Warning> latest = [];
var count = 0;
if (ulong.TryParse(request.User, out var userId))
{
(latest, count) = await _ups.GetUserWarnings(request.GuildId, userId, request.Page);
}
else if (_client.GetGuild(request.GuildId)?.Users.FirstOrDefault(x => x.Username == request.User) is { } user)
{
(latest, count) = await _ups.GetUserWarnings(request.GuildId, user.Id, request.Page);
}
else
{
}
var reply = new GetUserWarningsReply
{
TotalCount = count
};
reply.Warnings.AddRange(latest.Select(MapWarningToGrpcWarning));
return reply;
}
private Warning MapWarningToGrpcWarning(Db.Models.Warning x)
{
return new Warning
{
Id = new kwum(x.Id).ToString(),
Forgiven = x.Forgiven,
ForgivenBy = x.ForgivenBy ?? string.Empty,
Reason = x.Reason ?? string.Empty,
Timestamp = x.DateAdded is { } da ? Ellie.Common.Extensions.ToTimestamp(da) : 0,
Weight = x.Weight,
Moderator = x.Moderator ?? string.Empty,
User = _client.GetUser(x.UserId)?.Username ?? x.UserId.ToString(),
UserId = x.UserId
};
}
public override async Task<ForgiveWarningReply> ForgiveWarning(
ForgiveWarningRequest request,
ServerCallContext context)
{
if (!kwum.TryParse(request.WarnId, out var wid))
throw new RpcException(new Status(StatusCode.InvalidArgument, "Invalid warning ID"));
var succ = await _ups.ForgiveWarning(request.GuildId, wid, request.ModName);
return new ForgiveWarningReply
{
Success = succ
};
}
public override async Task<ForgiveWarningReply> DeleteWarning(
ForgiveWarningRequest request,
ServerCallContext context)
{
if (!kwum.TryParse(request.WarnId, out var wid))
throw new RpcException(new Status(StatusCode.InvalidArgument, "Invalid warning ID"));
var succ = await _ups.WarnDelete(request.GuildId, wid);
return new ForgiveWarningReply
{
Success = succ
};
}
}