mirror of
https://github.com/CannedNet/CannedNet.git
synced 2026-10-27 16:09:03 -07:00
current src
This commit is contained in:
@@ -0,0 +1,8 @@
|
|||||||
|
bin/
|
||||||
|
obj/
|
||||||
|
/packages/
|
||||||
|
riderModule.iml
|
||||||
|
/_ReSharper.Caches/
|
||||||
|
/.idea
|
||||||
|
/CannedNet.API/Migrations
|
||||||
|
CannedNet.sln.DotSettings.user
|
||||||
@@ -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>
|
||||||
@@ -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");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace CannedNet;
|
||||||
|
|
||||||
|
public enum JuniorState
|
||||||
|
{
|
||||||
|
BasedOnBirthday = 0,
|
||||||
|
ModerationOverride = 1,
|
||||||
|
PendingOverride = 2
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
@@ -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; }
|
||||||
|
}
|
||||||
@@ -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();
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"DefaultConnection": "Host=localhost;Port=5432;Database=cannednet;Username=postgres;Password=postgres"
|
||||||
|
},
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"ConnectionStrings": {
|
||||||
|
"DefaultConnection": "Data Source=game.db;Cache=Shared"
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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}"
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
"hi :3"
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -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
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<Solution>
|
||||||
|
<Folder Name="/Solution Items/" />
|
||||||
|
<Project Path="CannedNet.API/CannedNet.API.csproj" />
|
||||||
|
</Solution>
|
||||||
Reference in New Issue
Block a user