diff --git a/RecRoomArchive.Models/API/Activities/CharadesWord.cs b/RecRoomArchive.Models/API/Activities/CharadesWord.cs
new file mode 100644
index 0000000..58f507f
--- /dev/null
+++ b/RecRoomArchive.Models/API/Activities/CharadesWord.cs
@@ -0,0 +1,10 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Activities
+{
+ public class CharadesWord(string word, CharadesWordsDifficulty difficulty = CharadesWordsDifficulty.Easy)
+ {
+ [JsonPropertyName(name: "Difficulty")] public CharadesWordsDifficulty Difficulty { get; set; } = difficulty;
+ [JsonPropertyName(name: "EN_US")] public string EN_US { get; set; } = word;
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Activities/CharadesWordsDifficulty.cs b/RecRoomArchive.Models/API/Activities/CharadesWordsDifficulty.cs
new file mode 100644
index 0000000..0c151ab
--- /dev/null
+++ b/RecRoomArchive.Models/API/Activities/CharadesWordsDifficulty.cs
@@ -0,0 +1,8 @@
+namespace RecRoomArchive.Models.API.Activities
+{
+ public enum CharadesWordsDifficulty
+ {
+ Easy,
+ Hard
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Avatar/PlayerAvatar.cs b/RecRoomArchive.Models/API/Avatar/PlayerAvatar.cs
new file mode 100644
index 0000000..d02995f
--- /dev/null
+++ b/RecRoomArchive.Models/API/Avatar/PlayerAvatar.cs
@@ -0,0 +1,23 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Avatar
+{
+ ///
+ /// The avatar of the player
+ ///
+ public class PlayerAvatar
+ {
+ ///
+ /// The outfit that the player has on. This includes data like their hair model, torso, hats, glasses, torso, etc...
+ ///
+ [JsonPropertyName(name: "OutfitSelections")] public string OutfitSelections { get; set; } = string.Empty;
+ ///
+ /// The skin color guid of the player
+ ///
+ [JsonPropertyName(name: "SkinColor")] public string SkinColor { get; set; } = string.Empty;
+ ///
+ /// The hair color guid of the player
+ ///
+ [JsonPropertyName(name: "HairColor")] public string HairColor { get; set; } = string.Empty;
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Config/DailyObjective.cs b/RecRoomArchive.Models/API/Config/DailyObjective.cs
new file mode 100644
index 0000000..4c26d38
--- /dev/null
+++ b/RecRoomArchive.Models/API/Config/DailyObjective.cs
@@ -0,0 +1,10 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Config
+{
+ public class DailyObjective
+ {
+ [JsonPropertyName(name: "type")] public ObjectiveType Type { get; set; }
+ [JsonPropertyName(name: "score")] public int Score { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Config/GameConfig.cs b/RecRoomArchive.Models/API/Config/GameConfig.cs
new file mode 100644
index 0000000..2aae8bd
--- /dev/null
+++ b/RecRoomArchive.Models/API/Config/GameConfig.cs
@@ -0,0 +1,10 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Config
+{
+ public class GameConfig
+ {
+ [JsonPropertyName(name: "Key")] public required string Key { get; set; }
+ [JsonPropertyName(name: "Value")] public required string Value { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Config/LevelProgressionMap.cs b/RecRoomArchive.Models/API/Config/LevelProgressionMap.cs
new file mode 100644
index 0000000..94fe336
--- /dev/null
+++ b/RecRoomArchive.Models/API/Config/LevelProgressionMap.cs
@@ -0,0 +1,10 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Config
+{
+ public class LevelProgressionMap(int level, int requiredXp)
+ {
+ [JsonPropertyName(name: "Level")] public int Level { get; set; } = level;
+ [JsonPropertyName(name: "RequiredXp")] public int RequiredXp { get; set; } = requiredXp;
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Config/MatchmakingParams.cs b/RecRoomArchive.Models/API/Config/MatchmakingParams.cs
new file mode 100644
index 0000000..b0e70db
--- /dev/null
+++ b/RecRoomArchive.Models/API/Config/MatchmakingParams.cs
@@ -0,0 +1,10 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Config
+{
+ public class MatchmakingParams
+ {
+ [JsonPropertyName(name: "PreferFullRoomsFrequency")] public float PreferFullRoomsFrequency { get; set; } = 1.0f;
+ [JsonPropertyName(name: "PreferEmptyRoomsFrequency")] public float PreferEmptyRoomsFrequency { get; set; } = 0.0f;
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Config/ObjectiveType.cs b/RecRoomArchive.Models/API/Config/ObjectiveType.cs
new file mode 100644
index 0000000..64115ce
--- /dev/null
+++ b/RecRoomArchive.Models/API/Config/ObjectiveType.cs
@@ -0,0 +1,139 @@
+namespace RecRoomArchive.Models.API.Config
+{
+ public enum ObjectiveType
+ {
+ Default = -1,
+ FirstSessionOfDay = 1,
+ AddAFriend,
+ PartyUp,
+ AllOtherChallenges,
+ LevelUp,
+ CheerAPlayer,
+ PointedAtPlayer,
+ CheerARoom,
+ SubscribeToPlayer,
+ DailyObjective1,
+ DailyObjective2,
+ DailyObjective3,
+ AllDailyObjectives,
+ CompleteAnyDaily,
+ CompleteAnyWeekly,
+ OOBE_GoToLockerRoom = 20,
+ OOBE_GoToActivity,
+ OOBE_FinishActivity,
+ NUX_PunchcardObjective = 25,
+ NUX_AllPunchcardObjectives,
+ GoToRecCenter = 30,
+ FinishActivity,
+ VisitACustomRoom,
+ CreateACustomRoom,
+ ScoreBasketInRecCenter = 35,
+ UploadPhotoToRecNet,
+ UpdatePlayerBio,
+ SaveOutfitSlot,
+ PurchaseClothingItem,
+ PurchaseNonClothingItem,
+ DrinkWater,
+ ColorOnWhiteboard,
+ SetBasketballSkin,
+ ThrowBasketball,
+ PlaceInventionInDorm,
+ ChangeDormRoomSkin,
+ ToggleOwnedClothes,
+ EquipHat,
+ LoadOutfit,
+ SaveNewOutfitSlot,
+ SpawnCamera,
+ TakeSelfie,
+ PrintSelfie,
+ TakePictureOfPlayer,
+ PrintPictureOfPlayer,
+ PublishSelfieWithPlayer,
+ SpawnFoodWithOtherPlayers,
+ EmoteInRecCenter,
+ SendRoomChatInRecCenter,
+ UseFrendotron,
+ GoToDormRoom,
+ VisitSpecificRoom,
+ VisitPublicRRO,
+ VisitPublicRoomBySource,
+ FavoriteARoom,
+ TakePhotoWithFilter,
+ OpenYourPlayerProfile,
+ OpenOnlineStatusModal,
+ ChangeProfilePicture,
+ ChangePlayerDisplayName,
+ ChangePlayerDescriptionText,
+ OpenPlayerPronounsModal,
+ OpenOtherPlayersProfile,
+ VisitPlayersPortfolio,
+ FavoriteAFriend,
+ CharadesGames = 100,
+ CharadesWinsPerformer,
+ CharadesWinsGuesser,
+ DiscGolfWins = 200,
+ DiscGolfGames,
+ DiscGolfHolesUnderPar,
+ DodgeballWins = 300,
+ DodgeballGames,
+ DodgeballHits,
+ PaddleballGames = 400,
+ PaddleballWins,
+ PaddleballScores,
+ PaintballAnyModeGames = 500,
+ PaintballAnyModeWins,
+ PaintballAnyModeHits,
+ PaintballCTFWins = 600,
+ PaintballCTFGames,
+ PaintballCTFHits,
+ PaintballFlagCaptures,
+ PaintballTeamBattleWins = 700,
+ PaintballTeamBattleGames,
+ PaintballTeamBattleHits,
+ PaintballFreeForAllWins = 710,
+ PaintballFreeForAllGames,
+ PaintballFreeForAllHits,
+ SoccerWins = 800,
+ SoccerGames,
+ SoccerGoals,
+ BowlingGames = 900,
+ BowlingWins,
+ BowlingStrike,
+ QuestGames = 1000,
+ QuestWins,
+ QuestPlayerRevives,
+ QuestEnemyKills,
+ QuestGames_Goblin1 = 1010,
+ QuestWins_Goblin1,
+ QuestPlayerRevives_Goblin1,
+ QuestEnemyKills_Goblin1,
+ QuestGames_Goblin2 = 1020,
+ QuestWins_Goblin2,
+ QuestPlayerRevives_Goblin2,
+ QuestEnemyKills_Goblin2,
+ QuestGames_Scifi1 = 1030,
+ QuestWins_Scifi1,
+ QuestPlayerRevives_Scifi1,
+ QuestEnemyKills_Scifi1,
+ QuestGames_Pirate1 = 1040,
+ QuestWins_Pirate1,
+ QuestPlayerRevives_Pirate1,
+ QuestEnemyKills_Pirate1,
+ QuestGames_Dracula1 = 1050,
+ QuestWins_Dracula1,
+ QuestPlayerRevives_Dracula1,
+ QuestEnemyKills_Dracula1,
+ ArenaGames = 2000,
+ ArenaWins,
+ ArenaPlayerRevives,
+ ArenaHeroTags,
+ ArenaBotTags,
+ RecRoyaleGames = 3000,
+ RecRoyaleWins,
+ RecRoyaleTags,
+ StuntRunnerGames = 4000,
+ StuntRunnerWins,
+ RecRallyGames = 5000,
+ RecRallyWins
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Config/PhotonConfig.cs b/RecRoomArchive.Models/API/Config/PhotonConfig.cs
new file mode 100644
index 0000000..8c68fff
--- /dev/null
+++ b/RecRoomArchive.Models/API/Config/PhotonConfig.cs
@@ -0,0 +1,10 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Config
+{
+ public class PhotonConfig
+ {
+ [JsonPropertyName(name: "CloudRegion")] public string CloudRegion { get; set; } = "us";
+ [JsonPropertyName(name: "CrcCheckEnabled")] public bool CrcCheckEnabled { get; set; } = true;
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Config/RecRoomConfig.cs b/RecRoomArchive.Models/API/Config/RecRoomConfig.cs
new file mode 100644
index 0000000..ac073fd
--- /dev/null
+++ b/RecRoomArchive.Models/API/Config/RecRoomConfig.cs
@@ -0,0 +1,16 @@
+using System.Text.Json.Serialization;
+using System.Xml.Linq;
+
+namespace RecRoomArchive.Models.API.Config
+{
+ public class RecRoomConfig
+ {
+ [JsonPropertyName(name: "MessageOfTheDay")] public string MessageOfTheDay { get; set; } = string.Empty;
+ [JsonPropertyName(name: "CdnBaseUri")] public string CdnBaseUri { get; set; } = string.Empty;
+ [JsonPropertyName(name: "MatchmakingParams")] public required MatchmakingParams MatchmakingParams { get; set; }
+ [JsonPropertyName(name: "LevelProgressionMaps")] public required List LevelProgressionMaps { get; set; }
+ [JsonPropertyName(name: "DailyObjectives")] public required DailyObjective[][] DailyObjectives { get; set; }
+ [JsonPropertyName(name: "PhotonConfig")] public required PhotonConfig PhotonConfig { get; set; }
+ [JsonPropertyName(name: "ConfigTable")] public required List ConfigTable { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Messages/GameInviteResponseDetails.cs b/RecRoomArchive.Models/API/Messages/GameInviteResponseDetails.cs
new file mode 100644
index 0000000..ff59e90
--- /dev/null
+++ b/RecRoomArchive.Models/API/Messages/GameInviteResponseDetails.cs
@@ -0,0 +1,12 @@
+namespace RecRoomArchive.Models.API.Messages
+{
+ public enum GameInviteResponseDetails
+ {
+ Declined,
+ Accepted,
+ ComeToMe,
+ GiveMe2,
+ GiveMe5,
+ GiveMe10
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Messages/MessageType.cs b/RecRoomArchive.Models/API/Messages/MessageType.cs
new file mode 100644
index 0000000..0ba092c
--- /dev/null
+++ b/RecRoomArchive.Models/API/Messages/MessageType.cs
@@ -0,0 +1,9 @@
+namespace RecRoomArchive.Models.API.Messages
+{
+ public enum MessageType
+ {
+ GameInvite,
+ GameInviteResponse,
+ GameJoinFailed
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Platform/PlatformMask.cs b/RecRoomArchive.Models/API/Platform/PlatformMask.cs
new file mode 100644
index 0000000..3f7ead2
--- /dev/null
+++ b/RecRoomArchive.Models/API/Platform/PlatformMask.cs
@@ -0,0 +1,21 @@
+namespace RecRoomArchive.Models.API.Platform
+{
+ ///
+ /// The types of platforms that Rec Room has support for...as a mask!
+ ///
+ [Flags]
+ public enum PlatformMask
+ {
+ None = 0,
+ Steam = 1,
+ Oculus = 2,
+ PlayStation = 4,
+ Xbox = 8,
+ RecNet = 16,
+ IOS = 32,
+ GooglePlay = 64,
+ Standalone = 128,
+ Pico = 256,
+ All = -1
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Platform/PlatformType.cs b/RecRoomArchive.Models/API/Platform/PlatformType.cs
new file mode 100644
index 0000000..1f82adb
--- /dev/null
+++ b/RecRoomArchive.Models/API/Platform/PlatformType.cs
@@ -0,0 +1,19 @@
+namespace RecRoomArchive.Models.API.Platform
+{
+ ///
+ /// The types of platforms that Rec Room has support for
+ ///
+ public enum PlatformType
+ {
+ All = -1,
+ Steam,
+ Oculus,
+ PlayStation,
+ Xbox,
+ RecNet,
+ IOS,
+ GooglePlay,
+ Standalone,
+ Pico
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/PlatformLogin/Requests/BaseLoginRequest.cs b/RecRoomArchive.Models/API/PlatformLogin/Requests/BaseLoginRequest.cs
new file mode 100644
index 0000000..b8d6d35
--- /dev/null
+++ b/RecRoomArchive.Models/API/PlatformLogin/Requests/BaseLoginRequest.cs
@@ -0,0 +1,16 @@
+using RecRoomArchive.Models.API.Platform;
+
+namespace RecRoomArchive.Models.API.PlatformLogin.Requests
+{
+ public class BaseLoginRequest
+ {
+ public required PlatformType Platform { get; set; }
+ public required string PlatformId { get; set; }
+ public string? Name { get; set; }
+ public required long ClientTimestamp { get; set; }
+ public required string DeviceId { get; set; }
+ public required long BuildTimestamp { get; set; }
+ public required string AuthParams { get; set; }
+ public required string Verify { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/PlatformLogin/Responses/BaseLoginResponse.cs b/RecRoomArchive.Models/API/PlatformLogin/Responses/BaseLoginResponse.cs
new file mode 100644
index 0000000..b0d4ea9
--- /dev/null
+++ b/RecRoomArchive.Models/API/PlatformLogin/Responses/BaseLoginResponse.cs
@@ -0,0 +1,13 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.PlatformLogin.Responses
+{
+ public class BaseLoginResponse
+ {
+ [JsonPropertyName(name: "Token")]
+ public string Token { get; set; } = string.Empty;
+
+ [JsonPropertyName(name: "PlayerId")]
+ public ulong PlayerId { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Players/AugustProfile.cs b/RecRoomArchive.Models/API/Players/AugustProfile.cs
new file mode 100644
index 0000000..0e4a1e3
--- /dev/null
+++ b/RecRoomArchive.Models/API/Players/AugustProfile.cs
@@ -0,0 +1,44 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Players
+{
+ ///
+ /// Extensions of data used in August 2016 Rec Room
+ ///
+ public class AugustProfile : BaseProfile
+ {
+ public AugustProfile(BaseProfile baseProfile)
+ {
+ Id = baseProfile.Id;
+ Username = baseProfile.Username;
+ DisplayName = baseProfile.DisplayName;
+ XP = baseProfile.XP;
+ Level = baseProfile.Level;
+ Reputation = baseProfile.Reputation;
+ Developer = baseProfile.Developer;
+ Bio = baseProfile.Bio;
+ RegistrationStatus = baseProfile.RegistrationStatus;
+ CanReceiveInvites = baseProfile.CanReceiveInvites;
+ ProfileImageName = baseProfile.ProfileImageName;
+ JuniorProfile = baseProfile.JuniorProfile;
+ ForceJuniorImages = baseProfile.ForceJuniorImages;
+ PendingJunior = baseProfile.PendingJunior;
+ HasBirthday = baseProfile.HasBirthday;
+ HasEmail = baseProfile.HasEmail;
+ AvoidJuniors = baseProfile.AvoidJuniors;
+ }
+
+ ///
+ /// Used in early versions of Rec Room from 2016 as the players DisplayName
+ ///
+ [JsonPropertyName(name: "Name")] public string Name => DisplayName;
+ ///
+ /// The SteamID of the local player, used in 2016
+ ///
+ [JsonPropertyName(name: "SteamID")] public ulong SteamID { get; set; }
+ ///
+ /// The..gender?? of the local player, this isn't used by Rec Room at all so I'm guessing whoever made their webmanager just added this to add it
+ ///
+ [JsonPropertyName(name: "Gender")] public string Gender { get; set; } = string.Empty;
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Players/BaseProfile.cs b/RecRoomArchive.Models/API/Players/BaseProfile.cs
new file mode 100644
index 0000000..9485096
--- /dev/null
+++ b/RecRoomArchive.Models/API/Players/BaseProfile.cs
@@ -0,0 +1,84 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Players
+{
+ ///
+ /// The profile of the player from 2016-2019
+ ///
+ public class BaseProfile
+ {
+ ///
+ /// The unique id of the player
+ ///
+ [JsonPropertyName(name: "Id")] public ulong Id { get; set; }
+ ///
+ /// The username of the player. This usually doesn't show up in game until around 2017...
+ ///
+ [JsonPropertyName(name: "Username")] public string Username { get; set; } = string.Empty;
+ ///
+ /// The display name of the player, this is what's most commonly used in game and is seen on the players nametag
+ ///
+ [JsonPropertyName(name: "DisplayName")] public string DisplayName { get; set; } = string.Empty;
+ ///
+ /// The XP of the player, this determines how much XP is required until the next level up but because this is a local server, who gaf
+ ///
+ [JsonPropertyName(name: "XP")] public int XP { get; set; } = 0;
+ ///
+ /// The level of the player, usually in a range from 1-30 or 1-50 depending on your time period
+ ///
+ [JsonPropertyName(name: "Level")] public int Level { get; set; } = 1;
+ ///
+ /// The internal reputation of the player, reputation works in mysterious ways so I'm not too sure about this one...
+ ///
+ [JsonPropertyName(name: "Reputation")] public float Reputation { get; set; } = 1.0f;
+ ///
+ /// If the player has a verified email on their Rec Room account (which they always will)
+ ///
+ [JsonPropertyName(name: "Verified")] public bool Verified => RegistrationStatus == RegistrationStatus.Registered;
+ ///
+ /// If the player is a developer of Rec Room (they always will be)
+ ///
+ [JsonPropertyName(name: "Developer")] public bool Developer { get; set; } = true;
+
+ ///
+ /// The bio of the player, I need to find what build this is added in so I can add it to its model...
+ ///
+ [JsonPropertyName(name: "Bio")] public string Bio { get; set; } = string.Empty;
+ ///
+ /// The registration status of the player, determined by if they have an email
+ ///
+ [JsonPropertyName(name: "RegistrationStatus")] public RegistrationStatus RegistrationStatus { get; set; } = RegistrationStatus.Registered;
+ ///
+ /// If the local player is allowed to recieve invites (junior restriction?)
+ ///
+ [JsonPropertyName(name: "CanReceiveInvites")] public bool CanReceiveInvites { get; set; } = true;
+ ///
+ /// The image name of the player
+ ///
+ [JsonPropertyName(name: "ProfileImageName")] public string ProfileImageName { get; set; } = "DefaultProfileImage";
+ ///
+ /// If the player is allowed to recieve invites (junior restriction?)
+ ///
+ [JsonPropertyName(name: "JuniorProfile")] public bool JuniorProfile { get; set; } = false;
+ ///
+ /// If the player is forced to only see alt images like a junior player
+ ///
+ [JsonPropertyName(name: "ForceJuniorImages")] public bool ForceJuniorImages { get; set; } = false;
+ ///
+ /// If the player is about to become a junior
+ ///
+ [JsonPropertyName(name: "PendingJunior")] public bool PendingJunior { get; set; } = false;
+ ///
+ /// If the player has a birthday on their account
+ ///
+ [JsonPropertyName(name: "HasBirthday")] public bool HasBirthday { get; set; } = true;
+ ///
+ /// If the player has an email on their account
+ ///
+ [JsonPropertyName(name: "HasEmail")] public bool HasEmail { get; set; } = true;
+ ///
+ /// If the player perfers to not matchmake with junior players, can be null
+ ///
+ [JsonIgnore(Condition = JsonIgnoreCondition.WhenWritingNull), JsonPropertyName(name: "AvoidJuniors")] public bool? AvoidJuniors { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Players/BlockDurationDTO.cs b/RecRoomArchive.Models/API/Players/BlockDurationDTO.cs
new file mode 100644
index 0000000..2860587
--- /dev/null
+++ b/RecRoomArchive.Models/API/Players/BlockDurationDTO.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Players
+{
+ public class BlockDurationDTO
+ {
+ [JsonPropertyName(name: "BlockedDuration")] public int BlockedDuration { get; set; } = 0;
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Players/PhoneNumberDTO.cs b/RecRoomArchive.Models/API/Players/PhoneNumberDTO.cs
new file mode 100644
index 0000000..7d40354
--- /dev/null
+++ b/RecRoomArchive.Models/API/Players/PhoneNumberDTO.cs
@@ -0,0 +1,9 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Players
+{
+ public class PhoneNumberDTO
+ {
+ [JsonPropertyName(name: "PhoneNumber")] public string PhoneNumber { get; set; } = string.Empty;
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Players/RegistrationStatus.cs b/RecRoomArchive.Models/API/Players/RegistrationStatus.cs
new file mode 100644
index 0000000..06a1fef
--- /dev/null
+++ b/RecRoomArchive.Models/API/Players/RegistrationStatus.cs
@@ -0,0 +1,21 @@
+namespace RecRoomArchive.Models.API.Players
+{
+ ///
+ /// The status of the players registration to Rec Room
+ ///
+ public enum RegistrationStatus
+ {
+ ///
+ /// This player has no email entered for Rec Room and may be prompted to enter one
+ ///
+ Unregistered,
+ ///
+ /// This player has a pending email from Rec Room that they have not accepted yet
+ ///
+ PendingEmailVerification,
+ ///
+ /// This player has a verified Rec Room Profile!
+ ///
+ Registered
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/API/Setting/Setting.cs b/RecRoomArchive.Models/API/Setting/Setting.cs
new file mode 100644
index 0000000..0990676
--- /dev/null
+++ b/RecRoomArchive.Models/API/Setting/Setting.cs
@@ -0,0 +1,19 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.API.Setting
+{
+ ///
+ /// The players local settings and preferences
+ ///
+ public class Setting
+ {
+ ///
+ /// The key of the setting (ex: DebugGuiEnabled)
+ ///
+ [JsonPropertyName(name: "Key")] public required string Key { get; set; }
+ ///
+ /// The value related to the key (ex: true)
+ ///
+ [JsonPropertyName(name: "Value")] public required string Value { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/Common/OkResponse.cs b/RecRoomArchive.Models/Common/OkResponse.cs
new file mode 100644
index 0000000..dfca52c
--- /dev/null
+++ b/RecRoomArchive.Models/Common/OkResponse.cs
@@ -0,0 +1,13 @@
+using System.Text.Json.Serialization;
+
+namespace RecRoomArchive.Models.Common
+{
+ public class OkResponse
+ {
+ public static OkResponse Ok(string? message = null) => new() { Success = true, Message = message };
+ public static OkResponse Fail(string message) => new() { Success = false, Message = message };
+
+ [JsonPropertyName("Success")] public bool Success { get; set; }
+ [JsonPropertyName("Message")] public string? Message { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive.Models/RecRoomArchive.Models.csproj b/RecRoomArchive.Models/RecRoomArchive.Models.csproj
new file mode 100644
index 0000000..b760144
--- /dev/null
+++ b/RecRoomArchive.Models/RecRoomArchive.Models.csproj
@@ -0,0 +1,9 @@
+
+
+
+ net10.0
+ enable
+ enable
+
+
+
diff --git a/RecRoomArchive.slnx b/RecRoomArchive.slnx
new file mode 100644
index 0000000..c90c7a0
--- /dev/null
+++ b/RecRoomArchive.slnx
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/RecRoomArchive/Controllers/API/Activities/Charades/V1/ActivitiesController.cs b/RecRoomArchive/Controllers/API/Activities/Charades/V1/ActivitiesController.cs
new file mode 100644
index 0000000..1e4b912
--- /dev/null
+++ b/RecRoomArchive/Controllers/API/Activities/Charades/V1/ActivitiesController.cs
@@ -0,0 +1,18 @@
+using Microsoft.AspNetCore.Mvc;
+using RecRoomArchive.Models.API.Activities;
+using RecRoomArchive.Services;
+
+namespace RecRoomArchive.Controllers.API.Activities.Charades.V1
+{
+ [Route(template: "api/[controller]/charades/v1")]
+ [ApiController]
+ public class ActivitiesController(MessageOfTheDayService motdService) : ControllerBase
+ {
+ // TODO: Move out of MOTD service
+ [HttpGet(template: "words")]
+ public async Task>> GetCharadesWords()
+ {
+ return Ok(await motdService.GetCharadesWordsList());
+ }
+ }
+}
\ No newline at end of file
diff --git a/RecRoomArchive/Controllers/API/Avatar/V2/AvatarController.cs b/RecRoomArchive/Controllers/API/Avatar/V2/AvatarController.cs
new file mode 100644
index 0000000..13e27d5
--- /dev/null
+++ b/RecRoomArchive/Controllers/API/Avatar/V2/AvatarController.cs
@@ -0,0 +1,41 @@
+using Microsoft.AspNetCore.Mvc;
+using RecRoomArchive.Models.API.Avatar;
+using RecRoomArchive.Services;
+using System.Text.Json;
+
+namespace RecRoomArchive.Controllers.API.Avatar.V2
+{
+ [Route(template: "api/[controller]/v2")]
+ [ApiController]
+ public class AvatarController(FileService fileService) : ControllerBase
+ {
+ [HttpGet]
+ public async Task> GetAvatar()
+ {
+ var avatarData = fileService.GetData("avatar.json");
+
+ if (string.IsNullOrWhiteSpace(avatarData))
+ {
+ var baseAvatar = new PlayerAvatar();
+ fileService.SetData("avatar.json", JsonSerializer.Serialize(baseAvatar));
+ return Ok(baseAvatar);
+ }
+
+ var avatar = JsonSerializer.Deserialize(avatarData);
+ return Ok(avatar);
+ }
+
+ [HttpGet(template: "gifts")]
+ public async Task>> GetPendingGifts()
+ {
+ return Ok(new List