mirror of
https://github.com/DorkSquadRR/DorkNet.git
synced 2026-10-25 23:18:44 -07:00
Import december-2020-12-18 from private repo (scrubbed 2026-05-27)
Targets Rec Room 2020.12.18 client.
Re-import after adding:
- DorkNet.ClientMod/dorknet-clientmod.json.template — config schema
the launcher's manifest-driven patcher renders into UserData/.
- tools/build-patcher-zip.ps1 — produces the dorknet-clientpatch-{key}.zip
Release asset the launcher fetches.
- .github/workflows/release.yml — auto-publishes both Release assets
on v1-december-* tag push.
Scrubbed via maintainer-side scrub-for-public.ps1: same drop rules as
the prior import, plus build-patcher-zip.ps1 added to the tools/
allow-list so it survives the scrub.
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text.Json;
|
||||
using DorkNet.Server.Auth;
|
||||
using DorkNet.Server.Data;
|
||||
using DorkNet.Server.Data.Entities;
|
||||
|
||||
namespace DorkNet.Server.Controllers.API.Compatibility;
|
||||
|
||||
[ApiController]
|
||||
public class CompatibilityFeatureController(DorkNetDbContext db) : ControllerBase
|
||||
{
|
||||
[HttpPost("api/banappeal/generateCode")]
|
||||
[Authorize]
|
||||
public async Task<IActionResult> GenerateBanAppealCode()
|
||||
{
|
||||
var pid = this.RequireCurrentPlayerId();
|
||||
var code = $"BA-{RandomNumberGenerator.GetInt32(100000, 999999)}";
|
||||
db.PlayerSettings.Add(new PlayerSettingEntity
|
||||
{
|
||||
PlayerId = pid,
|
||||
Key = $"banappeal:{DateTime.UtcNow:yyyyMMddHHmmss}",
|
||||
Value = code,
|
||||
});
|
||||
await db.SaveChangesAsync();
|
||||
return Ok(new { value = code });
|
||||
}
|
||||
|
||||
[HttpPost("api/CampusCard/v1/UpdateAndGetSubscription")]
|
||||
[Authorize]
|
||||
[Consumes("application/json", "application/x-www-form-urlencoded", "multipart/form-data")]
|
||||
public async Task<IActionResult> UpdateAndGetCampusCardSubscription()
|
||||
{
|
||||
var pid = this.RequireCurrentPlayerId();
|
||||
var req = await ReadCampusCardRequestAsync();
|
||||
var targetId = req.PlatformAccountSubscribedPlayerId > 0
|
||||
? req.PlatformAccountSubscribedPlayerId
|
||||
: pid;
|
||||
|
||||
if (targetId != pid && req.Subscription)
|
||||
{
|
||||
var exists = await db.Subscriptions.AnyAsync(s =>
|
||||
s.SubscriberPlayerId == pid && s.TargetPlayerId == targetId);
|
||||
if (!exists)
|
||||
{
|
||||
db.Subscriptions.Add(new SubscriptionEntity
|
||||
{
|
||||
SubscriberPlayerId = pid,
|
||||
TargetPlayerId = targetId,
|
||||
});
|
||||
await db.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
else if (targetId != pid && !req.Subscription)
|
||||
{
|
||||
await db.Subscriptions
|
||||
.Where(s => s.SubscriberPlayerId == pid && s.TargetPlayerId == targetId)
|
||||
.ExecuteDeleteAsync();
|
||||
}
|
||||
|
||||
// 2020.12 deserializer for this response expects `subscription` to be a
|
||||
// nested OBJECT (Subscription DTO with subscriptionId/recNetPlayerId/...
|
||||
// fields), NOT a boolean. Sending a bool throws InvalidCastException
|
||||
// on the client ("Unable to cast object of type 'Boolean' to type
|
||||
// 'Dictionary`2'"). Send null when there's no active subscription —
|
||||
// the client's generic-cast helper returns default(T) which is fine.
|
||||
return Ok(new
|
||||
{
|
||||
subscription = (object?)null,
|
||||
platformAccountSubscribedPlayerId = targetId,
|
||||
});
|
||||
}
|
||||
|
||||
[HttpPost("api/clubreporting/v1/report")]
|
||||
[Authorize]
|
||||
[Consumes("application/json", "application/x-www-form-urlencoded", "multipart/form-data")]
|
||||
public async Task<IActionResult> ClubReport()
|
||||
{
|
||||
var pid = this.RequireCurrentPlayerId();
|
||||
var req = await ReadClubReportAsync();
|
||||
var club = req.ClubId > 0
|
||||
? await db.Clubs.FirstOrDefaultAsync(c => c.Id == req.ClubId)
|
||||
: null;
|
||||
if (club is null) return Ok(new { Success = false, Message = "club_not_found" });
|
||||
|
||||
var message = $"Club report: {req.Message ?? string.Empty}".Trim();
|
||||
if (message.Length > 1000) message = message[..1000];
|
||||
db.Reports.Add(new ReportEntity
|
||||
{
|
||||
ReporterPlayerId = pid,
|
||||
TargetPlayerId = club.CreatorPlayerId,
|
||||
Category = req.ReportCategory,
|
||||
Message = message,
|
||||
});
|
||||
await db.SaveChangesAsync();
|
||||
return Ok(new { Success = true, Message = string.Empty });
|
||||
}
|
||||
|
||||
private async Task<CampusCardRequest> ReadCampusCardRequestAsync()
|
||||
{
|
||||
if (Request.HasFormContentType)
|
||||
{
|
||||
var form = await Request.ReadFormAsync();
|
||||
return new CampusCardRequest
|
||||
{
|
||||
Subscription = bool.TryParse(form["subscription"].FirstOrDefault(), out var s) && s,
|
||||
PlatformAccountSubscribedPlayerId = long.TryParse(
|
||||
form["platformAccountSubscribedPlayerId"].FirstOrDefault(), out var id) ? id : 0,
|
||||
};
|
||||
}
|
||||
try
|
||||
{
|
||||
return await JsonSerializer.DeserializeAsync<CampusCardRequest>(
|
||||
Request.Body,
|
||||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new CampusCardRequest();
|
||||
}
|
||||
catch (JsonException) { return new CampusCardRequest(); }
|
||||
}
|
||||
|
||||
private async Task<ClubReportRequest> ReadClubReportAsync()
|
||||
{
|
||||
if (Request.HasFormContentType)
|
||||
{
|
||||
var form = await Request.ReadFormAsync();
|
||||
return new ClubReportRequest
|
||||
{
|
||||
ClubId = long.TryParse(form["clubId"].FirstOrDefault()
|
||||
?? form["ClubId"].FirstOrDefault(), out var clubId) ? clubId : 0,
|
||||
ReportCategory = int.TryParse(form["reportCategory"].FirstOrDefault()
|
||||
?? form["ReportCategory"].FirstOrDefault(), out var cat) ? cat : 5,
|
||||
Message = form["message"].FirstOrDefault() ?? form["Message"].FirstOrDefault(),
|
||||
};
|
||||
}
|
||||
try
|
||||
{
|
||||
return await JsonSerializer.DeserializeAsync<ClubReportRequest>(
|
||||
Request.Body,
|
||||
new JsonSerializerOptions { PropertyNameCaseInsensitive = true }) ?? new ClubReportRequest();
|
||||
}
|
||||
catch (JsonException) { return new ClubReportRequest(); }
|
||||
}
|
||||
|
||||
private sealed class CampusCardRequest
|
||||
{
|
||||
public bool Subscription { get; set; }
|
||||
public long PlatformAccountSubscribedPlayerId { get; set; }
|
||||
}
|
||||
|
||||
private sealed class ClubReportRequest
|
||||
{
|
||||
public long ClubId { get; set; }
|
||||
public int ReportCategory { get; set; } = 5;
|
||||
public string? Message { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user