current src

This commit is contained in:
Lapis
2026-03-31 17:06:41 -04:00
parent fede8440f7
commit e74618ddce
20 changed files with 1245 additions and 0 deletions
+17
View File
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>CannedNet</RootNamespace>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.2.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.0" />
</ItemGroup>
</Project>
+38
View File
@@ -0,0 +1,38 @@
using Microsoft.EntityFrameworkCore;
namespace CannedNet.Data;
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
public DbSet<Account> Accounts { get; set; }
public DbSet<CachedLogin> CachedLogins { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// accounts
modelBuilder.Entity<Account>(entity =>
{
entity.HasKey(e => e.AccountId);
entity.Property(e => e.AccountId).ValueGeneratedNever();
entity.Property(e => e.Username).IsRequired();
entity.Property(e => e.DisplayName).IsRequired();
entity.ToTable("accounts");
});
// cachedlogins
modelBuilder.Entity<CachedLogin>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ValueGeneratedOnAdd();
entity.HasIndex(e => new { e.Platform, e.PlatformID }).IsUnique();
entity.ToTable("cached_logins");
});
}
}
+8
View File
@@ -0,0 +1,8 @@
namespace CannedNet;
public enum JuniorState
{
BasedOnBirthday = 0,
ModerationOverride = 1,
PendingOverride = 2
}
+15
View File
@@ -0,0 +1,15 @@
namespace CannedNet;
public enum PlatformType
{
All = -1,
Steam = 0,
Oculus = 1,
PlayStation = 2,
Xbox = 3,
RecNet = 4,
IOS = 5,
GooglePlay = 6,
Standalone = 7,
Pico = 8
}
+110
View File
@@ -0,0 +1,110 @@
using System.Security.Cryptography;
using System.Security.Claims;
using Microsoft.IdentityModel.Tokens;
using System.IdentityModel.Tokens.Jwt;
namespace CannedNet;
public class JwtTokenService
{
private static readonly RSA _rsa = RSA.Create(2048);
private readonly RsaSecurityKey _securityKey;
private readonly SigningCredentials _signingCredentials;
private const string KeyId = "7C2F041398671515B0862CB23FAF95B03";
public JwtTokenService()
{
_securityKey = new RsaSecurityKey(_rsa) { KeyId = KeyId };
_signingCredentials = new SigningCredentials(_securityKey, SecurityAlgorithms.RsaSha256);
}
public string GenerateToken(string accountId, string platformId, string platform = "Steam")
{
var now = DateTime.UtcNow;
var exp = now.AddHours(1);
// theres gotta be some other better way to do this, but im fucking stupid so :shrug:
// if it works it works ig idk, someone can clean this up later or i will later
var claims = new List<Claim>
{
new Claim("iss", "https://rr.lapis.codes"),
new Claim("nbf", ((DateTimeOffset)now).ToUnixTimeSeconds().ToString()),
new Claim("iat", ((DateTimeOffset)now).ToUnixTimeSeconds().ToString()),
new Claim("exp", ((DateTimeOffset)exp).ToUnixTimeSeconds().ToString()),
new Claim("aud", "https://rr.lapis.codes/resources"),
new Claim("amr", "cached_login"),
new Claim("client_id", "recroom"),
new Claim("sub", accountId),
new Claim("auth_time", ((DateTimeOffset)now).ToUnixTimeSeconds().ToString()),
new Claim("idp", "local"),
new Claim("platform", platform),
new Claim("platform_id", platformId),
new Claim("rn.ver", "20210129"),
new Claim("rn.plat", "0"),
new Claim("role", "gameClient"),
new Claim("jti", Guid.NewGuid().ToString("N").Substring(0, 32).ToUpper())
};
claims.Add(new Claim("scope", "profile"));
claims.Add(new Claim("scope", "rn"));
claims.Add(new Claim("scope", "rn.accounts"));
claims.Add(new Claim("scope", "rn.accounts.gc"));
claims.Add(new Claim("scope", "rn.api"));
claims.Add(new Claim("scope", "rn.chat"));
claims.Add(new Claim("scope", "rn.clubs"));
claims.Add(new Claim("scope", "rn.commerce"));
claims.Add(new Claim("scope", "rn.match.read"));
claims.Add(new Claim("scope", "rn.match.write"));
claims.Add(new Claim("scope", "rn.notify"));
claims.Add(new Claim("scope", "rn.rooms"));
claims.Add(new Claim("scope", "rn.storage"));
claims.Add(new Claim("scope", "offline_access"));
var identity = new ClaimsIdentity(claims, "jwt");
var handler = new JwtSecurityTokenHandler();
var token = handler.CreateJwtSecurityToken(
issuer: "https://auth.epicquest.live",
audience: "https://auth.epicquest.live/resources",
subject: identity,
notBefore: now,
issuedAt: now,
expires: exp,
signingCredentials: _signingCredentials);
return handler.WriteToken(token);
}
public string? ValidateAndGetAccountId(string token)
{
try
{
var handler = new JwtSecurityTokenHandler();
handler.InboundClaimTypeMap.Clear();
var parameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = _securityKey,
ValidateIssuer = true,
ValidIssuer = "https://auth.epicquest.live",
ValidateAudience = true,
ValidAudience = "https://auth.epicquest.live/resources",
ValidateLifetime = true,
ClockSkew = TimeSpan.Zero
};
var principal = handler.ValidateToken(token, parameters, out SecurityToken validatedToken);
var accountIdClaim = principal.Claims.FirstOrDefault(c => c.Type == "sub");
return accountIdClaim?.Value;
}
catch (Exception ex)
{
return null;
}
}
}
+16
View File
@@ -0,0 +1,16 @@
using System.Text.Json.Serialization;
namespace CannedNet;
public class Account
{
[JsonPropertyName("accountId")] public int? AccountId { get; set; }
[JsonPropertyName("profileImage")] public string? ProfileImage { get; set; }
[JsonPropertyName("isJunior")] public bool IsJunior { get; set; }
[JsonPropertyName("platforms")] public int? Platforms { get; set; }
[JsonPropertyName("personalPronouns")] public int? PersonalPronouns { get; set; }
[JsonPropertyName("identityFlags")] public int? IdentityFlags { get; set; }
[JsonPropertyName("username")] public string? Username { get; set; }
[JsonPropertyName("displayName")] public string? DisplayName { get; set; }
[JsonPropertyName("createdAt")] public DateTime CreatedAt { get; set; }
}
+24
View File
@@ -0,0 +1,24 @@
using System.Text.Json.Serialization;
namespace CannedNet;
public class CachedLogin
{
[JsonIgnore]
public int Id { get; set; }
[JsonPropertyName("accountId")]
public int AccountId { get; set; }
[JsonPropertyName("platform")]
public PlatformType Platform { get; set; }
[JsonPropertyName("platformId")]
public string PlatformID { get; set; }
[JsonPropertyName("lastLoginTime")]
public DateTime LastLoginTime { get; set; }
[JsonPropertyName("requirePassword")]
public bool RequirePassword { get; set; } = false;
}
+20
View File
@@ -0,0 +1,20 @@
using System.Text.Json.Serialization;
namespace CannedNet;
public class RecNetResultWithValue<T> : RecNetResult
{
[JsonPropertyName("value")] public required T? Value { get; set; }
}
public class RecNetResult
{
public static RecNetResult Ok() => new RecNetResult { Success = true };
public static RecNetResult Err(string error) => new RecNetResult { Success = false, Error = error };
public static RecNetResultWithValue<T> Ok<T>(T value) => new RecNetResultWithValue<T> { Success = true, Value = value };
public static RecNetResultWithValue<T> Err<T>(string error) => new RecNetResultWithValue<T> { Success = false, Error = error, Value = default };
[JsonPropertyName("success")] public bool Success { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("error")] public string? Error { get; set; }
}
+15
View File
@@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace CannedNet;
public class SelfAccount : Account
{
[JsonPropertyName("email")] public string? Email { get; set; }
[JsonPropertyName("phone")] public string? Phone { get; set; }
[JsonPropertyName("juniorState")] public JuniorState? JuniorState { get; set; }
[JsonPropertyName("birthday")] public DateTime? Birthday { get; set; }
[JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull)]
[JsonPropertyName("parentAccountId")] public string? ParentAccountId { get; set; }
[JsonPropertyName("availableUsernameChanges")] public int? AvailableUsernameChanges { get; set; }
}
+337
View File
@@ -0,0 +1,337 @@
using CannedNet;
using CannedNet.Data;
using Microsoft.EntityFrameworkCore;
var builder = WebApplication.CreateBuilder(args);
// TODO: organize this into multiple files
// TODO: cdn stuff soon so i can not just have 0 images for this lmao
// TODO: setup signalr and get websockets running, currently should focus on notifications as logging in is being blocked by that
// needed so it won't try to auto capitalize random stuff that may be case-sensitive
builder.Services.ConfigureHttpJsonOptions(options =>
{
options.SerializerOptions.PropertyNamingPolicy = null;
});
// postgresql db, will probably have it configurable later on but for now just hardcode it in
var connectionString = builder.Configuration.GetConnectionString("DefaultConnection")
?? "Host=localhost;Port=5432;Database=cannednet;Username=postgres;Password=postgres";
builder.Services.AddDbContext<AppDbContext>(options =>
options.UseNpgsql(connectionString));
builder.Services.AddScoped<JwtTokenService>();
var app = builder.Build();
// apply db migrations on startup so we don't have to worry about it later bc i hate doing db things manually lol
using (var scope = app.Services.CreateScope())
{
var db = scope.ServiceProvider.GetRequiredService<AppDbContext>();
db.Database.Migrate();
}
var jwtService = app.Services.GetRequiredService<JwtTokenService>();
// request logging
app.Use(async (context, next) =>
{
var request = context.Request;
Console.WriteLine($"\n{request.Method} {request.Path}{request.QueryString}");
foreach (var header in request.Headers)
Console.WriteLine($" {header.Key}: {string.Join(", ", header.Value)}");
if (request.ContentLength > 0)
{
request.EnableBuffering();
using (var reader = new StreamReader(request.Body, leaveOpen: true))
{
var body = await reader.ReadToEndAsync();
Console.WriteLine($" Body: {body}");
}
request.Body.Position = 0;
}
await next(context);
});
app.MapGet("/", () =>
{
var json = File.ReadAllText("endpoints.json");
return Results.Content(json, "application/json");
});
app.MapGet("/api/config/v1/amplitude", () =>
{
var config = new
{
AmplitudeKey = "fd846cd67066d19eec62fbdd00be9258",
StatSigKey = "client-mnew4Ggjuu3Fbh86Ed3tRgWUxapp0D7PPB0i3MXUEao",
RudderStackKey = "37qVlzZyXqdmZckXJ61vQeEJp8Y",
UseRudderStack = true
};
return Results.Ok(config);
});
app.MapGet("/api/config/v2", () =>
{
var json = File.ReadAllText("configv2.json");
return Results.Content(json, "application/json");
});
app.MapGet("/api/versioncheck/v4", () =>
{
return Results.Content("{\"VersionStatus\":0}","application/json");
});
app.MapGet("/api/gameconfigs/v1/all", () =>
{
var json = File.ReadAllText("gameconfigs.json");
return Results.Content(json, "application/json");
});
app.MapGet("/photon", () =>
{
var json = File.ReadAllText("photonsettings.json");
return Results.Content(json, "application/json");
});
app.MapGet("/eac/challenge", () =>
{
var file = File.ReadAllText("eacchallenge.txt");
return Results.Content(file,"text/plain");
});
app.MapGet("/api/playerReputation/v1/{id}", (string id) =>
{
// TODO: make rep actually work
return Results.Content($"{{\"AccountId\":{id},\"Noteriety\":0,\"CheerGeneral\":0,\"CheerHelpful\":0,\"CheerCreative\":0,\"CheerGreatHost\":0,\"CheerSportsman\":0,\"CheerCredit\":20,\"SelectedCheer\":null}}","application/json");
});
app.MapGet("/api/players/v1/progression/{id}", (string id) =>
{
// TODO: make progression actually work
return Results.Content($"{{\"PlayerId\":{id},\"Level\":1,\"XP\":0}}","application/json");
});
app.MapGet("/api/PlayerReporting/v1/moderationBlockDetails", () =>
{
// TODO: make this actually work
return Results.Content($"{{\"ReportCategory\":0,\"Duration\":0,\"GameSessionId\":0,\"IsHostKick\":false,\"Message\":\"\",\"PlayerIdReporter\":null,\"IsBan\":false}}","application/json");
});
app.MapPost("/player/login", () =>
{
return Results.Ok();
});
app.MapGet("/cachedlogin/forplatformid/{platform}/{id}", async (string platform, string id, AppDbContext db) =>
{
var platformType = int.Parse(platform);
var logins = await db.CachedLogins
.Where(c => c.Platform == (PlatformType)platformType && c.PlatformID == id)
.ToListAsync();
return Results.Json(logins.Any() ? logins : new List<object>());
});
app.MapGet("/account/me", (HttpRequest request, AppDbContext db) =>
{
var authHeader = request.Headers.Authorization.ToString();
if (string.IsNullOrEmpty(authHeader) || !authHeader.StartsWith("Bearer ", StringComparison.OrdinalIgnoreCase))
return Results.Unauthorized();
var token = authHeader.Substring("Bearer ".Length);
var accountId = jwtService.ValidateAndGetAccountId(token);
if (string.IsNullOrEmpty(accountId) || !int.TryParse(accountId, out var id))
return Results.Unauthorized();
var selfAccount = new SelfAccount
{
AccountId = id,
ProfileImage = "hdqeamlcmatc6qzoi2ybgf0ddijjcf.jpg",
IsJunior = false,
Platforms = 0,
PersonalPronouns = 0,
IdentityFlags = 0,
Username = $"Player{id}",
DisplayName = $"Player{id}",
CreatedAt = DateTime.UtcNow,
Email = null,
Phone = null,
JuniorState = null,
Birthday = null,
ParentAccountId = null,
AvailableUsernameChanges = 1
};
return Results.Ok(selfAccount);
});
app.MapGet("/account/bulk", (HttpRequest request) =>
{
var ids = request.Query["id"];
var accounts = new List<Account>();
foreach (var id in ids)
{
if (int.TryParse(id, out var accountId))
{
var account = new Account
{
AccountId = accountId,
ProfileImage = "hdqeamlcmatc6qzoi2ybgf0ddijjcf.jpg",
IsJunior = false,
Platforms = 0,
PersonalPronouns = 0,
IdentityFlags = 0,
Username = $"Player{accountId}",
DisplayName = $"Player{accountId}",
CreatedAt = DateTime.UtcNow
};
accounts.Add(account);
}
}
return Results.Json(accounts);
});
app.MapPost("/account/create", async (HttpRequest httpRequest, AppDbContext db) =>
{
int platform = 0;
string platformId = "";
if (httpRequest.ContentLength.HasValue && httpRequest.ContentLength > 0)
{
try
{
var contentType = httpRequest.ContentType ?? "";
httpRequest.EnableBuffering();
using (var reader = new StreamReader(httpRequest.Body, leaveOpen: true))
{
var body = await reader.ReadToEndAsync();
if (!string.IsNullOrWhiteSpace(body))
{
if (contentType.Contains("application/x-www-form-urlencoded"))
{
var pairs = body.Split('&');
foreach (var pair in pairs)
{
var keyValue = pair.Split('=');
if (keyValue.Length == 2)
{
var key = Uri.UnescapeDataString(keyValue[0]);
var value = Uri.UnescapeDataString(keyValue[1]);
if (key == "platform" && int.TryParse(value, out var parsedPlatform))
platform = parsedPlatform;
else if (key == "platformId")
platformId = value;
}
}
}
}
}
httpRequest.Body.Position = 0;
}
catch { }
}
var accountId = new Random().Next(10000, 99999);
var account = new Account
{
AccountId = accountId,
ProfileImage = "hdqeamlcmatc6qzoi2ybgf0ddijjcf.jpg",
IsJunior = false,
Platforms = 0,
PersonalPronouns = 0,
IdentityFlags = 0,
Username = $"Player{accountId}",
DisplayName = $"Player{accountId}",
CreatedAt = DateTime.UtcNow
};
db.Accounts.Add(account);
if (!string.IsNullOrEmpty(platformId))
{
var loginRecord = new CachedLogin
{
AccountId = accountId,
Platform = (PlatformType)platform,
PlatformID = platformId,
LastLoginTime = DateTime.UtcNow,
RequirePassword = false
};
db.CachedLogins.Add(loginRecord);
}
await db.SaveChangesAsync();
return Results.Ok(RecNetResultWithValue<Account>.Ok(account));
});
app.MapPost("/connect/token", async (HttpRequest httpRequest) =>
{
string accountId = "";
string platformId = "";
string platform = "";
if (httpRequest.ContentLength.HasValue && httpRequest.ContentLength > 0)
{
try
{
httpRequest.EnableBuffering();
using (var reader = new StreamReader(httpRequest.Body, leaveOpen: true))
{
var body = await reader.ReadToEndAsync();
if (!string.IsNullOrWhiteSpace(body))
{
var pairs = body.Split('&');
foreach (var pair in pairs)
{
var keyValue = pair.Split('=');
if (keyValue.Length == 2)
{
var key = Uri.UnescapeDataString(keyValue[0]);
var value = Uri.UnescapeDataString(keyValue[1]);
if (key == "account_id")
accountId = value;
else if (key == "platform_id")
platformId = value;
}
}
}
}
httpRequest.Body.Position = 0;
}
catch { }
}
var accessToken = jwtService.GenerateToken(accountId, platformId, platform);
var response = new
{
access_token = accessToken,
expires_in = 3600,
token_type = "Bearer",
refresh_token = Guid.NewGuid().ToString("N").ToUpper() + "-1",
scope = "offline_access profile rn rn.accounts rn.accounts.gc rn.api rn.chat rn.clubs rn.commerce rn.match.read rn.match.write rn.notify rn.rooms rn.storage",
key = "8oQ+e+WQaOBPbEcakhqs3dwZZdOmmyDUmJSD9u4AHMY="
};
return Results.Json(response);
});
app.Run();
+11
View File
@@ -0,0 +1,11 @@
{
"ConnectionStrings": {
"DefaultConnection": "Host=localhost;Port=5432;Database=cannednet;Username=postgres;Password=postgres"
},
"Logging": {
"LogLevel": {
"Default": "Information"
}
}
}
+13
View File
@@ -0,0 +1,13 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"ConnectionStrings": {
"DefaultConnection": "Data Source=game.db;Cache=Shared"
},
"AllowedHosts": "*"
}
+373
View File
@@ -0,0 +1,373 @@
{
"LevelProgressionMaps": [
{
"Level": 0,
"RequiredXp": 0,
"GiftRarity": -1
},
{
"Level": 1,
"RequiredXp": 10,
"GiftRarity": 10
},
{
"Level": 2,
"RequiredXp": 10,
"GiftRarity": 10
},
{
"Level": 3,
"RequiredXp": 10,
"GiftRarity": 10
},
{
"Level": 4,
"RequiredXp": 20,
"GiftRarity": 10
},
{
"Level": 5,
"RequiredXp": 20,
"GiftRarity": 10
},
{
"Level": 6,
"RequiredXp": 20,
"GiftRarity": 10
},
{
"Level": 7,
"RequiredXp": 20,
"GiftRarity": 10
},
{
"Level": 8,
"RequiredXp": 20,
"GiftRarity": 10
},
{
"Level": 9,
"RequiredXp": 20,
"GiftRarity": 10
},
{
"Level": 10,
"RequiredXp": 20,
"GiftRarity": 10
},
{
"Level": 11,
"RequiredXp": 45,
"GiftRarity": 10
},
{
"Level": 12,
"RequiredXp": 45,
"GiftRarity": 10
},
{
"Level": 13,
"RequiredXp": 45,
"GiftRarity": 10
},
{
"Level": 14,
"RequiredXp": 45,
"GiftRarity": 10
},
{
"Level": 15,
"RequiredXp": 45,
"GiftRarity": 20
},
{
"Level": 16,
"RequiredXp": 45,
"GiftRarity": 20
},
{
"Level": 17,
"RequiredXp": 45,
"GiftRarity": 20
},
{
"Level": 18,
"RequiredXp": 45,
"GiftRarity": 20
},
{
"Level": 19,
"RequiredXp": 45,
"GiftRarity": 20
},
{
"Level": 20,
"RequiredXp": 45,
"GiftRarity": 20
},
{
"Level": 21,
"RequiredXp": 115,
"GiftRarity": 20
},
{
"Level": 22,
"RequiredXp": 115,
"GiftRarity": 20
},
{
"Level": 23,
"RequiredXp": 115,
"GiftRarity": 20
},
{
"Level": 24,
"RequiredXp": 115,
"GiftRarity": 20
},
{
"Level": 25,
"RequiredXp": 115,
"GiftRarity": 20
},
{
"Level": 26,
"RequiredXp": 115,
"GiftRarity": 20
},
{
"Level": 27,
"RequiredXp": 115,
"GiftRarity": 20
},
{
"Level": 28,
"RequiredXp": 115,
"GiftRarity": 20
},
{
"Level": 29,
"RequiredXp": 115,
"GiftRarity": 20
},
{
"Level": 30,
"RequiredXp": 115,
"GiftRarity": 20
},
{
"Level": 31,
"RequiredXp": 360,
"GiftRarity": 20
},
{
"Level": 32,
"RequiredXp": 360,
"GiftRarity": 20
},
{
"Level": 33,
"RequiredXp": 360,
"GiftRarity": 20
},
{
"Level": 34,
"RequiredXp": 360,
"GiftRarity": 20
},
{
"Level": 35,
"RequiredXp": 360,
"GiftRarity": 20
},
{
"Level": 36,
"RequiredXp": 360,
"GiftRarity": 20
},
{
"Level": 37,
"RequiredXp": 360,
"GiftRarity": 20
},
{
"Level": 38,
"RequiredXp": 360,
"GiftRarity": 20
},
{
"Level": 39,
"RequiredXp": 360,
"GiftRarity": 20
},
{
"Level": 40,
"RequiredXp": 360,
"GiftRarity": 30
},
{
"Level": 41,
"RequiredXp": 1080,
"GiftRarity": 30
},
{
"Level": 42,
"RequiredXp": 1080,
"GiftRarity": 30
},
{
"Level": 43,
"RequiredXp": 1080,
"GiftRarity": 30
},
{
"Level": 44,
"RequiredXp": 1080,
"GiftRarity": 30
},
{
"Level": 45,
"RequiredXp": 1080,
"GiftRarity": 30
},
{
"Level": 46,
"RequiredXp": 1080,
"GiftRarity": 30
},
{
"Level": 47,
"RequiredXp": 1080,
"GiftRarity": 30
},
{
"Level": 48,
"RequiredXp": 1080,
"GiftRarity": 30
},
{
"Level": 49,
"RequiredXp": 1080,
"GiftRarity": 30
},
{
"Level": 50,
"RequiredXp": 1080,
"GiftRarity": 50
}
],
"DailyObjectives": [
[
{
"type": 1030,
"score": 1
},
{
"type": 1033,
"score": 10
},
{
"type": 2000,
"score": 1
}
],
[
{
"type": 601,
"score": 2
},
{
"type": 31,
"score": 1
},
{
"type": 6,
"score": 1
}
],
[
{
"type": 301,
"score": 2
},
{
"type": 300,
"score": 2
},
{
"type": 6,
"score": 1
}
],
[
{
"type": 700,
"score": 2
},
{
"type": 701,
"score": 20
},
{
"type": 31,
"score": 1
}
],
[
{
"type": 1010,
"score": 1
},
{
"type": 1013,
"score": 10
},
{
"type": 6,
"score": 1
}
],
[
{
"type": 500,
"score": 2
},
{
"type": 502,
"score": 20
},
{
"type": 2000,
"score": 1
}
],
[
{
"type": 1020,
"score": 1
},
{
"type": 1023,
"score": 10
},
{
"type": 31,
"score": 1
}
]
],
"ServerMaintenance": {
"StartsInMinutes": 0
},
"AutoMicMutingConfig": {
"MicSpamVolumeThreshold": 0.75,
"MicVolumeSampleInterval": 0.25,
"MicVolumeSampleRollingWindowLength": 10,
"MicSpamSamplePercentageForWarning": 0.8,
"MicSpamSamplePercentageForWarningToEnd": 0.2,
"MicSpamSamplePercentageForForceMute": 0.8,
"MicSpamSamplePercentageForForceMuteToEnd": 0.2,
"MicSpamWarningStateVolumeMultiplier": 0.25
},
"ShareBaseUrl": "http://localhost:5000/{0}"
}
+1
View File
@@ -0,0 +1 @@
"hi :3"
+26
View File
@@ -0,0 +1,26 @@
{
"Auth": "https://rr.lapis.codes",
"API": "https://rr.lapis.codes",
"WWW": "https://www.lapis.codes",
"Notifications": "https://rr.lapis.codes",
"Images": "https://rr.lapis.codes",
"CDN": "https://rr.lapis.codes",
"Commerce": "https://rr.lapis.codes",
"Matchmaking": "https://rr.lapis.codes",
"Storage": "https://rr.lapis.codes",
"Chat": "https://rr.lapis.codes",
"Leaderboard": "https://rr.lapis.codes",
"Accounts": "https://rr.lapis.codes",
"Link": "https://rr.lapis.codes",
"RoomComments": "https://rr.lapis.codes",
"Clubs": "https://rr.lapis.codes",
"Rooms": "https://rr.lapis.codes",
"PlatformNotifications": "https://rr.lapis.codes",
"Moderation": "https://rr.lapis.codes",
"DataCollection": "https://rr.lapis.codes",
"BugReporting": "https://rr.lapis.codes",
"Discovery": "https://rr.lapis.codes",
"PlayerSettings": "https://rr.lapis.codes",
"Rendering": "https://rr.lapis.codes",
"Launcher": "https://rr.lapis.codes"
}
+26
View File
@@ -0,0 +1,26 @@
{
"Auth": "https://auth.epicquest.live",
"API": "https://api.epicquest.live",
"WWW": "https://www.epicquest.live",
"Notifications": "https://notify.epicquest.live",
"Images": "https://img.epicquest.live",
"CDN": "https://cdn.epicquest.live",
"Commerce": "https://commerce.epicquest.live",
"Matchmaking": "https://match.epicquest.live",
"Storage": "https://storage.epicquest.live",
"Chat": "https://chat.epicquest.live",
"Leaderboard": "https://leaderboard.epicquest.live",
"Accounts": "https://accounts.epicquest.live",
"Link": "https://link.epicquest.live",
"RoomComments": "https://roomcomments.epicquest.live",
"Clubs": "https://clubs.epicquest.live",
"Rooms": "https://rooms.epicquest.live",
"PlatformNotifications": "https://api.epicquest.live",
"Moderation": "https://api.epicquest.live",
"DataCollection": "https://api.epicquest.live",
"BugReporting": "https://api.epicquest.live",
"Discovery": "https://api.epicquest.live",
"PlayerSettings": "https://api.epicquest.live",
"Rendering": "https://api.epicquest.live",
"Launcher": "https://launcher.epicquest.live"
}
+170
View File
@@ -0,0 +1,170 @@
[
{
"Key": "Debug.Watchdog.AdditionalTraceFlagsForLoading",
"Value": "None"
},
{
"Key": "Debug.Watchdog.CorruptRoomDetectionProbability",
"Value": "0"
},
{
"Key": "Door.Creative.Query",
"Value": "#horror"
},
{
"Key": "Door.Creative.Title",
"Value": "HORROR"
},
{
"Key": "Door.Featured.Query",
"Value": ""
},
{
"Key": "Door.Featured.Title",
"Value": "Door"
},
{
"Key": "Door.Quests.Query",
"Value": "#quest #recroomoriginal"
},
{
"Key": "Door.Quests.Title",
"Value": "QUESTS"
},
{
"Key": "Door.Shooters.Query",
"Value": "#shooters"
},
{
"Key": "Door.Shooters.Title",
"Value": "SHOOTERS"
},
{
"Key": "Door.Sports.Query",
"Value": "#recroomoriginal #sports | #pvp #recroomoriginal "
},
{
"Key": "Door.Sports.Title",
"Value": "SPORTS & PVP"
},
{
"Key": "Door.StuntRunner.Query",
"Value": "#stuntrunner #community"
},
{
"Key": "Door.StuntRunner.Title",
"Value": "COMMUNITY"
},
{
"Key": "EnableRoomResetLogs",
"Value": "1"
},
{
"Key": "FentReactor.Enabled",
"Value": "True"
},
{
"Key": "Friends.PostGamePromptUnderFriendCount",
"Value": "10"
},
{
"Key": "Friends.SuggestFriendCodeOnFriendsScreenCount",
"Value": "25"
},
{
"Key": "Growth.ShouldPromptForCreatorEmail",
"Value": "true"
},
{
"Key": "loadingNetworkTimeout",
"Value": "180"
},
{
"Key": "Marquee",
"Value": "CannedNet"
},
{
"Key": "RAC:CurrentChallenge",
"Value": "{\"Challenge\":\"AQJCIIXfWaPue2PO75i5nM9nVCPTCbhjnQDUU94I+v//SrxkmVSoLfdEoY5Dp/BwBB+wgIh3kbNL5SPZk2KRQeDDVn+LC/EQoajdcxE59qSDYLM8G1bXued1vRv/Wlk0p5M+Ov2LrnNxS6r8uL2o7V3prYZzEOTrdculBU8rbq4=\",\"LastUpdated\":\"2026-01-15T01:18:34.167596Z\"}"
},
{
"Key": "Rendering.DisableSrpBatcher",
"Value": "true"
},
{
"Key": "Rewards.SelectionTimeout",
"Value": "1800"
},
{
"Key": "Rewards.UseRewardSelection",
"Value": "false"
},
{
"Key": "RoomDetails.PhotoRollEnabled",
"Value": "true"
},
{
"Key": "RoomScaleMotionCheatDetector.MaxAllowedAverageHmdSpeed",
"Value": "1024"
},
{
"Key": "RoomScaleMotionCheatDetector.MeasurementPeriodInSeconds",
"Value": "5"
},
{
"Key": "RoomScaleMotionCheatDetector.MinHmdSpeedAboveTriggerCount",
"Value": "1024"
},
{
"Key": "RoomScaleMotionCheatDetector.ShouldBootToDormWhenDetected.Oculus",
"Value": "false"
},
{
"Key": "RoomScaleMotionCheatDetector.ShouldBootToDormWhenDetected.Steam",
"Value": "false"
},
{
"Key": "RoomScaleMotionCheatDetector.TriggerHmdSpeed",
"Value": "1024"
},
{
"Key": "runningNetworkTimeout",
"Value": "30"
},
{
"Key": "Screens.ForceVerification",
"Value": "1"
},
{
"Key": "splitTestHardOverrides",
"Value": "GottaGoFastNUX_2020_09_04=Off;PlayMenuRRUI_2021_01_11=Off;RoomRecommendations_2020_05_06=On;"
},
{
"Key": "splitTestSegmentProbabilities",
"Value": ""
},
{
"Key": "splitTestSoftOverrides",
"Value": "FentReactorDebugGuiEnabled_2025_11_20=DeveloperOnly;"
},
{
"Key": "SynchronizedField.RemoveDefaultEntries",
"Value": "true"
},
{
"Key": "UGC.ScreenSharing.HorizontalResolution",
"Value": "360"
},
{
"Key": "UGC.ScreenSharing.ImageCompressionQuality",
"Value": "50"
},
{
"Key": "UGC.ScreenSharing.RefreshHz",
"Value": "15"
},
{
"Key": "VR.ForceVerification",
"Value": "1"
}
]
+13
View File
@@ -0,0 +1,13 @@
{
"RealtimeAppId": "038c1828-7979-4735-8d30-50c3276c30a7",
"VoiceAppId": "f6a30374-c1ce-4ea5-8919-45bc29203bc9",
"ChatAppId": "f6a30374-c1ce-4ea5-8919-45bc29203bc9",
"HostingOption": 1,
"Protocol": 0,
"ServerAddress": "127.0.0.1",
"ServerPort": -1,
"VoiceServerPort": -1,
"ChatServerPort": -1,
"NetworkLogging": 0,
"PunLogging": 0
}