From 8b608c2f20567a023f13b8472b61ca01f1703944 Mon Sep 17 00:00:00 2001 From: Geekyhobo <66805063+Geekyhobo@users.noreply.github.com> Date: Sat, 27 Jul 2024 11:28:07 -0400 Subject: [PATCH] Add the Capability to mass ban players based on .tsv files (#59) * Add the Capability to mass ban players based on .tsv files * I SWEAR TO GOD IT DELKETES THE .NAME EVERY TIME ADASDASDASDSAD * small changes * fixes * check for header and error if its not there * package shit * tsv record --------- Co-authored-by: Geekyhobo <66805063+Ahlytlex@users.noreply.github.com> --- .idea/.idea.SS14.Admin/.idea/.name | 2 +- Directory.Packages.props | 1 + SS14.Admin/Pages/Bans/CreateMassBan.cshtml | 79 +++++++++++ SS14.Admin/Pages/Bans/CreateMassBan.cshtml.cs | 133 ++++++++++++++++++ SS14.Admin/Pages/Bans/Hits.cshtml | 1 + SS14.Admin/Pages/Bans/Index.cshtml | 5 + SS14.Admin/SS14.Admin.csproj | 1 + 7 files changed, 221 insertions(+), 1 deletion(-) create mode 100644 SS14.Admin/Pages/Bans/CreateMassBan.cshtml create mode 100644 SS14.Admin/Pages/Bans/CreateMassBan.cshtml.cs diff --git a/.idea/.idea.SS14.Admin/.idea/.name b/.idea/.idea.SS14.Admin/.idea/.name index a6ced5a..98db39a 100644 --- a/.idea/.idea.SS14.Admin/.idea/.name +++ b/.idea/.idea.SS14.Admin/.idea/.name @@ -1 +1 @@ -SS14.Admin \ No newline at end of file +SS14.Admin diff --git a/Directory.Packages.props b/Directory.Packages.props index c011b62..2ebb5db 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,6 +4,7 @@ true + diff --git a/SS14.Admin/Pages/Bans/CreateMassBan.cshtml b/SS14.Admin/Pages/Bans/CreateMassBan.cshtml new file mode 100644 index 0000000..2bfbe67 --- /dev/null +++ b/SS14.Admin/Pages/Bans/CreateMassBan.cshtml @@ -0,0 +1,79 @@ +@page +@model SS14.Admin.Pages.Bans.CreateMassBanModel + +@{ + ViewData["Title"] = "Create New Mass Ban"; +} + + + + + Create New Mass Ban + + + TSV Format Explanation: + TSV is a CSV using tabs instead of commas. The fields are: + + user_id (user guid) + address (ip address/CIDR) + hwid (base64 encoded hwid) + reason (string to use as ban reason) + datacenter (bool to set DC ban exemption flag) + blacklisted_range (bool to set blacklisted range ban exemption flag) + + + + + + + + Choose a .TSV file to Upload: + + + + Ban + + + Are you sure? + + + + + + +@if (!ModelState.IsValid) +{ + + + @foreach (var modelState in ViewData.ModelState.Values) + { + foreach (var error in modelState.Errors) + { + @error.ErrorMessage + } + } + + +} + +@if (TempData["StatusMessage"] != null) +{ + + @TempData["StatusMessage"] + +} + +@section Scripts { + +} diff --git a/SS14.Admin/Pages/Bans/CreateMassBan.cshtml.cs b/SS14.Admin/Pages/Bans/CreateMassBan.cshtml.cs new file mode 100644 index 0000000..3910c02 --- /dev/null +++ b/SS14.Admin/Pages/Bans/CreateMassBan.cshtml.cs @@ -0,0 +1,133 @@ +using System.Globalization; +using Content.Server.Database; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.RazorPages; +using SS14.Admin.Helpers; +using CsvHelper; + +namespace SS14.Admin.Pages.Bans +{ + [Authorize(Roles = "MASSBAN")] + [ValidateAntiForgeryToken] + public class CreateMassBanModel : PageModel + { + private readonly PostgresServerDbContext _dbContext; + private readonly BanHelper _banHelper; + + public CreateMassBanModel(PostgresServerDbContext dbContext, BanHelper banHelper) + { + _dbContext = dbContext; + _banHelper = banHelper; + } + + public int BanCount { get; private set; } + + public record TsvEntry( + string UserId, + string Address, + string Hwid, + string Reason, + bool Datacenter, + bool BlacklistedRange + ); + + public async Task OnPostAsync(IFormFile file) + { + if (file == null || file.Length <= 0) + { + ModelState.AddModelError(string.Empty, "Please select a file."); + return Page(); + } + + if (!file.FileName.EndsWith(".tsv", StringComparison.OrdinalIgnoreCase)) + { + ModelState.AddModelError(string.Empty, "Only TSV files are allowed."); + return Page(); + } + + try + { + using var stream = new StreamReader(file.OpenReadStream()); + var entries = ParseTsv(stream); + + foreach (var entry in entries) + { + var ExemptFlags = BanExemptions.GetExemptionFromForm(Request.Form); + + var ban = new ServerBan(); + + var ipAddr = entry.Address; + var hwid = entry.Hwid; + + ban.ExemptFlags = ExemptFlags; + // ban.AutoDelete = Input.AutoDelete; // Uncomment and use if necessary + //ban.Hidden = Input.Hidden; + //ban.Severity = Input.Severity; + + var error = await _banHelper.FillBanCommon( + ban, + entry.UserId, + ipAddr, + hwid, + 0, // Assuming lengthMinutes is always 0 for mass bans for now + entry.Reason); + + if (error != null) + { + ModelState.AddModelError(string.Empty, error); + return Page(); + } + + _dbContext.Ban.Add(ban); + } + + await _dbContext.SaveChangesAsync(); + + TempData["StatusMessage"] = $"{entries.Count} ban(s) created successfully."; + return RedirectToPage("./Index"); + } + catch (Exception ex) + { + ModelState.AddModelError(string.Empty, $"An error occurred: {ex.Message}"); + return Page(); + } + } + + private List ParseTsv(StreamReader reader) + { + var records = new List(); + + var config = new CsvHelper.Configuration.CsvConfiguration(CultureInfo.InvariantCulture) + { + Delimiter = "\t", // Specify tab as the delimiter + HasHeaderRecord = true, // TSV files have a header row + MissingFieldFound = null // Ignore missing fields + }; + + using (var csvReader = new CsvReader(reader, config)) + { + if (!csvReader.Read() || !csvReader.ReadHeader()) + { + throw new InvalidDataException("The TSV file is missing a header."); + } + + while (csvReader.Read()) + { + var record = new TsvEntry( + csvReader.GetField("user_id"), + csvReader.GetField("address"), + csvReader.GetField("hwid"), + csvReader.GetField("reason"), + csvReader.GetField("datacenter"), + csvReader.GetField("blacklisted_range") + ); + records.Add(record); + BanCount += 1; + } + } + + return records; + } + } +} diff --git a/SS14.Admin/Pages/Bans/Hits.cshtml b/SS14.Admin/Pages/Bans/Hits.cshtml index 87ef844..a1cf61f 100644 --- a/SS14.Admin/Pages/Bans/Hits.cshtml +++ b/SS14.Admin/Pages/Bans/Hits.cshtml @@ -1,6 +1,7 @@ @page "{ban}" @using SS14.Admin.Helpers @using SS14.Admin.Pages.Tables +@using Microsoft.AspNetCore.Mvc.TagHelpers @model SS14.Admin.Pages.Bans.Hits @{ diff --git a/SS14.Admin/Pages/Bans/Index.cshtml b/SS14.Admin/Pages/Bans/Index.cshtml index d7d5863..d3426f2 100644 --- a/SS14.Admin/Pages/Bans/Index.cshtml +++ b/SS14.Admin/Pages/Bans/Index.cshtml @@ -1,6 +1,7 @@ @page @using SS14.Admin.Pages.Tables @using SS14.Admin.Helpers +@using Microsoft.AspNetCore.Mvc.TagHelpers @model SS14.Admin.Pages.BansModel @{ @@ -19,6 +20,10 @@ { Create new ban } + @if (User.IsInRole("MASSBAN")) + { + Create new Mass Ban + } diff --git a/SS14.Admin/SS14.Admin.csproj b/SS14.Admin/SS14.Admin.csproj index 620c11b..8b06f1a 100644 --- a/SS14.Admin/SS14.Admin.csproj +++ b/SS14.Admin/SS14.Admin.csproj @@ -10,6 +10,7 @@ +
TSV is a CSV using tabs instead of commas. The fields are: