Import march-2020-03-10 from private repo (scrubbed 2026-05-27)

Targets Rec Room 2020.03.10 client (also serves 2020.03.06).

Re-import after adding:
- DorkNet.ClientMod/dorknet-clientmod.json.template — config schema
  the launcher's manifest-driven patcher renders into UserData/.
- tools/build-patcher-zip.ps1 — produces dorknet-clientpatch-{key}.zip
  for v1-march-* Release uploads.
- .github/workflows/release.yml — on tag push publishes both
  dorknet-server-march_2020_03_10-win-x64.zip and
  dorknet-clientpatch-march_2020_03_10.zip as Release assets.

Same scrub rules as december; tools/build-patcher-zip.ps1 added to
the maintainer-side allow-list so it survives.
This commit is contained in:
Alexa
2026-05-27 01:06:12 +03:00
commit d471b418b9
389 changed files with 104767 additions and 0 deletions
+109
View File
@@ -0,0 +1,109 @@
using DorkNet.Models.Config;
namespace DorkNet.Server.Services;
public class ConfigService(IConfiguration config, DomainConfig domain)
{
public RecRoomConfig GetConfig(string baseUrl)
{
var photon = new PhotonConfig
{
AppId = config["Photon:AppId"] ?? string.Empty,
VoiceAppId = config["Photon:VoiceAppId"] ?? string.Empty,
CloudRegion = config["Photon:CloudRegion"] ?? "us",
};
// baseUrl was previously parsed to mirror the request's apex
// back at the client, but with DomainConfig as the single
// source of truth every outbound URL is built off the
// configured deployment apex regardless of which Host header
// the client used to hit us. The baseUrl parameter is kept
// for API stability but is no longer dereferenced.
_ = baseUrl;
var apex = domain.Apex;
return new RecRoomConfig
{
MessageOfTheDay = config["Server:MOTD"] ?? "Welcome to the private server!",
CdnBaseUri = $"https://{domain.Sub("cdn")}",
PhotonConfig = photon,
ServiceUrls = BuildServiceUrlMap(apex),
ConfigTable = new Dictionary<string, string>
{
// Season keys the 2019/2020 client checks at startup
["Season"] = "Spring",
["CurrentSeason"] = "Spring",
["SeasonId"] = "1",
["SeasonName"] = "Spring",
["ActiveEvent"] = "None",
["EventName"] = "",
// Feature flags — keep everything on
["FriendsEnabled"] = "true",
["ChatEnabled"] = "true",
["VoiceEnabled"] = "true",
},
};
}
/// <summary>
/// Subdomain → service-name map. The wire response wraps each
/// value with <c>https://</c> + the configured apex domain
/// (<see cref="DomainConfig"/>, driven by DORKNET_DOMAIN) so
/// every URL the client sees comes from one source of truth.
/// </summary>
private static readonly (string Service, string Subdomain)[] ServiceSubdomains = new[]
{
("WWW", ""), // apex
("API", "api"),
("Accounts", "accounts"),
("Auth", "auth"),
("BugReporting", "bugreporting"),
("Cards", "cards"),
("CDN", "cdn"),
("Chat", "chat"),
("Clubs", "clubs"),
("CMS", "cms"),
("Commerce", "commerce"),
("Data", "data"),
("DataCollection", "datacollection"),
("Discovery", "discovery"),
("Econ", "econ"),
("GameLogs", "gamelogs"),
("Geo", "geo"),
("Images", "img"),
("Leaderboard", "leaderboard"),
("Link", "link"),
("Lists", "lists"),
("Matchmaking", "match"),
("Moderation", "moderation"),
("NameServer", "ns"),
("Notifications", "notify"),
("PlatformNotifications", "platformnotifications"),
("PlayerSettings", "playersettings"),
("RoomComments", "roomcomments"),
("RoomieIntegrations", "roomieintegrations"),
("Rooms", "rooms"),
("Storage", "storage"),
("Strings", "strings"),
("StringsCDN", "strings-cdn"),
("Studio", "studio"),
("Thorn", "thorn"),
("Videos", "videos"),
};
/// <summary>Build the service URL map for a specific apex
/// domain. Used by NsController + the client config endpoints;
/// the apex is fed in by the caller (typically
/// <see cref="DomainConfig.Apex"/>) so the map stays a single
/// source of truth.</summary>
public static Dictionary<string, string> BuildServiceUrlMap(string apex)
{
var map = new Dictionary<string, string>(ServiceSubdomains.Length);
foreach (var (service, sub) in ServiceSubdomains)
{
var host = string.IsNullOrEmpty(sub) ? apex : $"{sub}.{apex}";
map[service] = $"https://{host}";
}
return map;
}
}