using System.ComponentModel.DataAnnotations; namespace DorkNet.Server.Data.Entities; /// /// Per RecNet.Avatars+GiftPackage wire shape (decompiled at /// Cpp2IL_CS/.../RecNet/Avatars.cs:192-555) — a queued gift the /// recipient can claim from the watch's "gifts" inbox. Used for both /// admin-granted gifts and gift-drop / mystery-box / level-up prizes. /// /// Field names + types match the client's /// GiftPackage.Deserialize(Dictionary<String, Object>) /// directly so the watch round-trips cleanly. /// is the bool the client reads — we additionally stamp /// for server-side bookkeeping (not on wire). /// public class GiftPackageEntity { public long Id { get; set; } /// The player whose inbox this gift sits in. public long RecipientPlayerId { get; set; } /// Wire field (Nullable<Int32>) — the player who /// sent the gift, or null for system / drop gifts. public int? FromPlayerId { get; set; } [MaxLength(128)] public string ConsumableItemDesc { get; set; } = string.Empty; /// Wire field AvatarItemType as Nullable<int> /// (0 = Outfit, 1 = HairDye). Null when the gift has no avatar /// item (currency-only, equipment-only, etc.). public int? AvatarItemType { get; set; } /// Wire field name is exactly AvatarItemDescOrHairDyeDesc /// — content is either the AvatarItem GUID (when AvatarItemType=0) /// or the HairDye desc string (when AvatarItemType=1). [MaxLength(128)] public string AvatarItemDescOrHairDyeDesc { get; set; } = string.Empty; [MaxLength(128)] public string EquipmentPrefabName { get; set; } = string.Empty; [MaxLength(64)] public string EquipmentModificationGuid { get; set; } = string.Empty; /// CurrencyType enum: 0=Invalid, 1=LaserTagTickets, /// 2=RecCenterTokens, 100=LostSkullsGold, 101=DraculaSilver, /// 200=RecRoyale_Season1. public int CurrencyType { get; set; } = 0; public int Currency { get; set; } = 0; public int Xp { get; set; } = 0; public int Level { get; set; } = 0; /// GiftContext enum (large, see Avatars.cs comments). /// 0 = Default, 100 = LevelUp, 1000 = Holiday, etc. public int GiftContext { get; set; } = 0; /// GiftRarity: -1=None, 0=Common, 10=Uncommon, 20=Rare, /// 30=Epic, 50=Legendary. public int GiftRarity { get; set; } = 0; [MaxLength(512)] public string Message { get; set; } = string.Empty; /// PlatformType: -1=All, 0=Steam, 1=Oculus, 2=PlayStation, /// 3=Microsoft, 4=HeadlessBot, 5=IOS. public int Platform { get; set; } = -1; /// Asset name string for the Unity Material that the /// gift box renders with. [MaxLength(128)] public string PackageMaterial { get; set; } = string.Empty; /// Asset name string for the GiftPackageVariant /// ScriptableObject (e.g. "Standard", "Holiday", etc.). [MaxLength(128)] public string PackageVariant { get; set; } = string.Empty; public bool Consumed { get; set; } = false; public bool IsValid { get; set; } = true; [MaxLength(512)] public string ErrorMessage { get; set; } = string.Empty; public bool SupportsCurrentPlatform { get; set; } = true; public bool IsGifted { get; set; } = false; /// Server-side audit timestamp; not part of wire /// shape. public DateTime? ConsumedAt { get; set; } public DateTime CreatedAt { get; set; } = DateTime.UtcNow; }