mirror of
https://github.com/LBPUnion/ProjectLighthouse.git
synced 2025-05-09 11:52:27 +00:00
Add grief report webhook, add ability to link to individual reports
This commit is contained in:
parent
2dcf8dd390
commit
6ca81e0421
9 changed files with 317 additions and 212 deletions
|
@ -2,6 +2,7 @@
|
|||
using System.Text.Json;
|
||||
using System.Xml.Serialization;
|
||||
using LBPUnion.ProjectLighthouse.Administration.Reports;
|
||||
using LBPUnion.ProjectLighthouse.Configuration;
|
||||
using LBPUnion.ProjectLighthouse.Helpers;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
|
||||
using LBPUnion.ProjectLighthouse.Types;
|
||||
|
@ -45,6 +46,13 @@ public class ReportController : ControllerBase
|
|||
this.database.Reports.Add(report);
|
||||
await this.database.SaveChangesAsync();
|
||||
|
||||
await WebhookHelper.SendWebhook(
|
||||
title: "New grief report",
|
||||
description: $"Submitted by {user.Username}\n" +
|
||||
$"To view it, click [here]({ServerConfiguration.Instance.ExternalUrl}/admin/report/{report.ReportId}).",
|
||||
dest: WebhookHelper.WebhookDestination.Moderation
|
||||
);
|
||||
|
||||
return this.Ok();
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
<script>
|
||||
function getReportId(name){
|
||||
let split = name.split("-");
|
||||
return split[split.length-1];
|
||||
}
|
||||
const colours = ["#96dd3c", "#ceb424", "#cc0a1d", "#c800cc"];
|
||||
let displayType;
|
||||
window.addEventListener("load", function () {
|
||||
document.querySelectorAll(".hover-players").forEach(item => {
|
||||
item.addEventListener('mouseenter', function () {
|
||||
let reportId = getReportId(item.id);
|
||||
const canvas = canvases[reportId];
|
||||
displayType = 1;
|
||||
|
||||
canvas.className = "photo-subjects";
|
||||
|
||||
redraw(reportId);
|
||||
});
|
||||
});
|
||||
document.querySelectorAll(".hover-region").forEach(item => {
|
||||
item.addEventListener('mouseenter', function () {
|
||||
let reportId = getReportId(item.id);
|
||||
const canvas = canvases[reportId];
|
||||
const image = document.getElementById("game-image-" + reportId.toString());
|
||||
displayType = 0;
|
||||
|
||||
canvas.className = "photo-subjects";
|
||||
|
||||
canvas.width = image.offsetWidth;
|
||||
canvas.height = image.clientHeight; // space for names to hang off
|
||||
|
||||
redraw(reportId);
|
||||
});
|
||||
});
|
||||
document.querySelectorAll(".hover-region, .hover-players").forEach(item => {
|
||||
item.addEventListener('mouseleave', function () {
|
||||
canvases[getReportId(item.id)].className = "photo-subjects hide-subjects";
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
|
||||
function redraw(reportId){
|
||||
let context = ctx[reportId];
|
||||
let canvas = canvases[reportId];
|
||||
let image = images[reportId];
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
let w = canvas.width;
|
||||
let h = canvas.height;
|
||||
|
||||
// halfwidth, halfheight
|
||||
const hw = w / 2;
|
||||
const hh = h / 2;
|
||||
switch (displayType){
|
||||
case 0: {
|
||||
let imageBounds = bounds[reportId];
|
||||
const x1 = imageBounds.Left;
|
||||
const x2 = imageBounds.Right;
|
||||
const y1 = imageBounds.Top;
|
||||
const y2 = imageBounds.Bottom;
|
||||
const scaleX = image.naturalWidth / canvas.width;
|
||||
const scaleY = image.naturalHeight / canvas.height;
|
||||
const bx = canvas.width-(x2/scaleX);
|
||||
const by = canvas.height-(y2/scaleY);
|
||||
const bw = (x2 - x1) / scaleX;
|
||||
const bh = (y2 - y1) / scaleY;
|
||||
context.beginPath();
|
||||
context.globalAlpha = 0.6;
|
||||
context.fillStyle = "black";
|
||||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||
context.clearRect(bx, by, bw, bh);
|
||||
context.beginPath();
|
||||
context.lineWidth = 2;
|
||||
context.strokeStyle = "#957a24";
|
||||
context.rect(bx, by, bw, bh);
|
||||
context.stroke();
|
||||
context.globalAlpha = 1.0;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
let subject = subjects[reportId];
|
||||
subject.forEach((s, si) => {
|
||||
const colour = colours[si % 4];
|
||||
|
||||
// Bounding box
|
||||
const x1 = s.Location.Left;
|
||||
const x2 = s.Location.Right;
|
||||
const y1 = s.Location.Top;
|
||||
const y2 = s.Location.Bottom;
|
||||
|
||||
const scaleX = image.naturalWidth / canvas.width;
|
||||
const scaleY = image.naturalHeight / canvas.height;
|
||||
|
||||
|
||||
const bx = canvas.width-(x2/scaleX);
|
||||
const by = canvas.height-(y2/scaleY);
|
||||
const bw = (x2 - x1) / scaleX;
|
||||
const bh = (y2 - y1) / scaleY;
|
||||
|
||||
context.beginPath();
|
||||
context.lineWidth = 3;
|
||||
context.strokeStyle = colour;
|
||||
context.rect(bx, by, bw, bh);
|
||||
context.stroke();
|
||||
|
||||
// Move into relative coordinates from bounding box
|
||||
context.translate(bx, by);
|
||||
|
||||
// Username label
|
||||
context.font = "16px Lato";
|
||||
context.fillStyle = colour;
|
||||
|
||||
// Text width/height for the label background
|
||||
const tw = context.measureText(s.Name).width;
|
||||
const th = 24;
|
||||
|
||||
// Check if the label will flow off the bottom of the frame
|
||||
const overflowBottom = (y2+tw - 24) > (canvas.width);
|
||||
// Check if the label will flow off the left of the frame
|
||||
const overflowLeft = (x2) < (24);
|
||||
|
||||
// Set alignment
|
||||
context.textAlign = overflowLeft ? "start" : "end";
|
||||
|
||||
// Text x / y
|
||||
const lx = overflowLeft ? -bw + 6 : -6;
|
||||
const ly = overflowBottom ? -bh - 6 : 16;
|
||||
|
||||
// Label background x / y
|
||||
const lbx = overflowLeft ? bw - tw - 12 : 0;
|
||||
const lby = overflowBottom ? bh : -24;
|
||||
|
||||
// Draw background
|
||||
context.fillRect(lbx, lby, tw+8, th);
|
||||
|
||||
// Draw text, rotated back upright (canvas draws rotated 180deg)
|
||||
context.fillStyle = "white";
|
||||
context.rotate(Math.PI);
|
||||
context.fillText(s.Name, lx, ly);
|
||||
|
||||
// reset transform
|
||||
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -0,0 +1,63 @@
|
|||
@using LBPUnion.ProjectLighthouse.Administration.Reports
|
||||
@model LBPUnion.ProjectLighthouse.Administration.Reports.GriefReport
|
||||
|
||||
<div class="ui segment">
|
||||
<div>
|
||||
<canvas class="hide-subjects" id="canvas-subjects-@Model.ReportId" width="1920" height="1080"
|
||||
style="position: absolute; transform: rotate(180deg)">
|
||||
</canvas>
|
||||
<img class="hover-region" id="game-image-@Model.ReportId" src="/gameAssets/@Model.JpegHash" alt="Grief report picture" style="width: 100%; height: auto; border-radius: .28571429rem;">
|
||||
</div>
|
||||
<p>
|
||||
<i>
|
||||
Report submitted by
|
||||
<b>
|
||||
<a href="/user/@Model.ReportingPlayerId">@Model.ReportingPlayer.Username</a>
|
||||
</b>
|
||||
</i>
|
||||
</p>
|
||||
<b class="hover-players" id="hover-subjects-2-@Model.ReportId">Report contains @Model.XmlPlayers.Length @(Model.XmlPlayers.Length == 1 ? "player" : "players")</b>
|
||||
@foreach (ReportPlayer player in Model.XmlPlayers)
|
||||
{
|
||||
<div id="hover-subjects-@Model.ReportId" class="hover-players">
|
||||
<a href="/">@player.Name</a>
|
||||
</div>
|
||||
}
|
||||
|
||||
<br>
|
||||
<div>
|
||||
<b>Report time: </b>@(DateTimeOffset.FromUnixTimeMilliseconds(Model.Timestamp).ToString("R"))
|
||||
</div>
|
||||
<div>
|
||||
<b>Report reason: </b>@Model.Type
|
||||
</div>
|
||||
<div>
|
||||
<b>Level ID:</b> @Model.LevelId
|
||||
</div>
|
||||
<div>
|
||||
<b>Level type:</b> @Model.LevelType
|
||||
</div>
|
||||
<div>
|
||||
<b>Level owner:</b> @Model.LevelOwner
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<a class="ui green small button" href="/admin/report/@Model.ReportId/dismiss">
|
||||
<i class="checkmark icon"></i>
|
||||
<span>Dismiss</span>
|
||||
</a>
|
||||
<a class="ui red small button" href="/admin/report/@Model.ReportId/remove">
|
||||
<i class="trash icon"></i>
|
||||
<span>Remove all related assets</span>
|
||||
</a>
|
||||
</div>
|
||||
<script>
|
||||
subjects[@Model.ReportId] = @Html.Raw(Model.Players)
|
||||
bounds[@Model.ReportId] = @Html.Raw(Model.Bounds)
|
||||
images[@Model.ReportId] = document.getElementById("game-image-@Model.ReportId")
|
||||
canvases[@Model.ReportId] = document.getElementById("canvas-subjects-@Model.ReportId")
|
||||
canvases[@Model.ReportId].width = images[@Model.ReportId].offsetWidth;
|
||||
canvases[@Model.ReportId].height = images[@Model.ReportId].clientHeight;
|
||||
ctx[@Model.ReportId] = canvases[@Model.ReportId].getContext('2d');
|
||||
</script>
|
||||
|
18
ProjectLighthouse.Servers.Website/Pages/ReportPage.cshtml
Normal file
18
ProjectLighthouse.Servers.Website/Pages/ReportPage.cshtml
Normal file
|
@ -0,0 +1,18 @@
|
|||
@page "/admin/report/{reportId:int}"
|
||||
@model LBPUnion.ProjectLighthouse.Servers.Website.Pages.ReportPage
|
||||
|
||||
@{
|
||||
Layout = "Layouts/BaseLayout";
|
||||
Model.Title = $"Report {Model.Report.ReportId}";
|
||||
}
|
||||
|
||||
<script>
|
||||
let subjects = [];
|
||||
let bounds = [];
|
||||
let canvases = [];
|
||||
let ctx = [];
|
||||
let images = [];
|
||||
</script>
|
||||
|
||||
@await Html.PartialAsync("Partials/ReportPartial", Model.Report)
|
||||
@await Html.PartialAsync("Partials/RenderReportBoundsPartial")
|
42
ProjectLighthouse.Servers.Website/Pages/ReportPage.cshtml.cs
Normal file
42
ProjectLighthouse.Servers.Website/Pages/ReportPage.cshtml.cs
Normal file
|
@ -0,0 +1,42 @@
|
|||
using System.Text.Json;
|
||||
using LBPUnion.ProjectLighthouse.Administration.Reports;
|
||||
using LBPUnion.ProjectLighthouse.PlayerData.Profiles;
|
||||
using LBPUnion.ProjectLighthouse.Servers.Website.Pages.Layouts;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.RazorPages;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace LBPUnion.ProjectLighthouse.Servers.Website.Pages;
|
||||
|
||||
public class ReportPage : BaseLayout
|
||||
{
|
||||
public ReportPage(Database database) : base(database)
|
||||
{}
|
||||
|
||||
public GriefReport Report;
|
||||
|
||||
public async Task<IActionResult> OnGet([FromRoute] int reportId)
|
||||
{
|
||||
User? user = this.Database.UserFromWebRequest(this.Request);
|
||||
if (user == null) return this.Redirect("~/login");
|
||||
if (!user.IsAdmin) return this.NotFound();
|
||||
|
||||
GriefReport? report = await this.Database.Reports
|
||||
.Include(r => r.ReportingPlayer)
|
||||
.FirstOrDefaultAsync(r => r.ReportId == reportId);
|
||||
if (report == null) return this.NotFound();
|
||||
|
||||
report.XmlPlayers = (ReportPlayer[])JsonSerializer.Deserialize(report.Players,
|
||||
typeof(ReportPlayer[]))!;
|
||||
|
||||
report.XmlBounds = new Marqee
|
||||
{
|
||||
Rect = (Rectangle)JsonSerializer.Deserialize(report.Bounds,
|
||||
typeof(Rectangle))!,
|
||||
};
|
||||
|
||||
this.Report = report;
|
||||
|
||||
return this.Page();
|
||||
}
|
||||
}
|
|
@ -28,214 +28,10 @@
|
|||
|
||||
@foreach (GriefReport report in Model.Reports)
|
||||
{
|
||||
<div class="ui segment">
|
||||
<div>
|
||||
<canvas class="hide-subjects" id="canvas-subjects-@report.ReportId" width="1920" height="1080"
|
||||
style="position: absolute; transform: rotate(180deg)">
|
||||
</canvas>
|
||||
<img class="hover-region" id="game-image-@report.ReportId" src="/gameAssets/@report.JpegHash" alt="Grief report picture" style="width: 100%; height: auto; border-radius: .28571429rem;">
|
||||
</div>
|
||||
<p>
|
||||
<i>
|
||||
Report submitted by
|
||||
<b>
|
||||
<a href="/user/@report.ReportingPlayerId">@report.ReportingPlayer.Username</a>
|
||||
</b>
|
||||
</i>
|
||||
</p>
|
||||
<b class="hover-players" id="hover-subjects-2-@report.ReportId">Report contains @report.XmlPlayers.Length @(report.XmlPlayers.Length == 1 ? "player" : "players")</b>
|
||||
@foreach (ReportPlayer player in report.XmlPlayers)
|
||||
{
|
||||
<div id="hover-subjects-@report.ReportId" class="hover-players">
|
||||
<a href="/">@player.Name</a>
|
||||
</div>
|
||||
@await Html.PartialAsync("Partials/ReportPartial", report)
|
||||
}
|
||||
|
||||
<br>
|
||||
<div>
|
||||
<b>Report time: </b>@(DateTimeOffset.FromUnixTimeMilliseconds(report.Timestamp).ToString("R"))
|
||||
</div>
|
||||
<div>
|
||||
<b>Report reason: </b>@report.Type
|
||||
</div>
|
||||
<div>
|
||||
<b>Level ID:</b> @report.LevelId
|
||||
</div>
|
||||
<div>
|
||||
<b>Level type:</b> @report.LevelType
|
||||
</div>
|
||||
<div>
|
||||
<b>Level owner:</b> @report.LevelOwner
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<a class="ui green small button" href="/admin/report/@report.ReportId/dismiss">
|
||||
<i class="checkmark icon"></i>
|
||||
<span>Dismiss</span>
|
||||
</a>
|
||||
<a class="ui red small button" href="/admin/report/@report.ReportId/remove">
|
||||
<i class="trash icon"></i>
|
||||
<span>Remove all related assets</span>
|
||||
</a>
|
||||
</div>
|
||||
<script>
|
||||
subjects[@report.ReportId] = @Html.Raw(report.Players)
|
||||
bounds[@report.ReportId] = @Html.Raw(report.Bounds)
|
||||
images[@report.ReportId] = document.getElementById("game-image-@report.ReportId")
|
||||
canvases[@report.ReportId] = document.getElementById("canvas-subjects-@report.ReportId")
|
||||
canvases[@report.ReportId].width = images[@report.ReportId].offsetWidth;
|
||||
canvases[@report.ReportId].height = images[@report.ReportId].clientHeight;
|
||||
ctx[@report.ReportId] = canvases[@report.ReportId].getContext('2d');
|
||||
</script>
|
||||
}
|
||||
|
||||
<script>
|
||||
function getReportId(name){
|
||||
let split = name.split("-");
|
||||
return split[split.length-1];
|
||||
}
|
||||
const colours = ["#96dd3c", "#ceb424", "#cc0a1d", "#c800cc"];
|
||||
let displayType;
|
||||
window.addEventListener("load", function () {
|
||||
document.querySelectorAll(".hover-players").forEach(item => {
|
||||
item.addEventListener('mouseenter', function () {
|
||||
let reportId = getReportId(item.id);
|
||||
const canvas = canvases[reportId];
|
||||
displayType = 1;
|
||||
|
||||
canvas.className = "photo-subjects";
|
||||
|
||||
redraw(reportId);
|
||||
});
|
||||
});
|
||||
document.querySelectorAll(".hover-region").forEach(item => {
|
||||
item.addEventListener('mouseenter', function () {
|
||||
let reportId = getReportId(item.id);
|
||||
const canvas = canvases[reportId];
|
||||
const image = document.getElementById("game-image-" + reportId.toString());
|
||||
displayType = 0;
|
||||
|
||||
canvas.className = "photo-subjects";
|
||||
|
||||
canvas.width = image.offsetWidth;
|
||||
canvas.height = image.clientHeight; // space for names to hang off
|
||||
|
||||
redraw(reportId);
|
||||
});
|
||||
});
|
||||
document.querySelectorAll(".hover-region, .hover-players").forEach(item => {
|
||||
item.addEventListener('mouseleave', function () {
|
||||
canvases[getReportId(item.id)].className = "photo-subjects hide-subjects";
|
||||
});
|
||||
});
|
||||
}, false);
|
||||
|
||||
function redraw(reportId){
|
||||
let context = ctx[reportId];
|
||||
let canvas = canvases[reportId];
|
||||
let image = images[reportId];
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
let w = canvas.width;
|
||||
let h = canvas.height;
|
||||
|
||||
// halfwidth, halfheight
|
||||
const hw = w / 2;
|
||||
const hh = h / 2;
|
||||
switch (displayType){
|
||||
case 0: {
|
||||
let imageBounds = bounds[reportId];
|
||||
const x1 = imageBounds.Left;
|
||||
const x2 = imageBounds.Right;
|
||||
const y1 = imageBounds.Top;
|
||||
const y2 = imageBounds.Bottom;
|
||||
const scaleX = image.naturalWidth / canvas.width;
|
||||
const scaleY = image.naturalHeight / canvas.height;
|
||||
const bx = canvas.width-(x2/scaleX);
|
||||
const by = canvas.height-(y2/scaleY);
|
||||
const bw = (x2 - x1) / scaleX;
|
||||
const bh = (y2 - y1) / scaleY;
|
||||
context.beginPath();
|
||||
context.globalAlpha = 0.6;
|
||||
context.fillStyle = "black";
|
||||
context.fillRect(0, 0, canvas.width, canvas.height);
|
||||
context.clearRect(bx, by, bw, bh);
|
||||
context.beginPath();
|
||||
context.lineWidth = 2;
|
||||
context.strokeStyle = "#957a24";
|
||||
context.rect(bx, by, bw, bh);
|
||||
context.stroke();
|
||||
context.globalAlpha = 1.0;
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
let subject = subjects[reportId];
|
||||
subject.forEach((s, si) => {
|
||||
const colour = colours[si % 4];
|
||||
|
||||
// Bounding box
|
||||
const x1 = s.Location.Left;
|
||||
const x2 = s.Location.Right;
|
||||
const y1 = s.Location.Top;
|
||||
const y2 = s.Location.Bottom;
|
||||
|
||||
const scaleX = image.naturalWidth / canvas.width;
|
||||
const scaleY = image.naturalHeight / canvas.height;
|
||||
|
||||
|
||||
const bx = canvas.width-(x2/scaleX);
|
||||
const by = canvas.height-(y2/scaleY);
|
||||
const bw = (x2 - x1) / scaleX;
|
||||
const bh = (y2 - y1) / scaleY;
|
||||
|
||||
context.beginPath();
|
||||
context.lineWidth = 3;
|
||||
context.strokeStyle = colour;
|
||||
context.rect(bx, by, bw, bh);
|
||||
context.stroke();
|
||||
|
||||
// Move into relative coordinates from bounding box
|
||||
context.translate(bx, by);
|
||||
|
||||
// Username label
|
||||
context.font = "16px Lato";
|
||||
context.fillStyle = colour;
|
||||
|
||||
// Text width/height for the label background
|
||||
const tw = context.measureText(s.Name).width;
|
||||
const th = 24;
|
||||
|
||||
// Check if the label will flow off the bottom of the frame
|
||||
const overflowBottom = (y2+tw - 24) > (canvas.width);
|
||||
// Check if the label will flow off the left of the frame
|
||||
const overflowLeft = (x2) < (24);
|
||||
|
||||
// Set alignment
|
||||
context.textAlign = overflowLeft ? "start" : "end";
|
||||
|
||||
// Text x / y
|
||||
const lx = overflowLeft ? -bw + 6 : -6;
|
||||
const ly = overflowBottom ? -bh - 6 : 16;
|
||||
|
||||
// Label background x / y
|
||||
const lbx = overflowLeft ? bw - tw - 12 : 0;
|
||||
const lby = overflowBottom ? bh : -24;
|
||||
|
||||
// Draw background
|
||||
context.fillRect(lbx, lby, tw+8, th);
|
||||
|
||||
// Draw text, rotated back upright (canvas draws rotated 180deg)
|
||||
context.fillStyle = "white";
|
||||
context.rotate(Math.PI);
|
||||
context.fillText(s.Name, lx, ly);
|
||||
|
||||
// reset transform
|
||||
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@await Html.PartialAsync("Partials/RenderReportBoundsPartial")
|
||||
|
||||
@if (Model.PageNumber != 0)
|
||||
{
|
||||
|
|
|
@ -8,4 +8,6 @@ public class DiscordIntegrationConfiguration
|
|||
public bool DiscordIntegrationEnabled { get; set; }
|
||||
|
||||
public string Url { get; set; } = "";
|
||||
|
||||
public string ModerationUrl { get; set; } = "";
|
||||
}
|
|
@ -23,7 +23,7 @@ public class ServerConfiguration
|
|||
// You can use an ObsoleteAttribute instead. Make sure you set it to error, though.
|
||||
//
|
||||
// Thanks for listening~
|
||||
public const int CurrentConfigVersion = 7;
|
||||
public const int CurrentConfigVersion = 8;
|
||||
|
||||
#region Meta
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Discord;
|
||||
using Discord.Webhook;
|
||||
|
@ -7,18 +8,45 @@ namespace LBPUnion.ProjectLighthouse.Helpers;
|
|||
|
||||
public static class WebhookHelper
|
||||
{
|
||||
private static readonly DiscordWebhookClient client = (ServerConfiguration.Instance.DiscordIntegration.DiscordIntegrationEnabled
|
||||
/// <summary>
|
||||
/// The destination of the webhook post.
|
||||
/// </summary>
|
||||
public enum WebhookDestination : byte
|
||||
{
|
||||
/// <summary>
|
||||
/// A channel intended for public viewing; where new levels and photos are sent.
|
||||
/// </summary>
|
||||
Public,
|
||||
/// <summary>
|
||||
/// A channel intended for moderators; where grief reports are sent.
|
||||
/// </summary>
|
||||
Moderation,
|
||||
}
|
||||
|
||||
private static readonly DiscordWebhookClient publicClient = (ServerConfiguration.Instance.DiscordIntegration.DiscordIntegrationEnabled
|
||||
? new DiscordWebhookClient(ServerConfiguration.Instance.DiscordIntegration.Url)
|
||||
: null);
|
||||
|
||||
private static readonly DiscordWebhookClient moderationClient = (ServerConfiguration.Instance.DiscordIntegration.DiscordIntegrationEnabled
|
||||
? new DiscordWebhookClient(ServerConfiguration.Instance.DiscordIntegration.ModerationUrl)
|
||||
: null);
|
||||
|
||||
public static readonly Color UnionColor = new(0, 140, 255);
|
||||
|
||||
public static Task SendWebhook(EmbedBuilder builder) => SendWebhook(builder.Build());
|
||||
public static Task SendWebhook(EmbedBuilder builder, WebhookDestination dest = WebhookDestination.Public)
|
||||
=> SendWebhook(builder.Build(), dest);
|
||||
|
||||
public static async Task SendWebhook(Embed embed)
|
||||
public static async Task SendWebhook(Embed embed, WebhookDestination dest = WebhookDestination.Public)
|
||||
{
|
||||
if (!ServerConfiguration.Instance.DiscordIntegration.DiscordIntegrationEnabled) return;
|
||||
|
||||
DiscordWebhookClient client = dest switch
|
||||
{
|
||||
WebhookDestination.Public => publicClient,
|
||||
WebhookDestination.Moderation => moderationClient,
|
||||
_ => throw new ArgumentOutOfRangeException(nameof(dest), dest, null),
|
||||
};
|
||||
|
||||
await client.SendMessageAsync
|
||||
(
|
||||
embeds: new[]
|
||||
|
@ -28,7 +56,7 @@ public static class WebhookHelper
|
|||
);
|
||||
}
|
||||
|
||||
public static Task SendWebhook(string title, string description)
|
||||
public static Task SendWebhook(string title, string description, WebhookDestination dest = WebhookDestination.Public)
|
||||
=> SendWebhook
|
||||
(
|
||||
new EmbedBuilder
|
||||
|
@ -36,6 +64,7 @@ public static class WebhookHelper
|
|||
Title = title,
|
||||
Description = description,
|
||||
Color = UnionColor,
|
||||
}
|
||||
},
|
||||
dest
|
||||
);
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue