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
@@ -0,0 +1,82 @@
using System.Text.Json;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using RadicadeServer.API.Notifications;
using RadicadeServer.DB;
using RadicadeServer.RecNet.Enums.Messages;
using RadicadeServer.RecNet.Messages;
using Xunit;
namespace RadicadeServer.Tests;
public sealed class SqlServerInviteFactAttribute : FactAttribute
{
public SqlServerInviteFactAttribute()
{
if (string.IsNullOrWhiteSpace(Environment.GetEnvironmentVariable("RADICADE_SQL_TEST_CONNECTION")))
Skip = "Set RADICADE_SQL_TEST_CONNECTION to a SQL Server with permission to create a scratch database.";
}
}
[Collection(DbFactoryCollection.Name)]
public class SqlServerInvitePersistenceTests
{
private sealed class Factory(string connection) : IDbContextFactory<RecDBContext>
{
public RecDBContext CreateDbContext() => new(TestDbOptions.Create()
.UseSqlServer(connection, sql => sql.EnableRetryOnFailure(3)).Options);
}
[SqlServerInviteFact]
public async Task InvitePayloadCommitsWithSqlServerRetriesEnabled()
{
// Never write test invitations into the user's database or notify real players.
var database = "RadicadeInviteTest_" + Guid.NewGuid().ToString("N");
var connection = new SqlConnectionStringBuilder(
Environment.GetEnvironmentVariable("RADICADE_SQL_TEST_CONNECTION"));
connection.InitialCatalog = "master";
await using var admin = new SqlConnection(connection.ConnectionString);
await admin.OpenAsync();
await using (var create = new SqlCommand($"CREATE DATABASE [{database}]", admin))
await create.ExecuteNonQueryAsync();
var previous = Notify.DbFactory;
try
{
connection.InitialCatalog = database;
var factory = new Factory(connection.ConnectionString);
await using var db = factory.CreateDbContext();
await db.Database.ExecuteSqlRawAsync("""
CREATE TABLE [Messages] (
[Id] bigint IDENTITY PRIMARY KEY,
[FromPlayerId] bigint NOT NULL, [ToPlayerId] bigint NOT NULL,
[SentTime] datetime2 NOT NULL, [Type] int NOT NULL,
[Data] nvarchar(max) NOT NULL, [Details] nvarchar(max) NOT NULL,
[RoomId] bigint NULL, [PlayerEventId] bigint NULL,
[IsDismissed] bit NOT NULL);
""");
Notify.DbFactory = factory;
var message = new Message
{
FromPlayerId = long.MaxValue - 1, RoomId = 45, Type = MessageType.GameInviteV2
};
await Notify.SendMessage(long.MaxValue, message, prepareWithId: stored =>
stored.Data = JsonSerializer.Serialize(new RoomInviteDetails
{
InviteId = stored.Id, Name = "SQL invite test", RoomInstanceId = 123
}));
var saved = await db.Messages.AsNoTracking().SingleAsync();
Assert.True(saved.Id > 0);
Assert.Equal(saved.Id, JsonSerializer.Deserialize<RoomInviteDetails>(saved.Data)!.InviteId);
Assert.Equal(123L, RoomInviteDetails.GetInstanceId(saved));
Assert.Equal(long.MaxValue, saved.ToPlayerId);
}
finally
{
Notify.DbFactory = previous;
SqlConnection.ClearAllPools();
await using var drop = new SqlCommand(
$"ALTER DATABASE [{database}] SET SINGLE_USER WITH ROLLBACK IMMEDIATE; DROP DATABASE [{database}]", admin);
await drop.ExecuteNonQueryAsync();
}
}
}