implemented the basics of the reporting system

added comments to the ``ModerationService`` as the reporting functionality will be here aswell
This commit is contained in:
Alan Moon 2025-02-10 17:01:56 -08:00
parent 329046b498
commit b0c9f47375
6 changed files with 112 additions and 1 deletions

View File

@ -1,9 +1,21 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using sodoff.Attributes;
using sodoff.Model;
using sodoff.Schema; using sodoff.Schema;
using sodoff.Services;
namespace sodoff.Controllers.Common; namespace sodoff.Controllers.Common;
public class MessagingController : Controller { 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] [HttpPost]
[Produces("application/xml")] [Produces("application/xml")]
[Route("MessagingWebService.asmx/GetUserMessageQueue")] [Route("MessagingWebService.asmx/GetUserMessageQueue")]
@ -36,4 +48,21 @@ public class MessagingController : Controller {
// TODO - placeholder // TODO - placeholder
return Ok(new ArrayOfMessageInfo()); 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();
}
} }

View File

@ -26,6 +26,7 @@ public class DBContext : DbContext {
public DbSet<Neighborhood> Neighborhoods { get; set; } = null!; public DbSet<Neighborhood> Neighborhoods { get; set; } = null!;
// we had a brief debate on whether it's neighborhoods or neighborheed // we had a brief debate on whether it's neighborhoods or neighborheed
public DbSet<UserBan> UserBans { get; set; } = null!; public DbSet<UserBan> UserBans { get; set; } = null!;
public DbSet<Report> UserReports { get; set; } = null!;
public DbSet<Group> Groups { get; set; } = null!; public DbSet<Group> Groups { get; set; } = null!;
public DbSet<Rating> Ratings { get; set; } = null!; public DbSet<Rating> Ratings { get; set; } = null!;
public DbSet<RatingRank> RatingRanks { get; set; } = null!; public DbSet<RatingRank> RatingRanks { get; set; } = null!;
@ -149,6 +150,12 @@ public class DBContext : DbContext {
builder.Entity<Viking>().HasMany(v => v.Ratings) builder.Entity<Viking>().HasMany(v => v.Ratings)
.WithOne(r => r.Viking); .WithOne(r => r.Viking);
builder.Entity<Viking>().HasMany(v => v.ReportsMade)
.WithOne(r => r.Viking);
builder.Entity<Viking>().HasMany(v => v.ReportsReceived)
.WithOne(r => r.ReportedViking);
// Dragons // Dragons
builder.Entity<Dragon>().HasOne(d => d.Viking) builder.Entity<Dragon>().HasOne(d => d.Viking)
.WithMany(e => e.Dragons) .WithMany(e => e.Dragons)
@ -270,10 +277,19 @@ public class DBContext : DbContext {
.WithOne(e => e.Neighborhood) .WithOne(e => e.Neighborhood)
.HasForeignKey<Neighborhood>(e => e.VikingId); .HasForeignKey<Neighborhood>(e => e.VikingId);
// Moderation
builder.Entity<UserBan>().HasOne(r => r.User) builder.Entity<UserBan>().HasOne(r => r.User)
.WithMany(e => e.Bans) .WithMany(e => e.Bans)
.HasForeignKey(e => e.UserId); .HasForeignKey(e => e.UserId);
builder.Entity<Report>().HasOne(r => r.Viking)
.WithMany(e => e.ReportsMade)
.HasForeignKey(e => e.VikingId);
builder.Entity<Report>().HasOne(r => r.ReportedViking)
.WithMany(e => e.ReportsReceived)
.HasForeignKey(e => e.ReportedVikingId);
// Groups // Groups
builder.Entity<Group>().HasMany(r => r.Vikings) builder.Entity<Group>().HasMany(r => r.Vikings)
.WithMany(e => e.Groups); .WithMany(e => e.Groups);

23
src/Model/Report.cs Normal file
View File

@ -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; }
}

View File

@ -41,6 +41,8 @@ public class Viking {
public virtual Neighborhood? Neighborhood { get; set; } = null!; public virtual Neighborhood? Neighborhood { get; set; } = null!;
public virtual ICollection<Group> Groups { get; set; } = null!; public virtual ICollection<Group> Groups { get; set; } = null!;
public virtual ICollection<Rating> Ratings { get; set; } = null!; public virtual ICollection<Rating> Ratings { get; set; } = null!;
public virtual ICollection<Report> ReportsMade { get; set; } = null!;
public virtual ICollection<Report> ReportsReceived { get; set; } = null!;
public virtual Dragon? SelectedDragon { get; set; } public virtual Dragon? SelectedDragon { get; set; }
public DateTime? CreationDate { get; set; } public DateTime? CreationDate { get; set; }

9
src/Schema/ReportType.cs Normal file
View File

@ -0,0 +1,9 @@
namespace sodoff.Schema;
public enum ReportType
{
BadWords = 1,
PersonalInformation = 2,
RudeOrMean = 3
}

View File

@ -7,12 +7,15 @@ namespace sodoff.Services;
public class ModerationService public class ModerationService
{ {
private readonly DBContext ctx; private readonly DBContext ctx;
private readonly MMOCommunicationService mmoCommService;
public ModerationService(DBContext ctx) public ModerationService(DBContext ctx, MMOCommunicationService mmoCommService)
{ {
this.ctx = ctx; this.ctx = ctx;
this.mmoCommService = mmoCommService;
} }
// Banning
public UserBan AddBanToUser(User user, UserBanType banType, DateTime dateEnd = new DateTime()) public UserBan AddBanToUser(User user, UserBanType banType, DateTime dateEnd = new DateTime())
{ {
// create a ban in relation to the specified user // 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(); 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 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;
}
} }