This commit is contained in:
skidfire
2026-09-06 19:59:27 -04:00
parent 55d8e11a5d
commit fe3468c65d
247 changed files with 338183 additions and 0 deletions
+904
View File
@@ -0,0 +1,904 @@
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Vanadium.Auth;
using Vanadium.Classes.DBs;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using static Vanadium.Classes.DBs.DBClasses.ClubsDBClasses;
namespace Vanadium.Controllers
{
[ApiController]
public class ClubsController : ControllerBase
{
private static int ParseVisibility(string? raw)
{
if (string.IsNullOrWhiteSpace(raw)) return -1;
return raw.ToLowerInvariant() switch
{
"public" => (int)ClubVisibility.Public,
"unlisted" => (int)ClubVisibility.Unlisted,
"private" => (int)ClubVisibility.Private,
"0" => (int)ClubVisibility.Private,
"1" => (int)ClubVisibility.Public,
"2" => (int)ClubVisibility.Unlisted,
_ => -1
};
}
private static int ParseJoinability(string? raw)
{
if (string.IsNullOrWhiteSpace(raw)) return -1;
return raw.ToLowerInvariant() switch
{
"open" => (int)ClubJoinability.Open,
"approvalrequired" => (int)ClubJoinability.ApprovalRequired,
"closed" => (int)ClubJoinability.Closed,
"0" => (int)ClubJoinability.Open,
"1" => (int)ClubJoinability.ApprovalRequired,
"2" => (int)ClubJoinability.Closed,
_ => -1
};
}
[HttpGet("/club/{clubId}/members/{userId}")]
public IActionResult GetClubMember(long clubId, long userId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var member = ClubsDB.GetClubMembers(clubId).FirstOrDefault(m => m.AccountId == userId);
if (member == null) return Ok(new {});
return Ok(member);
}
[HttpGet("/club/search")]
public IActionResult SearchClubs(
[FromQuery] string? query,
[FromQuery] string? category,
[FromQuery] int sort = 0,
[FromQuery] int count = 30,
[FromQuery] int skip = 0)
{
count = Math.Clamp(count, 1, 100);
var result = ClubsDB.Search(query, category, sort, count, skip);
return new ContentResult
{
Content = JsonConvert.SerializeObject(result),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPost("/club/create")]
public IActionResult CreateClub(
[FromForm] string name,
[FromForm] string? description,
[FromForm] string? category)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var club = ClubsDB.CreateClub(
id.Value,
name.Trim(),
description?.Trim() ?? "",
(category ?? "Social").Trim());
return new ContentResult
{
Content = JsonConvert.SerializeObject(new
{
success = true,
error = "",
value = ClubsDB.ToDetails(club, id.Value)
}),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpGet("/club/categoryTags")]
public IActionResult GetClubCategoryTags()
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var tags = new List<string>
{
"Social",
"Creative",
"Competitive",
"Casual",
"Educational",
"Entertainment",
"Lifestyle"
};
return Ok(tags);
}
[HttpGet("/club/mine/created")]
public IActionResult GetMyCreatedClubs()
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var clubs = ClubsDB.GetClubsCreatedBy(id.Value)
.Select(ClubsDB.ToSummary)
.ToList();
return new ContentResult
{
Content = JsonConvert.SerializeObject(clubs),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpGet("/club/mine/member")]
public IActionResult GetMyMemberClubs()
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var clubs = ClubsDB.GetClubsJoinedBy(id.Value)
.Where(c => c.Visibility != 2)
.Select(ClubsDB.ToSummary)
.ToList();
return new ContentResult
{
Content = JsonConvert.SerializeObject(clubs),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpGet("/club/account/{player}/created")]
public IActionResult GetOthersCreatedClubs(long player)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var clubs = ClubsDB.GetClubsCreatedBy(player)
.Where(c => c.Visibility != 2)
.Select(ClubsDB.ToSummary)
.ToList();
return new ContentResult
{
Content = JsonConvert.SerializeObject(clubs),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpGet("/club/{clubId}")]
[HttpGet("/club/{clubId}/details")]
public IActionResult GetClubDetails(long clubId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
return Ok(new ClubDetailsDTO
{
Club = ClubsDB.ToSummary(club),
CustomTags = club.CustomTags,
AdditionalImages = club.AdditionalImages,
CoownerPermissions = club.Permissions.FirstOrDefault(p => p.Type == (int)ClubMemberType.CoOwner),
ModeratorPermissions = club.Permissions.FirstOrDefault(p => p.Type == (int)ClubMemberType.Moderator),
MemberPermissions = club.Permissions.FirstOrDefault(p => p.Type == (int)ClubMemberType.Member),
MyMembershipType = club.Members
.FirstOrDefault(m => m.AccountId == id.Value)?.MemberType ?? 0
});
}
[HttpGet("/club/{clubId}/members")]
public IActionResult GetClubMembers(long clubId, [FromQuery] int? membershipType)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
var members = ClubsDB.GetClubMembers(clubId);
if (membershipType.HasValue)
members = members.Where(m => m.MembershipType == membershipType.Value).ToList();
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { value = members, success = true, error_id = (int?)null, error = (string?)null }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpDelete("/club/{clubId}")]
public IActionResult DeleteClub(long clubId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
if (club.CreatorAccountId != id.Value)
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to delete club {clubId} but is not the creator.");
return StatusCode(403);
}
ClubsDB.DeleteClub(clubId);
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = (string?)null, value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/modify")]
public IActionResult ModifyClub(
long clubId,
[FromForm] string? name,
[FromForm] string? description,
[FromForm] string? category)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var existing = ClubsDB.GetClub(clubId);
if (existing == null) return NotFound("");
if (!ClubsDB.CanEditDetails(clubId, id.Value))
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to modify club {clubId} but does not have permission.");
return StatusCode(403);
}
var club = ClubsDB.Modify(
clubId,
(name ?? existing.Name).Trim(),
(description ?? existing.Description ?? "").Trim(),
(category ?? existing.Category).Trim(),
id.Value);
if (club == null) return Unauthorized("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = (string?)null, value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/modifydetails")]
public IActionResult ModifyClubDetails(
long clubId,
[FromForm] string? visibility,
[FromForm] string? joinability,
[FromForm] string? allowJuniors,
[FromForm] string? customTags)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
if (!ClubsDB.CanEditDetails(clubId, id.Value))
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to modify club {clubId} but does not have permission. (2)");
return StatusCode(403);
}
int? vis = visibility != null ? ParseVisibility(visibility) : (int?)null;
int? join = joinability != null ? ParseJoinability(joinability) : (int?)null;
if (join == 1) return StatusCode(501);
bool? juniors = null;
if (allowJuniors != null)
juniors = allowJuniors.ToLowerInvariant() is "true" or "1";
List<string>? tags = null;
if (customTags != null)
tags = customTags
.Split(',', StringSplitOptions.RemoveEmptyEntries)
.Select(t => t.Trim())
.Where(t => !string.IsNullOrEmpty(t))
.ToList();
var club = ClubsDB.ModifyDetails(clubId, vis, join, juniors, tags, id.Value);
if (club == null) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/minlevel")]
public IActionResult SetMinLevel(long clubId, [FromForm] int minLevel)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
if (!ClubsDB.CanEditDetails(clubId, id.Value))
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to set min level for club {clubId} but does not have permission.");
return StatusCode(403);
}
var club = ClubsDB.SetMinLevel(clubId, minLevel, id.Value);
if (club == null) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = (string?)null, value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/mainimage")]
public IActionResult SetMainImage(long clubId, [FromForm] string imageName)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var existing = ClubsDB.GetClub(clubId);
if (existing == null) return NotFound("");
if (!ClubsDB.CanEditDetails(clubId, id.Value))
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to set the main image for club {clubId} but does not have permission.");
return StatusCode(403);
}
var club = ClubsDB.SetMainImage(clubId, imageName, id.Value);
if (club == null) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpDelete("/club/{clubId}/mainimage")]
public IActionResult DeleteMainImage(long clubId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var existing = ClubsDB.GetClub(clubId);
if (existing == null) return NotFound("");
if (!ClubsDB.CanEditDetails(clubId, id.Value))
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to delete the main image for club {clubId} but does not have permission.");
return StatusCode(403);
}
if (existing.AdditionalImages.Count == 0)
return StatusCode(405);
var club = ClubsDB.DeleteMainImage(clubId, id.Value);
if (club == null) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/additionalimage/{index}")]
public IActionResult SetAdditionalImage(long clubId, int index, [FromForm] string imageName)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var existing = ClubsDB.GetClub(clubId);
if (existing == null) return NotFound("");
if (!ClubsDB.CanEditDetails(clubId, id.Value))
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to set additional image {index} for club {clubId} but does not have permission.");
return StatusCode(403);
}
var club = ClubsDB.SetAdditionalImage(clubId, index, imageName, id.Value);
if (club == null) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/clubhouse")]
public IActionResult SetClubhouse(long clubId, [FromForm] long roomId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var existing = ClubsDB.GetClub(clubId);
if (existing == null) return NotFound("");
if (!ClubsDB.IsOwnerOrCoOwner(clubId, id.Value) && existing.CreatorAccountId != id.Value)
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to set clubhouse for club {clubId} but does not have permission.");
return StatusCode(403);
}
var club = ClubsDB.SetClubhouse(clubId, roomId, id.Value);
if (club == null) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpDelete("/club/{clubId}/clubhouse")]
public IActionResult RemoveClubhouse(long clubId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var existing = ClubsDB.GetClub(clubId);
if (existing == null) return NotFound("");
if (!ClubsDB.IsOwnerOrCoOwner(clubId, id.Value) && existing.CreatorAccountId != id.Value)
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to remove clubhouse for club {clubId} but does not have permission.");
return StatusCode(403);
}
var club = ClubsDB.RemoveClubhouse(clubId, id.Value);
if (club == null) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpGet("/club/{clubId}/hasDisabledClubChat")]
public IActionResult HasDisabledClubChat(long clubId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
return Ok(false);
}
[HttpPut("/club/{clubId}/members/requesttojoin")]
public async Task<IActionResult> RequestToJoin(long clubId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var existing = ClubsDB.GetClub(clubId);
if (existing == null) return NotFound("");
if (existing.Joinability == (int)ClubJoinability.Closed) return BadRequest(new { success = false, error = "The club is invite only", error_id = "Club.InviteOnly", value = (object?)null });
var club = ClubsDB.JoinClub(clubId, id.Value);
if (club == null) return NotFound("");
var joined = club.Members.FirstOrDefault(m => m.AccountId == id.Value);
if (joined != null)
{
await NotificationsController.BroadcastClubMembershipUpdate(joined.MemberId, id.Value, clubId, joined.MemberType, joined.JoinedAt);
await NotificationsController.BroadcastCreatorClubSubscriptionUpdate(club.CreatorAccountId, clubId, joined.MemberType);
}
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPost("/club/{clubId}/members/leave")]
public async Task<IActionResult> RequestLeaveClub(long clubId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var existing = ClubsDB.GetClub(clubId);
if (existing == null) return NotFound("");
var leaving = existing.Members.FirstOrDefault(m => m.AccountId == id.Value);
var club = ClubsDB.LeaveClub(clubId, id.Value);
if (club == null) return NotFound("");
if (leaving != null)
{
await NotificationsController.BroadcastClubMembershipUpdate(leaving.MemberId, id.Value, clubId, 0, DateTime.UtcNow);
await NotificationsController.BroadcastCreatorClubSubscriptionUpdate(existing.CreatorAccountId, clubId, 0);
}
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/permissions/{membershipType}")]
public IActionResult SetPermissions(long clubId, int membershipType, [FromForm] bool approveMember, [FromForm] bool banUnban, [FromForm] bool createEvent, [FromForm] bool editDetails, [FromForm] bool editPermissionSettings, [FromForm] bool postAnnouncement)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var existing = ClubsDB.GetClub(clubId);
if (existing == null) return NotFound("");
if (!ClubsDB.IsOwnerOrCoOwner(clubId, id.Value))
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to set permissions for club {clubId} but does not have permission.");
return StatusCode(403);
}
var club = ClubsDB.SetPermissions(clubId, membershipType, approveMember, banUnban, createEvent, editDetails, editPermissionSettings, postAnnouncement);
if (club == null) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = ClubsDB.ToDetails(club, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpGet("/club/home/me")]
public IActionResult GetMyHomeClub()
{
var player = AuthStuff.GetCurrentPlayer(Request);
if (player == null) return Unauthorized("");
int homeClubId = (int)player.Player.PlayerExtra.HomeClubhouseId;
if (homeClubId == 0 || homeClubId == null) return NotFound("");
var club = ClubsDB.GetClub(homeClubId);
if (club == null) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(ClubsDB.ToSummary(club)),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/home/me")]
public IActionResult SetMyHomeClub([FromForm] long clubId)
{
var player = AuthStuff.GetCurrentPlayer(Request);
if (player == null) return Unauthorized("");
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
player.Player.PlayerExtra.HomeClubhouseId = clubId;
PlayerDB.Players.Update(player);
return Ok(new { success = true, error = (string?)null, value = (object?)null });
}
[HttpDelete("/club/home/me")]
public IActionResult DeleteMyHomeClub([FromForm] long clubId)
{
var player = AuthStuff.GetCurrentPlayer(Request);
if (player == null) return Unauthorized("");
player.Player.PlayerExtra.HomeClubhouseId = 0;
PlayerDB.Players.Update(player);
return Ok(new { success = true, error = (string?)null, value = (object?)null });
}
[HttpGet("/announcements/mine")]
public IActionResult GetMyAnnouncements()
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var result = ClubsDB.GetAnnouncementsForMyClubs(id.Value);
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = result }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpGet("/announcements/club/{clubId}")]
public IActionResult GetClubAnnouncements(long clubId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var result = ClubsDB.GetClubAnnouncements(clubId, id.Value);
if (result == null) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = result }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPost("/announcements/club/{clubId}")]
public IActionResult CreateAnnouncement(
long clubId,
[FromForm] string title,
[FromForm] string body,
[FromForm] string? imageName,
[FromForm] string? meta)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
if (string.IsNullOrWhiteSpace(title) || title.Length > 50)
return BadRequest(new { success = false, error = "Title must be between 1 and 50 characters." });
if (string.IsNullOrWhiteSpace(body) || body.Length > 1000)
return BadRequest(new { success = false, error = "Body must be between 1 and 1000 characters." });
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
if (!ClubsDB.CanPostAnnouncement(clubId, id.Value))
return StatusCode(403);
var announcement = ClubsDB.CreateAnnouncement(clubId, id.Value, title, body, imageName, meta);
if (announcement == null) return StatusCode(500);
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = announcement.AnnouncementId }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/announcements/club/{clubId}/{announcementId}")]
public IActionResult EditAnnouncement(
long clubId,
long announcementId,
[FromForm] string title,
[FromForm] string body,
[FromForm] string? imageName,
[FromForm] string? meta)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
if (string.IsNullOrWhiteSpace(title) || title.Length > 50)
return BadRequest(new { success = false, error = "Title must be between 1 and 50 characters." });
if (string.IsNullOrWhiteSpace(body) || body.Length > 1000)
return BadRequest(new { success = false, error = "Body must be between 1 and 1000 characters." });
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
var announcement = ClubsDB.EditAnnouncement(clubId, announcementId, id.Value, title, body, imageName, meta);
if (announcement == null) return StatusCode(403);
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = "", value = announcement.AnnouncementId }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpDelete("/announcements/club/{clubId}/{announcementId}")]
public IActionResult DeleteAnnouncement(long clubId, long announcementId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
bool deleted = ClubsDB.DeleteAnnouncement(clubId, announcementId, id.Value);
if (!deleted) return StatusCode(403);
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = (string?)null, value = (object?)null }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPost("/announcements/club/{clubId}/{announcementId}/read")]
public IActionResult MarkAnnouncementRead(long clubId, long announcementId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
bool ok = ClubsDB.MarkAnnouncementRead(clubId, announcementId, id.Value);
if (!ok) return NotFound("");
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = (string?)null, value = (object?)null }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/members/{targetId}/role")]
public async Task<IActionResult> SetMemberRole(long clubId, long targetId, [FromForm] int membershipType)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
if (!ClubsDB.IsOwnerOrCoOwner(clubId, id.Value) && club.CreatorAccountId != id.Value)
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to set role in club {clubId} but does not have permission.");
return StatusCode(403);
}
var target = club.Members.FirstOrDefault(m => m.AccountId == targetId);
if (target == null) return NotFound("");
bool ok = ClubsDB.SetMemberRole(clubId, targetId, membershipType, id.Value);
if (!ok) return NotFound("");
await NotificationsController.BroadcastClubMembershipUpdate(target.MemberId, targetId, clubId, membershipType, target.JoinedAt);
var updated = ClubsDB.GetClub(clubId);
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = (string?)null, value = updated != null ? ClubsDB.ToDetails(updated, id.Value) : null }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/members/{targetId}/kick")]
public async Task<IActionResult> KickMember(long clubId, long targetId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
var target = club.Members.FirstOrDefault(m => m.AccountId == targetId);
var result = ClubsDB.KickMember(clubId, targetId, id.Value);
if (result == null)
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to kick {targetId} from club {clubId} but does not have permission.");
return StatusCode(403);
}
if (target != null)
await NotificationsController.BroadcastClubMembershipUpdate(target.MemberId, targetId, clubId, 0, DateTime.UtcNow);
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = (string?)null, value = ClubsDB.ToDetails(result, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/members/{targetId}/ban")]
public async Task<IActionResult> BanMember(long clubId, long targetId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
var target = club.Members.FirstOrDefault(m => m.AccountId == targetId);
bool ok = ClubsDB.BanMember(clubId, targetId, id.Value);
if (!ok)
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to ban {targetId} from club {clubId} but does not have permission.");
return StatusCode(403);
}
if (target != null)
await NotificationsController.BroadcastClubMembershipUpdate(target.MemberId, targetId, clubId, 0, DateTime.UtcNow);
var updated = ClubsDB.GetClub(clubId);
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = (string?)null, value = updated != null ? ClubsDB.ToDetails(updated, id.Value) : null }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/members/{targetId}/unban")]
public IActionResult UnbanMember(long clubId, long targetId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
bool ok = ClubsDB.UnbanMember(clubId, targetId, id.Value);
if (!ok)
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to unban {targetId} from club {clubId} but does not have permission.");
return StatusCode(403);
}
var updated = ClubsDB.GetClub(clubId);
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = (string?)null, value = updated != null ? ClubsDB.ToDetails(updated, id.Value) : null }),
ContentType = "application/json",
StatusCode = 200
};
}
[HttpPut("/club/{clubId}/members/{targetId}/approve")]
public async Task<IActionResult> ApproveMember(long clubId, long targetId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null) return Unauthorized("");
var club = ClubsDB.GetClub(clubId);
if (club == null) return NotFound("");
var result = ClubsDB.ApproveMember(clubId, targetId, id.Value);
if (result == null)
{
APIController.SendNonHileWebhook(id.Value, $"Attempted to approve {targetId} in club {clubId} but does not have permission.");
return StatusCode(403);
}
var member = result.Members.FirstOrDefault(m => m.AccountId == targetId);
if (member != null)
{
await NotificationsController.BroadcastClubMembershipUpdate(member.MemberId, targetId, clubId, member.MemberType, member.JoinedAt);
await NotificationsController.BroadcastCreatorClubSubscriptionUpdate(result.CreatorAccountId, clubId, member.MemberType);
}
return new ContentResult
{
Content = JsonConvert.SerializeObject(new { success = true, error = (string?)null, value = ClubsDB.ToDetails(result, id.Value) }),
ContentType = "application/json",
StatusCode = 200
};
}
}
}
+230
View File
@@ -0,0 +1,230 @@
//using Microsoft.AspNetCore.Mvc;
//using Vanadium.Auth;
//using Vanadium.Classes;
//using Vanadium.Classes.DBs;
//using System.Text;
//using System.Text.Json;
//using System.Text.Json.Serialization;
//using Vanadium.Classes;
//namespace Vanadium.Controllers
//{
// [ApiController]
// public class PhotonController : ControllerBase
// {
// private readonly HttpClient _httpClient = new();
// private bool IsRealClient()
// {
// var accept = Request.Headers["Accept"].ToString();
// var userAgent = Request.Headers["User-Agent"].ToString();
// return userAgent == "BestHTTP"
// && accept.Contains("application/json")
// && accept.Contains("image/png")
// && accept.Contains("image/jpeg");
// }
// private async Task SendFakeClientWebhook(string ip, string headersPretty, string body)
// {
// try
// {
// const int maxLen = 950;
// var truncatedHeaders = headersPretty.Length > maxLen
// ? headersPretty.Substring(0, maxLen) + "\n... (truncated)"
// : headersPretty;
// var embed = new
// {
// title = "⚠️ Fake Client Hit AppSettings (served decoy)",
// color = 15158332,
// fields = new object[]
// {
// new { name = "IP", value = $"`{ip}`", inline = false },
// new { name = "Headers", value = $"```\n{truncatedHeaders}\n```", inline = false },
// new { name = "Body", value = $"json```\n{body}\n```", inline = false }
// },
// timestamp = DateTime.UtcNow.ToString("O")
// };
// var payload = new
// {
// embeds = new[] { embed }
// };
// var content = new StringContent(
// JsonSerializer.Serialize(payload),
// Encoding.UTF8,
// "application/json"
// );
// await _httpClient.PostAsync(ServerConfig.PhotonWebhook, content);
// }
// catch (Exception ex)
// {
// Console.WriteLine($"Fake client webhook error: {ex.Message}");
// }
// }
// [HttpGet("/photon/appSettings")]
// public IActionResult GetPhoton()
// {
// return NotFound("");
// Console.WriteLine("photon called");
// if (!IsRealClient()) // dont touch this a fix for the photon botter botting us
// {
// var fakeIp = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown";
// var fakeHeaders = GetHeadersPretty();
// var decoy = new AppSettings
// {
// PhotonRealtimeId = "aaae496f-ece0-4b1b-82ac-aea17d766c82",
// PhotonVoiceId = "d1b950c8-95e4-4725-9a3b-f6fc57853484",
// PhotonRegion = "us"
// };
// string decoyJson = JsonSerializer.Serialize(decoy, new JsonSerializerOptions { WriteIndented = true });
// _ = SendFakeClientWebhook(fakeIp, fakeHeaders, decoyJson);
// return Ok(decoy);
// }
// var ip = HttpContext.Connection.RemoteIpAddress?.ToString() ?? "unknown";
// var settings = ServerConfig.appSettings;
// string settingsJson = JsonSerializer.Serialize(settings, new JsonSerializerOptions { WriteIndented = true });
// string headersPretty = GetHeadersPretty();
// _ = SendAppSettingsWebhook(ip, headersPretty, settingsJson);
// return Ok(settings);
//}
// private string GetHeadersPretty()
// {
// var sb = new StringBuilder();
// foreach (var header in Request.Headers)
// {
// sb.AppendLine($"{header.Key}: {header.Value}");
// }
// return sb.ToString();
// }
// [HttpPost("/photon/{url}")]
// public async Task<IActionResult> stub(string url)
// {
// return await HandleStub("", "/photon", url);
// }
// [HttpPost("/photon_realtime/{url}")]
// public async Task<IActionResult> stubRealtime(string url)
// {
// return await HandleStub("Realtime", "/photon_realtime", url);
// }
// [HttpPost("/photon_voice/{url}")]
// public async Task<IActionResult> stubVoice(string url)
// {
// return await HandleStub("Voice", "/photon_voice", url);
// }
// private async Task<IActionResult> HandleStub(string type, string urltype, string url)
// {
// Request.EnableBuffering();
// string rawBody;
// using (var reader = new StreamReader(Request.Body, Encoding.UTF8, detectEncodingFromByteOrderMarks: false, bufferSize: 1024, leaveOpen: true))
// {
// rawBody = await reader.ReadToEndAsync();
// Request.Body.Position = 0;
// }
// string prettyJson = rawBody;
// try
// {
// if (!string.IsNullOrWhiteSpace(rawBody))
// {
// using var doc = JsonDocument.Parse(rawBody);
// prettyJson = JsonSerializer.Serialize(doc, new JsonSerializerOptions { WriteIndented = true });
// }
// }
// catch (JsonException)
// {
// }
// Console.WriteLine($"Stub called: url={urltype}/{url}, body={rawBody}");
// await SendStubWebhook(type, urltype, url, prettyJson);
// return Ok(new
// {
// ResultCode = 0
// });
// }
// private async Task SendAppSettingsWebhook(string ip, string headersPretty, string bodyValue)
//{
// try
// {
// const int maxLen = 950;
// var truncatedHeaders = headersPretty.Length > maxLen
// ? headersPretty.Substring(0, maxLen) + "\n... (truncated)"
// : headersPretty;
// var embed = new
// {
// title = "Photon GET AppSettings Called",
// color = 15105570,
// fields = new object[]
// {
// new { name = "IP", value = $"`{ip}`", inline = false },
// new { name = "Headers", value = $"json```\n{truncatedHeaders}\n```", inline = false },
// new { name = "Body", value = $"json```\n{bodyValue}\n```", inline = false }
// },
// timestamp = DateTime.UtcNow.ToString("O")
// };
// var payload = new
// {
// embeds = new[] { embed }
// };
// var content = new StringContent(
// JsonSerializer.Serialize(payload),
// Encoding.UTF8,
// "application/json"
// );
// var response = await _httpClient.PostAsync(ServerConfig.PhotonWebhook, content);
// }
// catch (Exception ex)
// {
// }
//}
// private async Task SendStubWebhook(string type, string urltype, string url, string prettyJson)
// {
// try
// {
// const int maxLen = 950;
// var body = string.IsNullOrWhiteSpace(prettyJson) ? "(empty)" : prettyJson;
// var truncated = body.Length > maxLen
// ? body.Substring(0, maxLen) + "\n... (truncated)"
// : body;
// var bodyValue = body == "(empty)"
// ? "(empty)"
// : $"```json\n{truncated}\n```";
// var embed = new
// {
// title = $"Photon {type} Called",
// color = 15105570,
// fields = new object[]
// {
// new { name = "URL", value = $"`{urltype}/{url}`", inline = false },
// new { name = "Body", value = bodyValue, inline = false }
// },
// timestamp = DateTime.UtcNow.ToString("O")
// };
// var payload = new
// {
// embeds = new[] { embed }
// };
// var content = new StringContent(
// JsonSerializer.Serialize(payload),
// Encoding.UTF8,
// "application/json"
// );
// var response = await _httpClient.PostAsync(ServerConfig.PhotonWebhook, content);
// Console.WriteLine($"Stub webhook sent: {response.StatusCode}");
// }
// catch (Exception ex)
// {
// Console.WriteLine($"Stub webhook error: {ex.Message}");
// }
// }
// }
//}
+434
View File
@@ -0,0 +1,434 @@
using Microsoft.AspNetCore.Mvc;
using Vanadium.Auth;
using Vanadium.Classes.DBs;
using Vanadium.Classes;
using static Vanadium.Classes.DBs.DBClasses.EventDBClasses;
namespace Vanadium.Controllers
{
[ApiController]
public partial class PlayerEventsController : ControllerBase
{
[HttpGet("/api/playerevents/v1/tagfilters")]
public async Task<IActionResult> PlayerEventTags()
{
return Ok(System.Text.Json.JsonSerializer.Deserialize<object>(
System.IO.File.ReadAllText(
Path.Combine(Environment.CurrentDirectory, "Data", "APIS", "EventTags.json"))));
}
[HttpGet("/api/playerevents/v1/all")]
public async Task<IActionResult> GetAllPlayerEvents()
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var created = EventDB.GetPlayerEvents(id.Value);
var attending = EventDB.GetAttendingEvents(id.Value);
var hosting = EventDB.GetHostingEvents(id.Value);
var responses = EventDB.GetResponsesForPlayer(id.Value);
return Ok(new
{
Created = created,
Attending = attending,
Hosting = hosting,
Responses = responses
});
}
[HttpGet("/api/playerevents/v1/searchlive")]
public async Task<IActionResult> GetLiveEvents()
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var events = EventDB.GetLiveEvents();
return Ok(events);
}
[HttpGet("/api/playerevents/v1/search")]
public async Task<IActionResult> SearchEvents(
[FromQuery] string? query,
[FromQuery] string? sort,
[FromQuery] string? scheduleFilter)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var events = EventDB.SearchEvents(query, sort, scheduleFilter);
return Ok(events);
}
[HttpGet("/api/playerevents/v1/room/{roomId}")]
public async Task<IActionResult> GetEventsForRoom(long roomId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var events = EventDB.GetEventsByRoomId(roomId);
return Ok(events);
}
[HttpGet("/api/playerevents/v1/club")]
[HttpGet("/api/playerevents/v1/clubs")]
public async Task<IActionResult> GetEventsForClub()
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
return Ok(new List<object>());
}
[HttpGet("/api/playerevents/v1/{eventId}")]
public async Task<IActionResult> GetPlayerEvent(long eventId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var ev = EventDB.GetPlayerEventById(eventId);
if (ev == null)
return NotFound("");
return Ok(ev);
}
[HttpPost("/api/playerevents/v2")]
public async Task<IActionResult> CreatePlayerEvent([FromBody] PlayerEventRequest request)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
if (Sanitize.ContainsSwears(request.Name) || Sanitize.ContainsSwears(request.Description))
return Ok(new PlayerEventResponse { PlayerEvent = null, Result = 14 });
var response = EventDB.CreatePlayerEvent(id.Value, request);
if (response.Result != 0)
return Ok(response);
var wsJson = Newtonsoft.Json.JsonConvert.SerializeObject(new Vanadium.Classes.WebSocket.WebsocketEvents.Response
{
Id = "PlayerEventCreated",
Msg = response.PlayerEvent
});
await NotificationsController.SendToAll(wsJson);
return Ok(response);
}
[HttpDelete("/api/playerevents/v2/delete/{eventId}")]
public async Task<IActionResult> DeletePlayerEvent(long eventId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var deleted = EventDB.DeletePlayerEvent(eventId, id.Value);
return Ok(new { success = deleted });
}
[HttpPost("/api/playerevents/v2/{eventId}/rsvp")]
public async Task<IActionResult> RsvpPlayerEvent(long eventId, [FromBody] RsvpRequest request)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var ev = EventDB.GetPlayerEventById(eventId);
if (ev == null)
return NotFound("");
var response = EventDB.SetResponse(eventId, id.Value, request.Type);
return Ok(new { success = true, value = response });
}
[HttpGet("/api/playerevents/v2/{eventId}/rsvp")]
public async Task<IActionResult> GetRsvp(long eventId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var response = EventDB.GetResponse(eventId, id.Value);
var type = response?.Type ?? (int)PlayerEventResponseType.None;
return Ok(new { type });
}
[HttpGet("/api/playerevents/v2/{eventId}/responses")]
public async Task<IActionResult> GetEventResponses(long eventId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var responses = EventDB.GetResponsesForEvent(eventId);
return Ok(responses);
}
[HttpPost("/api/playerevents/v1/respond")]
public async Task<IActionResult> RespondToPlayerEvent([FromBody] RespondRequest request)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
if (request == null || request.PlayerEventId == 0)
return BadRequest(new { success = false, error = "PlayerEventId required." });
var ev = EventDB.GetPlayerEventById(request.PlayerEventId);
if (ev == null)
return NotFound("");
int typeInt = request.Type switch
{
"Yes" => (int)PlayerEventResponseType.Yes,
"Interested" => (int)PlayerEventResponseType.Interested,
"No" => (int)PlayerEventResponseType.No,
_ => (int)PlayerEventResponseType.None
};
var response = EventDB.SetResponse(request.PlayerEventId, id.Value, typeInt);
var updatedEvent = EventDB.GetPlayerEventById(request.PlayerEventId);
var wsJson = Newtonsoft.Json.JsonConvert.SerializeObject(new Vanadium.Classes.WebSocket.WebsocketEvents.Response
{
Id = "PlayerEventResponseChanged",
Msg = updatedEvent
});
await NotificationsController.SendToAll(wsJson);
return Ok(new { success = true, value = response });
}
[HttpGet("/api/playerevents/v1/{eventId}/responses")]
public async Task<IActionResult> GetEventResponsesV1(long eventId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
return Ok(EventDB.GetResponsesForEvent(eventId));
}
[HttpPut("/api/playerevents/v2/{eventId}/name")]
[HttpPost("/api/playerevents/v2/{eventId}/name")]
public async Task<IActionResult> EditEventName(long eventId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var name = await ReadBodyValue("name", "value");
if (name == null)
return BadRequest(new { success = false, error = "Name required." });
var ev = EventDB.EditPlayerEvent(eventId, id.Value, e => e.Name = name);
if (ev == null) return NotFound();
var wsJson = Newtonsoft.Json.JsonConvert.SerializeObject(new Vanadium.Classes.WebSocket.WebsocketEvents.Response
{
Id = "PlayerEventUpdated",
Msg = ev
});
await NotificationsController.SendToAll(wsJson);
return Ok(new { success = true, value = ev });
}
[HttpPut("/api/playerevents/v2/{eventId}/description")]
[HttpPost("/api/playerevents/v2/{eventId}/description")]
public async Task<IActionResult> EditEventDescription(long eventId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var desc = await ReadBodyValue("description", "value");
if (desc == null)
return BadRequest(new { success = false, error = "Description required." });
var ev = EventDB.EditPlayerEvent(eventId, id.Value, e => e.Description = desc);
if (ev == null) return NotFound();
var wsJson = Newtonsoft.Json.JsonConvert.SerializeObject(new Vanadium.Classes.WebSocket.WebsocketEvents.Response
{
Id = "PlayerEventUpdated",
Msg = ev
});
await NotificationsController.SendToAll(wsJson);
return Ok(new { success = true, value = ev });
}
[HttpPut("/api/playerevents/v2/{eventId}/image")]
[HttpPost("/api/playerevents/v2/{eventId}/image")]
public async Task<IActionResult> EditEventImage(long eventId)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var image = await ReadBodyValue("imageName", "image", "value");
if (image == null)
return BadRequest(new { success = false, error = "ImageName required." });
var ev = EventDB.EditPlayerEvent(eventId, id.Value, e => e.ImageName = image);
if (ev == null) return NotFound();
var wsJson = Newtonsoft.Json.JsonConvert.SerializeObject(new Vanadium.Classes.WebSocket.WebsocketEvents.Response
{
Id = "PlayerEventUpdated",
Msg = ev
});
await NotificationsController.SendToAll(wsJson);
return Ok(new { success = true, value = ev });
}
[HttpPut("/api/playerevents/v2/{eventId}/room")]
[HttpPost("/api/playerevents/v2/{eventId}/room")]
public async Task<IActionResult> EditEventRoom(long eventId, [FromBody] PlayerEventRoomRequest body)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
if (body == null || body.RoomId == 0)
return BadRequest(new { success = false, error = "RoomId required." });
var ev = EventDB.EditPlayerEvent(eventId, id.Value, e =>
{
e.RoomId = body.RoomId;
e.SubRoomId = body.SubRoomId;
});
if (ev == null) return NotFound();
var wsJson = Newtonsoft.Json.JsonConvert.SerializeObject(new Vanadium.Classes.WebSocket.WebsocketEvents.Response
{
Id = "PlayerEventUpdated",
Msg = ev
});
await NotificationsController.SendToAll(wsJson);
return Ok(new { success = true, value = ev });
}
[HttpPut("/api/playerevents/v2/{eventId}/time")]
[HttpPost("/api/playerevents/v2/{eventId}/time")]
public async Task<IActionResult> EditEventTime(long eventId, [FromBody] PlayerEventTimeRequest body)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
if (body == null || (string.IsNullOrWhiteSpace(body.StartTime) && string.IsNullOrWhiteSpace(body.EndTime)))
return BadRequest(new { success = false, error = "StartTime or EndTime required." });
DateTime? start = null, end = null;
try
{
if (!string.IsNullOrWhiteSpace(body.StartTime)) start = DateTime.Parse(body.StartTime);
if (!string.IsNullOrWhiteSpace(body.EndTime)) end = DateTime.Parse(body.EndTime);
}
catch
{
return BadRequest(new { success = false, error = "Invalid time format." });
}
var ev = EventDB.EditPlayerEvent(eventId, id.Value, e =>
{
if (start.HasValue) e.StartTime = start.Value;
if (end.HasValue) e.EndTime = end.Value;
});
if (ev == null) return NotFound();
var wsJson = Newtonsoft.Json.JsonConvert.SerializeObject(new Vanadium.Classes.WebSocket.WebsocketEvents.Response
{
Id = "PlayerEventUpdated",
Msg = ev
});
await NotificationsController.SendToAll(wsJson);
return Ok(new { success = true, value = ev });
}
[HttpPut("/api/playerevents/v2/{eventId}/club")]
[HttpPost("/api/playerevents/v2/{eventId}/club")]
public async Task<IActionResult> EditEventClub(long eventId, [FromBody] PlayerEventClubRequest body)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
var ev = EventDB.EditPlayerEvent(eventId, id.Value, e => e.ClubId = body?.ClubId);
if (ev == null) return NotFound();
var wsJson = Newtonsoft.Json.JsonConvert.SerializeObject(new Vanadium.Classes.WebSocket.WebsocketEvents.Response
{
Id = "PlayerEventUpdated",
Msg = ev
});
await NotificationsController.SendToAll(wsJson);
return Ok(new { success = true, value = ev });
}
[HttpPut("/api/playerevents/v2/{eventId}/multiinstance")]
[HttpPost("/api/playerevents/v2/{eventId}/multiinstance")]
public async Task<IActionResult> EditEventMultiInstance(long eventId, [FromBody] PlayerEventMultiInstanceRequest body)
{
var id = AuthStuff.GetPlayerId(Request);
if (id == null)
return Unauthorized("");
if (body == null)
return BadRequest(new { success = false, error = "Body required." });
var ev = EventDB.EditPlayerEvent(eventId, id.Value, e =>
{
e.IsMultiInstance = body.IsMultiInstance;
e.SupportMultiInstanceRoomChat = body.SupportMultiInstanceRoomChat;
});
if (ev == null) return NotFound();
var wsJson = Newtonsoft.Json.JsonConvert.SerializeObject(new Vanadium.Classes.WebSocket.WebsocketEvents.Response
{
Id = "PlayerEventUpdated",
Msg = ev
});
await NotificationsController.SendToAll(wsJson);
return Ok(new { success = true, value = ev });
}
private async Task<string?> ReadBodyValue(params string[] keys)
{
using var reader = new StreamReader(Request.Body);
var raw = (await reader.ReadToEndAsync())?.Trim();
if (string.IsNullOrEmpty(raw))
return null;
if (raw.StartsWith("{"))
{
try
{
using var doc = System.Text.Json.JsonDocument.Parse(raw);
foreach (var prop in doc.RootElement.EnumerateObject())
foreach (var k in keys)
if (string.Equals(prop.Name, k, StringComparison.OrdinalIgnoreCase))
return prop.Value.ValueKind == System.Text.Json.JsonValueKind.String
? prop.Value.GetString()
: prop.Value.ToString();
}
catch { }
return null;
}
if (raw.StartsWith("\""))
{
try { return System.Text.Json.JsonSerializer.Deserialize<string>(raw); }
catch { return raw.Trim('"'); }
}
return raw;
}
public class RsvpRequest
{
public int Type { get; set; }
}
}
}