Skip to content

Add concurrency controls and fix security/config issues#4

Merged
discostu105 merged 3 commits intomasterfrom
claude/analyze-project-quality-SJYhC
Mar 21, 2026
Merged

Add concurrency controls and fix security/config issues#4
discostu105 merged 3 commits intomasterfrom
claude/analyze-project-quality-SJYhC

Conversation

@discostu105
Copy link
Copy Markdown
Owner

Summary

This PR addresses critical concurrency issues in the stateful game server, removes hardcoded secrets, and improves code quality through dependency updates and cleanup.

Key Changes

Security & Configuration

  • Removed hardcoded Rookout token from Program.cs and moved to configuration-based approach using builder.Configuration["Rookout:Token"]
  • Removed hardcoded Discord OAuth credentials and replaced with configuration-based retrieval from builder.Configuration["Discord:ClientId"] and builder.Configuration["Discord:ClientSecret"]
  • Added null-coalescing with InvalidOperationException to fail fast if required secrets are missing

Concurrency Control

Added thread-safe locking to all write operations in repository classes to prevent race conditions in the in-memory stateful server:

  • UnitRepositoryWrite: Wrapped BuildUnit, MergeUnits, SplitUnit, SendUnit, and ReturnUnitsHome with lock (_lock)
  • PlayerRepositoryWrite: Wrapped IncrementTick and CreatePlayer with lock (_lock)
  • AssetRepositoryWrite: Wrapped BuildAsset and ExecuteGameActions with lock (_lock)
  • ResourceRepositoryWrite: Wrapped DeductCost and AddResources with lock (_lock)
  • ActionQueueRepository: Wrapped GetAndRemoveDueActions, Remove, and AddAction with lock (_lock)
  • WorldState: Added lock field for future synchronization

Code Quality

  • Removed unused imports across multiple files (System.Security.Cryptography.X509Certificates, System.Reflection.PortableExecutable, System.Runtime.InteropServices.ComTypes, etc.)
  • Added .editorconfig with team conventions for C#, XML, JSON, and YAML files (tab indentation, nullable reference type warnings, code style preferences)
  • Removed legacy azure-pipelines.yml (targeting .NET 5, superseded by GitHub Actions)
  • Refactored MergeUnits to extract internal logic into MergeUnitsInternal to avoid lock nesting

Dependency Updates

  • Upgraded Blazor and ASP.NET Core packages from 7.0.0-preview.7.* to stable 8.0.0 releases
  • Updated test framework packages to stable versions
  • Stabilized all preview dependencies to production-ready releases

Implementation Details

  • Each repository write class now has a private object _lock = new() field for synchronization
  • Lock scope is minimal—only protecting the critical section of state mutation
  • Configuration-based secrets use builder.Configuration with null-coalescing operators to ensure required values are present at startup

https://claude.ai/code/session_01PeKjLeL9dZx8eR2hVsqCzA

claude added 3 commits March 21, 2026 21:08
Comprehensive review covering architecture, code quality, testing,
dependencies, security, and observability across all 11 projects.

https://claude.ai/code/session_01PeKjLeL9dZx8eR2hVsqCzA
- Remove hardcoded secrets: Rookout token and Discord OAuth credentials
  now read from configuration (user-secrets/env vars) instead of source
- Upgrade all preview/pre-release packages to stable .NET 8 versions
  across BlazorClient, FrontendServer, StatefulGameServer, and Test projects
- Add lock-based concurrency control to all repository write operations
  (UnitRepositoryWrite, ResourceRepositoryWrite, PlayerRepositoryWrite,
  AssetRepositoryWrite, ActionQueueRepository, WorldState)
- Remove unused System.Security.Cryptography.X509Certificates imports
  and other dead using directives from 5 files
- Delete legacy azure-pipelines.yml (superseded by GitHub Actions)
- Add .editorconfig for consistent code style enforcement

https://claude.ai/code/session_01PeKjLeL9dZx8eR2hVsqCzA
The workflow was still targeting .NET 5.0.100 while all projects
target net8.0. Also bumps actions/checkout and actions/setup-dotnet
to v4.

https://claude.ai/code/session_01PeKjLeL9dZx8eR2hVsqCzA
@discostu105 discostu105 merged commit 638653e into master Mar 21, 2026
1 check passed
discostu105 added a commit that referenced this pull request Mar 30, 2026
- Convert GameLobbyViewModels to record types (Architect blocking #1)
- Add GameDefType and EndTime fields to GameSummaryViewModel and GameInfo (Architect required #5)
- Fix AddPlayer() race condition: move PlayerCount update inside lock, return bool for duplicate-join detection (Architect blocking #2 and #3 / QA blocking #2)
- Fix duplicate-join: return Conflict(409) if player already joined (Architect blocking #2)
- Add [AllowAnonymous] to GetAll() — game list is a public endpoint per BGE-131 plan (Architect required #4)
- Update controller to use record constructor syntax and handle AddPlayer bool return

Build: 0 errors | Tests: 117/117 passed

Co-Authored-By: Paperclip <noreply@paperclip.ing>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants