feat: Enhance UgcPurchasablesController to handle bulk requests with object arrays

- Updated Bulk method to parse incoming JSON object arrays for UGC item IDs.
- Introduced ReadBulkIdsAsync to handle both object arrays and flat GUID lists.
- Added synthetic placeholder responses for missing UGC items to prevent client errors.

feat: Implement MatchmakeRoom and MatchmakeSubRoom endpoints in GoToController

- Added MatchmakeRoom and MatchmakeSubRoom methods to facilitate joining public and sub-rooms by numeric ID.
- Enhanced ApplySubRoomMutation to ensure proper state transitions for sub-rooms.
- Improved logging for matchmaking actions.

fix: Refactor PlayerSettingsController to handle database save exceptions

- Introduced SaveSettingsChangesAsync to manage DbUpdateException for busy SQLite scenarios.
- Updated methods to call SaveSettingsChangesAsync instead of direct SaveChangesAsync.

chore: Update URL coverage documentation for new matchmaking endpoints

- Documented new MatchmakeRoom and MatchmakeSubRoom endpoints in url-coverage.md.

chore: Add default room data file for room loading

- Included default_room.room to serve as a fallback for missing room data.

fix: Improve SQLite concurrency handling in DatabaseBootstrap

- Configured SQLite to use WAL mode and set a busy timeout for better concurrency.

chore: Create SqliteErrors utility for handling SQLite exceptions

- Added SqliteErrors class to encapsulate logic for detecting busy SQLite exceptions.

refactor: Update RoomDataBlobService to serve default room data

- Modified GetDefaultBlob to load and serve a default room blob with proper role data.
This commit is contained in:
Alexa
2026-06-23 20:54:29 +03:00
parent ed6c13ec07
commit fda64ca3ce
18 changed files with 1327 additions and 170 deletions
@@ -1,4 +1,5 @@
using Microsoft.EntityFrameworkCore;
using System.Data;
using DorkNet.Server.Data;
using DorkNet.Server.Services;
using Serilog;
@@ -36,6 +37,7 @@ public static class DatabaseBootstrap
if (db.Database.IsSqlite())
{
await ConfigureSqliteForLocalConcurrencyAsync(db);
BaselineExistingSchemaIfNeeded(db);
db.Database.Migrate();
}
@@ -171,6 +173,27 @@ public static class DatabaseBootstrap
Controllers.Health.HealthController.MigrationsComplete = true;
}
private static async Task ConfigureSqliteForLocalConcurrencyAsync(DorkNetDbContext db)
{
var conn = db.Database.GetDbConnection();
var closeAfter = conn.State != ConnectionState.Open;
if (closeAfter) await conn.OpenAsync();
try
{
await using var cmd = conn.CreateCommand();
cmd.CommandText = "PRAGMA journal_mode=WAL;";
await cmd.ExecuteScalarAsync();
cmd.CommandText = "PRAGMA busy_timeout=30000;";
await cmd.ExecuteNonQueryAsync();
}
finally
{
if (closeAfter) await conn.CloseAsync();
}
}
/// <summary>Idempotently create the SignupCodes + PendingDevices
/// tables on whichever provider is in use. Safe to run every boot:
/// CREATE TABLE / INDEX IF NOT EXISTS no-op once they exist (whether