Radicade Public Code

This commit is contained in:
JogmansonReal
2026-10-16 23:33:13 -07:00
commit 55175acdf6
832 changed files with 363261 additions and 0 deletions
+11
View File
@@ -0,0 +1,11 @@
namespace RadicadeServer.RecNet.Messages
{
public class ChatMessage
{
public long chatMessageId { get; set; }
public long chatThreadeId { get; set; }
public long senderPlayerId { get; set; }
public DateTime timeSent { get; set; }
public string contents { get; set; } = null!;
}
}
+54
View File
@@ -0,0 +1,54 @@
using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using System.Text.Json;
using RadicadeServer.Extensions;
namespace RadicadeServer.RecNet.Messages
{
public class ChatThread
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long chatThreadId { get; set; }
public string chatThreadName { get; set; } = null!;
public long lastReadMessageId { get; set; }
public string messages { get; set; } = null!;
public string playerIds { get; set; } = null!;
public string? favoritedBy { get; set; }
public List<long> GetFavoritedBy() =>
string.IsNullOrWhiteSpace(favoritedBy) ? new List<long>() : favoritedBy.FromJson<List<long>>() ?? new List<long>();
public void SetFavoritedBy(IEnumerable<long> playerIds)
{
favoritedBy = playerIds.Distinct().OrderBy(x => x).ToList().ToJson();
}
public List<long>? GetPlayerIds()
{
return playerIds.FromJson<List<long>>();
}
public List<ChatMessage>? GetMessages()
{
if (string.IsNullOrWhiteSpace(messages)) return new List<ChatMessage>();
if (messages.TrimStart().StartsWith("{", StringComparison.Ordinal))
{
var message = messages.FromJson<ChatMessage>();
return message == null ? new List<ChatMessage>() : new List<ChatMessage> { message };
}
return messages.FromJson<List<ChatMessage>>();
}
public string AddMessage(ChatMessage message)
{
var messages = GetMessages() ?? new List<ChatMessage>();
messages.Add(message);
return messages.ToJson();
}
public string AddPlayer(long player)
{
var players = GetPlayerIds() ?? new List<long>();
players.Add(player);
return players.ToJson(); ;
}
}
}
@@ -0,0 +1,7 @@
namespace RadicadeServer.RecNet.Messages
{
public class DeleteMessageRequestDTO
{
public List<long> MessageIds { get; set; } = null!;
}
}
+30
View File
@@ -0,0 +1,30 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text.Json.Serialization;
using RadicadeServer.RecNet.Enums.Messages;
namespace RadicadeServer.RecNet.Messages
{
public class Message
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public long Id { get; set; }
public long FromPlayerId { get; set; }
[JsonIgnore]
public long ToPlayerId { get; set; }
[JsonIgnore]
public bool IsDismissed { get; set; }
public DateTime SentTime { get; set; }
public MessageType Type { get; set; }
public string Data { get; set; } = string.Empty;
public string Details { get; set; } = string.Empty;
public long? RoomId { get; set; }
public long? PlayerEventId { get; set; }
}
}
+122
View File
@@ -0,0 +1,122 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using RadicadeServer.API.Notifications;
using RadicadeServer.DB;
using RadicadeServer.Extensions;
using RadicadeServer.RecNet.Enums.Messages;
using RadicadeServer.RecNet.Messages;
using RadicadeServer.RecNet.Responses;
namespace RadicadeServer.API.Messages
{
[Route("api/messages/")]
public class MessagesAPI : Controller
{
RecDBContext db;
public MessagesAPI(RecDBContext context)
{
this.db = context;
}
[HttpGet("v1/favoriteFriendOnlineStatus"), Authorize]
public async Task<Success> NotifyFavoriteFriends()
{
var userId = User.GetUserId();
var favoritedUsers = await db.Relationships.Where(x => x.AccountId == userId && x.Favorited != RecNet.Relationships.ReciprocalStatus.None).ToListAsync();
foreach (var favorited in favoritedUsers)
{
var presence = await db.Presences.FirstOrDefaultAsync(x => x.isOnline && x.playerId == favorited.PlayerId);
if (presence != null)
await Notify.SendMessage(favorited.AccountId, new Message { FromPlayerId = (long)userId!, Type = MessageType.FriendStatusOnline });
}
return new Success(true, null, null);
}
[HttpGet("v2/get"), Authorize]
public async Task<List<Message>?> GetMessages()
{
var userId = User.GetUserId();
return await db.Messages.Where(x => x.ToPlayerId == userId && !x.IsDismissed).ToListAsync();
}
[HttpPost("v3/delete"), Authorize]
public async Task<Success?> DeleteMessage([FromBody] DeleteMessageRequestDTO req)
{
var userId = User.GetUserId();
if (req.MessageIds == null || req.MessageIds.Count == 0) return new Success(false, "Invalid Ids", null);
int deleted = 0;
foreach (var id in req.MessageIds)
{
var msg = await db.Messages.FirstOrDefaultAsync(x => x.Id == id && x.ToPlayerId == userId);
if (msg == null) { continue; }
if (msg.Type == MessageType.GameInviteV2 || msg.Type == MessageType.GameInvite)
msg.IsDismissed = true;
else
db.Messages.Remove(msg);
deleted++;
}
await db.SaveChangesAsync();
return new Success(true, null, null);
}
[HttpPost("v2/send"), Authorize]
public async Task<Success> SendMessage([FromForm] long ToPlayerId, [FromForm] MessageType Type, [FromForm] string? Data, [FromForm] long? RoomId)
{
var userId = User.GetUserId();
await Notify.SendMessage(ToPlayerId, new Message { FromPlayerId = (long)userId!, Type = Type, Data = Data ?? "", RoomId = RoomId });
return new Success(true, null, null);
}
[HttpPost("v1/sendMultiple"), Authorize]
public async Task<Success> SendMultipleMessages([FromBody] SendMultipleMessagesRequestDTO req)
{
var userId = User.GetUserId();
if (userId == null) return new Success(false, "Not signed in", null);
var recipients = (req.ToPlayerIds ?? new List<long>())
.Where(id => id > 0)
.Distinct()
.ToList();
if (recipients.Count == 0) return new Success(false, "ToPlayerIds is required", null);
foreach (var toPlayerId in recipients)
await Notify.SendMessage(toPlayerId, new Message
{
FromPlayerId = userId.Value,
Type = req.Type,
Data = req.Data ?? ""
});
return new Success(true, null, null);
}
[HttpPost("v1/friendOnlineStatus"), Authorize]
public async Task<Success> FriendOnlineStatus()
{
var userId = User.GetUserId();
if (userId == null)
return new Success(false, "Not signed in", null);
var friendIds = await db.Relationships.AsNoTracking()
.Where(x => x.AccountId == userId && x.RelationshipType == RecNet.Relationships.RelationshipType.Friend)
.Select(x => x.PlayerId)
.ToListAsync();
var onlineCount = friendIds.Count == 0
? 0
: await db.Presences.AsNoTracking()
.CountAsync(p => friendIds.Contains(p.playerId) && p.isOnline);
return new Success(true, null, new { FriendsOnlineCount = onlineCount });
}
}
}
+25
View File
@@ -0,0 +1,25 @@
using System.Text.Json;
using RadicadeServer.RecNet.Enums.Messages;
namespace RadicadeServer.RecNet.Messages;
public sealed class RoomInviteDetails
{
public long InviteId { get; set; }
public string Name { get; set; } = string.Empty;
public int InviteMode { get; set; }
public long RoomInstanceId { get; set; }
public static long? GetInstanceId(Message message)
{
if (message.Type == MessageType.GameInvite)
return long.TryParse(message.Data, out var id) && id > 0 ? id : null;
if (message.Type != MessageType.GameInviteV2) return null;
try
{
var details = JsonSerializer.Deserialize<RoomInviteDetails>(message.Data);
return details?.RoomInstanceId > 0 ? details.RoomInstanceId : null;
}
catch (JsonException) { return null; }
}
}
@@ -0,0 +1,11 @@
using RadicadeServer.RecNet.Enums.Messages;
namespace RadicadeServer.RecNet.Messages
{
public class SendMultipleMessagesRequestDTO
{
public List<long>? ToPlayerIds { get; set; }
public MessageType Type { get; set; }
public string? Data { get; set; }
}
}