make rooms be loaded from db

This commit is contained in:
Lapis
2026-04-03 17:43:07 -04:00
parent c7882b9bde
commit 1c3526e8c0
19 changed files with 2596 additions and 105 deletions
@@ -0,0 +1,6 @@
{
"Hosting": {
"Url": "http://*:5010"
}
}
+66
View File
@@ -16,6 +16,12 @@ public class AppDbContext : DbContext
public DbSet<PlayerAvatar> PlayerAvatars { get; set; }
public DbSet<SavedOutfit> SavedOutfits { get; set; }
public DbSet<RoomInstance> RoomInstances { get; set; }
public DbSet<Room> Rooms { get; set; }
public DbSet<SubRoom> SubRooms { get; set; }
public DbSet<LoadScreen> LoadScreens { get; set; }
public DbSet<PromoImage> PromoImages { get; set; }
public DbSet<PromoExternalContent> PromoExternalContents { get; set; }
public DbSet<RoomRole> RoomRoles { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
@@ -102,6 +108,66 @@ public class AppDbContext : DbContext
entity.HasIndex(e => e.OwnerAccountId).IsUnique();
entity.ToTable("room_instances");
});
// rooms
modelBuilder.Entity<Room>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ValueGeneratedNever();
entity.Property(e => e.Name).IsRequired();
entity.HasIndex(e => e.CreatorAccountId);
entity.ToTable("rooms");
});
// sub_rooms
modelBuilder.Entity<SubRoom>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ValueGeneratedOnAdd();
entity.Property(e => e.RoomId).IsRequired();
entity.HasIndex(e => e.RoomId);
entity.ToTable("sub_rooms");
});
// load_screens
modelBuilder.Entity<LoadScreen>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ValueGeneratedOnAdd();
entity.Property(e => e.RoomId).IsRequired();
entity.HasIndex(e => e.RoomId);
entity.ToTable("load_screens");
});
// promo_images
modelBuilder.Entity<PromoImage>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ValueGeneratedOnAdd();
entity.Property(e => e.RoomId).IsRequired();
entity.HasIndex(e => e.RoomId);
entity.ToTable("promo_images");
});
// promo_external_contents
modelBuilder.Entity<PromoExternalContent>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ValueGeneratedOnAdd();
entity.Property(e => e.RoomId).IsRequired();
entity.HasIndex(e => e.RoomId);
entity.ToTable("promo_external_contents");
});
// room_roles
modelBuilder.Entity<RoomRole>(entity =>
{
entity.HasKey(e => e.Id);
entity.Property(e => e.Id).ValueGeneratedOnAdd();
entity.Property(e => e.RoomId).IsRequired();
entity.HasIndex(e => e.RoomId);
entity.ToTable("room_roles");
});
}
}
File diff suppressed because one or more lines are too long
+2 -2
View File
@@ -5,12 +5,12 @@
"Notifications": "https://notify.lapis.codes",
"Images": "http://localhost:5008",
"CDN": "https://cdn.lapis.codes",
"Commerce": "https://commerce.lapis.codes",
"Commerce": "http://localhost:5010",
"Matchmaking": "https://match.lapis.codes",
"Storage": "https://storage.lapis.codes",
"Chat": "https://chatrr.lapis.codes",
"Leaderboard": "https://rr.lapis.codes",
"Accounts": "http://localhost:5005",
"Accounts": "https://accounts.lapis.codes",
"Link": "https://link.lapis.codes",
"RoomComments": "https://roomcomments.lapis.codes",
"Clubs": "http://localhost:5009",
File diff suppressed because one or more lines are too long
+568
View File
@@ -0,0 +1,568 @@
// <auto-generated />
using System;
using CannedNet.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace CannedNet.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20260403184818_AddRooms")]
partial class AddRooms
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("CannedNet.Account", b =>
{
b.Property<int?>("AccountId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accountId");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone")
.HasAnnotation("Relational:JsonPropertyName", "createdAt");
b.Property<string>("DisplayName")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "displayName");
b.Property<int?>("IdentityFlags")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "identityFlags");
b.Property<bool>("IsJunior")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isJunior");
b.Property<int?>("PersonalPronouns")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "personalPronouns");
b.Property<int?>("Platforms")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "platforms");
b.Property<string>("ProfileImage")
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "profileImage");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "username");
b.HasKey("AccountId");
b.ToTable("accounts", (string)null);
});
modelBuilder.Entity("CannedNet.AvatarItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("AvatarItemDesc")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "avatarItemDesc");
b.Property<int>("AvatarItemType")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "avatarItemType");
b.Property<string>("FriendlyName")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "friendlyName");
b.Property<int>("OwnerAccountId")
.HasColumnType("integer");
b.Property<int>("PlatformMask")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "platformMask");
b.Property<int>("Rarity")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "rarity");
b.Property<string>("Tooltip")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tooltip");
b.HasKey("Id");
b.HasIndex("OwnerAccountId");
b.ToTable("avatar_items", (string)null);
});
modelBuilder.Entity("CannedNet.CachedLogin", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accountId");
b.Property<DateTime>("LastLoginTime")
.HasColumnType("timestamp with time zone")
.HasAnnotation("Relational:JsonPropertyName", "lastLoginTime");
b.Property<int>("Platform")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "platform");
b.Property<string>("PlatformID")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "platformId");
b.Property<bool>("RequirePassword")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "requirePassword");
b.HasKey("Id");
b.HasIndex("Platform", "PlatformID")
.IsUnique();
b.ToTable("cached_logins", (string)null);
});
modelBuilder.Entity("CannedNet.PlayerAvatar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("FaceFeatures")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "FaceFeatures");
b.Property<string>("HairColor")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "HairColor");
b.Property<string>("OutfitSelections")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "OutfitSelections");
b.Property<int>("OwnerAccountId")
.HasColumnType("integer");
b.Property<string>("SkinColor")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "SkinColor");
b.HasKey("Id");
b.HasIndex("OwnerAccountId")
.IsUnique();
b.ToTable("player_avatars", (string)null);
});
modelBuilder.Entity("CannedNet.PlayerProgression", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Level")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "level");
b.Property<int>("PlayerId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "playerId");
b.Property<int>("Xp")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "xp");
b.HasKey("Id");
b.HasIndex("PlayerId")
.IsUnique();
b.ToTable("player_progressions", (string)null);
});
modelBuilder.Entity("CannedNet.PlayerSetting", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Key")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "key");
b.Property<int>("PlayerId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "playerId");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "value");
b.HasKey("Id");
b.HasIndex("PlayerId", "Key")
.IsUnique();
b.ToTable("player_settings", (string)null);
});
modelBuilder.Entity("CannedNet.Room", b =>
{
b.Property<int>("Id")
.HasColumnType("integer");
b.Property<int>("Accessibility")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accessibility");
b.Property<bool>("CloningAllowed")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "cloningAllowed");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone")
.HasAnnotation("Relational:JsonPropertyName", "createdAt");
b.Property<int>("CreatorAccountId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "creatorAccountId");
b.Property<string>("CustomWarning")
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "customWarning");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "description");
b.Property<bool>("DisableMicAutoMute")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "disableMicAutoMute");
b.Property<bool>("DisableRoomComments")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "disableRoomComments");
b.Property<bool>("EncryptVoiceChat")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "encryptVoiceChat");
b.Property<string>("ImageName")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "imageName");
b.Property<bool>("IsDorm")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isDorm");
b.Property<bool>("IsRRO")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isRRO");
b.Property<int>("MinLevel")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "minLevel");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "name");
b.Property<int>("RoomId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "roomId");
b.Property<int>("State")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "state");
b.Property<bool>("SupportsJuniors")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsJuniors");
b.Property<bool>("SupportsLevelVoting")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsLevelVoting");
b.Property<bool>("SupportsMobile")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsMobile");
b.Property<bool>("SupportsQuest2")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsQuest2");
b.Property<bool>("SupportsScreens")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsScreens");
b.Property<bool>("SupportsTeleportVR")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsTeleportVR");
b.Property<bool>("SupportsVRLow")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsVRLow");
b.Property<bool>("SupportsWalkVR")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsWalkVR");
b.Property<string>("Tags")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tags");
b.Property<int>("WarningMask")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "warningMask");
b.HasKey("Id");
b.HasIndex("CreatorAccountId");
b.ToTable("rooms", (string)null);
});
modelBuilder.Entity("CannedNet.RoomInstance", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<bool>("EncryptVoiceChat")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "EncryptVoiceChat");
b.Property<int>("OwnerAccountId")
.HasColumnType("integer");
b.Property<int>("clubId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "clubId");
b.Property<string>("dataBlob")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "dataBlob");
b.Property<int>("eventId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "eventId");
b.Property<bool>("isFull")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isFull");
b.Property<bool>("isInProgress")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isInProgress");
b.Property<bool>("isPrivate")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isPrivate");
b.Property<string>("location")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "location");
b.Property<int>("maxCapacity")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "maxCapacity");
b.Property<string>("name")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "name");
b.Property<string>("photonRegionId")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "photonRegionId");
b.Property<string>("photonRoomId")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "photonRoomId");
b.Property<string>("roomCode")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "roomCode");
b.Property<int>("roomId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "roomId");
b.Property<int>("roomInstanceId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "roomInstanceId");
b.Property<int>("roomInstanceType")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "roomInstanceType");
b.Property<int>("subRoomId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "subRoomId");
b.HasKey("Id");
b.HasIndex("OwnerAccountId")
.IsUnique();
b.ToTable("room_instances", (string)null);
});
modelBuilder.Entity("CannedNet.SavedOutfit", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("FaceFeatures")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "FaceFeatures");
b.Property<string>("HairColor")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "HairColor");
b.Property<string>("OutfitSelections")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "OutfitSelections");
b.Property<int>("OwnerAccountId")
.HasColumnType("integer");
b.Property<string>("PreviewImageName")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "PreviewImageName");
b.Property<string>("SkinColor")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "SkinColor");
b.Property<int>("Slot")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "Slot");
b.HasKey("Id");
b.HasIndex("OwnerAccountId")
.IsUnique();
b.ToTable("saved_outfits", (string)null);
});
modelBuilder.Entity("CannedNet.SubRoom", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Accessibility")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accessibility");
b.Property<string>("DataBlob")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "dataBlob");
b.Property<DateTime>("DataSavedAt")
.HasColumnType("timestamp with time zone")
.HasAnnotation("Relational:JsonPropertyName", "dataSavedAt");
b.Property<bool>("IsSandbox")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isSandbox");
b.Property<int>("MaxPlayers")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "maxPlayers");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "name");
b.Property<int>("RoomId")
.HasColumnType("integer");
b.Property<int>("SubRoomId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "subRoomId");
b.Property<string>("UnitySceneId")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "unitySceneId");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("sub_rooms", (string)null);
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,94 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace CannedNet.Migrations
{
/// <inheritdoc />
public partial class AddRooms : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "rooms",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false),
RoomId = table.Column<int>(type: "integer", nullable: false),
Name = table.Column<string>(type: "text", nullable: false),
Description = table.Column<string>(type: "text", nullable: false),
CreatorAccountId = table.Column<int>(type: "integer", nullable: false),
ImageName = table.Column<string>(type: "text", nullable: false),
State = table.Column<int>(type: "integer", nullable: false),
Accessibility = table.Column<int>(type: "integer", nullable: false),
SupportsLevelVoting = table.Column<bool>(type: "boolean", nullable: false),
IsRRO = table.Column<bool>(type: "boolean", nullable: false),
IsDorm = table.Column<bool>(type: "boolean", nullable: false),
CloningAllowed = table.Column<bool>(type: "boolean", nullable: false),
SupportsVRLow = table.Column<bool>(type: "boolean", nullable: false),
SupportsQuest2 = table.Column<bool>(type: "boolean", nullable: false),
SupportsMobile = table.Column<bool>(type: "boolean", nullable: false),
SupportsScreens = table.Column<bool>(type: "boolean", nullable: false),
SupportsWalkVR = table.Column<bool>(type: "boolean", nullable: false),
SupportsTeleportVR = table.Column<bool>(type: "boolean", nullable: false),
SupportsJuniors = table.Column<bool>(type: "boolean", nullable: false),
MinLevel = table.Column<int>(type: "integer", nullable: false),
WarningMask = table.Column<int>(type: "integer", nullable: false),
CustomWarning = table.Column<string>(type: "text", nullable: true),
DisableMicAutoMute = table.Column<bool>(type: "boolean", nullable: false),
DisableRoomComments = table.Column<bool>(type: "boolean", nullable: false),
EncryptVoiceChat = table.Column<bool>(type: "boolean", nullable: false),
CreatedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
Tags = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_rooms", x => x.Id);
});
migrationBuilder.CreateTable(
name: "sub_rooms",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RoomId = table.Column<int>(type: "integer", nullable: false),
SubRoomId = table.Column<int>(type: "integer", nullable: false),
Name = table.Column<string>(type: "text", nullable: false),
DataBlob = table.Column<string>(type: "text", nullable: false),
IsSandbox = table.Column<bool>(type: "boolean", nullable: false),
MaxPlayers = table.Column<int>(type: "integer", nullable: false),
Accessibility = table.Column<int>(type: "integer", nullable: false),
UnitySceneId = table.Column<string>(type: "text", nullable: false),
DataSavedAt = table.Column<DateTime>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_sub_rooms", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_rooms_CreatorAccountId",
table: "rooms",
column: "CreatorAccountId");
migrationBuilder.CreateIndex(
name: "IX_sub_rooms_RoomId",
table: "sub_rooms",
column: "RoomId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "rooms");
migrationBuilder.DropTable(
name: "sub_rooms");
}
}
}
@@ -0,0 +1,694 @@
// <auto-generated />
using System;
using CannedNet.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace CannedNet.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20260403192656_AddRoomTables")]
partial class AddRoomTables
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "8.0.0")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("CannedNet.Account", b =>
{
b.Property<int?>("AccountId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accountId");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone")
.HasAnnotation("Relational:JsonPropertyName", "createdAt");
b.Property<string>("DisplayName")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "displayName");
b.Property<int?>("IdentityFlags")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "identityFlags");
b.Property<bool>("IsJunior")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isJunior");
b.Property<int?>("PersonalPronouns")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "personalPronouns");
b.Property<int?>("Platforms")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "platforms");
b.Property<string>("ProfileImage")
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "profileImage");
b.Property<string>("Username")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "username");
b.HasKey("AccountId");
b.ToTable("accounts", (string)null);
});
modelBuilder.Entity("CannedNet.AvatarItem", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("AvatarItemDesc")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "avatarItemDesc");
b.Property<int>("AvatarItemType")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "avatarItemType");
b.Property<string>("FriendlyName")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "friendlyName");
b.Property<int>("OwnerAccountId")
.HasColumnType("integer");
b.Property<int>("PlatformMask")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "platformMask");
b.Property<int>("Rarity")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "rarity");
b.Property<string>("Tooltip")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tooltip");
b.HasKey("Id");
b.HasIndex("OwnerAccountId");
b.ToTable("avatar_items", (string)null);
});
modelBuilder.Entity("CannedNet.CachedLogin", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accountId");
b.Property<DateTime>("LastLoginTime")
.HasColumnType("timestamp with time zone")
.HasAnnotation("Relational:JsonPropertyName", "lastLoginTime");
b.Property<int>("Platform")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "platform");
b.Property<string>("PlatformID")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "platformId");
b.Property<bool>("RequirePassword")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "requirePassword");
b.HasKey("Id");
b.HasIndex("Platform", "PlatformID")
.IsUnique();
b.ToTable("cached_logins", (string)null);
});
modelBuilder.Entity("CannedNet.LoadScreen", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ImageUrl")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "imageUrl");
b.Property<bool>("IsThumbnail")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isThumbnail");
b.Property<int>("RoomId")
.HasColumnType("integer");
b.Property<string>("Tooltip")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tooltip");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("load_screens", (string)null);
});
modelBuilder.Entity("CannedNet.PlayerAvatar", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("FaceFeatures")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "FaceFeatures");
b.Property<string>("HairColor")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "HairColor");
b.Property<string>("OutfitSelections")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "OutfitSelections");
b.Property<int>("OwnerAccountId")
.HasColumnType("integer");
b.Property<string>("SkinColor")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "SkinColor");
b.HasKey("Id");
b.HasIndex("OwnerAccountId")
.IsUnique();
b.ToTable("player_avatars", (string)null);
});
modelBuilder.Entity("CannedNet.PlayerProgression", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Level")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "level");
b.Property<int>("PlayerId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "playerId");
b.Property<int>("Xp")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "xp");
b.HasKey("Id");
b.HasIndex("PlayerId")
.IsUnique();
b.ToTable("player_progressions", (string)null);
});
modelBuilder.Entity("CannedNet.PlayerSetting", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Key")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "key");
b.Property<int>("PlayerId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "playerId");
b.Property<string>("Value")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "value");
b.HasKey("Id");
b.HasIndex("PlayerId", "Key")
.IsUnique();
b.ToTable("player_settings", (string)null);
});
modelBuilder.Entity("CannedNet.PromoExternalContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("RoomId")
.HasColumnType("integer");
b.Property<string>("Tooltip")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tooltip");
b.Property<int>("Type")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "type");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "url");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("promo_external_contents", (string)null);
});
modelBuilder.Entity("CannedNet.PromoImage", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ImageUrl")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "imageUrl");
b.Property<int>("RoomId")
.HasColumnType("integer");
b.Property<int>("SortOrder")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "sortOrder");
b.Property<string>("Tooltip")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tooltip");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("promo_images", (string)null);
});
modelBuilder.Entity("CannedNet.Room", b =>
{
b.Property<int>("Id")
.HasColumnType("integer");
b.Property<int>("Accessibility")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accessibility");
b.Property<bool>("CloningAllowed")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "cloningAllowed");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone")
.HasAnnotation("Relational:JsonPropertyName", "createdAt");
b.Property<int>("CreatorAccountId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "creatorAccountId");
b.Property<string>("CustomWarning")
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "customWarning");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "description");
b.Property<bool>("DisableMicAutoMute")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "disableMicAutoMute");
b.Property<bool>("DisableRoomComments")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "disableRoomComments");
b.Property<bool>("EncryptVoiceChat")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "encryptVoiceChat");
b.Property<string>("ImageName")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "imageName");
b.Property<bool>("IsDorm")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isDorm");
b.Property<bool>("IsRRO")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isRRO");
b.Property<int>("MinLevel")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "minLevel");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "name");
b.Property<int>("RoomId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "roomId");
b.Property<int>("State")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "state");
b.Property<bool>("SupportsJuniors")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsJuniors");
b.Property<bool>("SupportsLevelVoting")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsLevelVoting");
b.Property<bool>("SupportsMobile")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsMobile");
b.Property<bool>("SupportsQuest2")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsQuest2");
b.Property<bool>("SupportsScreens")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsScreens");
b.Property<bool>("SupportsTeleportVR")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsTeleportVR");
b.Property<bool>("SupportsVRLow")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsVRLow");
b.Property<bool>("SupportsWalkVR")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsWalkVR");
b.Property<string>("Tags")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tags");
b.Property<int>("WarningMask")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "warningMask");
b.HasKey("Id");
b.HasIndex("CreatorAccountId");
b.ToTable("rooms", (string)null);
});
modelBuilder.Entity("CannedNet.RoomInstance", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<bool>("EncryptVoiceChat")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "EncryptVoiceChat");
b.Property<int>("OwnerAccountId")
.HasColumnType("integer");
b.Property<int>("clubId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "clubId");
b.Property<string>("dataBlob")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "dataBlob");
b.Property<int>("eventId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "eventId");
b.Property<bool>("isFull")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isFull");
b.Property<bool>("isInProgress")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isInProgress");
b.Property<bool>("isPrivate")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isPrivate");
b.Property<string>("location")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "location");
b.Property<int>("maxCapacity")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "maxCapacity");
b.Property<string>("name")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "name");
b.Property<string>("photonRegionId")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "photonRegionId");
b.Property<string>("photonRoomId")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "photonRoomId");
b.Property<string>("roomCode")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "roomCode");
b.Property<int>("roomId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "roomId");
b.Property<int>("roomInstanceId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "roomInstanceId");
b.Property<int>("roomInstanceType")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "roomInstanceType");
b.Property<int>("subRoomId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "subRoomId");
b.HasKey("Id");
b.HasIndex("OwnerAccountId")
.IsUnique();
b.ToTable("room_instances", (string)null);
});
modelBuilder.Entity("CannedNet.RoomRole", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accountId");
b.Property<int>("InvitedRole")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "invitedRole");
b.Property<int>("Role")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "role");
b.Property<int>("RoomId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("room_roles", (string)null);
});
modelBuilder.Entity("CannedNet.SavedOutfit", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("FaceFeatures")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "FaceFeatures");
b.Property<string>("HairColor")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "HairColor");
b.Property<string>("OutfitSelections")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "OutfitSelections");
b.Property<int>("OwnerAccountId")
.HasColumnType("integer");
b.Property<string>("PreviewImageName")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "PreviewImageName");
b.Property<string>("SkinColor")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "SkinColor");
b.Property<int>("Slot")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "Slot");
b.HasKey("Id");
b.HasIndex("OwnerAccountId")
.IsUnique();
b.ToTable("saved_outfits", (string)null);
});
modelBuilder.Entity("CannedNet.SubRoom", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Accessibility")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accessibility");
b.Property<string>("DataBlob")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "dataBlob");
b.Property<DateTime>("DataSavedAt")
.HasColumnType("timestamp with time zone")
.HasAnnotation("Relational:JsonPropertyName", "dataSavedAt");
b.Property<bool>("IsSandbox")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isSandbox");
b.Property<int>("MaxPlayers")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "maxPlayers");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "name");
b.Property<int>("RoomId")
.HasColumnType("integer");
b.Property<int>("SubRoomId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "subRoomId");
b.Property<string>("UnitySceneId")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "unitySceneId");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("sub_rooms", (string)null);
});
#pragma warning restore 612, 618
}
}
}
@@ -0,0 +1,115 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace CannedNet.Migrations
{
/// <inheritdoc />
public partial class AddRoomTables : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "load_screens",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RoomId = table.Column<int>(type: "integer", nullable: false),
ImageUrl = table.Column<string>(type: "text", nullable: false),
Tooltip = table.Column<string>(type: "text", nullable: false),
IsThumbnail = table.Column<bool>(type: "boolean", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_load_screens", x => x.Id);
});
migrationBuilder.CreateTable(
name: "promo_external_contents",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RoomId = table.Column<int>(type: "integer", nullable: false),
Type = table.Column<int>(type: "integer", nullable: false),
Url = table.Column<string>(type: "text", nullable: false),
Tooltip = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_promo_external_contents", x => x.Id);
});
migrationBuilder.CreateTable(
name: "promo_images",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RoomId = table.Column<int>(type: "integer", nullable: false),
ImageUrl = table.Column<string>(type: "text", nullable: false),
Tooltip = table.Column<string>(type: "text", nullable: false),
SortOrder = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_promo_images", x => x.Id);
});
migrationBuilder.CreateTable(
name: "room_roles",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
RoomId = table.Column<int>(type: "integer", nullable: false),
AccountId = table.Column<int>(type: "integer", nullable: false),
Role = table.Column<int>(type: "integer", nullable: false),
InvitedRole = table.Column<int>(type: "integer", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_room_roles", x => x.Id);
});
migrationBuilder.CreateIndex(
name: "IX_load_screens_RoomId",
table: "load_screens",
column: "RoomId");
migrationBuilder.CreateIndex(
name: "IX_promo_external_contents_RoomId",
table: "promo_external_contents",
column: "RoomId");
migrationBuilder.CreateIndex(
name: "IX_promo_images_RoomId",
table: "promo_images",
column: "RoomId");
migrationBuilder.CreateIndex(
name: "IX_room_roles_RoomId",
table: "room_roles",
column: "RoomId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "load_screens");
migrationBuilder.DropTable(
name: "promo_external_contents");
migrationBuilder.DropTable(
name: "promo_images");
migrationBuilder.DropTable(
name: "room_roles");
}
}
}
@@ -149,6 +149,38 @@ namespace CannedNet.Migrations
b.ToTable("cached_logins", (string)null);
});
modelBuilder.Entity("CannedNet.LoadScreen", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ImageUrl")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "imageUrl");
b.Property<bool>("IsThumbnail")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isThumbnail");
b.Property<int>("RoomId")
.HasColumnType("integer");
b.Property<string>("Tooltip")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tooltip");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("load_screens", (string)null);
});
modelBuilder.Entity("CannedNet.PlayerAvatar", b =>
{
b.Property<int>("Id")
@@ -246,6 +278,190 @@ namespace CannedNet.Migrations
b.ToTable("player_settings", (string)null);
});
modelBuilder.Entity("CannedNet.PromoExternalContent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("RoomId")
.HasColumnType("integer");
b.Property<string>("Tooltip")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tooltip");
b.Property<int>("Type")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "type");
b.Property<string>("Url")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "url");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("promo_external_contents", (string)null);
});
modelBuilder.Entity("CannedNet.PromoImage", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("ImageUrl")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "imageUrl");
b.Property<int>("RoomId")
.HasColumnType("integer");
b.Property<int>("SortOrder")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "sortOrder");
b.Property<string>("Tooltip")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tooltip");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("promo_images", (string)null);
});
modelBuilder.Entity("CannedNet.Room", b =>
{
b.Property<int>("Id")
.HasColumnType("integer");
b.Property<int>("Accessibility")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accessibility");
b.Property<bool>("CloningAllowed")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "cloningAllowed");
b.Property<DateTime>("CreatedAt")
.HasColumnType("timestamp with time zone")
.HasAnnotation("Relational:JsonPropertyName", "createdAt");
b.Property<int>("CreatorAccountId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "creatorAccountId");
b.Property<string>("CustomWarning")
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "customWarning");
b.Property<string>("Description")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "description");
b.Property<bool>("DisableMicAutoMute")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "disableMicAutoMute");
b.Property<bool>("DisableRoomComments")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "disableRoomComments");
b.Property<bool>("EncryptVoiceChat")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "encryptVoiceChat");
b.Property<string>("ImageName")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "imageName");
b.Property<bool>("IsDorm")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isDorm");
b.Property<bool>("IsRRO")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isRRO");
b.Property<int>("MinLevel")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "minLevel");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "name");
b.Property<int>("RoomId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "roomId");
b.Property<int>("State")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "state");
b.Property<bool>("SupportsJuniors")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsJuniors");
b.Property<bool>("SupportsLevelVoting")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsLevelVoting");
b.Property<bool>("SupportsMobile")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsMobile");
b.Property<bool>("SupportsQuest2")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsQuest2");
b.Property<bool>("SupportsScreens")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsScreens");
b.Property<bool>("SupportsTeleportVR")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsTeleportVR");
b.Property<bool>("SupportsVRLow")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsVRLow");
b.Property<bool>("SupportsWalkVR")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "supportsWalkVR");
b.Property<string>("Tags")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "tags");
b.Property<int>("WarningMask")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "warningMask");
b.HasKey("Id");
b.HasIndex("CreatorAccountId");
b.ToTable("rooms", (string)null);
});
modelBuilder.Entity("CannedNet.RoomInstance", b =>
{
b.Property<int>("Id")
@@ -339,6 +555,36 @@ namespace CannedNet.Migrations
b.ToTable("room_instances", (string)null);
});
modelBuilder.Entity("CannedNet.RoomRole", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("AccountId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accountId");
b.Property<int>("InvitedRole")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "invitedRole");
b.Property<int>("Role")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "role");
b.Property<int>("RoomId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("room_roles", (string)null);
});
modelBuilder.Entity("CannedNet.SavedOutfit", b =>
{
b.Property<int>("Id")
@@ -386,6 +632,59 @@ namespace CannedNet.Migrations
b.ToTable("saved_outfits", (string)null);
});
modelBuilder.Entity("CannedNet.SubRoom", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<int>("Accessibility")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "accessibility");
b.Property<string>("DataBlob")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "dataBlob");
b.Property<DateTime>("DataSavedAt")
.HasColumnType("timestamp with time zone")
.HasAnnotation("Relational:JsonPropertyName", "dataSavedAt");
b.Property<bool>("IsSandbox")
.HasColumnType("boolean")
.HasAnnotation("Relational:JsonPropertyName", "isSandbox");
b.Property<int>("MaxPlayers")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "maxPlayers");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "name");
b.Property<int>("RoomId")
.HasColumnType("integer");
b.Property<int>("SubRoomId")
.HasColumnType("integer")
.HasAnnotation("Relational:JsonPropertyName", "subRoomId");
b.Property<string>("UnitySceneId")
.IsRequired()
.HasColumnType("text")
.HasAnnotation("Relational:JsonPropertyName", "unitySceneId");
b.HasKey("Id");
b.HasIndex("RoomId");
b.ToTable("sub_rooms", (string)null);
});
#pragma warning restore 612, 618
}
}
+130
View File
@@ -0,0 +1,130 @@
using System.Text.Json.Serialization;
namespace CannedNet;
public class Room
{
public int Id { get; set; }
[JsonPropertyName("roomId")]
public int RoomId { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; } = "";
[JsonPropertyName("description")]
public string Description { get; set; } = "";
[JsonPropertyName("creatorAccountId")]
public int CreatorAccountId { get; set; }
[JsonPropertyName("imageName")]
public string ImageName { get; set; } = "";
[JsonPropertyName("state")]
public int State { get; set; }
[JsonPropertyName("accessibility")]
public int Accessibility { get; set; }
[JsonPropertyName("supportsLevelVoting")]
public bool SupportsLevelVoting { get; set; }
[JsonPropertyName("isRRO")]
public bool IsRRO { get; set; }
[JsonPropertyName("isDorm")]
public bool IsDorm { get; set; }
[JsonPropertyName("cloningAllowed")]
public bool CloningAllowed { get; set; }
[JsonPropertyName("supportsVRLow")]
public bool SupportsVRLow { get; set; }
[JsonPropertyName("supportsQuest2")]
public bool SupportsQuest2 { get; set; }
[JsonPropertyName("supportsMobile")]
public bool SupportsMobile { get; set; }
[JsonPropertyName("supportsScreens")]
public bool SupportsScreens { get; set; }
[JsonPropertyName("supportsWalkVR")]
public bool SupportsWalkVR { get; set; }
[JsonPropertyName("supportsTeleportVR")]
public bool SupportsTeleportVR { get; set; }
[JsonPropertyName("supportsJuniors")]
public bool SupportsJuniors { get; set; }
[JsonPropertyName("minLevel")]
public int MinLevel { get; set; }
[JsonPropertyName("warningMask")]
public int WarningMask { get; set; }
[JsonPropertyName("customWarning")]
public string? CustomWarning { get; set; }
[JsonPropertyName("disableMicAutoMute")]
public bool DisableMicAutoMute { get; set; }
[JsonPropertyName("disableRoomComments")]
public bool DisableRoomComments { get; set; }
[JsonPropertyName("encryptVoiceChat")]
public bool EncryptVoiceChat { get; set; }
[JsonPropertyName("createdAt")]
public DateTime CreatedAt { get; set; }
[JsonPropertyName("tags")]
public string Tags { get; set; } = "[]";
}
public class SubRoom
{
public int Id { get; set; }
public int RoomId { get; set; }
[JsonPropertyName("subRoomId")]
public int SubRoomId { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; } = "";
[JsonPropertyName("dataBlob")]
public string DataBlob { get; set; } = "";
[JsonPropertyName("isSandbox")]
public bool IsSandbox { get; set; }
[JsonPropertyName("maxPlayers")]
public int MaxPlayers { get; set; }
[JsonPropertyName("accessibility")]
public int Accessibility { get; set; }
[JsonPropertyName("unitySceneId")]
public string UnitySceneId { get; set; } = "";
[JsonPropertyName("dataSavedAt")]
public DateTime DataSavedAt { get; set; }
}
public class LoadScreen
{
public int Id { get; set; }
public int RoomId { get; set; }
[JsonPropertyName("imageUrl")]
public string ImageUrl { get; set; } = "";
[JsonPropertyName("tooltip")]
public string Tooltip { get; set; } = "";
[JsonPropertyName("isThumbnail")]
public bool IsThumbnail { get; set; }
}
public class PromoImage
{
public int Id { get; set; }
public int RoomId { get; set; }
[JsonPropertyName("imageUrl")]
public string ImageUrl { get; set; } = "";
[JsonPropertyName("tooltip")]
public string Tooltip { get; set; } = "";
[JsonPropertyName("sortOrder")]
public int SortOrder { get; set; }
}
public class PromoExternalContent
{
public int Id { get; set; }
public int RoomId { get; set; }
[JsonPropertyName("type")]
public int Type { get; set; }
[JsonPropertyName("url")]
public string Url { get; set; } = "";
[JsonPropertyName("tooltip")]
public string Tooltip { get; set; } = "";
}
public class RoomRole
{
public int Id { get; set; }
public int RoomId { get; set; }
[JsonPropertyName("accountId")]
public int AccountId { get; set; }
[JsonPropertyName("role")]
public int Role { get; set; }
[JsonPropertyName("invitedRole")]
public int InvitedRole { get; set; }
}
+6 -6
View File
@@ -15,21 +15,21 @@ public class RoomInstance
[JsonPropertyName("roomInstanceType")]
public int roomInstanceType { get; set; }
[JsonPropertyName("location")]
public string location { get; set; }
public string location { get; set; } = "";
[JsonPropertyName("dataBlob")]
public string dataBlob { get; set; }
public string dataBlob { get; set; } = "";
[JsonPropertyName("eventId")]
public int eventId { get; set; }
[JsonPropertyName("clubId")]
public int clubId { get; set; }
[JsonPropertyName("roomCode")]
public string roomCode { get; set; }
public string roomCode { get; set; } = "";
[JsonPropertyName("photonRegionId")]
public string photonRegionId { get; set; }
public string photonRegionId { get; set; } = "";
[JsonPropertyName("photonRoomId")]
public string photonRoomId { get; set; }
public string photonRoomId { get; set; } = "";
[JsonPropertyName("name")]
public string name { get; set; }
public string name { get; set; } = "";
[JsonPropertyName("maxCapacity")]
public int maxCapacity { get; set; }
[JsonPropertyName("isFull")]
+15
View File
@@ -0,0 +1,15 @@
using System.Text.Json.Serialization;
namespace CannedNet;
public class RoomStats
{
[JsonPropertyName("CheerCount")]
public int CheerCount { get; set; }
[JsonPropertyName("FavoriteCount")]
public int FavoriteCount { get; set; }
[JsonPropertyName("VisitorCount")]
public int VisitorCount { get; set; }
[JsonPropertyName("VisitCount")]
public int VisitCount { get; set; }
}
+399 -14
View File
@@ -108,11 +108,170 @@ public class APIService
if (!int.TryParse(accountId.AsSpan(), out var id))
return Results.Unauthorized();
var items = await db.AvatarItems
var ownedItems = await db.AvatarItems
.Where(i => i.OwnerAccountId == id)
.ToListAsync();
var defaultItems = new List<object>
{
new { AvatarItemType = 0, AvatarItemDesc = "5d13a7a2-8213-40e6-90a6-efdd76a3fdcb,,,", PlatformMask = -1, FriendlyName = "Flowing Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "1d27b674-f9e2-4ffc-9d8c-a58a1be06457,,,", PlatformMask = -1, FriendlyName = "Afro Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "d84c0ff9-8fbe-4ed8-abf3-7996e81888ab,,,", PlatformMask = -1, FriendlyName = "Large Afro Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "e5b83dfc-b2e1-4dcb-a4ab-9d3a4c8a34ae,,,", PlatformMask = -1, FriendlyName = "Long Wavy Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "7dd6f7b0-7ba0-429f-a04f-e32d3a79ee61,,,", PlatformMask = -1, FriendlyName = "Short Wavy Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "eb9611c6-bb50-41a2-93e9-7f959815a846,,,", PlatformMask = -1, FriendlyName = "Dreads Long Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "1fd69ef8-0b74-4962-af5a-67f0bf0358f2,,,", PlatformMask = -1, FriendlyName = "Ponytail Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "a12f724f-4a73-4ab8-aad4-6bfc662b4dd6,,,", PlatformMask = -1, FriendlyName = "Undercut Long Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "0753d7a4-8247-4fca-a6fc-359c26086140,,,", PlatformMask = -1, FriendlyName = "Fonzie Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "77d3c585-4928-4471-a425-89036efe7299,,,", PlatformMask = -1, FriendlyName = "Spiky Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "92302d9d-c527-418c-ac5d-1fa869727505,,,", PlatformMask = -1, FriendlyName = "Part Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "f9dd08f8-16d3-4c39-af4f-89f7bb6e80d3,,,", PlatformMask = -1, FriendlyName = "Undercut Short Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "b148cb1e-df81-442f-aea6-ab1727aad00e,,,", PlatformMask = -1, FriendlyName = "Chunky Afro Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "e36bcd98-7e85-43fa-89f8-57e4ec33823a,,,", PlatformMask = -1, FriendlyName = "Bob with Bangs Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "880a3cc0-7407-4b61-b759-f9dd890fe9e5,,,", PlatformMask = -1, FriendlyName = "Bob Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "21599b51-c50f-43d8-ac5f-62c30cd02ca5,,,", PlatformMask = -1, FriendlyName = "Lori Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "193a3bf9-abc0-4d78-8d63-92046908b1c5,,,", PlatformMask = -1, FriendlyName = "Emo Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "79b90274-6eec-4664-acfb-4a123334661e,,,", PlatformMask = -1, FriendlyName = "Pig Tails Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "da4e7b34-2095-4a9e-801e-4f409039e0dd,,,", PlatformMask = -1, FriendlyName = "Buzz Cut Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "9d9fadb6-97eb-480e-a224-4e0179082071,,,", PlatformMask = -1, FriendlyName = "Meatball Buns Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "d8280c0c-d803-4513-be10-a0ba96d8821e,,,", PlatformMask = -1, FriendlyName = "Flowhawk Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "e286863c-2967-4d00-b837-b49487b9484a,,,", PlatformMask = -1, FriendlyName = "Fauxhawk Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2cb4f372-3372-4583-8b57-c4e3988e3c28,,,", PlatformMask = -1, FriendlyName = "Punky Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "06306723-ca20-4aa6-b7b3-917113f41ac3,,,", PlatformMask = -1, FriendlyName = "Cat-Eye Glasses (Red)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "c70005d5-6276-4a98-acb3-6a77bc19379a,,,", PlatformMask = -1, FriendlyName = "Glasses (Teal)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "8d10cc78-6b00-45f3-affb-205e9cc5b03f,,,", PlatformMask = -1, FriendlyName = "Beard (Close)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "cc96f8a5-bc5b-4f89-83b7-ecd53905ada7,,,", PlatformMask = -1, FriendlyName = "Beard (Thick)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "c6c08eb5-381a-4193-9722-80da95d62abe,,,", PlatformMask = -1, FriendlyName = "Business Tie (Black)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "4d507dfa-4a99-4ac0-8537-229e9dc0eb4a,,,", PlatformMask = -1, FriendlyName = "Rec Room Tank Top (Orange)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "d0a9262f-5504-46a7-bb10-7507503db58e,,,", PlatformMask = -1, FriendlyName = "Rec Room Shirt (Crew Neck, White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "d0a9262f-5504-46a7-bb10-7507503db58e,95e4cc30-cb68-473d-a395-feadf5b51512,0440f08f-ef1d-49d8-942b-523056e8bb45,", PlatformMask = -1, FriendlyName = "Rec Room T-Shirt (Crew Neck, Orange)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2e59d8d0-91a0-4449-bfdc-a5d663fd9343,,,", PlatformMask = -1, FriendlyName = "Collared Shirt (Plaid, Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "7b857a8c-92ad-4028-a2c2-b3c20cdab5f2,,,", PlatformMask = -1, FriendlyName = "T-Shirt", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "8aa79563-ace1-4ba7-ad0c-f3210a78142f,,,", PlatformMask = -1, FriendlyName = "Rec Room Shirt (V-Neck, White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "8aa79563-ace1-4ba7-ad0c-f3210a78142f,95e4cc30-cb68-473d-a395-feadf5b51512,05f0ee6e-c824-470e-9178-5ed576c6fe0c,", PlatformMask = -1, FriendlyName = "Rec Room T-Shirt (V-Neck, Orange)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "21caa68e-c3fa-474c-af5e-af1e742b7a60,,,", PlatformMask = -1, FriendlyName = "Tennis Skirt (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "21caa68e-c3fa-474c-af5e-af1e742b7a60,c5deba2a-6e35-4b13-8e94-8ba5457f39df,b75ef67d-00c3-4ac1-9b72-212032460294,", PlatformMask = -1, FriendlyName = "Tennis Skirt (Yellow)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "21caa68e-c3fa-474c-af5e-af1e742b7a60,758752bd-db2f-43d2-b580-55b3e1efffd5,b75ef67d-00c3-4ac1-9b72-212032460294,", PlatformMask = -1, FriendlyName = "Tennis Skirt (Red)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2296ed0d-df56-4d46-b33a-aae9230a47fc,,,", PlatformMask = -1, FriendlyName = "Zipper Dress (Yellow)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,,,", PlatformMask = -1, FriendlyName = "Wristbands (White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "71921831-ba6f-408b-a00e-2fd97663636f,,,", PlatformMask = -1, FriendlyName = "Wrist Tape (White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2e59d8d0-91a0-4449-bfdc-a5d663fd9343,55901f12-d5b5-4fa8-b4c8-e479689ee39d,f600037d-c9c0-43fa-b45b-02f456f9dd5f,", PlatformMask = -1, FriendlyName = "Collared Shirt (Denim)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2e59d8d0-91a0-4449-bfdc-a5d663fd9343,bf82f2f6-9af8-431e-a296-0890dea48ba7,d015cae7-a905-49e4-8823-6dec069689a6,", PlatformMask = -1, FriendlyName = "Collared Shirt (Argyle)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2e59d8d0-91a0-4449-bfdc-a5d663fd9343,EfdMcnfHt0mr0PQ_maaYOg,DRJcNhkqvkKFEaZpOguR6w,", PlatformMask = -1, FriendlyName = "Collared Shirt (Flowers, Green)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "7b857a8c-92ad-4028-a2c2-b3c20cdab5f2,6d703981-2734-4c45-8983-cdd5f328902f,a0271cd0-e172-4d3f-aa2f-9806f21a82d2,", PlatformMask = -1, FriendlyName = "Tank Top (Camo)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "7b857a8c-92ad-4028-a2c2-b3c20cdab5f2,5c4a2b35-0e1c-44de-8c3a-96d4a6458b1b,9c03f381-7357-4d0f-8cda-8737d4c43d25,", PlatformMask = -1, FriendlyName = "Tank Top (Rainbow)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "7b857a8c-92ad-4028-a2c2-b3c20cdab5f2,51ef8d39-2b94-4f9e-9620-07b6b0a913a5,d2a692e6-e1a9-4cfe-8154-10b52be7f8c8,", PlatformMask = -1, FriendlyName = "Jersey (Orange)", Tooltip = "", Rarity = 10 },
new { AvatarItemType = 0, AvatarItemDesc = "7b857a8c-92ad-4028-a2c2-b3c20cdab5f2,ad61c418-6d77-4a99-8ac5-9f10f5a3d42f,b292eb4b-07e3-4a48-99b5-3c6587a1e02e,", PlatformMask = -1, FriendlyName = "Tank Top (Dots)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "7b857a8c-92ad-4028-a2c2-b3c20cdab5f2,48abd952-214f-48b2-a8f1-1146f6f69aa2,b78008e8-abbd-4ece-be34-9a911f721fcc,", PlatformMask = -1, FriendlyName = "Tank Top (Zebra)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "14ef6b00-debf-4a85-9755-b4d37df496d3,8377ab96-c908-457f-9fee-b784c9a759f3,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Baseball Cap (Red)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "14ef6b00-debf-4a85-9755-b4d37df496d3,dee70c38-7a99-4c2b-9181-665f1bf75aca,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Baseball Cap (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,7d8e55fe-3c34-4b4b-9753-0021f6cc6454,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Headband (Cream)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,1b1d08f2-12ca-43dd-a44f-ea2820b919b4,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Headband (Black)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,51ef8d39-2b94-4f9e-9620-07b6b0a913a5,018a5c07-e956-457d-a540-a5e2cd68da09,", PlatformMask = -1, FriendlyName = "Headband (Orange, White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,cbe29e9f-f2ac-47fb-97e1-8bad16abb89d,018a5c07-e956-457d-a540-a5e2cd68da09,", PlatformMask = -1, FriendlyName = "Headband (Pink, White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,dee70c38-7a99-4c2b-9181-665f1bf75aca,018a5c07-e956-457d-a540-a5e2cd68da09,", PlatformMask = -1, FriendlyName = "Headband (Blue, White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,6dd95046-acf8-42fe-ab78-80a334096a9d,56a92c8d-af53-413e-929e-4a9a3cfad780,", PlatformMask = -1, FriendlyName = "Headband (Red, White, Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,dee70c38-7a99-4c2b-9181-665f1bf75aca,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wristbands (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,1b1d08f2-12ca-43dd-a44f-ea2820b919b4,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wristbands (Black)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,51ef8d39-2b94-4f9e-9620-07b6b0a913a5,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wristbands (Orange)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,cbe29e9f-f2ac-47fb-97e1-8bad16abb89d,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wristbands (Pink)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,8377ab96-c908-457f-9fee-b784c9a759f3,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wristbands (Red)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "fcfcaf63-deb4-45f7-b711-c051c9ea45cb,,,", PlatformMask = -1, FriendlyName = "Top Bun Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "de0ac50d-2adb-4114-bd2e-68953b13d706,,,", PlatformMask = -1, FriendlyName = "Blazer (Blue, White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "de0ac50d-2adb-4114-bd2e-68953b13d706,6f2e74bf-1e95-463d-97db-d5d1a53b2c28,be2b9293-1d3c-4b1c-b4c5-fad3ab16cf54,", PlatformMask = -1, FriendlyName = "Blazer (Black, White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "de0ac50d-2adb-4114-bd2e-68953b13d706,9374bf66-2ee5-493b-8439-efce4b201904,be2b9293-1d3c-4b1c-b4c5-fad3ab16cf54,", PlatformMask = -1, FriendlyName = "Blazer (Grey, Black)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "de0ac50d-2adb-4114-bd2e-68953b13d706,272fe8eb-5061-4729-a7a8-414ff667a82f,be2b9293-1d3c-4b1c-b4c5-fad3ab16cf54,", PlatformMask = -1, FriendlyName = "Blazer (Grey, White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "de0ac50d-2adb-4114-bd2e-68953b13d706,0ffad843-d6c9-425a-8686-7217009c867e,be2b9293-1d3c-4b1c-b4c5-fad3ab16cf54,", PlatformMask = -1, FriendlyName = "Blazer (Green, Black)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "9c8fc7f0-8f99-4aad-a34f-8d979f6ae352,e0397982-c2c2-4733-9a40-46e18675b5af,dafa658e-753b-46cb-bd85-85c1de5e6ea7,", PlatformMask = -1, FriendlyName = "Button Top (Orange)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "9c8fc7f0-8f99-4aad-a34f-8d979f6ae352,,,", PlatformMask = -1, FriendlyName = "Button Top (Pink)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "9c8fc7f0-8f99-4aad-a34f-8d979f6ae352,49f5864f-9d40-497c-88c8-e87f64d41d74,dafa658e-753b-46cb-bd85-85c1de5e6ea7,", PlatformMask = -1, FriendlyName = "Button Top (Tan)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "9c8fc7f0-8f99-4aad-a34f-8d979f6ae352,c5deba2a-6e35-4b13-8e94-8ba5457f39df,dafa658e-753b-46cb-bd85-85c1de5e6ea7,", PlatformMask = -1, FriendlyName = "Button Top (Yellow)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "6d815b35-6f68-4ed4-817d-70f141e1a571,f750de46-3758-4f7d-9709-0a84b1027009,2c8924aa-68f8-4912-9759-18992f72f08a,", PlatformMask = -1, FriendlyName = "Collared Dress (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "6d815b35-6f68-4ed4-817d-70f141e1a571,d66aa400-aa5a-4539-a25d-5f8ce94dc281,2c8924aa-68f8-4912-9759-18992f72f08a,", PlatformMask = -1, FriendlyName = "Collared Dress (Green)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "6d815b35-6f68-4ed4-817d-70f141e1a571,6564acf1-4d70-4f92-92ac-08e2b76dbb6b,2c8924aa-68f8-4912-9759-18992f72f08a,", PlatformMask = -1, FriendlyName = "Collared Dress (Purple)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "6d815b35-6f68-4ed4-817d-70f141e1a571,,,", PlatformMask = -1, FriendlyName = "Collared Dress (Red)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "241506f6-bf88-4b46-b5fe-513a225421f4,,,", PlatformMask = -1, FriendlyName = "Half Up Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "6b9e022c-0b68-48fd-8eca-da8573c18900,d6edbc00-3c1d-4f49-8412-3ef8c7c5f4c2,cf119781-5bd9-4b85-9a0b-12e82e988c23,", PlatformMask = -1, FriendlyName = "Long Scarf (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2296ed0d-df56-4d46-b33a-aae9230a47fc,6d703981-2734-4c45-8983-cdd5f328902f,cfabdefe-0890-436e-b2a3-b5c712e22955,", PlatformMask = -1, FriendlyName = "Zipper Dress (Green)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2296ed0d-df56-4d46-b33a-aae9230a47fc,830be2fa-60a5-48cc-931f-34b670eae4bd,cfabdefe-0890-436e-b2a3-b5c712e22955,", PlatformMask = -1, FriendlyName = "Zipper Dress (Purple)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2296ed0d-df56-4d46-b33a-aae9230a47fc,bbfa08e3-8e6b-4e0f-b264-1b398d7cd44a,cfabdefe-0890-436e-b2a3-b5c712e22955,", PlatformMask = -1, FriendlyName = "Zipper Dress (White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,484b6c13-af22-4ad5-8c43-34c0de095d49,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wristbands (Light Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,f8b0cfe8-e129-4578-8bb5-f60af5d38599,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wristbands (Green)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,67bcca75-4ab1-4964-8688-9908c464d355,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wristbands (Gold)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "7b857a8c-92ad-4028-a2c2-b3c20cdab5f2,1b1d08f2-12ca-43dd-a44f-ea2820b919b4,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Tank Top (Black)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "7b857a8c-92ad-4028-a2c2-b3c20cdab5f2,dee70c38-7a99-4c2b-9181-665f1bf75aca,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Tank Top (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "7b857a8c-92ad-4028-a2c2-b3c20cdab5f2,51ef8d39-2b94-4f9e-9620-07b6b0a913a5,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Tank Top (Orange)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "7b857a8c-92ad-4028-a2c2-b3c20cdab5f2,8377ab96-c908-457f-9fee-b784c9a759f3,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Tank Top (Red)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "6b9e022c-0b68-48fd-8eca-da8573c18900,5c4a2b35-0e1c-44de-8c3a-96d4a6458b1b,cf119781-5bd9-4b85-9a0b-12e82e988c23,", PlatformMask = -1, FriendlyName = "Long Scarf (Purple)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "6b9e022c-0b68-48fd-8eca-da8573c18900,6dd95046-acf8-42fe-ab78-80a334096a9d,cf119781-5bd9-4b85-9a0b-12e82e988c23,", PlatformMask = -1, FriendlyName = "Long Scarf (White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,dee70c38-7a99-4c2b-9181-665f1bf75aca,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Headband (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,f8b0cfe8-e129-4578-8bb5-f60af5d38599,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Headband (Green)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,8377ab96-c908-457f-9fee-b784c9a759f3,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Headband (Red)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,,,", PlatformMask = -1, FriendlyName = "Headband (White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,67bcca75-4ab1-4964-8688-9908c464d355,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Headband (Yellow)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "24a240f4-1574-420b-b898-a7e91f170759,,,", PlatformMask = -1, FriendlyName = "Back Bun Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "c45ed7b8-99bd-4a4b-a9ff-e16edf5d7a18,,,", PlatformMask = -1, FriendlyName = "High Pony Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "14ef6b00-debf-4a85-9755-b4d37df496d3,484b6c13-af22-4ad5-8c43-34c0de095d49,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Baseball Cap (Light Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "14ef6b00-debf-4a85-9755-b4d37df496d3,1b1d08f2-12ca-43dd-a44f-ea2820b919b4,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Baseball Cap (Black)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "14ef6b00-debf-4a85-9755-b4d37df496d3,51ef8d39-2b94-4f9e-9620-07b6b0a913a5,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Baseball Cap (Orange)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "14ef6b00-debf-4a85-9755-b4d37df496d3,,,", PlatformMask = -1, FriendlyName = "Baseball Cap (White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "14ef6b00-debf-4a85-9755-b4d37df496d3,67bcca75-4ab1-4964-8688-9908c464d355,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Baseball Cap (Yellow)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "896c2491-2f96-4986-9cbd-b3b31ef5d8c5,,,", PlatformMask = -1, FriendlyName = "Equestrian Coat (Black)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "896c2491-2f96-4986-9cbd-b3b31ef5d8c5,55901f12-d5b5-4fa8-b4c8-e479689ee39d,d344b8cc-85a8-4ace-9f92-38c84f396e99,", PlatformMask = -1, FriendlyName = "Equestrian Coat (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "896c2491-2f96-4986-9cbd-b3b31ef5d8c5,4828b50c-95b6-466a-bb25-514891d78202,d344b8cc-85a8-4ace-9f92-38c84f396e99,", PlatformMask = -1, FriendlyName = "Equestrian Coat (Grey)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "896c2491-2f96-4986-9cbd-b3b31ef5d8c5,d6823e01-69f0-4f85-b94a-74894356a2cf,d344b8cc-85a8-4ace-9f92-38c84f396e99,", PlatformMask = -1, FriendlyName = "Equestrian Coat (Maroon)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "09177621-9ecd-4f6a-b6a5-64490139141d,,,", PlatformMask = -1, FriendlyName = "Flat Top Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "95ab7a7c-c35d-4da5-9955-0921064470b6,,,", PlatformMask = -1, FriendlyName = "Gekko Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,0ecb8a2a-cffc-47db-aeda-fb0684aef1e5,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Headband (Grey)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,484b6c13-af22-4ad5-8c43-34c0de095d49,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Headband (Light Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,51ef8d39-2b94-4f9e-9620-07b6b0a913a5,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Headband (Orange)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,cbe29e9f-f2ac-47fb-97e1-8bad16abb89d,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Headband (Pink)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "40528de7-38a3-4a7c-8f93-6d3bfa5573f2,8377ab96-c908-457f-9fee-b784c9a759f3,018a5c07-e956-457d-a540-a5e2cd68da09,", PlatformMask = -1, FriendlyName = "Headband (Red, White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "62ce4109-8dee-4895-bf1b-bfa143db4c7e,,,", PlatformMask = -1, FriendlyName = "Slim Blazer (Teal)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "62ce4109-8dee-4895-bf1b-bfa143db4c7e,cd5d7285-202d-42d0-b93f-04245875793e,0f36bb97-c61b-4281-929f-ff1d0d11be86,", PlatformMask = -1, FriendlyName = "Slim Blazer (Green)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "62ce4109-8dee-4895-bf1b-bfa143db4c7e,ad61c418-6d77-4a99-8ac5-9f10f5a3d42f,0f36bb97-c61b-4281-929f-ff1d0d11be86,", PlatformMask = -1, FriendlyName = "Slim Blazer (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "8b9f1413-e786-4a30-946c-9292f207875a,,,", PlatformMask = -1, FriendlyName = "Pulp Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "5cd08cfb-c729-4c30-96d9-6a99bb934d91,,,", PlatformMask = -1, FriendlyName = "Rec Room Sash", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "1a71064b-794f-40fa-9109-8ad36602b6e1,,,", PlatformMask = -1, FriendlyName = "Shagg Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "84cd594c-1cd8-4b4d-8409-85c8fd5fb02a,761a3193-60f0-4190-80c7-285b8192e794,91a451c1-b285-4c48-b14d-59ded8cc006f,", PlatformMask = -1, FriendlyName = "Stoll Dress (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "84cd594c-1cd8-4b4d-8409-85c8fd5fb02a,a819f49b-6c7a-49d3-9e6a-d9d79ef5019f,91a451c1-b285-4c48-b14d-59ded8cc006f,", PlatformMask = -1, FriendlyName = "Stoll Dress (Green)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "84cd594c-1cd8-4b4d-8409-85c8fd5fb02a,64850553-cdfe-455a-ac00-dafbe63d613e,91a451c1-b285-4c48-b14d-59ded8cc006f,", PlatformMask = -1, FriendlyName = "Stoll Dress (Orange)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "84cd594c-1cd8-4b4d-8409-85c8fd5fb02a,,,", PlatformMask = -1, FriendlyName = "Stoll Dress (Pink)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "71921831-ba6f-408b-a00e-2fd97663636f,1b1d08f2-12ca-43dd-a44f-ea2820b919b4,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wrist Tape (Black)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "71921831-ba6f-408b-a00e-2fd97663636f,7d8e55fe-3c34-4b4b-9753-0021f6cc6454,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wrist Tape (Cream)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,0ecb8a2a-cffc-47db-aeda-fb0684aef1e5,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wristbands (Grey)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ecc1dbe6-ca06-4564-b2a6-30956194d1e9,7d8e55fe-3c34-4b4b-9753-0021f6cc6454,0b2395e1-ebcc-47e9-aaf1-faf9e9cec4cd,", PlatformMask = -1, FriendlyName = "Wristbands (Cream)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "6b9e022c-0b68-48fd-8eca-da8573c18900,,,", PlatformMask = -1, FriendlyName = "Long Scarf (Red)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2e59d8d0-91a0-4449-bfdc-a5d663fd9343,0iSsaY-HgkmLaRHCn5vEdw,PioQ0o3yP0a6szPZ4EKs2A,", PlatformMask = -1, FriendlyName = "Collared Shirt (Blue)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2e59d8d0-91a0-4449-bfdc-a5d663fd9343,jGj28vhq8EGwP2RuM074aQ,PioQ0o3yP0a6szPZ4EKs2A,", PlatformMask = -1, FriendlyName = "Collared Shirt (Yellow)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2e59d8d0-91a0-4449-bfdc-a5d663fd9343,kmj5zOjcwku_WWKroCeiVQ,PioQ0o3yP0a6szPZ4EKs2A,", PlatformMask = -1, FriendlyName = "Collared Shirt (Pink)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2e59d8d0-91a0-4449-bfdc-a5d663fd9343,FAviMCQ_EE2Mpt6QPo5OEw,PioQ0o3yP0a6szPZ4EKs2A,", PlatformMask = -1, FriendlyName = "Collared Shirt (Red)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "2e59d8d0-91a0-4449-bfdc-a5d663fd9343,MFrcSQ1DYUm8imvy4ypgvw,PioQ0o3yP0a6szPZ4EKs2A,", PlatformMask = -1, FriendlyName = "Collared Shirt (White)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "de0ac50d-2adb-4114-bd2e-68953b13d706,05ac07e1-67f0-486c-abf5-a62866475abb,be2b9293-1d3c-4b1c-b4c5-fad3ab16cf54,", PlatformMask = -1, FriendlyName = "Blazer (Black, Cream)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "0088603e-ec3b-4478-8694-e6fb1989b3f2,,,", PlatformMask = -1, FriendlyName = "Angled Bob Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "ffea7a65-613f-4835-921e-6dd15f357b7e,,,", PlatformMask = -1, FriendlyName = "Long Bangs Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "45f5e714-8a5f-4385-a97f-675066167011,,,", PlatformMask = -1, FriendlyName = "Seventies Stache", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "9bf5d259-7774-4cbe-a90f-7f188cc0dce7,,,", PlatformMask = -1, FriendlyName = "Thick Goatee", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "a6cbfe76-534a-4655-a8a8-3fed13d001c7,,,", PlatformMask = -1, FriendlyName = "Bald Top Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "CTcrvbo3OEepIV4oW8bx4w,,,", PlatformMask = -1, FriendlyName = "Receding Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "-twtjyBdQ02EAdOfBGTiEw,,,", PlatformMask = -1, FriendlyName = "Van Dyke Beard", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "45eaab67-19c2-4601-8f80-3565a4dceba4,,,", PlatformMask = -1, FriendlyName = "Pompadour Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "c855dcc3-96cb-470d-b159-d37a025a47d1,,,", PlatformMask = -1, FriendlyName = "Dutch Braid Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "d7730a9e-78a1-4356-bc09-6b066615850b,,,", PlatformMask = -1, FriendlyName = "Afro Updo Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "8c35c804-e8d5-49d2-8d5a-ea19fb70bfa6,,,", PlatformMask = -1, FriendlyName = "Pencil Bun Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "5beeb4c4-f276-4eae-87aa-9302e45b05b7,,,", PlatformMask = -1, FriendlyName = "Cornrows Hair", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "b6rLwzD4NkKV7xKn9ZYVkA,sxUE0iOSZEmezm54T7xI3Q,tlpa7195x0CkmSjpR1RArQ,", PlatformMask = -1, FriendlyName = "Rec Room Hoodie - Pride (Rainbow Pride)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "fe15ca53-c5b8-4acf-9309-ff3f4e610fc9,,,", PlatformMask = -1, FriendlyName = "Winged Hat - Pride (Rainbow Pride)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "b6rLwzD4NkKV7xKn9ZYVkA,D_Xmo0rOzkS-kgq1CYXt3g,tnCJp2eDI0SwjVfJMhk3LQ,", PlatformMask = -1, FriendlyName = "Rec Room Hoodie - Pride (Trans Pride)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "fe15ca53-c5b8-4acf-9309-ff3f4e610fc9,knXPidb-Rkayfc3kSHfZeQ,1yMyo6oTjU-VAygoeWaohQ,", PlatformMask = -1, FriendlyName = "Winged Hat - Pride (Trans Pride)", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "88b6ddeb-a455-460d-91d9-a4569ef6903c,,,", PlatformMask = -1, FriendlyName = "Square Earrings ", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "0abb6b08-20ce-444f-879e-0d1344df096c,,,", PlatformMask = -1, FriendlyName = "Round Earrings", Tooltip = "", Rarity = 0 },
new { AvatarItemType = 0, AvatarItemDesc = "9b5bde11-7408-4798-9fcb-c7ec175444df,,,", PlatformMask = -1, FriendlyName = "Hoop Earrings", Tooltip = "", Rarity = 0 }
};
var allItems = ownedItems.Cast<object>().Concat(defaultItems).ToList();
return Results.Json(items);
return Results.Json(allItems);
});
app.MapGet("/api/avatar/v2", async (HttpRequest request, AppDbContext db) =>
@@ -432,6 +591,109 @@ public class APIService
return Results.Content(json, "application/json");
//return "{}";
});
app.MapGet("/roomserver/rooms/bulk", async (HttpRequest request, AppDbContext db) =>
{
var idParam = request.Query["id"].FirstOrDefault();
var nameParam = request.Query["name"].FirstOrDefault();
if (string.IsNullOrEmpty(idParam) && string.IsNullOrEmpty(nameParam))
return Results.BadRequest("Either 'id' or 'name' query parameter is required");
List<Room> results = new();
if (!string.IsNullOrEmpty(idParam))
{
var ids = idParam.Split(',').Select(s => int.TryParse(s.Trim(), out var i) ? i : -1).Where(i => i != -1);
results.AddRange(db.Rooms.Where(r => ids.Contains(r.RoomId)).ToList());
}
if (!string.IsNullOrEmpty(nameParam))
{
var names = nameParam.Split(',').Select(s => s.Trim().ToLower()).Where(s => !string.IsNullOrEmpty(s));
results.AddRange(db.Rooms.Where(r => names.Any(n => r.Name.ToLower().Contains(n))).ToList());
}
var roomIds = results.Select(r => r.RoomId).ToList();
if (roomIds.Count == 0)
{
return Results.Json(new object[0]);
}
var subRooms = db.SubRooms.Where(s => roomIds.Contains(s.RoomId)).ToList();
var roles = db.RoomRoles.Where(r => roomIds.Contains(r.RoomId)).ToList();
var loadScreens = db.LoadScreens.Where(l => roomIds.Contains(l.RoomId)).ToList();
var promoImages = db.PromoImages.Where(p => roomIds.Contains(p.RoomId)).ToList();
var promoExternalContents = db.PromoExternalContents.Where(p => roomIds.Contains(p.RoomId)).ToList();
var response = results.Distinct().Select(r => new
{
r.RoomId,
r.Name,
r.Description,
r.CreatorAccountId,
r.ImageName,
r.State,
r.Accessibility,
r.SupportsLevelVoting,
r.IsRRO,
r.IsDorm,
r.CloningAllowed,
r.SupportsVRLow,
r.SupportsQuest2,
r.SupportsMobile,
r.SupportsScreens,
r.SupportsWalkVR,
r.SupportsTeleportVR,
r.SupportsJuniors,
r.MinLevel,
r.WarningMask,
r.CustomWarning,
r.DisableMicAutoMute,
r.DisableRoomComments,
r.EncryptVoiceChat,
r.CreatedAt,
Stats = new { CheerCount = 0, FavoriteCount = 0, VisitorCount = 0, VisitCount = 0 },
SubRooms = subRooms.Where(s => s.RoomId == r.RoomId).Select(s => new
{
s.SubRoomId,
s.Name,
s.DataBlob,
s.IsSandbox,
s.MaxPlayers,
s.Accessibility,
s.UnitySceneId,
DataSavedAt = s.DataSavedAt
}).ToList(),
Roles = roles.Where(ro => ro.RoomId == r.RoomId).Select(ro => new
{
ro.AccountId,
ro.Role,
ro.InvitedRole
}).ToList(),
LoadScreens = loadScreens.Where(l => l.RoomId == r.RoomId).Select(l => new
{
l.ImageUrl,
l.Tooltip,
l.IsThumbnail
}).ToList(),
PromoImages = promoImages.Where(p => p.RoomId == r.RoomId).Select(p => new
{
p.ImageUrl,
p.Tooltip,
p.SortOrder
}).ToList(),
PromoExternalContent = promoExternalContents.Where(p => p.RoomId == r.RoomId).Select(p => new
{
p.Type,
p.Url,
p.Tooltip
}).ToList(),
Tags = new object[0]
}).ToList();
return Results.Json(response);
});
app.MapGet("/roomserver/rooms/createdby/me", async (HttpRequest request, AppDbContext db) =>
{
// TODO ADD FUNCTIONALITY
@@ -440,20 +702,131 @@ public class APIService
});
app.MapGet("/roomserver/rooms/{id}", async (HttpRequest request, AppDbContext db, string id) =>
{
var json = File.ReadAllText("JSON/ownedrooms.json");
using var doc = System.Text.Json.JsonDocument.Parse(json);
var root = doc.RootElement;
if (root.ValueKind == JsonValueKind.Array)
// this sucked to do
if (!int.TryParse(id, out var roomId))
return Results.NotFound();
var room = await db.Rooms
.FirstOrDefaultAsync(r => r.RoomId == roomId);
if (room == null)
return Results.NotFound();
var include = request.Query["include"].FirstOrDefault() ?? "";
bool includeSubRooms = include.Contains("subRooms", StringComparison.OrdinalIgnoreCase);
bool includeRoles = include.Contains("roles", StringComparison.OrdinalIgnoreCase);
bool includeLoadScreens = include.Contains("loadScreens", StringComparison.OrdinalIgnoreCase);
bool includePromoImages = include.Contains("promoImages", StringComparison.OrdinalIgnoreCase);
bool includeExternal = include.Contains("promoExternalContent", StringComparison.OrdinalIgnoreCase);
var subRooms = includeSubRooms
? await db.SubRooms.Where(x => x.RoomId == room.RoomId).ToListAsync()
: new List<SubRoom>();
var roles = includeRoles
? await db.RoomRoles.Where(x => x.RoomId == room.RoomId).ToListAsync()
: new List<RoomRole>();
var loadScreens = includeLoadScreens
? await db.LoadScreens.Where(x => x.RoomId == room.RoomId).ToListAsync()
: new List<LoadScreen>();
var promoImages = includePromoImages
? await db.PromoImages.Where(x => x.RoomId == room.RoomId).ToListAsync()
: new List<PromoImage>();
var external = includeExternal
? await db.PromoExternalContents.Where(x => x.RoomId == room.RoomId).ToListAsync()
: new List<PromoExternalContent>();
var response = new
{
foreach (var room in root.EnumerateArray())
room.RoomId,
room.Name,
room.Description,
room.CreatorAccountId,
room.ImageName,
room.State,
room.Accessibility,
room.SupportsLevelVoting,
room.IsRRO,
room.IsDorm,
room.CloningAllowed,
room.SupportsVRLow,
room.SupportsQuest2,
room.SupportsMobile,
room.SupportsScreens,
room.SupportsWalkVR,
room.SupportsTeleportVR,
room.SupportsJuniors,
room.MinLevel,
room.WarningMask,
room.CustomWarning,
room.DisableMicAutoMute,
room.DisableRoomComments,
room.EncryptVoiceChat,
room.CreatedAt,
Stats = new RoomStats
{
if (room.TryGetProperty("RoomId", out var roomIdProp) && roomIdProp.TryGetInt32(out var roomId) && roomId.ToString() == id)
{
return Results.Content(room.GetRawText(), "application/json");
}
}
}
return Results.NotFound();
CheerCount = 0,
FavoriteCount = 0,
VisitorCount = 1,
VisitCount = 1
},
SubRooms = subRooms.Select(s => new
{
s.SubRoomId,
s.Name,
s.DataBlob,
s.IsSandbox,
s.MaxPlayers,
s.Accessibility,
s.UnitySceneId,
s.DataSavedAt
}).ToList(),
Roles = roles.Select(r => new
{
r.AccountId,
r.Role,
r.InvitedRole
}).ToList(),
LoadScreens = loadScreens.Select(l => new
{
l.ImageUrl,
l.Tooltip,
l.IsThumbnail
}).ToList(),
PromoImages = promoImages.Select(p => new
{
p.ImageUrl,
p.Tooltip,
p.SortOrder
}).ToList(),
PromoExternalContent = external.Select(e => new
{
e.Type,
e.Url,
e.Tooltip
}).ToList(),
Tags = string.IsNullOrEmpty(room.Tags)
? new string[0]
: System.Text.Json.JsonSerializer.Deserialize<string[]>(room.Tags)
};
return Results.Json(response);
});
app.MapGet("/api/images/v2/named", async (HttpRequest request, AppDbContext db) =>
{
@@ -465,6 +838,18 @@ public class APIService
// stops crashing the game due to bepinex winhttp.dll (or melonloader version.dll)
return Results.Ok();
});
app.MapGet("/api/storefronts/v3/giftdropstore/300", async (HttpRequest request, AppDbContext db) =>
{
// TODO ADD FUNCTIONALITY
var json = File.ReadAllText("JSON/cafestorefront.json");
return Results.Content(json, "application/json");
});
app.MapGet("/api/storefronts/v3/giftdropstore/2", async (HttpRequest request, AppDbContext db) =>
{
// TODO ADD FUNCTIONALITY
var json = File.ReadAllText("JSON/storefront12.json");
return Results.Content(json, "application/json");
});
}
private static async Task<List<int>> ParseFormIds(HttpRequest httpRequest)
+18
View File
@@ -170,5 +170,23 @@ public class AccountsService
return Results.Ok(RecNetResultWithValue<Account>.Ok(account));
});
app.MapGet("/parentalcontrol/me", async (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))
return Results.Unauthorized();
if (!int.TryParse(accountId.AsSpan(), out var id))
return Results.Unauthorized();
return Results.Content($"{{\"accountId\":{accountId},\"disallowInAppPurchases\":false}}", "application/json");
});
}
}
+11 -1
View File
@@ -28,7 +28,7 @@ public class AuthService
return Results.Json(logins.Any() ? logins : new List<object>());
});
app.MapPost("/connect/token", async (HttpRequest httpRequest) =>
app.MapPost("/connect/token", async (HttpRequest httpRequest, AppDbContext db) =>
{
string accountId = "";
string platformId = "";
@@ -65,6 +65,16 @@ public class AuthService
}
var accessToken = jwtService.GenerateToken(accountId, platformId, platform);
if (!string.IsNullOrEmpty(accountId) && int.TryParse(accountId, out var id))
{
var roomInstance = await db.RoomInstances.FirstOrDefaultAsync(r => r.OwnerAccountId == id);
if (roomInstance != null)
{
db.RoomInstances.Remove(roomInstance);
await db.SaveChangesAsync();
}
}
return Results.Json(new
{
+14
View File
@@ -0,0 +1,14 @@
namespace CannedNet.Services;
public class CommerceService
{
public WebApplicationBuilder Initialize(string[]? args = null) => ServiceExtensions.CreateRecNetBuilder(args);
public void MapEndpoints(WebApplication app)
{
app.MapGet("/purchase/v1/hasspentmoney", (HttpRequest request) =>
{
return "true";
});
}
}
+155 -81
View File
@@ -59,81 +59,144 @@ public class MatchmakingService
if (!int.TryParse(accountId.AsSpan(), out var id))
return Results.Unauthorized();
var photonRoomId = Guid.NewGuid().ToString();
Room? roomData = null;
var roomLower = room.ToLower();
var existingInstance = await db.RoomInstances.FirstOrDefaultAsync(r => r.OwnerAccountId == id);
if (existingInstance != null)
if (int.TryParse(room, out var roomId))
{
existingInstance.roomInstanceId = 1;
existingInstance.roomId = 1;
existingInstance.subRoomId = 1;
existingInstance.roomInstanceType = 2;
existingInstance.location = "76d98498-60a1-430c-ab76-b54a29b7a163";
existingInstance.dataBlob = "";
existingInstance.eventId = 0;
existingInstance.clubId = 0;
existingInstance.roomCode = "";
existingInstance.photonRegionId = "us";
existingInstance.photonRoomId = photonRoomId;
existingInstance.name = room;
existingInstance.maxCapacity = 4;
existingInstance.isFull = false;
existingInstance.isPrivate = true;
existingInstance.isInProgress = false;
existingInstance.EncryptVoiceChat = false;
roomData = await db.Rooms.FirstOrDefaultAsync(r => r.RoomId == roomId);
}
if (roomData == null)
{
roomData = await db.Rooms.FirstOrDefaultAsync(r => r.Name.ToLower() == roomLower);
}
if (roomData == null && roomLower == "dormroom")
{
roomData = new Room
{
RoomId = 1,
Name = "DormRoom",
Description = "Your private room",
CreatorAccountId = id,
EncryptVoiceChat = false
};
}
if (roomData == null)
{
return Results.NotFound("Room not found");
}
var subRoom = await db.SubRooms.FirstOrDefaultAsync(s => s.RoomId == roomData.RoomId);
string location = subRoom?.UnitySceneId ?? "";
int subRoomId = subRoom?.SubRoomId ?? 0;
int maxCapacity = subRoom?.MaxPlayers ?? 4;
if (string.IsNullOrEmpty(location))
{
location = "76d98498-60a1-430c-ab76-b54a29b7a163";
}
if (subRoomId == 0)
{
subRoomId = 1;
}
var publicInstance = await db.RoomInstances
.FirstOrDefaultAsync(r => r.roomId == roomData.RoomId && !r.isPrivate && !r.isFull);
RoomInstance? instanceToUse;
string photonRoomId;
if (publicInstance != null)
{
photonRoomId = publicInstance.photonRoomId ?? Guid.NewGuid().ToString();
publicInstance.photonRoomId = photonRoomId;
publicInstance.roomInstanceId = publicInstance.Id;
instanceToUse = publicInstance;
}
else
{
db.RoomInstances.Add(new RoomInstance
photonRoomId = Guid.NewGuid().ToString();
var existingInstance = await db.RoomInstances.FirstOrDefaultAsync(r => r.OwnerAccountId == id);
if (existingInstance != null)
{
OwnerAccountId = id,
roomInstanceId = 1,
roomId = 1,
subRoomId = 1,
roomInstanceType = 2,
location = "76d98498-60a1-430c-ab76-b54a29b7a163",
dataBlob = "",
eventId = 0,
clubId = 0,
roomCode = "",
photonRegionId = "us",
photonRoomId = photonRoomId,
name = room,
maxCapacity = 4,
isFull = false,
isPrivate = true,
isInProgress = false,
EncryptVoiceChat = false
});
existingInstance.roomInstanceId = existingInstance.Id;
existingInstance.roomId = roomData.RoomId;
existingInstance.subRoomId = subRoomId;
existingInstance.location = location;
existingInstance.dataBlob = "";
existingInstance.photonRegionId = "us";
existingInstance.photonRoomId = photonRoomId;
existingInstance.name = roomData.Name;
existingInstance.maxCapacity = maxCapacity;
existingInstance.isFull = false;
existingInstance.isPrivate = false;
instanceToUse = existingInstance;
}
else
{
instanceToUse = new RoomInstance
{
OwnerAccountId = id,
roomInstanceId = 1,
roomId = roomData.RoomId,
subRoomId = subRoomId,
roomInstanceType = 2,
location = location,
dataBlob = "",
photonRegionId = "us",
photonRoomId = photonRoomId,
name = roomData.Name,
maxCapacity = maxCapacity,
isFull = false,
isPrivate = false,
isInProgress = false,
EncryptVoiceChat = roomData.EncryptVoiceChat
};
db.RoomInstances.Add(instanceToUse);
}
}
await db.SaveChangesAsync();
if (instanceToUse.Id == 0)
{
instanceToUse = await db.RoomInstances.FirstOrDefaultAsync(r => r.OwnerAccountId == id && r.roomId == roomData.RoomId);
}
return Results.Json(new
var response = new
{
errorCode = 0,
roomInstance = new
{
roomInstanceId = 1,
roomId = 1,
subRoomId = 1,
roomInstanceType = 2,
location = "76d98498-60a1-430c-ab76-b54a29b7a163",
dataBlob = "",
eventId = 0,
clubId = 0,
roomCode = "",
photonRegionId = "us",
photonRoomId = photonRoomId,
name = room,
maxCapacity = 4,
isFull = false,
isPrivate = true,
isInProgress = false,
EncryptVoiceChat = false
roomInstanceId = instanceToUse?.Id ?? 1,
roomId = instanceToUse?.roomId ?? roomData.RoomId,
subRoomId = instanceToUse?.subRoomId ?? subRoomId,
roomInstanceType = instanceToUse?.roomInstanceType ?? 2,
location = instanceToUse?.location ?? location,
dataBlob = instanceToUse?.dataBlob ?? "",
eventId = instanceToUse?.eventId ?? 0,
clubId = instanceToUse?.clubId ?? 0,
roomCode = instanceToUse?.roomCode ?? "",
photonRegionId = instanceToUse?.photonRegionId ?? "us",
photonRoomId = instanceToUse?.photonRoomId ?? photonRoomId,
name = instanceToUse?.name ?? roomData.Name,
maxCapacity = instanceToUse?.maxCapacity ?? maxCapacity,
isFull = instanceToUse?.isFull ?? false,
isPrivate = instanceToUse?.isPrivate ?? false,
isInProgress = instanceToUse?.isInProgress ?? false,
EncryptVoiceChat = instanceToUse?.EncryptVoiceChat ?? roomData.EncryptVoiceChat
}
});
};
Console.WriteLine($"[DEBUG] Full response: {System.Text.Json.JsonSerializer.Serialize(response)}");
return Results.Json(response);
});
app.MapPost("/goto/none", (HttpRequest request) =>
@@ -204,30 +267,30 @@ public class MatchmakingService
return Results.Json(new
{
playerId = id,
playerId = heartbeat.playerId != 0 ? heartbeat.playerId : id,
statusVisibility = heartbeat.statusVisibility,
deviceClass = heartbeat.deviceClass,
vrMovementMode = heartbeat.vrMovementMode,
roomInstance = new
vrMovementMode = heartbeat.vrMovementMode != 0 ? heartbeat.vrMovementMode : 1,
roomInstance = roomInstance != null ? new RoomInstance()
{
roomInstanceId = roomInstance?.roomInstanceId ?? 0,
roomId = roomInstance?.roomId ?? 0,
subRoomId = roomInstance?.subRoomId ?? 0,
roomInstanceType = roomInstance?.roomInstanceType ?? 0,
location = roomInstance?.location ?? "",
dataBlob = roomInstance?.dataBlob ?? "",
eventId = roomInstance?.eventId ?? 0,
clubId = roomInstance?.clubId ?? 0,
roomCode = roomInstance?.roomCode ?? "",
photonRegionId = roomInstance?.photonRegionId ?? "us",
photonRoomId = roomInstance?.photonRoomId ?? "",
name = roomInstance?.name ?? "",
maxCapacity = roomInstance?.maxCapacity ?? 0,
isFull = roomInstance?.isFull ?? false,
isPrivate = roomInstance?.isPrivate ?? false,
isInProgress = roomInstance?.isInProgress ?? false,
EncryptVoiceChat = roomInstance?.EncryptVoiceChat ?? false
},
roomInstanceId = roomInstance.Id > 0 ? roomInstance.Id : roomInstance.roomInstanceId,
roomId = roomInstance.roomId,
subRoomId = roomInstance.subRoomId,
roomInstanceType = roomInstance.roomInstanceType,
location = roomInstance.location,
dataBlob = roomInstance.dataBlob,
eventId = roomInstance.eventId,
clubId = roomInstance.clubId,
roomCode = roomInstance.roomCode,
photonRegionId = roomInstance.photonRegionId,
photonRoomId = roomInstance.photonRoomId,
name = roomInstance.name,
maxCapacity = roomInstance.maxCapacity,
isFull = roomInstance.isFull,
isPrivate = roomInstance.isPrivate,
isInProgress = roomInstance.isInProgress,
EncryptVoiceChat = roomInstance.EncryptVoiceChat
} : null,
isOnline = true,
appVersion = heartbeat.appVersion ?? "",
platform = heartbeat.platform
@@ -238,6 +301,17 @@ public class MatchmakingService
// TODO ADD FUNCTIONALITY
return Results.Ok();
});
app.MapPut("/roominstance/{id}/reportjoinresult", async (HttpRequest request, AppDbContext db) =>
{
request.EnableBuffering();
request.Body.Position = 0;
using var reader = new StreamReader(request.Body);
var body = await reader.ReadToEndAsync();
Console.WriteLine($"[DEBUG] reportjoinresult body: {body}");
return Results.Ok();
});
}
}
+2 -1
View File
@@ -24,6 +24,7 @@ public static class Services
new() { Name = "Notify", Port = 5006, ServiceType = typeof(NotifyService), ConfigureBuilder = b => b.ConfigureRecNetServices(), MapEndpoints = (app, _) => new NotifyService().MapEndpoints(app) },
new() { Name = "CDN", Port = 5007, ServiceType = typeof(CDNService), ConfigureBuilder = b => b.ConfigureRecNetServices(), MapEndpoints = (app, _) => new CDNService().MapEndpoints(app) },
new() { Name = "Image", Port = 5008, ServiceType = typeof(ImageService), ConfigureBuilder = b => b.ConfigureRecNetServices(), MapEndpoints = (app, _) => new ImageService().MapEndpoints(app) },
new() { Name = "Clubs", Port = 5009, ServiceType = typeof(ClubsService), ConfigureBuilder = b => b.ConfigureRecNetServices(), MapEndpoints = (app, _) => new ClubsService().MapEndpoints(app) }
new() { Name = "Clubs", Port = 5009, ServiceType = typeof(ClubsService), ConfigureBuilder = b => b.ConfigureRecNetServices(), MapEndpoints = (app, _) => new ClubsService().MapEndpoints(app) },
new() { Name = "Commerce", Port = 5010, ServiceType = typeof(CommerceService), ConfigureBuilder = b => b.ConfigureRecNetServices(), MapEndpoints = (app, _) => new CommerceService().MapEndpoints(app) }
];
}