From b0c9f47375736fffdd132014fe12436896ec4bd4 Mon Sep 17 00:00:00 2001 From: AlanMoonbase Date: Mon, 10 Feb 2025 17:01:56 -0800 Subject: [PATCH] implemented the basics of the reporting system added comments to the ``ModerationService`` as the reporting functionality will be here aswell --- src/Controllers/Common/MessagingController.cs | 29 ++++++++++++++++ src/Model/DBContext.cs | 16 +++++++++ src/Model/Report.cs | 23 +++++++++++++ src/Model/Viking.cs | 2 ++ src/Schema/ReportType.cs | 9 +++++ src/Services/ModerationService.cs | 34 ++++++++++++++++++- 6 files changed, 112 insertions(+), 1 deletion(-) create mode 100644 src/Model/Report.cs create mode 100644 src/Schema/ReportType.cs diff --git a/src/Controllers/Common/MessagingController.cs b/src/Controllers/Common/MessagingController.cs index b4e71de..888ef31 100644 --- a/src/Controllers/Common/MessagingController.cs +++ b/src/Controllers/Common/MessagingController.cs @@ -1,9 +1,21 @@ using Microsoft.AspNetCore.Mvc; +using sodoff.Attributes; +using sodoff.Model; using sodoff.Schema; +using sodoff.Services; namespace sodoff.Controllers.Common; public class MessagingController : Controller { + public readonly ModerationService moderationService; + public readonly DBContext ctx; + + public MessagingController(ModerationService moderationService, DBContext ctx) + { + this.moderationService = moderationService; + this.ctx = ctx; + } + [HttpPost] [Produces("application/xml")] [Route("MessagingWebService.asmx/GetUserMessageQueue")] @@ -36,4 +48,21 @@ public class MessagingController : Controller { // TODO - placeholder return Ok(new ArrayOfMessageInfo()); } + + [HttpPost] + [Produces("application/xml")] + [Route("ChatWebService.asmx/ReportUser")] + [VikingSession] + public IActionResult ReportUser(Viking viking, [FromForm] string apiToken, [FromForm] Guid reportUserID, [FromForm] int reportReason) + { + // find viking + Viking? vikingToReport = ctx.Vikings.FirstOrDefault(e => e.Uid == reportUserID); + + if (vikingToReport != null) + { + Report reportFiled = moderationService.AddReportToViking(apiToken, viking, vikingToReport, (ReportType)reportReason); + if (reportFiled != null) return Ok(true); + else return Unauthorized(); + } else return Unauthorized(); + } } diff --git a/src/Model/DBContext.cs b/src/Model/DBContext.cs index 18d18b0..61d6451 100644 --- a/src/Model/DBContext.cs +++ b/src/Model/DBContext.cs @@ -26,6 +26,7 @@ public class DBContext : DbContext { public DbSet Neighborhoods { get; set; } = null!; // we had a brief debate on whether it's neighborhoods or neighborheed public DbSet UserBans { get; set; } = null!; + public DbSet UserReports { get; set; } = null!; public DbSet Groups { get; set; } = null!; public DbSet Ratings { get; set; } = null!; public DbSet RatingRanks { get; set; } = null!; @@ -149,6 +150,12 @@ public class DBContext : DbContext { builder.Entity().HasMany(v => v.Ratings) .WithOne(r => r.Viking); + builder.Entity().HasMany(v => v.ReportsMade) + .WithOne(r => r.Viking); + + builder.Entity().HasMany(v => v.ReportsReceived) + .WithOne(r => r.ReportedViking); + // Dragons builder.Entity().HasOne(d => d.Viking) .WithMany(e => e.Dragons) @@ -270,10 +277,19 @@ public class DBContext : DbContext { .WithOne(e => e.Neighborhood) .HasForeignKey(e => e.VikingId); + // Moderation builder.Entity().HasOne(r => r.User) .WithMany(e => e.Bans) .HasForeignKey(e => e.UserId); + builder.Entity().HasOne(r => r.Viking) + .WithMany(e => e.ReportsMade) + .HasForeignKey(e => e.VikingId); + + builder.Entity().HasOne(r => r.ReportedViking) + .WithMany(e => e.ReportsReceived) + .HasForeignKey(e => e.ReportedVikingId); + // Groups builder.Entity().HasMany(r => r.Vikings) .WithMany(e => e.Groups); diff --git a/src/Model/Report.cs b/src/Model/Report.cs new file mode 100644 index 0000000..1362836 --- /dev/null +++ b/src/Model/Report.cs @@ -0,0 +1,23 @@ +using System; +using System.ComponentModel.DataAnnotations; +using sodoff.Model; + +namespace sodoff.Model; + +public class Report +{ + [Key] + public int Id { get; set; } + + public int VikingId { get; set; } + + public int ReportedVikingId { get; set; } + + public int ReportType { get; set; } + + public DateTime? CreatedAt { get; set; } + + public virtual Viking? Viking { get; set; } + + public virtual Viking? ReportedViking { get; set; } +} diff --git a/src/Model/Viking.cs b/src/Model/Viking.cs index 6403745..b24cfb8 100644 --- a/src/Model/Viking.cs +++ b/src/Model/Viking.cs @@ -41,6 +41,8 @@ public class Viking { public virtual Neighborhood? Neighborhood { get; set; } = null!; public virtual ICollection Groups { get; set; } = null!; public virtual ICollection Ratings { get; set; } = null!; + public virtual ICollection ReportsMade { get; set; } = null!; + public virtual ICollection ReportsReceived { get; set; } = null!; public virtual Dragon? SelectedDragon { get; set; } public DateTime? CreationDate { get; set; } diff --git a/src/Schema/ReportType.cs b/src/Schema/ReportType.cs new file mode 100644 index 0000000..18c1cab --- /dev/null +++ b/src/Schema/ReportType.cs @@ -0,0 +1,9 @@ +namespace sodoff.Schema; + + +public enum ReportType +{ + BadWords = 1, + PersonalInformation = 2, + RudeOrMean = 3 +} diff --git a/src/Services/ModerationService.cs b/src/Services/ModerationService.cs index 26526d4..94b03d1 100644 --- a/src/Services/ModerationService.cs +++ b/src/Services/ModerationService.cs @@ -7,12 +7,15 @@ namespace sodoff.Services; public class ModerationService { private readonly DBContext ctx; + private readonly MMOCommunicationService mmoCommService; - public ModerationService(DBContext ctx) + public ModerationService(DBContext ctx, MMOCommunicationService mmoCommService) { this.ctx = ctx; + this.mmoCommService = mmoCommService; } + // Banning public UserBan AddBanToUser(User user, UserBanType banType, DateTime dateEnd = new DateTime()) { // create a ban in relation to the specified user @@ -64,4 +67,33 @@ public class ModerationService if(descendingOrder) return user.Bans.OrderByDescending(e => e.CreatedAt).ToList(); else return user.Bans.OrderBy(e => e.CreatedAt).ToList(); // return sorted list by created date } + + // Reporting + + public Report AddReportToViking(string apiToken, Viking viking, Viking vikingToReport, ReportType reportReason) + { + // check if the report already exists with the viking creating the report + Report? existingReport = viking.ReportsMade.FirstOrDefault(e => e.ReportedVikingId == vikingToReport.Id); + if (existingReport != null && existingReport.ReportType == (int)reportReason) + { + return null!; + } + + // make report on offending user + Report report = new Report + { + ReportType = (int)reportReason, + CreatedAt = DateTime.UtcNow + }; + + // add report to "ReportsMade" on owner and "ReportsReceived" on offender, EF should do the rest + viking.ReportsMade.Add(report); + vikingToReport.ReportsReceived.Add(report); + ctx.SaveChanges(); + + // send a moderation message to the offender (they will receive it if they are online, later on a message will be added to their message board instead) + mmoCommService.SendPacketToPlayer(apiToken, vikingToReport.Uid.ToString(), "SMM", new string[] { "SMM", "-1", "REPORT_FILED", "Oops! Looks like you may have done something wrong! Repeated offences will result in an account ban." }); + + return report; + } }