From 1c3526e8c018fa91acc56279294aeffc54b7a58c Mon Sep 17 00:00:00 2001 From: Lapis <47952866+LapisGit@users.noreply.github.com> Date: Fri, 3 Apr 2026 17:43:07 -0400 Subject: [PATCH] make rooms be loaded from db --- .../AppConfigs/appsettings.Commerce.json | 6 + CannedNet/Data/AppDbContext.cs | 66 ++ CannedNet/JSON/cafestorefront.json | 1 + CannedNet/JSON/endpoints.json | 4 +- CannedNet/JSON/storefront12.json | 1 + .../20260403184818_AddRooms.Designer.cs | 568 ++++++++++++++ .../Migrations/20260403184818_AddRooms.cs | 94 +++ .../20260403192656_AddRoomTables.Designer.cs | 694 ++++++++++++++++++ .../20260403192656_AddRoomTables.cs | 115 +++ .../Migrations/AppDbContextModelSnapshot.cs | 299 ++++++++ CannedNet/Models/Room.cs | 130 ++++ CannedNet/Models/RoomInstance.cs | 12 +- CannedNet/Models/RoomStats.cs | 15 + CannedNet/Services/APIService.cs | 413 ++++++++++- CannedNet/Services/AccountsService.cs | 18 + CannedNet/Services/AuthService.cs | 12 +- CannedNet/Services/CommerceService.cs | 14 + CannedNet/Services/MatchmakingService.cs | 236 ++++-- CannedNet/Services/ServiceRegistry.cs | 3 +- 19 files changed, 2596 insertions(+), 105 deletions(-) create mode 100644 CannedNet/AppConfigs/appsettings.Commerce.json create mode 100644 CannedNet/JSON/cafestorefront.json create mode 100644 CannedNet/JSON/storefront12.json create mode 100644 CannedNet/Migrations/20260403184818_AddRooms.Designer.cs create mode 100644 CannedNet/Migrations/20260403184818_AddRooms.cs create mode 100644 CannedNet/Migrations/20260403192656_AddRoomTables.Designer.cs create mode 100644 CannedNet/Migrations/20260403192656_AddRoomTables.cs create mode 100644 CannedNet/Models/Room.cs create mode 100644 CannedNet/Models/RoomStats.cs create mode 100644 CannedNet/Services/CommerceService.cs diff --git a/CannedNet/AppConfigs/appsettings.Commerce.json b/CannedNet/AppConfigs/appsettings.Commerce.json new file mode 100644 index 0000000..b005764 --- /dev/null +++ b/CannedNet/AppConfigs/appsettings.Commerce.json @@ -0,0 +1,6 @@ +{ + "Hosting": { + "Url": "http://*:5010" + } +} + diff --git a/CannedNet/Data/AppDbContext.cs b/CannedNet/Data/AppDbContext.cs index 987baaa..b736174 100644 --- a/CannedNet/Data/AppDbContext.cs +++ b/CannedNet/Data/AppDbContext.cs @@ -16,6 +16,12 @@ public class AppDbContext : DbContext public DbSet PlayerAvatars { get; set; } public DbSet SavedOutfits { get; set; } public DbSet RoomInstances { get; set; } + public DbSet Rooms { get; set; } + public DbSet SubRooms { get; set; } + public DbSet LoadScreens { get; set; } + public DbSet PromoImages { get; set; } + public DbSet PromoExternalContents { get; set; } + public DbSet 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(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(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(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(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(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(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"); + }); } } diff --git a/CannedNet/JSON/cafestorefront.json b/CannedNet/JSON/cafestorefront.json new file mode 100644 index 0000000..1f51663 --- /dev/null +++ b/CannedNet/JSON/cafestorefront.json @@ -0,0 +1 @@ +{"StoreItems":[{"GiftDrops":[{"GiftDropId":3874,"FriendlyName":"Salted Pretzels","Tooltip":"","ConsumableItemDesc":"InQ25wQMGkG_bvuD5rf2Ag","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":13,"ItemSetFriendlyName":"Snickety Snacks"}],"PurchasableItemId":3890,"Type":0,"Prices":[{"CurrencyType":2,"Price":75}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3875,"FriendlyName":"Root Beer","Tooltip":"","ConsumableItemDesc":"JfnVXFmilU6ysv-VbTAe3A","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":3891,"Type":0,"Prices":[{"CurrencyType":2,"Price":50}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3876,"FriendlyName":"Bubbly","Tooltip":"","ConsumableItemDesc":"iiGTvhOCHkOTNJhb16Zbyw","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":20,"ItemSetFriendlyName":"Yummy Bubbly"}],"PurchasableItemId":3892,"Type":0,"Prices":[{"CurrencyType":2,"Price":1000}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3877,"FriendlyName":"Ego Potion","Tooltip":"","ConsumableItemDesc":"Tpxqe_lycUelySRHM8B0Vw","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":3893,"Type":0,"Prices":[{"CurrencyType":2,"Price":200}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3878,"FriendlyName":"Popcorn","Tooltip":"","ConsumableItemDesc":"QRx0aSTT9keMFdAJMQHdTg","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":13,"ItemSetFriendlyName":"Snickety Snacks"}],"PurchasableItemId":3894,"Type":0,"Prices":[{"CurrencyType":2,"Price":100}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3879,"FriendlyName":"Pepperoni Pizza","Tooltip":"","ConsumableItemDesc":"mq23W-RSP0G8iGNLdrcpUw","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":16,"ItemSetFriendlyName":"Pizza Aplenty"}],"PurchasableItemId":3895,"Type":0,"Prices":[{"CurrencyType":2,"Price":90}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3880,"FriendlyName":"Cheese Pizza","Tooltip":"","ConsumableItemDesc":"5hIAZ9wg5EyG1cILf4FS2A","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":16,"ItemSetFriendlyName":"Pizza Aplenty"}],"PurchasableItemId":3896,"Type":0,"Prices":[{"CurrencyType":2,"Price":85}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3881,"FriendlyName":"Supreme Pizza","Tooltip":"","ConsumableItemDesc":"wUCIKdJSvEmiQHYMyx4X4w","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":16,"ItemSetFriendlyName":"Pizza Aplenty"}],"PurchasableItemId":3897,"Type":0,"Prices":[{"CurrencyType":2,"Price":95}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3882,"FriendlyName":"Hawaiian Pizza","Tooltip":"","ConsumableItemDesc":"_jnjYGBcyEWY5Ub4OezXcA","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":16,"ItemSetFriendlyName":"Pizza Aplenty"}],"PurchasableItemId":3898,"Type":0,"Prices":[{"CurrencyType":2,"Price":95}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3883,"FriendlyName":"Glazed Donuts","Tooltip":"","ConsumableItemDesc":"7OZ5AE3uuUyqa0P-2W1ptg","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":18,"ItemSetFriendlyName":"Donuts by the Dozen"}],"PurchasableItemId":3899,"Type":0,"Prices":[{"CurrencyType":2,"Price":90},{"CurrencyType":400,"Price":100}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3884,"FriendlyName":"Frosted Donuts","Tooltip":"","ConsumableItemDesc":"mMCGPgK3tki5S_15q2Z81A","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":18,"ItemSetFriendlyName":"Donuts by the Dozen"}],"PurchasableItemId":3900,"Type":0,"Prices":[{"CurrencyType":2,"Price":95}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3885,"FriendlyName":"Assorted Donuts","Tooltip":"","ConsumableItemDesc":"ZuvkidodzkuOfGLDnTOFyg","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":18,"ItemSetFriendlyName":"Donuts by the Dozen"}],"PurchasableItemId":3901,"Type":0,"Prices":[{"CurrencyType":2,"Price":100}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null}],"StorefrontType":300,"NextUpdate":"2026-01-19T11:00:00","NewUntil":null} \ No newline at end of file diff --git a/CannedNet/JSON/endpoints.json b/CannedNet/JSON/endpoints.json index 4a43c89..21b2ffa 100644 --- a/CannedNet/JSON/endpoints.json +++ b/CannedNet/JSON/endpoints.json @@ -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", diff --git a/CannedNet/JSON/storefront12.json b/CannedNet/JSON/storefront12.json new file mode 100644 index 0000000..2f14274 --- /dev/null +++ b/CannedNet/JSON/storefront12.json @@ -0,0 +1 @@ +{"StoreItems":[{"GiftDrops":[{"GiftDropId":2975,"FriendlyName":"RecRoyale Backpack Skin Valentine","Tooltip":"","ConsumableItemDesc":null,"AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":"[RecRoyale_Backpack]","EquipmentModificationGuid":"w2NNBTTCVEah2WlP0JHezQ","IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":20,"CurrencyType":0,"Currency":0,"Context":1002,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":2991,"Type":0,"Prices":[{"CurrencyType":2,"Price":4000}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":2979,"FriendlyName":"ShareCamera Skin Heart","Tooltip":"","ConsumableItemDesc":null,"AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":"[ShareCamera]","EquipmentModificationGuid":"QQALCzCF-0ClDWqmmciHAQ","IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":20,"CurrencyType":0,"Currency":0,"Context":1000,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":2995,"Type":0,"Prices":[{"CurrencyType":2,"Price":2500}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3180,"FriendlyName":"Supreme Pizza","Tooltip":"","ConsumableItemDesc":"wUCIKdJSvEmiQHYMyx4X4w","AvatarItemDesc":null,"AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":0,"CurrencyType":0,"Currency":0,"Context":110000,"ItemSetId":16,"ItemSetFriendlyName":"Pizza Aplenty"}],"PurchasableItemId":3196,"Type":0,"Prices":[{"CurrencyType":2,"Price":95}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3240,"FriendlyName":"Cat Ears (White)","Tooltip":"","ConsumableItemDesc":null,"AvatarItemDesc":"3d5184e1-0201-4476-bf4b-4eb28190de62,c1e430c5-fd8d-4032-9e3f-8d87cc8784da,1e3195ab-f7f6-41f4-a5ec-378d09ecdf69,","AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":50,"CurrencyType":0,"Currency":0,"Context":0,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":3256,"Type":0,"Prices":[{"CurrencyType":2,"Price":9000}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3502,"FriendlyName":"Notes Headphones (Chillout)","Tooltip":"","ConsumableItemDesc":null,"AvatarItemDesc":"UcPo9SsF3EGTCBB2J-Efdw,4scG_UBlzE-5DWRhSrtm6g,_Yq00H-NWUyQNvGxRunHbg,","AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":50,"CurrencyType":0,"Currency":0,"Context":0,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":3518,"Type":0,"Prices":[{"CurrencyType":2,"Price":5000}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3832,"FriendlyName":"Captain Hat (White, Blue, Gold)","Tooltip":"","ConsumableItemDesc":null,"AvatarItemDesc":"f5c9743f-e77c-42f2-ba63-9843342cbf8e,,,","AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":false,"SubscribersOnly":false,"Level":0,"Rarity":30,"CurrencyType":0,"Currency":0,"Context":0,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":3848,"Type":0,"Prices":[{"CurrencyType":2,"Price":750}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3966,"FriendlyName":"Mobster Suit (Hearts)","Tooltip":"","ConsumableItemDesc":null,"AvatarItemDesc":"4308da04-af84-40bb-845a-7a9e1a2726ec,4VkPVbBVLE-eJHilwGMAbQ,HTjlzAlWZ0ezY6w3ngSQSg,","AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":true,"SubscribersOnly":false,"Level":0,"Rarity":30,"CurrencyType":0,"Currency":0,"Context":0,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":3944,"Type":0,"Prices":[{"CurrencyType":2,"Price":2000}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3967,"FriendlyName":"Big Head Bow (Hearts)","Tooltip":"","ConsumableItemDesc":null,"AvatarItemDesc":"JTrfBXhIT02o2-ssP94zew,D-SngK7hhkOpoZ2aMWv9EA,mkDVc0Mz4kmuLZ7powBHpQ,","AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":true,"SubscribersOnly":false,"Level":0,"Rarity":30,"CurrencyType":0,"Currency":0,"Context":0,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":3945,"Type":0,"Prices":[{"CurrencyType":2,"Price":1000}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3968,"FriendlyName":"Business Tie (Hearts)","Tooltip":"","ConsumableItemDesc":null,"AvatarItemDesc":"c6c08eb5-381a-4193-9722-80da95d62abe,31jelNWFyk6FlWt4HyPAlw,9zGwmle_yk25V-KnC_PJEg,","AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":true,"SubscribersOnly":false,"Level":0,"Rarity":20,"CurrencyType":0,"Currency":0,"Context":0,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":3946,"Type":0,"Prices":[{"CurrencyType":2,"Price":750}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null},{"GiftDrops":[{"GiftDropId":3969,"FriendlyName":"Swing Dress (Hearts)","Tooltip":"","ConsumableItemDesc":null,"AvatarItemDesc":"FHKZvPFMLkO8iAIPPQzu1A,,,","AvatarItemType":0,"EquipmentPrefabName":null,"EquipmentModificationGuid":null,"IsQuery":false,"Unique":true,"SubscribersOnly":false,"Level":0,"Rarity":30,"CurrencyType":0,"Currency":0,"Context":0,"ItemSetId":null,"ItemSetFriendlyName":null}],"PurchasableItemId":3947,"Type":0,"Prices":[{"CurrencyType":2,"Price":800}],"SubscriberPrices":[],"IsFeatured":false,"NewUntil":null}],"StorefrontType":2,"NextUpdate":"2026-02-11T13:00:00","NewUntil":null} \ No newline at end of file diff --git a/CannedNet/Migrations/20260403184818_AddRooms.Designer.cs b/CannedNet/Migrations/20260403184818_AddRooms.Designer.cs new file mode 100644 index 0000000..6e2fb7e --- /dev/null +++ b/CannedNet/Migrations/20260403184818_AddRooms.Designer.cs @@ -0,0 +1,568 @@ +// +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 + { + /// + 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("AccountId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accountId"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasAnnotation("Relational:JsonPropertyName", "createdAt"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "displayName"); + + b.Property("IdentityFlags") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "identityFlags"); + + b.Property("IsJunior") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isJunior"); + + b.Property("PersonalPronouns") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "personalPronouns"); + + b.Property("Platforms") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "platforms"); + + b.Property("ProfileImage") + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "profileImage"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "username"); + + b.HasKey("AccountId"); + + b.ToTable("accounts", (string)null); + }); + + modelBuilder.Entity("CannedNet.AvatarItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AvatarItemDesc") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "avatarItemDesc"); + + b.Property("AvatarItemType") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "avatarItemType"); + + b.Property("FriendlyName") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "friendlyName"); + + b.Property("OwnerAccountId") + .HasColumnType("integer"); + + b.Property("PlatformMask") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "platformMask"); + + b.Property("Rarity") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "rarity"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accountId"); + + b.Property("LastLoginTime") + .HasColumnType("timestamp with time zone") + .HasAnnotation("Relational:JsonPropertyName", "lastLoginTime"); + + b.Property("Platform") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "platform"); + + b.Property("PlatformID") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "platformId"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FaceFeatures") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "FaceFeatures"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "HairColor"); + + b.Property("OutfitSelections") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "OutfitSelections"); + + b.Property("OwnerAccountId") + .HasColumnType("integer"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Level") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "level"); + + b.Property("PlayerId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "playerId"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Key") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "key"); + + b.Property("PlayerId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "playerId"); + + b.Property("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("Id") + .HasColumnType("integer"); + + b.Property("Accessibility") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accessibility"); + + b.Property("CloningAllowed") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "cloningAllowed"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasAnnotation("Relational:JsonPropertyName", "createdAt"); + + b.Property("CreatorAccountId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "creatorAccountId"); + + b.Property("CustomWarning") + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "customWarning"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "description"); + + b.Property("DisableMicAutoMute") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "disableMicAutoMute"); + + b.Property("DisableRoomComments") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "disableRoomComments"); + + b.Property("EncryptVoiceChat") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "encryptVoiceChat"); + + b.Property("ImageName") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "imageName"); + + b.Property("IsDorm") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isDorm"); + + b.Property("IsRRO") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isRRO"); + + b.Property("MinLevel") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "minLevel"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "name"); + + b.Property("RoomId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "roomId"); + + b.Property("State") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "state"); + + b.Property("SupportsJuniors") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsJuniors"); + + b.Property("SupportsLevelVoting") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsLevelVoting"); + + b.Property("SupportsMobile") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsMobile"); + + b.Property("SupportsQuest2") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsQuest2"); + + b.Property("SupportsScreens") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsScreens"); + + b.Property("SupportsTeleportVR") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsTeleportVR"); + + b.Property("SupportsVRLow") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsVRLow"); + + b.Property("SupportsWalkVR") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsWalkVR"); + + b.Property("Tags") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "tags"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("EncryptVoiceChat") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "EncryptVoiceChat"); + + b.Property("OwnerAccountId") + .HasColumnType("integer"); + + b.Property("clubId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "clubId"); + + b.Property("dataBlob") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "dataBlob"); + + b.Property("eventId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "eventId"); + + b.Property("isFull") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isFull"); + + b.Property("isInProgress") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isInProgress"); + + b.Property("isPrivate") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isPrivate"); + + b.Property("location") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "location"); + + b.Property("maxCapacity") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "maxCapacity"); + + b.Property("name") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "name"); + + b.Property("photonRegionId") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "photonRegionId"); + + b.Property("photonRoomId") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "photonRoomId"); + + b.Property("roomCode") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "roomCode"); + + b.Property("roomId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "roomId"); + + b.Property("roomInstanceId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "roomInstanceId"); + + b.Property("roomInstanceType") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "roomInstanceType"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FaceFeatures") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "FaceFeatures"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "HairColor"); + + b.Property("OutfitSelections") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "OutfitSelections"); + + b.Property("OwnerAccountId") + .HasColumnType("integer"); + + b.Property("PreviewImageName") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "PreviewImageName"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "SkinColor"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Accessibility") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accessibility"); + + b.Property("DataBlob") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "dataBlob"); + + b.Property("DataSavedAt") + .HasColumnType("timestamp with time zone") + .HasAnnotation("Relational:JsonPropertyName", "dataSavedAt"); + + b.Property("IsSandbox") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isSandbox"); + + b.Property("MaxPlayers") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "maxPlayers"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "name"); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.Property("SubRoomId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "subRoomId"); + + b.Property("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 + } + } +} diff --git a/CannedNet/Migrations/20260403184818_AddRooms.cs b/CannedNet/Migrations/20260403184818_AddRooms.cs new file mode 100644 index 0000000..d566151 --- /dev/null +++ b/CannedNet/Migrations/20260403184818_AddRooms.cs @@ -0,0 +1,94 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace CannedNet.Migrations +{ + /// + public partial class AddRooms : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "rooms", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false), + RoomId = table.Column(type: "integer", nullable: false), + Name = table.Column(type: "text", nullable: false), + Description = table.Column(type: "text", nullable: false), + CreatorAccountId = table.Column(type: "integer", nullable: false), + ImageName = table.Column(type: "text", nullable: false), + State = table.Column(type: "integer", nullable: false), + Accessibility = table.Column(type: "integer", nullable: false), + SupportsLevelVoting = table.Column(type: "boolean", nullable: false), + IsRRO = table.Column(type: "boolean", nullable: false), + IsDorm = table.Column(type: "boolean", nullable: false), + CloningAllowed = table.Column(type: "boolean", nullable: false), + SupportsVRLow = table.Column(type: "boolean", nullable: false), + SupportsQuest2 = table.Column(type: "boolean", nullable: false), + SupportsMobile = table.Column(type: "boolean", nullable: false), + SupportsScreens = table.Column(type: "boolean", nullable: false), + SupportsWalkVR = table.Column(type: "boolean", nullable: false), + SupportsTeleportVR = table.Column(type: "boolean", nullable: false), + SupportsJuniors = table.Column(type: "boolean", nullable: false), + MinLevel = table.Column(type: "integer", nullable: false), + WarningMask = table.Column(type: "integer", nullable: false), + CustomWarning = table.Column(type: "text", nullable: true), + DisableMicAutoMute = table.Column(type: "boolean", nullable: false), + DisableRoomComments = table.Column(type: "boolean", nullable: false), + EncryptVoiceChat = table.Column(type: "boolean", nullable: false), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), + Tags = table.Column(type: "text", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_rooms", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "sub_rooms", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RoomId = table.Column(type: "integer", nullable: false), + SubRoomId = table.Column(type: "integer", nullable: false), + Name = table.Column(type: "text", nullable: false), + DataBlob = table.Column(type: "text", nullable: false), + IsSandbox = table.Column(type: "boolean", nullable: false), + MaxPlayers = table.Column(type: "integer", nullable: false), + Accessibility = table.Column(type: "integer", nullable: false), + UnitySceneId = table.Column(type: "text", nullable: false), + DataSavedAt = table.Column(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"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "rooms"); + + migrationBuilder.DropTable( + name: "sub_rooms"); + } + } +} diff --git a/CannedNet/Migrations/20260403192656_AddRoomTables.Designer.cs b/CannedNet/Migrations/20260403192656_AddRoomTables.Designer.cs new file mode 100644 index 0000000..2e2e965 --- /dev/null +++ b/CannedNet/Migrations/20260403192656_AddRoomTables.Designer.cs @@ -0,0 +1,694 @@ +// +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 + { + /// + 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("AccountId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accountId"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasAnnotation("Relational:JsonPropertyName", "createdAt"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "displayName"); + + b.Property("IdentityFlags") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "identityFlags"); + + b.Property("IsJunior") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isJunior"); + + b.Property("PersonalPronouns") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "personalPronouns"); + + b.Property("Platforms") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "platforms"); + + b.Property("ProfileImage") + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "profileImage"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "username"); + + b.HasKey("AccountId"); + + b.ToTable("accounts", (string)null); + }); + + modelBuilder.Entity("CannedNet.AvatarItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AvatarItemDesc") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "avatarItemDesc"); + + b.Property("AvatarItemType") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "avatarItemType"); + + b.Property("FriendlyName") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "friendlyName"); + + b.Property("OwnerAccountId") + .HasColumnType("integer"); + + b.Property("PlatformMask") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "platformMask"); + + b.Property("Rarity") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "rarity"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accountId"); + + b.Property("LastLoginTime") + .HasColumnType("timestamp with time zone") + .HasAnnotation("Relational:JsonPropertyName", "lastLoginTime"); + + b.Property("Platform") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "platform"); + + b.Property("PlatformID") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "platformId"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "imageUrl"); + + b.Property("IsThumbnail") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isThumbnail"); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FaceFeatures") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "FaceFeatures"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "HairColor"); + + b.Property("OutfitSelections") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "OutfitSelections"); + + b.Property("OwnerAccountId") + .HasColumnType("integer"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Level") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "level"); + + b.Property("PlayerId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "playerId"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Key") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "key"); + + b.Property("PlayerId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "playerId"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.Property("Tooltip") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "tooltip"); + + b.Property("Type") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "type"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "imageUrl"); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.Property("SortOrder") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "sortOrder"); + + b.Property("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("Id") + .HasColumnType("integer"); + + b.Property("Accessibility") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accessibility"); + + b.Property("CloningAllowed") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "cloningAllowed"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasAnnotation("Relational:JsonPropertyName", "createdAt"); + + b.Property("CreatorAccountId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "creatorAccountId"); + + b.Property("CustomWarning") + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "customWarning"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "description"); + + b.Property("DisableMicAutoMute") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "disableMicAutoMute"); + + b.Property("DisableRoomComments") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "disableRoomComments"); + + b.Property("EncryptVoiceChat") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "encryptVoiceChat"); + + b.Property("ImageName") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "imageName"); + + b.Property("IsDorm") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isDorm"); + + b.Property("IsRRO") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isRRO"); + + b.Property("MinLevel") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "minLevel"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "name"); + + b.Property("RoomId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "roomId"); + + b.Property("State") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "state"); + + b.Property("SupportsJuniors") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsJuniors"); + + b.Property("SupportsLevelVoting") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsLevelVoting"); + + b.Property("SupportsMobile") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsMobile"); + + b.Property("SupportsQuest2") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsQuest2"); + + b.Property("SupportsScreens") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsScreens"); + + b.Property("SupportsTeleportVR") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsTeleportVR"); + + b.Property("SupportsVRLow") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsVRLow"); + + b.Property("SupportsWalkVR") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsWalkVR"); + + b.Property("Tags") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "tags"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("EncryptVoiceChat") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "EncryptVoiceChat"); + + b.Property("OwnerAccountId") + .HasColumnType("integer"); + + b.Property("clubId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "clubId"); + + b.Property("dataBlob") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "dataBlob"); + + b.Property("eventId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "eventId"); + + b.Property("isFull") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isFull"); + + b.Property("isInProgress") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isInProgress"); + + b.Property("isPrivate") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isPrivate"); + + b.Property("location") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "location"); + + b.Property("maxCapacity") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "maxCapacity"); + + b.Property("name") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "name"); + + b.Property("photonRegionId") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "photonRegionId"); + + b.Property("photonRoomId") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "photonRoomId"); + + b.Property("roomCode") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "roomCode"); + + b.Property("roomId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "roomId"); + + b.Property("roomInstanceId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "roomInstanceId"); + + b.Property("roomInstanceType") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "roomInstanceType"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accountId"); + + b.Property("InvitedRole") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "invitedRole"); + + b.Property("Role") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "role"); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("room_roles", (string)null); + }); + + modelBuilder.Entity("CannedNet.SavedOutfit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("FaceFeatures") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "FaceFeatures"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "HairColor"); + + b.Property("OutfitSelections") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "OutfitSelections"); + + b.Property("OwnerAccountId") + .HasColumnType("integer"); + + b.Property("PreviewImageName") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "PreviewImageName"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "SkinColor"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Accessibility") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accessibility"); + + b.Property("DataBlob") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "dataBlob"); + + b.Property("DataSavedAt") + .HasColumnType("timestamp with time zone") + .HasAnnotation("Relational:JsonPropertyName", "dataSavedAt"); + + b.Property("IsSandbox") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isSandbox"); + + b.Property("MaxPlayers") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "maxPlayers"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "name"); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.Property("SubRoomId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "subRoomId"); + + b.Property("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 + } + } +} diff --git a/CannedNet/Migrations/20260403192656_AddRoomTables.cs b/CannedNet/Migrations/20260403192656_AddRoomTables.cs new file mode 100644 index 0000000..0cfd139 --- /dev/null +++ b/CannedNet/Migrations/20260403192656_AddRoomTables.cs @@ -0,0 +1,115 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace CannedNet.Migrations +{ + /// + public partial class AddRoomTables : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "load_screens", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RoomId = table.Column(type: "integer", nullable: false), + ImageUrl = table.Column(type: "text", nullable: false), + Tooltip = table.Column(type: "text", nullable: false), + IsThumbnail = table.Column(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(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RoomId = table.Column(type: "integer", nullable: false), + Type = table.Column(type: "integer", nullable: false), + Url = table.Column(type: "text", nullable: false), + Tooltip = table.Column(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(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RoomId = table.Column(type: "integer", nullable: false), + ImageUrl = table.Column(type: "text", nullable: false), + Tooltip = table.Column(type: "text", nullable: false), + SortOrder = table.Column(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(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + RoomId = table.Column(type: "integer", nullable: false), + AccountId = table.Column(type: "integer", nullable: false), + Role = table.Column(type: "integer", nullable: false), + InvitedRole = table.Column(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"); + } + + /// + 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"); + } + } +} diff --git a/CannedNet/Migrations/AppDbContextModelSnapshot.cs b/CannedNet/Migrations/AppDbContextModelSnapshot.cs index 7dae9d7..2b135b4 100644 --- a/CannedNet/Migrations/AppDbContextModelSnapshot.cs +++ b/CannedNet/Migrations/AppDbContextModelSnapshot.cs @@ -149,6 +149,38 @@ namespace CannedNet.Migrations b.ToTable("cached_logins", (string)null); }); + modelBuilder.Entity("CannedNet.LoadScreen", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "imageUrl"); + + b.Property("IsThumbnail") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isThumbnail"); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.Property("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("Id") @@ -246,6 +278,190 @@ namespace CannedNet.Migrations b.ToTable("player_settings", (string)null); }); + modelBuilder.Entity("CannedNet.PromoExternalContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.Property("Tooltip") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "tooltip"); + + b.Property("Type") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "type"); + + b.Property("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("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ImageUrl") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "imageUrl"); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.Property("SortOrder") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "sortOrder"); + + b.Property("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("Id") + .HasColumnType("integer"); + + b.Property("Accessibility") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accessibility"); + + b.Property("CloningAllowed") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "cloningAllowed"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone") + .HasAnnotation("Relational:JsonPropertyName", "createdAt"); + + b.Property("CreatorAccountId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "creatorAccountId"); + + b.Property("CustomWarning") + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "customWarning"); + + b.Property("Description") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "description"); + + b.Property("DisableMicAutoMute") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "disableMicAutoMute"); + + b.Property("DisableRoomComments") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "disableRoomComments"); + + b.Property("EncryptVoiceChat") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "encryptVoiceChat"); + + b.Property("ImageName") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "imageName"); + + b.Property("IsDorm") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isDorm"); + + b.Property("IsRRO") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isRRO"); + + b.Property("MinLevel") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "minLevel"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "name"); + + b.Property("RoomId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "roomId"); + + b.Property("State") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "state"); + + b.Property("SupportsJuniors") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsJuniors"); + + b.Property("SupportsLevelVoting") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsLevelVoting"); + + b.Property("SupportsMobile") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsMobile"); + + b.Property("SupportsQuest2") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsQuest2"); + + b.Property("SupportsScreens") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsScreens"); + + b.Property("SupportsTeleportVR") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsTeleportVR"); + + b.Property("SupportsVRLow") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsVRLow"); + + b.Property("SupportsWalkVR") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "supportsWalkVR"); + + b.Property("Tags") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "tags"); + + b.Property("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("Id") @@ -339,6 +555,36 @@ namespace CannedNet.Migrations b.ToTable("room_instances", (string)null); }); + modelBuilder.Entity("CannedNet.RoomRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accountId"); + + b.Property("InvitedRole") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "invitedRole"); + + b.Property("Role") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "role"); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("RoomId"); + + b.ToTable("room_roles", (string)null); + }); + modelBuilder.Entity("CannedNet.SavedOutfit", b => { b.Property("Id") @@ -386,6 +632,59 @@ namespace CannedNet.Migrations b.ToTable("saved_outfits", (string)null); }); + + modelBuilder.Entity("CannedNet.SubRoom", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Accessibility") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "accessibility"); + + b.Property("DataBlob") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "dataBlob"); + + b.Property("DataSavedAt") + .HasColumnType("timestamp with time zone") + .HasAnnotation("Relational:JsonPropertyName", "dataSavedAt"); + + b.Property("IsSandbox") + .HasColumnType("boolean") + .HasAnnotation("Relational:JsonPropertyName", "isSandbox"); + + b.Property("MaxPlayers") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "maxPlayers"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .HasAnnotation("Relational:JsonPropertyName", "name"); + + b.Property("RoomId") + .HasColumnType("integer"); + + b.Property("SubRoomId") + .HasColumnType("integer") + .HasAnnotation("Relational:JsonPropertyName", "subRoomId"); + + b.Property("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 } } diff --git a/CannedNet/Models/Room.cs b/CannedNet/Models/Room.cs new file mode 100644 index 0000000..0d52b8d --- /dev/null +++ b/CannedNet/Models/Room.cs @@ -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; } +} diff --git a/CannedNet/Models/RoomInstance.cs b/CannedNet/Models/RoomInstance.cs index ca11418..2204a44 100644 --- a/CannedNet/Models/RoomInstance.cs +++ b/CannedNet/Models/RoomInstance.cs @@ -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")] diff --git a/CannedNet/Models/RoomStats.cs b/CannedNet/Models/RoomStats.cs new file mode 100644 index 0000000..011198c --- /dev/null +++ b/CannedNet/Models/RoomStats.cs @@ -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; } +} \ No newline at end of file diff --git a/CannedNet/Services/APIService.cs b/CannedNet/Services/APIService.cs index 452b996..162d0b5 100644 --- a/CannedNet/Services/APIService.cs +++ b/CannedNet/Services/APIService.cs @@ -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 + { + 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().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 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(); + + var roles = includeRoles + ? await db.RoomRoles.Where(x => x.RoomId == room.RoomId).ToListAsync() + : new List(); + + var loadScreens = includeLoadScreens + ? await db.LoadScreens.Where(x => x.RoomId == room.RoomId).ToListAsync() + : new List(); + + var promoImages = includePromoImages + ? await db.PromoImages.Where(x => x.RoomId == room.RoomId).ToListAsync() + : new List(); + + var external = includeExternal + ? await db.PromoExternalContents.Where(x => x.RoomId == room.RoomId).ToListAsync() + : new List(); + + 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(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> ParseFormIds(HttpRequest httpRequest) diff --git a/CannedNet/Services/AccountsService.cs b/CannedNet/Services/AccountsService.cs index 6e3b755..3dd8811 100644 --- a/CannedNet/Services/AccountsService.cs +++ b/CannedNet/Services/AccountsService.cs @@ -170,5 +170,23 @@ public class AccountsService return Results.Ok(RecNetResultWithValue.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"); + }); } } diff --git a/CannedNet/Services/AuthService.cs b/CannedNet/Services/AuthService.cs index f8366a1..12a7909 100644 --- a/CannedNet/Services/AuthService.cs +++ b/CannedNet/Services/AuthService.cs @@ -28,7 +28,7 @@ public class AuthService return Results.Json(logins.Any() ? logins : new List()); }); - 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 { diff --git a/CannedNet/Services/CommerceService.cs b/CannedNet/Services/CommerceService.cs new file mode 100644 index 0000000..9c84822 --- /dev/null +++ b/CannedNet/Services/CommerceService.cs @@ -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"; + }); + } +} \ No newline at end of file diff --git a/CannedNet/Services/MatchmakingService.cs b/CannedNet/Services/MatchmakingService.cs index e20c326..385a8e9 100644 --- a/CannedNet/Services/MatchmakingService.cs +++ b/CannedNet/Services/MatchmakingService.cs @@ -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(); + }); } } diff --git a/CannedNet/Services/ServiceRegistry.cs b/CannedNet/Services/ServiceRegistry.cs index 8141114..f5e6968 100644 --- a/CannedNet/Services/ServiceRegistry.cs +++ b/CannedNet/Services/ServiceRegistry.cs @@ -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) } ]; }