the files
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
namespace Campus_live_rewrite.api.server.Classes.db_class
|
||||
{
|
||||
public class ChatDBClasses
|
||||
{
|
||||
public class ChatThread
|
||||
{
|
||||
public List<ChatMessage> Messages { get; set; }
|
||||
public long ChatThreadId { get; set; }
|
||||
public List<ulong> PlayerIds { get; set; }
|
||||
public long LastReadMessageId { get; set; }
|
||||
public string ChatThreadName { get; set; }
|
||||
public DateTime? SnoozedUntil { get; set; }
|
||||
public bool IsFavorited { get; set; }
|
||||
|
||||
// 0 = a normal DM / group thread, 1 = a PARTY thread (the party's chat; the client
|
||||
// finds it through /chat/thread/party and shows it in-room).
|
||||
public int ChatThreadType { get; set; } = 0;
|
||||
// Per-member read pointer / snooze / favorite. These are PER PLAYER in the real
|
||||
// service; the three thread-level fields above are the pre-existing shared ones and
|
||||
// are only read when a player has no entry here yet.
|
||||
public Dictionary<string, ChatMemberState> MemberStates { get; set; } = new();
|
||||
// Who created the party thread (party leader) - only meaningful for ChatThreadType 1.
|
||||
public ulong CreatorPlayerId { get; set; }
|
||||
// Nullable on purpose: a thread stored before these existed deserialises with null
|
||||
// (an initialiser would stamp "now" on every old thread and sort them above new ones).
|
||||
public DateTime? CreatedAt { get; set; }
|
||||
public DateTime? LastActivityAt { get; set; }
|
||||
}
|
||||
|
||||
public class ChatMemberState
|
||||
{
|
||||
public long LastReadMessageId { get; set; }
|
||||
public DateTime? SnoozedUntil { get; set; }
|
||||
public bool IsFavorited { get; set; }
|
||||
}
|
||||
|
||||
public class ChatMessage
|
||||
{
|
||||
public long ChatMessageId { get; set; }
|
||||
public long ChatThreadId { get; set; }
|
||||
public int SenderPlayerId { get; set; }
|
||||
public DateTime TimeSent { get; set; }
|
||||
public string Contents { get; set; }
|
||||
public int ModerationState { get; set; } // todo find the enum
|
||||
}
|
||||
|
||||
public class MessageJson
|
||||
{
|
||||
public MessageContentType Type { get; set; }
|
||||
public int Version { get; set; } // default ver is 2
|
||||
public string Data { get; set; }
|
||||
}
|
||||
|
||||
public struct SendMessageResponse
|
||||
{
|
||||
public ChatResults ChatResult { get; set; }
|
||||
public ChatThread ChatThread { get; set; }
|
||||
}
|
||||
|
||||
public class ChatPrivacySettings
|
||||
{
|
||||
public ulong playerId { get; set; }
|
||||
public ChatPrivacy directMessagePrivacySetting { get; set; } = ChatPrivacy.Friends;
|
||||
public ChatPrivacy groupChatPrivacySetting { get; set; } = ChatPrivacy.Friends;
|
||||
}
|
||||
|
||||
public enum ChatResults
|
||||
{
|
||||
Success,
|
||||
InvalidArguments,
|
||||
ThreadNotFound,
|
||||
MembershipNotFound,
|
||||
PlayerAlreadyOnThread,
|
||||
CannotMessagePlayer,
|
||||
InvalidCharacters,
|
||||
RecentlyLeftThread,
|
||||
ThreadTooLarge
|
||||
}
|
||||
|
||||
public enum ModerationState : byte
|
||||
{
|
||||
Active,
|
||||
Junior_Pending = 11,
|
||||
Moderation_Pending = 100,
|
||||
Moderation_Closed,
|
||||
Moderation_Banned,
|
||||
MarkedForDelete = 255
|
||||
}
|
||||
|
||||
public enum QueryMode
|
||||
{
|
||||
Latest,
|
||||
NewerThan,
|
||||
OlderThan
|
||||
}
|
||||
|
||||
public enum MessageContentType
|
||||
{
|
||||
Text,
|
||||
PartyInvite,
|
||||
Photo
|
||||
}
|
||||
|
||||
public enum ChatPrivacy
|
||||
{
|
||||
Friends,
|
||||
Favorites,
|
||||
NoOne
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Campus_live_rewrite.api.server.Classes.db_class
|
||||
{
|
||||
public class ClubDBClasses
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
using LiteDB;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
|
||||
namespace Campus_live_rewrite.api.server.Classes.db_class
|
||||
{
|
||||
public class EventDBClasses
|
||||
{
|
||||
public class CreateEventRequest
|
||||
{
|
||||
// {"RoomId":708,"SubRoomId":1444,"ClubId":null,"name":"awdadwdawdadwdawdadwd","Description":"awdadwdawdadwdawdadwdawdadwdawdadwdawdadwdawdadwdawdadwdawdadwdawdadwd","Tags":["grandopening"],"ImageName":"J9W8A0FUGWXG4CMBKFDJ46CUZHJOHP.png","StartTime":"2025-12-13T14:20:41.6244242Z","EndTime":"2025-12-13T14:50:41.6244242Z","Accessibility":1,"IsMultiInstance":false,"SupportMultiInstanceRoomChat":false,"DefaultBroadcastPermissions":0,"CanRequestBroadcastPermissions":0}
|
||||
public ulong RoomId { get; set; }
|
||||
public ulong? SubRoomId { get; set; }
|
||||
public ulong? ClubId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public List<string>? Tags { get; set; }
|
||||
public string? ImageName { get; set; }
|
||||
public DateTime StartTime { get; set; }
|
||||
public DateTime EndTime { get; set; }
|
||||
public PlayerEventAccessibility Accessibility { get; set; }
|
||||
public bool IsMultiInstance { get; set; } // this is just multi instance room
|
||||
public bool SupportMultiInstanceRoomChat { get; set; } // this let player talk betweeen room instance using room chat
|
||||
public int DefaultBroadcastPermissions { get; set; } // idk what this is used for
|
||||
public int CanRequestBroadcastPermissions { get; set; } // idk what this is used for
|
||||
}
|
||||
|
||||
public class FullPlayerEvent
|
||||
{
|
||||
public List<FullTag>? Tags { get; set; }
|
||||
public List<FullEventResponses>? Responses { get; set; }
|
||||
[BsonId]
|
||||
public ulong PlayerEventId { get; set; }
|
||||
public ulong? CreatorPlayerId { get; set; }
|
||||
public string? ImageName { get; set; }
|
||||
public ulong RoomId { get; set; }
|
||||
public ulong? SubRoomId { get; set; }
|
||||
public ulong? ClubId { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public DateTime StartTime { get; set; }
|
||||
public DateTime EndTime { get; set; }
|
||||
public int AttendeeCount { get; set; }
|
||||
public int State { get; set; }
|
||||
public PlayerEventAccessibility Accessibility { get; set; }
|
||||
public bool IsMultiInstance { get; set; } // this is just multi instance room
|
||||
public bool SupportMultiInstanceRoomChat { get; set; } // this let player talk betweeen room instance using room chat
|
||||
public BroadcastPermissionsEnum DefaultBroadcastPermissions { get; set; } // idk what this is used for
|
||||
public BroadcastPermissionsEnum CanRequestBroadcastPermissions { get; set; } // idk what this is used for
|
||||
public ulong BroadcastingRoomInstanceId { get; set; }
|
||||
public DateTime? RecurrenceSchedule { get; set; }
|
||||
}
|
||||
|
||||
public class FullTag
|
||||
{
|
||||
public string? Tag { get; set; }
|
||||
public TagType Type { get; set; }
|
||||
}
|
||||
|
||||
public class FullEventResponses
|
||||
{
|
||||
public ulong PlayerEventResponseId { get; set; }
|
||||
public ulong PlayerEventId { get; set; }
|
||||
public ulong PlayerId { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public PlayerEventResponseType Type { get; set; } = PlayerEventResponseType.None;
|
||||
}
|
||||
|
||||
public enum PlayerEventResponseType
|
||||
{
|
||||
None = -1,
|
||||
Yes,
|
||||
Interested,
|
||||
No,
|
||||
Pending
|
||||
}
|
||||
|
||||
public enum BroadcastPermissionsEnum
|
||||
{
|
||||
None,
|
||||
RoomOwners = 256,
|
||||
All = 2147483647
|
||||
}
|
||||
|
||||
public enum PlayerEventAccessibility
|
||||
{
|
||||
Private,
|
||||
Public,
|
||||
Unlisted
|
||||
}
|
||||
|
||||
public enum TagType
|
||||
{
|
||||
Unknown1 = 0,
|
||||
Unknown2 = 1,
|
||||
Unknown3 = 2
|
||||
}
|
||||
|
||||
public enum EventResults
|
||||
{
|
||||
Success,
|
||||
HasModeratorClosedEvent,
|
||||
DoesNotExist,
|
||||
PlayerDoesNotExist,
|
||||
RoomDoesNotExist,
|
||||
StatusUnchanged,
|
||||
PrivateEvent,
|
||||
SomethingWentWrong,
|
||||
DoesNotOwnRoom,
|
||||
ResponseDoesNotExist,
|
||||
PlayerAlreadyInvited,
|
||||
EventDatesInvalid,
|
||||
EventTooLong,
|
||||
EventTooShort,
|
||||
InappropriateName,
|
||||
InappropriateDescription,
|
||||
SomeInvitesFailed,
|
||||
CannotInviteJunior,
|
||||
EventCountLimitReached,
|
||||
DoesNotOwnEvent,
|
||||
UnregisteredOrJuniorNotAllowed,
|
||||
InvalidClubPermissions,
|
||||
ImageDoesNotExist,
|
||||
SubRoomDoesNotExist,
|
||||
DoesNotOwnSubRoom,
|
||||
ModifyTagsFailed,
|
||||
RoomCapacityTooLow,
|
||||
BroadcastEventNotMultiInstance,
|
||||
PlayerNotAllowedToCreateMultiInstanceEvents,
|
||||
PlayerBannedFromEventCreation,
|
||||
EventIsModerationClosed,
|
||||
EventIsModerationPendingReview
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
using System;
|
||||
using LiteDB;
|
||||
|
||||
namespace Campus_live_rewrite.api.server.Classes.db_class
|
||||
{
|
||||
public class YourFriendData
|
||||
{
|
||||
[BsonId]
|
||||
public ObjectId? Id { get; set; }
|
||||
public ulong PlayerID { get; set; }
|
||||
public RelationshipDetail Relationship { get; set; }
|
||||
}
|
||||
|
||||
public class FriendData
|
||||
{
|
||||
[BsonId]
|
||||
public ObjectId? Id { get; set; }
|
||||
public string? FriendId { get; set; }
|
||||
public RelationshipType Relationship { get; set; }
|
||||
public FriendInfo FriendFlags { get; set; }
|
||||
public ReciprocalStatus Status { get; set; }
|
||||
}
|
||||
|
||||
public class RelationshipDetail
|
||||
{
|
||||
public ulong Id { get; set; }
|
||||
public ulong PlayerID { get; set; }
|
||||
public ulong OtherPlayerID { get; set; }
|
||||
public RelationshipType RelationshipType { get; set; }
|
||||
public ReciprocalStatus Muted { get; set; }
|
||||
public ReciprocalStatus Ignored { get; set; }
|
||||
public ReciprocalStatus Favorited { get; set; }
|
||||
public int VoiceVolume { get; set; } = 100;
|
||||
}
|
||||
|
||||
public enum RelationshipType
|
||||
{
|
||||
None,
|
||||
FriendRequestSent,
|
||||
FriendRequestReceived,
|
||||
Friend,
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum FriendInfo
|
||||
{
|
||||
None = 0,
|
||||
Favorited = 1,
|
||||
Muted = 2,
|
||||
Ignored = 4,
|
||||
Blocked = 5
|
||||
}
|
||||
|
||||
public enum ReciprocalStatus
|
||||
{
|
||||
None,
|
||||
Local,
|
||||
Remote,
|
||||
Mutual
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace Campus_live_rewrite.api.server.Classes.db_class
|
||||
{
|
||||
public class LeaderboardDBClasses
|
||||
{
|
||||
public class GetNearbyScoresRequest
|
||||
{
|
||||
// {"PlayerId":2,"StatChannel":2,"RoomId":29,"FilterType":1,"SortAscending":false,"WindowSize":10}
|
||||
public ulong PlayerId { get; set; }
|
||||
public int StatChannel { get; set; }
|
||||
public ulong RoomId { get; set; }
|
||||
public FilterTypeEnum FilterType { get; set; }
|
||||
public bool SortAscending { get; set; }
|
||||
public int WindowSize { get; set; }
|
||||
}
|
||||
|
||||
public class GetRanksRequest
|
||||
{
|
||||
// {"PlayerId":2,"StatChannel":2,"RoomId":29,"FilterType":0,"SortAscending":false,"RankStart":0,"RankEnd":9}
|
||||
public ulong PlayerId { get; set; }
|
||||
public int StatChannel { get; set; }
|
||||
public ulong RoomId { get; set; }
|
||||
public FilterTypeEnum FilterType { get; set; }
|
||||
public bool SortAscending { get; set; }
|
||||
public int RankStart { get; set; } // skip
|
||||
public int RankEnd { get; set; } // take
|
||||
}
|
||||
|
||||
public class CheckAndSetStatRequest
|
||||
{
|
||||
// {"StatChannel":2,"RoomId":29,"StatValue":1,"CurrentStatValue":null}
|
||||
public int StatChannel { get; set; }
|
||||
public ulong RoomId { get; set; }
|
||||
public int StatValue { get; set; }
|
||||
public int? CurrentStatValue { get; set; }
|
||||
}
|
||||
|
||||
public class Entry
|
||||
{
|
||||
[Newtonsoft.Json.JsonIgnore] // serialized with Newtonsoft (JsonConvert); STJ's JsonIgnore is ignored there and leaked Id/StatChannel/RoomId
|
||||
public int Id { get; set; } // LiteDB PK
|
||||
|
||||
public int PlayerId { get; set; }
|
||||
[Newtonsoft.Json.JsonIgnore] // serialized with Newtonsoft (JsonConvert); STJ's JsonIgnore is ignored there and leaked Id/StatChannel/RoomId
|
||||
public int StatChannel { get; set; }
|
||||
[Newtonsoft.Json.JsonIgnore] // serialized with Newtonsoft (JsonConvert); STJ's JsonIgnore is ignored there and leaked Id/StatChannel/RoomId
|
||||
public long RoomId { get; set; }
|
||||
|
||||
public int Score { get; set; }
|
||||
public int Rank { get; set; }
|
||||
|
||||
// LeaderboardGuard bookkeeping. Not on the wire.
|
||||
[Newtonsoft.Json.JsonIgnore] public DateTime UpdatedAt { get; set; }
|
||||
[Newtonsoft.Json.JsonIgnore] public DateTime DayGainDate { get; set; }
|
||||
[Newtonsoft.Json.JsonIgnore] public long DayGain { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class SingleLeaderboard
|
||||
{
|
||||
public List<Entry> Rows { get; set; }
|
||||
}
|
||||
|
||||
public class FullLeaderboard
|
||||
{
|
||||
public List<Entry> GlobalOverall { get; set; }
|
||||
public List<Entry> GlobalPeriodic { get; set; }
|
||||
public List<Entry> FriendsOverall { get; set; }
|
||||
public List<Entry> FriendsPeriodic { get; set; }
|
||||
public DateTime NextResetUTC { get; set; }
|
||||
}
|
||||
|
||||
public enum RequestResult
|
||||
{
|
||||
Success,
|
||||
InvalidStat,
|
||||
RedisConnectionError
|
||||
}
|
||||
|
||||
public enum FilterType
|
||||
{
|
||||
Global,
|
||||
Friends
|
||||
}
|
||||
|
||||
public enum Timeframe
|
||||
{
|
||||
AllTime,
|
||||
TwoWeeks
|
||||
}
|
||||
|
||||
public enum FilterTypeEnum
|
||||
{
|
||||
NearbyScoresGlobal,
|
||||
NearbyScoresFriends,
|
||||
Champions,
|
||||
NUM_VALUES // wat
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,562 @@
|
||||
using System;
|
||||
using System.Text.Json.Serialization;
|
||||
using LiteDB;
|
||||
|
||||
namespace Campus_live_rewrite.api.server.Classes.db_class
|
||||
{
|
||||
public class account_data
|
||||
{
|
||||
[JsonPropertyOrder(1)]
|
||||
public ulong accountId { get; set; }
|
||||
[JsonPropertyOrder(2)]
|
||||
public string? username { get; set; }
|
||||
[JsonPropertyOrder(3)]
|
||||
public string? displayName { get; set; }
|
||||
[JsonPropertyOrder(4)]
|
||||
public string? profileImage { get; set; }
|
||||
[JsonPropertyOrder(5)]
|
||||
public bool? isJunior { get; set; }
|
||||
[JsonPropertyOrder(6)]
|
||||
public long platforms { get; set; }
|
||||
[JsonPropertyOrder(7)]
|
||||
public long personalPronouns { get; set; }
|
||||
[JsonPropertyOrder(8)]
|
||||
public long identityFlags { get; set; }
|
||||
[JsonPropertyOrder(9)]
|
||||
public DateTime createdAt { get; set; }
|
||||
[JsonPropertyOrder(10)]
|
||||
public bool isMetaPlatformBlocked { get; set; } = false;
|
||||
}
|
||||
public class setting_data
|
||||
{
|
||||
public ulong accountId { get; set; }
|
||||
public string Key { get; set; }
|
||||
public string Val { get; set; }
|
||||
}
|
||||
|
||||
public class player_data
|
||||
{
|
||||
public ulong id { get; set; }
|
||||
public ulong playerid { get; set; }
|
||||
public Platforms platform { get; set; }
|
||||
public List<string>? deviceId { get; set; }
|
||||
// Device bindings WITH the platform each was seen on. The flat deviceId list above stays
|
||||
// the source of truth for the anti-alt "one account per device" check; this parallel list
|
||||
// adds the platform so the account lock can enforce "one PC + one Quest headset" (see
|
||||
// AccountLock.TryEnforceAndBind). Null on legacy rows; populated lazily on next login.
|
||||
public List<mDeviceBind>? DeviceBindings { get; set; }
|
||||
// Where the account was made: true = in-game (the client's first-launch create_account),
|
||||
// false = the website. Null on rows older than the flag - see PlayerDB.OriginOf for how
|
||||
// those are classified. Drives the one-game-account-plus-one-website-account-per-device
|
||||
// rule (ConfigCampus.MaxAccountsPerDevice / AccountLock.CanShareSlot).
|
||||
public bool? CreatedInGame { get; set; }
|
||||
public string? authtoken { get; set; }
|
||||
public string? password { get; set; }
|
||||
public player_info? player { get; set; }
|
||||
public player_extra? player_Extra { get; set; }
|
||||
public DevFlag dev_Flag { get; set; }
|
||||
}
|
||||
|
||||
public enum Platforms
|
||||
{
|
||||
All = -1,
|
||||
Steam,
|
||||
Oculus,
|
||||
PlayStation,
|
||||
Xbox,
|
||||
RecNet,
|
||||
IOS,
|
||||
GooglePlay,
|
||||
Standalone
|
||||
}
|
||||
|
||||
public class player_extra
|
||||
{
|
||||
// Equipment skins this player owns, as "PrefabName|ModificationGuid". Null = none (the
|
||||
// tools' default looks). Devs ignore this and get the whole catalog (the dev locker).
|
||||
public List<string>? EquipmentSkins { get; set; }
|
||||
|
||||
public ulong? DormRoomID { get; set; }
|
||||
public List<string>? IpAddresses { get; set; }
|
||||
public ulong DiscordId { get; set; }
|
||||
// The linked Discord user's tag/username, stored purely so the website Settings > Discord
|
||||
// tab can show "Linked as <name>" instead of a bare numeric id. Set by the /link bot flow.
|
||||
public string? DiscordUsername { get; set; }
|
||||
// Name lock (admin panel > Edit Player). While true the player cannot change their own
|
||||
// @name or display name - in-game, on the website, or through the first-run onboarding
|
||||
// path. Admin edits still go through. Absent/false on every existing record.
|
||||
public bool NameLocked { get; set; }
|
||||
// Moderator locks on the rest of the profile (admin panel, Edit Player): the player can't
|
||||
// change it themselves - in-game, on the website or through the Discord bot. Admin edits
|
||||
// are never gated. See PlayerDB.IsProfileLocked.
|
||||
public bool BioLocked { get; set; }
|
||||
public bool PictureLocked { get; set; }
|
||||
public bool BannerLocked { get; set; }
|
||||
public string? Bio { get; set; }
|
||||
public string? avatar { get; set; }
|
||||
public List<avatar_data_saved>? SavedOutfits { get; set; }
|
||||
public Moderation_Detail.ModerationBlockDetails? ModerationBlockDetails { get; set; }
|
||||
// MIC BAN (token claim rn.privilege BanVChat - see PlayerDB "MIC BAN / ROOM-CHAT BAN").
|
||||
// Kept apart from ModerationBlockDetails so it never overwrites a real ban/kick (or the
|
||||
// reverse) and never counts as "banned" for login/matchmaking.
|
||||
public Moderation_Detail.ModerationBlockDetails? VoiceBan { get; set; }
|
||||
public List<ulong>? CheeredRooms { get; set; }
|
||||
public List<ulong>? FavoritedRooms { get; set; }
|
||||
// Last time each once-per-day game reward was claimed, keyed by reward type name.
|
||||
// Stored as a UTC date string (yyyy-MM-dd) so "already claimed today" is a plain
|
||||
// string compare and cannot drift with timezones.
|
||||
public Dictionary<string, string> DailyRewardClaims { get; set; } = new();
|
||||
|
||||
// Gift boxes waiting to be opened. Served by /api/avatar/v2/gifts.
|
||||
public List<PendingGiftBox> PendingGiftBoxes { get; set; } = new();
|
||||
|
||||
// Avatar items this account actually OWNS, as raw AvatarItemDesc strings.
|
||||
//
|
||||
// Until this existed /api/avatar/v4/items handed the entire 3061-item catalog to
|
||||
// everyone, so every account owned every item. Non-developers now start from
|
||||
// Data/APIS/items/DefaultAvatarItems.json and earn the rest; developers keep the
|
||||
// full catalog (the dev locker). See PlayerDB.OwnedAvatarItemDescs.
|
||||
//
|
||||
// null means "never granted the starter set" - distinct from an empty list, which
|
||||
// would mean a player who somehow owns nothing. The grant is lazy on first read so
|
||||
// existing accounts do not need a migration pass.
|
||||
public List<string>? AvatarItems { get; set; }
|
||||
/// <summary>Custom avatar items (UGC) this player bought or was gifted - the ids.</summary>
|
||||
public List<string>? CustomItems { get; set; }
|
||||
// Consumables the player owns: ConsumableItemDesc -> count left. Filled by gift boxes /
|
||||
// store buys; /api/consumables/v2/getUnlocked lists only these (devs keep the whole file).
|
||||
public Dictionary<string, int>? Consumables { get; set; }
|
||||
|
||||
// Per-currency balances, keyed by CurrencyType (see api/server/Classes/CurrencyType.cs):
|
||||
// 1=LaserTagTickets, 2=RecCenterTokens, 100=LostSkullsGold, 101=DraculaSilver,
|
||||
// 300=RoomCurrency, 500=RoomieCredits, etc. Value is the amount held.
|
||||
// Persisted with the rest of player_extra, so balances survive restarts.
|
||||
public Dictionary<int, long> Balances { get; set; } = new();
|
||||
|
||||
// ---- Quests / rewards progress (see APIController objectives + challenge, RewardsDB) ----
|
||||
// Daily objectives: the client owns the objective CATALOG (what Group/Index means, its
|
||||
// target and reward); the server only stores per-(Group,Index) progress numbers and a
|
||||
// once-only reward latch. Weekly challenges: only completion flags per (map,challenge),
|
||||
// plus which challenge maps have already paid their gift.
|
||||
public List<ObjectiveProgress> Objectives { get; set; } = new();
|
||||
public List<ObjectiveGroupProgress> ObjectiveGroups { get; set; } = new();
|
||||
public List<ChallengeStatus> ChallengeStatuses { get; set; } = new();
|
||||
public List<int> ClaimedChallengeMaps { get; set; } = new();
|
||||
|
||||
public int sub_count { get; set; } = 0;
|
||||
public List<ulong> SubbedTo { get; set; } = new();
|
||||
public bool IsRecentRoomHistoryVisible { get; set; } = true;
|
||||
public Influencer? Influencer { get; set; }
|
||||
public CustomAvatarItems CustomAvatarItems { get; set; } = new CustomAvatarItems();
|
||||
public MyRoomData MyRoomData { get; set; } = new MyRoomData();
|
||||
public List<MessageData>? Messages { get; set; }
|
||||
public PlayerPhotoTaggingSetting PlayerPhotoTaggingSetting { get; set; } = PlayerPhotoTaggingSetting.Anyone;
|
||||
|
||||
}
|
||||
|
||||
public enum PlayerPhotoTaggingSetting
|
||||
{
|
||||
Anyone,
|
||||
Friends,
|
||||
NoOne
|
||||
}
|
||||
|
||||
public class SetPlayerPhotoTaggingSettingRequest
|
||||
{
|
||||
public PlayerPhotoTaggingSetting Setting { get; set; }
|
||||
}
|
||||
|
||||
public class MyRoomData
|
||||
{
|
||||
public List<string> owned_room_keys { get; set; } = new List<string>();
|
||||
public List<PlayerData> PlayerData { get; set; } = new List<PlayerData>();
|
||||
public List<My_Room_currencies> Roomcurrencies { get; set; } = new List<My_Room_currencies>();
|
||||
}
|
||||
|
||||
public class PlayerData
|
||||
{
|
||||
public ulong RoomId { get; set; }
|
||||
public string Data { get; set; }
|
||||
}
|
||||
|
||||
public class My_Room_currencies
|
||||
{
|
||||
public long RoomId { get; set; }
|
||||
public string Id { get; set; }
|
||||
public long Value { get; set; }
|
||||
}
|
||||
|
||||
public class SubscribedToEntry
|
||||
{
|
||||
public ulong PlayerId { get; set; }
|
||||
}
|
||||
|
||||
public class avatar_data_saved
|
||||
{
|
||||
public ulong Slot { get; set; }
|
||||
public string? Avatar { get; set; }
|
||||
public string? ImageName { get; set; }
|
||||
|
||||
public List<CustomAvatarItemEntry>? CustomAvatarItems { get; set; }
|
||||
|
||||
public string? FaceFeatures { get; set; }
|
||||
public string? HairColor { get; set; }
|
||||
public string? Name { get; set; }
|
||||
public string? SkinColor { get; set; }
|
||||
public string? OutfitSelections { get; set; }
|
||||
public string? OutfitSelectionsV2 { get; set; }
|
||||
public string? PreviewImageName { get; set; }
|
||||
}
|
||||
|
||||
public class CustomAvatarItemEntry
|
||||
{
|
||||
public string? CustomAvatarItemId { get; set; }
|
||||
public int BodyPart { get; set; }
|
||||
}
|
||||
|
||||
public class avatar_data
|
||||
{
|
||||
public string? OutfitSelections { get; set; }
|
||||
public string? FaceFeatures { get; set; }
|
||||
public string? SkinColor { get; set; }
|
||||
public string? HairColor { get; set; }
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A gift box granted to a player but not yet opened.
|
||||
/// GiftContext identifies which box (4003 Golden, 4503 Jumbotron, ... see
|
||||
/// api/server/Classes/GameRewardType.cs -> GiftContextIds).
|
||||
/// </summary>
|
||||
public class PendingGiftBox
|
||||
{
|
||||
public string Id { get; set; } = System.Guid.NewGuid().ToString();
|
||||
/// <summary>How many of a consumable the box holds (the store row's ItemCount; 1 when unknown).</summary>
|
||||
public int ConsumableCount { get; set; }
|
||||
public int GiftContext { get; set; }
|
||||
public string? Message { get; set; }
|
||||
public ulong FromAccountId { get; set; }
|
||||
public System.DateTime CreatedAt { get; set; } = System.DateTime.UtcNow;
|
||||
public bool Opened { get; set; }
|
||||
|
||||
// Int32-safe numeric id. The client's gift package field is a 32-bit int: a
|
||||
// 13-digit millisecond timestamp overflows it, the package fails to deserialize,
|
||||
// and the box renders the "Update your game" placeholder while the item never
|
||||
// lands live. (Learned by the 2023 server - D:\Puck\Campus-Server.)
|
||||
public int NumericId { get; set; }
|
||||
|
||||
// What the box actually contains, when it came from a store purchase.
|
||||
//
|
||||
// AvatarItemDesc is stored RAW - exactly as the store file writes it, e.g.
|
||||
// "4ee2133d-...,,,". The client parses this as guid,combination,combination,
|
||||
// combination; hand it a bare guid with the empty fields stripped and it cannot
|
||||
// read it, so the item never reaches the locker. 746 of the 968 Watch items use
|
||||
// that trailing-comma form, which is why Laser Tag purchases always worked and
|
||||
// Watch ones did not.
|
||||
public string? AvatarItemDesc { get; set; }
|
||||
public string? ConsumableItemDesc { get; set; }
|
||||
public int AvatarItemType { get; set; }
|
||||
public int GiftDropId { get; set; }
|
||||
public string? FriendlyName { get; set; }
|
||||
public int Rarity { get; set; }
|
||||
public string? EquipmentPrefabName { get; set; }
|
||||
public string? EquipmentModificationGuid { get; set; }
|
||||
/// <summary>A UGC item (custom avatar item id) the box carries - a bought/gifted custom clothing item.</summary>
|
||||
public string? CustomAvatarItemId { get; set; }
|
||||
public bool Anonymous { get; set; }
|
||||
|
||||
// What a NON-item box pays: tokens (a duplicate reward converted, a level-up's token
|
||||
// tier) and/or XP. These are DISPLAY copies - the balance and the XP are banked when the
|
||||
// box is minted, not when it is opened - but the box has to carry them or the gifts list
|
||||
// and the open animation read "0 Tokens" / no XP, which is what players saw.
|
||||
public int CurrencyType { get; set; }
|
||||
public long Currency { get; set; }
|
||||
public int Xp { get; set; }
|
||||
// True = the Currency above is credited when the box is OPENED (consume), so the number
|
||||
// moves as the box pops rather than silently beforehand. False = already credited.
|
||||
public bool PayOnOpen { get; set; }
|
||||
// True = the Xp above is banked when the box is opened (an admin XP box). Game-reward boxes
|
||||
// carry Xp for display only (already banked at pick), so they leave this false.
|
||||
public bool XpOnOpen { get; set; }
|
||||
// Image the box / picker shows for a drop that has no item of its own (the token coin).
|
||||
// A plain file name under Data/Images, served by /img/<name> like a consumable's.
|
||||
public string? ThumbnailImageName { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Per-player progress for one daily objective, keyed by (Group, Index).</summary>
|
||||
public class ObjectiveProgress
|
||||
{
|
||||
public long Group { get; set; }
|
||||
public int Index { get; set; }
|
||||
public double Progress { get; set; }
|
||||
public double VisualProgress { get; set; }
|
||||
public bool IsCompleted { get; set; }
|
||||
// Latches true the first time the objective completes and never unlatches, so a replayed
|
||||
// or double-fired completion only ever pays its reward once.
|
||||
public bool HasClaimedReward { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Per-player state of one objective group.</summary>
|
||||
public class ObjectiveGroupProgress
|
||||
{
|
||||
public long Group { get; set; }
|
||||
public bool IsCompleted { get; set; }
|
||||
public string? ClearedAt { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>Per-player completion of one weekly challenge within a rotation (map).</summary>
|
||||
public class ChallengeStatus
|
||||
{
|
||||
public int ChallengeMapId { get; set; }
|
||||
public int ChallengeId { get; set; }
|
||||
public bool Complete { get; set; }
|
||||
public string? UpdatedAt { get; set; }
|
||||
}
|
||||
|
||||
public class player_info
|
||||
{
|
||||
public ulong Id { get; set; }
|
||||
public string? Username { get; set; }
|
||||
public string? DisplayName { get; set; }
|
||||
|
||||
public string? DisplayEmoji { get; set; }
|
||||
|
||||
public string? Email { get; set; }
|
||||
// ISO-8601 date the player entered at website signup. Used to drive account_data_me.birthday
|
||||
// (the client requires a valid date) and to decide junior status at creation. Null on legacy
|
||||
// accounts, which fall back to the old fixed placeholder date.
|
||||
public string? Birthday { get; set; }
|
||||
public int XP { get; set; }
|
||||
public int Level { get; set; }
|
||||
public int pronounFlags { get; set; }
|
||||
public int identityFlags { get; set; }
|
||||
public bool IsJunior { get; set; }
|
||||
public bool AvoidJuniors { get; set; }
|
||||
public mPlayerReputation? PlayerReputation { get; set; }
|
||||
public List<mPlatformID>? PlatformIds { get; set; }
|
||||
public DateTime created_at { get; set; }
|
||||
public DateTime last_login_time { get; set; }
|
||||
public List<ulong> recent_rooms { get; set; } = new List<ulong>();
|
||||
public string? bannerImage { get; set; }
|
||||
public string? profileImage { get; set; }
|
||||
}
|
||||
|
||||
public class AccountLogin
|
||||
{
|
||||
public DateTime createdAt { get; set; }
|
||||
public DateTime lastLoginTime { get; set; }
|
||||
public ulong accountId { get; set; }
|
||||
public Platforms platform { get; set; }
|
||||
public string? platformId { get; set; }
|
||||
// false = platform ownership is the credential -> the client cached-logs-in with no prompt.
|
||||
// true = no account/link behind this entry -> the client shows the username/password login
|
||||
// screen for it (the reference's FAKE cached-login trick). See AuthController.CachedLogins.
|
||||
public bool requirePassword { get; set; } = false;
|
||||
}
|
||||
|
||||
public class mPlatformID
|
||||
{
|
||||
public Platforms Platform { get; set; }
|
||||
public ulong PlatformId { get; set; }
|
||||
}
|
||||
|
||||
// One device the account has signed in from, plus the platform it signed in on. Used by the
|
||||
// account lock to cap an account at one PC device and one Quest (Oculus) device.
|
||||
public class mDeviceBind
|
||||
{
|
||||
public string? DeviceId { get; set; }
|
||||
public Platforms Platform { get; set; }
|
||||
/// <summary>Last login from this device (UTC). Null on rows written before it was tracked.</summary>
|
||||
public DateTime? LastSeen { get; set; }
|
||||
}
|
||||
|
||||
public class mPlayerReputation
|
||||
{
|
||||
public bool IsCheerful { get; set; }
|
||||
public int Noteriety { get; set; }
|
||||
public int CheerGeneral { get; set; }
|
||||
public int CheerHelpful { get; set; }
|
||||
public int CheerGreatHost { get; set; }
|
||||
public int CheerSportsman { get; set; }
|
||||
public int CheerCreative { get; set; }
|
||||
public int CheerCredit { get; set; }
|
||||
public int SubscriberCount { get; set; }
|
||||
public int SubscribedCount { get; set; }
|
||||
public CheerCategoryEnum SelectedCheer { get; set; }
|
||||
}
|
||||
|
||||
public class DeleteMessagesRequest
|
||||
{
|
||||
public List<ulong> MessageIds { get; set; }
|
||||
}
|
||||
|
||||
// POST /api/messages/v1/sendMultiple body: one message to several recipients.
|
||||
// JSON e.g. {"ToPlayerIds":[205],"Type":20,"Data":""}.
|
||||
public class SendMultipleMessagesRequest
|
||||
{
|
||||
public List<ulong>? ToPlayerIds { get; set; }
|
||||
public int Type { get; set; }
|
||||
public string? Data { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public enum CheerCategoryEnum
|
||||
{
|
||||
None = -1,
|
||||
General = 0,
|
||||
Helpful = 10,
|
||||
Sportmanship = 20,
|
||||
GreatHost = 30,
|
||||
Creative = 40,
|
||||
RecRoomDeveloper = 9000
|
||||
}
|
||||
|
||||
// The PUBLIC account DTO - the backbone of a player's profile.
|
||||
//
|
||||
// Every string here coalesces null -> "" via its setter, so the client NEVER receives a
|
||||
// null (or a missing key) for a string field. RecFlare's account DTO does exactly this on
|
||||
// purpose - it reads these as strings, and a null makes its parser throw, which is why a
|
||||
// profile with no banner / emoji / (rarely) display name would fail to load entirely even
|
||||
// though the account exists. Fixing it on the DTO covers every path that builds one
|
||||
// (account/{id}, account/bulk, account/me, admin) at once.
|
||||
public class account_data_web
|
||||
{
|
||||
private string _displayName = "";
|
||||
private string _displayEmoji = "";
|
||||
private string _profileImage = "DefaultProfileImage.jpg";
|
||||
private string _bannerImage = "";
|
||||
private string _username = "";
|
||||
|
||||
public ulong accountId { get; set; }
|
||||
public DateTime createdAt { get; set; }
|
||||
public string displayName { get => _displayName; set => _displayName = value ?? ""; }
|
||||
public string displayEmoji { get => _displayEmoji; set => _displayEmoji = value ?? ""; }
|
||||
public long identityFlags { get; set; }
|
||||
public bool isJunior { get; set; }
|
||||
public long personalPronouns { get; set; }
|
||||
public long platforms { get; set; }
|
||||
// Unset profile image falls back to "DefaultProfileImage.jpg" (RecFlare's default), not ""
|
||||
// - the client renders whatever name it is handed, and an empty name is a broken image.
|
||||
public string profileImage { get => _profileImage; set => _profileImage = string.IsNullOrEmpty(value) ? "DefaultProfileImage.jpg" : value; }
|
||||
public string bannerImage { get => _bannerImage; set => _bannerImage = value ?? ""; }
|
||||
public string username { get => _username; set => _username = value ?? ""; }
|
||||
}
|
||||
|
||||
// The /account/me (self) DTO. Matches RecFlare's toSelfAccountDto: the public account fields
|
||||
// PLUS email, birthday, availableUsernameChanges. Two rules the reference's tests spell out
|
||||
// and that a strict client parser enforces:
|
||||
// * string fields are "" when unset, never null - a null makes the client's parser throw
|
||||
// (which can leave a screen that reads the full account, like the profile, blank);
|
||||
// * the client reads `availableUsernameChanges` (capital U) and `birthday`. The birthday
|
||||
// just has to be PRESENT and a valid date - "the game client needs this to be set" - so a
|
||||
// fixed old date stands in until real birthdays are stored.
|
||||
public class account_data_me
|
||||
{
|
||||
private string _bannerImage = "";
|
||||
private string _email = "";
|
||||
private string _displayName = "";
|
||||
private string _displayEmoji = "";
|
||||
private string _profileImage = "DefaultProfileImage.jpg";
|
||||
private string _username = "";
|
||||
|
||||
public ulong accountId { get; set; }
|
||||
public int availableUsernameChanges { get; set; } = 3;
|
||||
public string bannerImage { get => _bannerImage; set => _bannerImage = value ?? ""; }
|
||||
public DateTime createdAt { get; set; }
|
||||
public string birthday { get; set; } = "1904-01-01T00:00:00.000Z";
|
||||
public string email { get => _email; set => _email = value ?? ""; }
|
||||
public string displayName { get => _displayName; set => _displayName = value ?? ""; }
|
||||
public string displayEmoji { get => _displayEmoji; set => _displayEmoji = value ?? ""; }
|
||||
public long identityFlags { get; set; }
|
||||
public bool hasBirthday { get; set; } = true;
|
||||
public bool isJunior { get; set; }
|
||||
public long personalPronouns { get; set; }
|
||||
public long platforms { get; set; }
|
||||
public string profileImage { get => _profileImage; set => _profileImage = string.IsNullOrEmpty(value) ? "DefaultProfileImage.jpg" : value; }
|
||||
public bool TreatAsJunior { get; set; } = false;
|
||||
public string username { get => _username; set => _username = value ?? ""; }
|
||||
}
|
||||
|
||||
public class CustomAvatarItems
|
||||
{
|
||||
public bool isCreationAllowedForAccount { get; set; } = true;
|
||||
public bool isCreationEnabled { get; set; } = true;
|
||||
public bool isRenderingEnabled { get; set; } = true;
|
||||
|
||||
public List<string> ownedItems { get; set; } = new List<string>();
|
||||
}
|
||||
|
||||
public class Influencer
|
||||
{
|
||||
public string creatorCode { get; set; } = "";
|
||||
public bool isInfluencer { get; set; } = false;
|
||||
public ulong SupportingInfluencer { get; set; }
|
||||
}
|
||||
|
||||
public class MessageData
|
||||
{
|
||||
/*
|
||||
[
|
||||
{
|
||||
"Id": 15909836337,
|
||||
"FromPlayerId": 64495891,
|
||||
"SentTime": "2025-05-27T11:39:25.12Z",
|
||||
"Type": 200,
|
||||
"Data": "58129955",
|
||||
"RoomId": null,
|
||||
"PlayerEventId": null
|
||||
}
|
||||
]
|
||||
*/
|
||||
public ulong Id { get; set; }
|
||||
public ulong FromPlayerId { get; set; }
|
||||
// The recipient - the reference's game-invite Message includes ToPlayerId; ours omitted it.
|
||||
// Harmless on chat/other messages (0 when unset), present on invites so the client's
|
||||
// invite-message parser has the field it expects.
|
||||
public ulong ToPlayerId { get; set; }
|
||||
public DateTime SentTime { get; set; }
|
||||
public WebsocketEvents.MessageType Type { get; set; }
|
||||
public string? Data { get; set; }
|
||||
public ulong? RoomId { get; set; }
|
||||
public ulong? PlayerEventId { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public enum DeviceClasses
|
||||
{
|
||||
Unknown,
|
||||
VR,
|
||||
Screen,
|
||||
Mobile,
|
||||
VRLow,
|
||||
Quest2
|
||||
}
|
||||
|
||||
public class account_login<T>
|
||||
{
|
||||
public bool success { get; set; }
|
||||
public string? error { get; set; }
|
||||
[JsonIgnore]
|
||||
public ulong accid { get; set; }
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum DevFlag
|
||||
{
|
||||
none = 0,
|
||||
screenshare = 1,
|
||||
dev = 2,
|
||||
mod = 4,
|
||||
owner = 8,
|
||||
junior = 16,
|
||||
keepsake = 32,
|
||||
newly_created_account = 64,
|
||||
restricted_account = 128,
|
||||
support = 256, // website Support staff: can see & manage all support tickets (SiteController.IsStaff)
|
||||
studio = 512, // CampusStudio: may publish recoloured items from the app (StudioController)
|
||||
unused_4 = 1024,
|
||||
unused_5 = 2048,
|
||||
unused_6 = 4096,
|
||||
unused_7 = 8192,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
using LiteDB;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Campus_live_rewrite.api.server.Classes.db_class
|
||||
{
|
||||
public class RoomDBClasses
|
||||
{
|
||||
public class Resultslist<T>
|
||||
{
|
||||
public List<T>? Results { get; set; }
|
||||
public long TotalResults { get; set; }
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum WarningMaskType
|
||||
{
|
||||
None = 0,
|
||||
Scary = 1,
|
||||
Mature = 2,
|
||||
FlashingLights = 4,
|
||||
IntenseMotion = 8,
|
||||
Violence = 16,
|
||||
Custom = 32,
|
||||
Reports = 64
|
||||
}
|
||||
|
||||
/// <summary>Writes JSON null whatever the value is (reads normally).</summary>
|
||||
public class NeverSentToClient : Newtonsoft.Json.JsonConverter
|
||||
{
|
||||
public override bool CanRead => false;
|
||||
public override bool CanConvert(Type objectType) => true;
|
||||
public override void WriteJson(Newtonsoft.Json.JsonWriter writer, object? value, Newtonsoft.Json.JsonSerializer serializer) => writer.WriteNull();
|
||||
public override object? ReadJson(Newtonsoft.Json.JsonReader reader, Type objectType, object? existingValue, Newtonsoft.Json.JsonSerializer serializer) => throw new NotSupportedException();
|
||||
}
|
||||
|
||||
public class RoomRoot
|
||||
{
|
||||
// The UI shows FriendlyName; `Name` is the internal slug (devin1s_MakerRoom_0601).
|
||||
// It is a real key on the client's 44-key Room DTO and was simply absent from ours
|
||||
// (wire-shapes: rooms-contributedby). Computed, never stored.
|
||||
[LiteDB.BsonIgnore]
|
||||
public string FriendlyName => Name ?? "";
|
||||
|
||||
// Live player count, shown on room cards. Nullable on the wire and filled only by the
|
||||
// list endpoints that can afford one presence pass; null = "unknown", which the client
|
||||
// renders as no count rather than zero.
|
||||
[LiteDB.BsonIgnore]
|
||||
public int? CCU { get; set; }
|
||||
|
||||
public RoomDBClasses.RoomAccessibility Accessibility { get; set; }
|
||||
public int AgeRating { get; set; }
|
||||
public bool AutoLocalizeRoom { get; set; }
|
||||
public DateTime? BecameRRStudioRoomAt { get; set; }
|
||||
public bool CloningAllowed { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public ulong CreatorAccountId { get; set; }
|
||||
public string? CurrentSnapshotId { get; set; }
|
||||
public bool NeedsSnapshotId { get; set; }
|
||||
public string CustomWarning { get; set; }
|
||||
public string DataBlob { get; set; }
|
||||
// public string DataBlobHash { get; set; }
|
||||
public string Description { get; set; }
|
||||
public bool DisableMicAutoMute { get; set; }
|
||||
public bool DisableRoomComments { get; set; }
|
||||
public bool EncryptVoiceChat { get; set; }
|
||||
public bool ExcludeFromLists { get; set; }
|
||||
public bool ExcludeFromSearch { get; set; }
|
||||
public string ImageName { get; set; }
|
||||
public bool IsDeveloperOwned { get; set; }
|
||||
// Set from the admin panel's "Dev room" tick (RoomDB.SetDevRoom): it is what keeps IsDeveloperOwned on
|
||||
// a player-made room, because FixPlayerRoomFlags clears that flag at every start. Server-side only.
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
public bool IsDevRoom { get; set; }
|
||||
public bool IsDorm { get; set; }
|
||||
public bool IsJuniorCreated { get; set; }
|
||||
public bool IsPlacePlay { get; set; }
|
||||
public bool IsRRO { get; set; }
|
||||
public bool IsRecRoomApproved { get; set; }
|
||||
public bool LoadScreenLocked { get; set; }
|
||||
public List<LoadScreen> LoadScreens { get; set; }
|
||||
public LocalizationContext LocalizationContext { get; set; }
|
||||
public int MaxPlayerCalculationMode { get; set; }
|
||||
public int MaxPlayers { get; set; }
|
||||
public int MinLevel { get; set; }
|
||||
public int? MinUgcSubVersion { get; set; }
|
||||
public string Name { get; set; }
|
||||
public int? PersistenceVersion { get; set; }
|
||||
public List<string> PromoExternalContent { get; set; }
|
||||
public List<string> PromoImages { get; set; }
|
||||
public int PublishState { get; set; }
|
||||
public DateTime PublishedAt { get; set; }
|
||||
public string RankedEntityId { get; set; }
|
||||
public object RankingContext { get; set; }
|
||||
public List<string> RestrictedCircuitsAllowListNames { get; set; }
|
||||
public List<RoleClass> Roles { get; set; }
|
||||
// The room-wide "last ban" record, kept in the db for the admin tools but NEVER sent to the game. The
|
||||
// client reads this key as THE VIEWER's own ban on the room and shows "Unable to Join Room - you have
|
||||
// been banned" from it; sent to everyone, one ban made the room look banned to every player who opened
|
||||
// it (and any room with a ban in its history, which is why it seemed to happen everywhere). The ban
|
||||
// itself is enforced at join (BannedFromRoom), so nothing is lost by sending null.
|
||||
[Newtonsoft.Json.JsonConverter(typeof(NeverSentToClient))]
|
||||
public RoomBanDetails RoomBanDetails { get; set; }
|
||||
// Every ban ever issued on this room (active, elapsed and lifted). RoomBanDetails above
|
||||
// is the single "current" record older code reads; this is the real list. Not part of
|
||||
// the room DTO the client gets.
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
public List<RoomBanDetails>? RoomBans { get; set; }
|
||||
[BsonId]
|
||||
public ulong RoomId { get; set; }
|
||||
public RoomState State { get; set; }
|
||||
public Stats Stats { get; set; }
|
||||
public List<SubRoom> SubRooms { get; set; }
|
||||
public bool SupportsJuniors { get; set; }
|
||||
public bool SupportsLevelVoting { get; set; }
|
||||
public bool SupportsMobile { get; set; }
|
||||
public bool SupportsQuest2 { get; set; }
|
||||
public bool SupportsScreens { get; set; }
|
||||
public bool SupportsTeleportVR { get; set; }
|
||||
public bool SupportsVRLow { get; set; }
|
||||
public bool SupportsWalkVR { get; set; }
|
||||
public List<TagClass> Tags { get; set; }
|
||||
public bool ToxmodEnabled { get; set; }
|
||||
public int? UgcSubVersion { get; set; }
|
||||
public int? UgcVersion { get; set; }
|
||||
public WarningMaskType WarningMask { get; set; }
|
||||
}
|
||||
|
||||
public class LoadScreen
|
||||
{
|
||||
public string ImageName { get; set; }
|
||||
public string Subtitle { get; set; }
|
||||
public string Title { get; set; }
|
||||
}
|
||||
|
||||
public class LocalizationContext
|
||||
{
|
||||
public List<string> LocalizedFields { get; set; }
|
||||
public string Scope { get; set; }
|
||||
public string TargetLocale { get; set; }
|
||||
}
|
||||
|
||||
public class RoleClass
|
||||
{
|
||||
public long AccountId { get; set; }
|
||||
public int InvitedRole { get; set; }
|
||||
public long? LastChangedByAccountId { get; set; }
|
||||
public RoomDBClasses.Role_data Role { get; set; }
|
||||
}
|
||||
|
||||
public class RoomBanDetails
|
||||
{
|
||||
public long AccountId { get; set; }
|
||||
public DateTime? BanEndTime { get; set; }
|
||||
public DateTime BanStartTime { get; set; }
|
||||
public long BannedByAccountId { get; set; }
|
||||
public string Reason { get; set; }
|
||||
public int Status { get; set; }
|
||||
public long? UnbannedByAccountId { get; set; }
|
||||
}
|
||||
|
||||
public class Stats
|
||||
{
|
||||
public int CheerCount { get; set; }
|
||||
public int FavoriteCount { get; set; }
|
||||
public int VisitCount { get; set; }
|
||||
public int VisitorCount { get; set; }
|
||||
}
|
||||
|
||||
public class SubRoom
|
||||
{
|
||||
[BsonId]
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
[System.Text.Json.Serialization.JsonIgnore]
|
||||
public ObjectId? Id { get; set; }
|
||||
|
||||
public CurrentSave? CurrentSave { get; set; }
|
||||
[JsonIgnore]
|
||||
public List<CurrentSave> AllSaves { get; set; } = new();
|
||||
public RoomAccessibility Accessibility { get; set; }
|
||||
public long? CreatorAccountId { get; set; }
|
||||
public bool IsSandbox { get; set; }
|
||||
public int LastModeratedSaveModerationState { get; set; }
|
||||
public int MaxPlayers { get; set; }
|
||||
public string Name { get; set; }
|
||||
public ulong RoomId { get; set; }
|
||||
public bool ShouldAutoStageSaves { get; set; }
|
||||
public long? StagedSubRoomDataSaveId { get; set; }
|
||||
public ulong SubRoomId { get; set; }
|
||||
public string UnitySceneId { get; set; }
|
||||
|
||||
// The permission overrides a manager saved for THIS subroom (RoomPermissions). Not on
|
||||
// the wire - the client reads them merged into GET /photon_access_token, never here.
|
||||
[Newtonsoft.Json.JsonIgnore]
|
||||
[System.Text.Json.Serialization.JsonIgnore]
|
||||
public List<Campus_live_rewrite.api.server.RoomPermissions.Entry>? Permissions { get; set; }
|
||||
}
|
||||
|
||||
public class CurrentSave
|
||||
{
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public string DataBlob { get; set; }
|
||||
//public string DataBlobHash { get; set; }
|
||||
public string Description { get; set; }
|
||||
public int ModerationState { get; set; }
|
||||
public int OMVersion { get; set; }
|
||||
public int PersistenceVersion { get; set; }
|
||||
public List<string> ReferencedUnityAssetIds { get; set; }
|
||||
public ulong? SavedByAccountId { get; set; }
|
||||
public DeviceClasses? SavedOnDeviceClass { get; set; }
|
||||
public Platforms? SavedOnPlatform { get; set; }
|
||||
public ulong SubRoomDataSaveId { get; set; }
|
||||
public ulong SubRoomId { get; set; }
|
||||
public int UgcSubVersion { get; set; }
|
||||
public string UnityAssetId { get; set; } // optional, may be null
|
||||
}
|
||||
|
||||
public class TagClass
|
||||
{
|
||||
public string Tag { get; set; }
|
||||
public int Type { get; set; } // 0 owner-set, 1 client-derived (autoTag: limitsv2 / beta), 2 server-derived (rro)
|
||||
// Present ONLY on the room's primary genre tag (never false) - the client keys on presence.
|
||||
[Newtonsoft.Json.JsonProperty(NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore)]
|
||||
[System.Text.Json.Serialization.JsonIgnore(Condition = System.Text.Json.Serialization.JsonIgnoreCondition.WhenWritingNull)]
|
||||
public bool? IsPrimaryGenre { get; set; }
|
||||
}
|
||||
|
||||
public class SubroomSaveResults
|
||||
{
|
||||
public List<CurrentSave> Results { get; set; } = new();
|
||||
public int TotalCount { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class RoomFileData
|
||||
{
|
||||
public RoomData? RoomData { get; set; }
|
||||
public SubRoomData? SubRoomData { get; set; }
|
||||
public string? InventionUsage { get; set; }
|
||||
public int PersistenceVersion { get; set; }
|
||||
public int OMVersion { get; set; }
|
||||
public int UgcSubVersion { get; set; }
|
||||
public string? Description { get; set; }
|
||||
public bool AutoPublish { get; set; }
|
||||
}
|
||||
|
||||
public class RoomData
|
||||
{
|
||||
public string? Filename { get; set; }
|
||||
public string? Hash { get; set; }
|
||||
public string? OwnershipProof { get; set; }
|
||||
}
|
||||
|
||||
public class SubRoomData
|
||||
{
|
||||
public string? Filename { get; set; }
|
||||
public string? Hash { get; set; }
|
||||
public string? OwnershipProof { get; set; }
|
||||
}
|
||||
|
||||
public enum RoomAccessibility
|
||||
{
|
||||
Private,
|
||||
Public,
|
||||
Unlisted,
|
||||
Dev_only,
|
||||
Dev_Unlisted,
|
||||
}
|
||||
|
||||
public enum RoomState
|
||||
{
|
||||
Active,
|
||||
PendingJunior = 11,
|
||||
Moderation_PendingReview = 100,
|
||||
Moderation_Closed,
|
||||
MarkedForDelete = 1000
|
||||
}
|
||||
|
||||
public class Tags
|
||||
{
|
||||
public string? Tag { get; set; }
|
||||
public int Type { get; set; }
|
||||
}
|
||||
public class LoadScreens
|
||||
{
|
||||
public string? ImageName { get; set; }
|
||||
public string? Title { get; set; }
|
||||
public string? Subtitle { get; set; }
|
||||
}
|
||||
|
||||
public enum Role_data : byte
|
||||
{
|
||||
None,
|
||||
Banned,
|
||||
Host = 10,
|
||||
Moderator = 20,
|
||||
Contributor = 25, // the client's value (was missing -> a contributor invite landed as CoOwner)
|
||||
CoOwner = 30,
|
||||
TemporaryCoOwner,
|
||||
Creator = 255
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using LiteDB;
|
||||
|
||||
namespace Campus_live_rewrite.api.server.Classes.db_class
|
||||
{
|
||||
public class PlayerSetting
|
||||
{
|
||||
[BsonId]
|
||||
public ulong PlayerId { get; set; }
|
||||
public List<Setting> Settings { get; set; } = new List<Setting>();
|
||||
}
|
||||
|
||||
public class Setting
|
||||
{
|
||||
public string? Key { get; set; }
|
||||
public string? Value { get; set; }
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user