diff --git a/EliteAPI/Controllers/Events/EventController.cs b/EliteAPI/Controllers/Events/EventController.cs index 403170c..387b510 100644 --- a/EliteAPI/Controllers/Events/EventController.cs +++ b/EliteAPI/Controllers/Events/EventController.cs @@ -2,12 +2,14 @@ using System.Text.Json; using Asp.Versioning; using AutoMapper; +using EliteAPI.Authentication; using EliteAPI.Configuration.Settings; using EliteAPI.Data; using EliteAPI.Models.DTOs.Outgoing; using EliteAPI.Models.Entities.Accounts; using EliteAPI.Models.Entities.Events; using EliteAPI.Services.Interfaces; +using EliteAPI.Utilities; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; @@ -156,6 +158,7 @@ public async Task>> GetEventMembers(ulo /// /// /// + [OptionalAuthorize] [HttpGet("member/{playerUuid}")] [ResponseCache(Duration = 60, Location = ResponseCacheLocation.Any)] [ProducesResponseType(StatusCodes.Status200OK)] @@ -174,8 +177,13 @@ public async Task> GetEventMember(ulong eventId, st if (member is null) return NotFound("Event member not found."); var mapped = mapper.Map(member); - - return Ok(mapped); + + if (User.GetId() is { } id && (id == member.UserId.ToString() || User.IsInRole(ApiUserPolicies.Moderator))) { + return mapped; + } else { + mapped.Notes = null; + return mapped; + } } /// diff --git a/EliteAPI/Data/Migrations/20250102201231_AddEventMemberEstimatedTime.Designer.cs b/EliteAPI/Data/Migrations/20250102201231_AddEventMemberEstimatedTime.Designer.cs new file mode 100644 index 0000000..d640b42 --- /dev/null +++ b/EliteAPI/Data/Migrations/20250102201231_AddEventMemberEstimatedTime.Designer.cs @@ -0,0 +1,2576 @@ +// +using System; +using System.Collections.Generic; +using System.Text.Json; +using EliteAPI.Data; +using EliteAPI.Models.Entities.Accounts; +using EliteAPI.Models.Entities.Discord; +using EliteAPI.Models.Entities.Events; +using EliteAPI.Models.Entities.Farming; +using EliteAPI.Models.Entities.Hypixel; +using EliteAPI.Models.Entities.Monetization; +using HypixelAPI.DTOs; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace EliteAPI.Data.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20250102201231_AddEventMemberEstimatedTime")] + partial class AddEventMemberEstimatedTime + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:CollationDefinition:case_insensitive", "en-u-ks-primary,en-u-ks-primary,icu,False") + .HasAnnotation("ProductVersion", "8.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.ApiUser", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccessFailedCount") + .HasColumnType("integer"); + + b.Property("AccountId") + .HasColumnType("numeric(20,0)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("DiscordAccessToken") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("DiscordAccessTokenExpires") + .HasColumnType("timestamp with time zone"); + + b.Property("DiscordRefreshToken") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("DiscordRefreshTokenExpires") + .HasColumnType("timestamp with time zone"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("boolean"); + + b.Property("GuildsLastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("LockoutEnabled") + .HasColumnType("boolean"); + + b.Property("LockoutEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("PasswordHash") + .HasColumnType("text"); + + b.Property("PhoneNumber") + .HasColumnType("text"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("boolean"); + + b.Property("SecurityStamp") + .HasColumnType("text"); + + b.Property("TwoFactorEnabled") + .HasColumnType("boolean"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.Badge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .IsRequired() + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("ImageId") + .HasMaxLength(48) + .HasColumnType("character varying(48)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(50) + .HasColumnType("character varying(50)"); + + b.Property("Requirements") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("TieToAccount") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.ToTable("Badges"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.EliteAccount", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("ActiveRewards") + .HasColumnType("boolean"); + + b.Property("Avatar") + .HasColumnType("text"); + + b.Property("Discriminator") + .HasColumnType("text"); + + b.Property("DisplayName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Email") + .HasColumnType("text"); + + b.Property("Locale") + .HasColumnType("text"); + + b.Property("UserSettingsId") + .HasColumnType("integer"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserSettingsId"); + + b.ToTable("Accounts"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.MinecraftAccount", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("AccountId") + .HasColumnType("numeric(20,0)"); + + b.Property>("FlagReasons") + .HasColumnType("jsonb"); + + b.Property("Flags") + .HasColumnType("integer"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text") + .UseCollation("case_insensitive"); + + b.Property("PlayerDataLastUpdated") + .HasColumnType("bigint"); + + b.Property("ProfilesLastUpdated") + .HasColumnType("bigint"); + + b.Property>("Properties") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Selected") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex(new[] { "Name" }, "idx_minecraft_accounts_name"); + + b.ToTable("MinecraftAccounts"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.UserBadge", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BadgeId") + .HasColumnType("integer"); + + b.Property("MinecraftAccountId") + .IsRequired() + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("Order") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("timestamp with time zone"); + + b.Property("Visible") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("BadgeId"); + + b.HasIndex("MinecraftAccountId"); + + b.ToTable("UserBadges"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.UserSettings", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Features") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("WeightStyleId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WeightStyleId"); + + b.ToTable("UserSettings"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.Guild", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("ActiveRewards") + .HasColumnType("boolean"); + + b.Property("AdminRole") + .HasColumnType("numeric(20,0)"); + + b.Property("BannerId") + .HasColumnType("character varying(48)"); + + b.Property("BotPermissions") + .HasColumnType("numeric(20,0)"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property>("DiscordFeatures") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Features") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("HasBot") + .HasColumnType("boolean"); + + b.Property("IconId") + .HasColumnType("character varying(48)"); + + b.Property("InviteCode") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("IsPublic") + .HasColumnType("boolean"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("MemberCount") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.HasKey("Id"); + + b.HasIndex("BannerId"); + + b.HasIndex("IconId"); + + b.ToTable("Guilds"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildChannel", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("BotPermissions") + .HasColumnType("numeric(20,0)"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Position") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GuildChannels"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AccountId") + .HasMaxLength(32) + .HasColumnType("character varying(32)"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("Permissions") + .HasColumnType("numeric(20,0)"); + + b.Property("Roles") + .IsRequired() + .HasColumnType("numeric(20,0)[]"); + + b.HasKey("Id"); + + b.HasIndex("AccountId"); + + b.HasIndex("GuildId"); + + b.ToTable("GuildMembers"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildRole", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("Permissions") + .HasColumnType("numeric(20,0)"); + + b.Property("Position") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("GuildId"); + + b.ToTable("GuildRoles"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.Event", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Active") + .HasColumnType("boolean"); + + b.Property("Approved") + .HasColumnType("boolean"); + + b.Property("BannerId") + .HasMaxLength(48) + .HasColumnType("character varying(48)"); + + b.Property("BlockedRole") + .HasMaxLength(24) + .HasColumnType("character varying(24)"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("DynamicStartTime") + .HasColumnType("boolean"); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinUntilTime") + .HasColumnType("timestamp with time zone"); + + b.Property("MaxTeamMembers") + .HasColumnType("integer"); + + b.Property("MaxTeams") + .HasColumnType("integer"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("PrizeInfo") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Public") + .HasColumnType("boolean"); + + b.Property("RequiredRole") + .HasMaxLength(24) + .HasColumnType("character varying(24)"); + + b.Property("Rules") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("BannerId"); + + b.HasIndex("GuildId"); + + b.ToTable("Events"); + + b.HasDiscriminator("Type").HasValue(0); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.EventMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("EndTime") + .HasColumnType("timestamp with time zone"); + + b.Property("EstimatedTimeActive") + .HasColumnType("bigint"); + + b.Property("EventId") + .HasColumnType("numeric(20,0)"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("Notes") + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Score") + .HasColumnType("double precision"); + + b.Property("StartTime") + .HasColumnType("timestamp with time zone"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("TeamId") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("numeric(20,0)"); + + b.HasKey("Id"); + + b.HasIndex("ProfileMemberId"); + + b.HasIndex("TeamId"); + + b.HasIndex("UserId"); + + b.HasIndex("EventId", "UserId") + .IsUnique(); + + b.ToTable("EventMembers"); + + b.HasDiscriminator("Type").HasValue(0); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.EventTeam", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Color") + .HasMaxLength(6) + .HasColumnType("character varying(6)"); + + b.Property("EventId") + .HasColumnType("numeric(20,0)"); + + b.Property("JoinCode") + .IsRequired() + .HasMaxLength(6) + .HasColumnType("character varying(6)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("UserId") + .IsRequired() + .HasMaxLength(22) + .HasColumnType("character varying(22)"); + + b.HasKey("Id"); + + b.HasIndex("EventId", "UserId") + .IsUnique(); + + b.ToTable("EventTeams"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Farming.Farming", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property>("BonusWeight") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property>("CropWeight") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Fortune") + .HasColumnType("jsonb"); + + b.Property("Inventory") + .HasColumnType("jsonb"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("TotalWeight") + .HasColumnType("double precision"); + + b.Property>("UncountedCrops") + .IsRequired() + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ProfileMemberId") + .IsUnique(); + + b.ToTable("FarmingWeights"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ChocolateFactory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Chocolate") + .HasColumnType("bigint"); + + b.Property("ChocolateSincePrestige") + .HasColumnType("bigint"); + + b.Property("ChocolateSpent") + .HasColumnType("bigint"); + + b.Property("CocoaFortuneUpgrades") + .HasColumnType("integer"); + + b.Property("LastViewedChocolateFactory") + .HasColumnType("bigint"); + + b.Property("Prestige") + .HasColumnType("integer"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("RefinedTrufflesConsumed") + .HasColumnType("integer"); + + b.Property("TotalChocolate") + .HasColumnType("bigint"); + + b.Property("UnlockedZorro") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("ProfileMemberId") + .IsUnique(); + + b.ToTable("ChocolateFactories"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ContestParticipation", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Collected") + .HasColumnType("integer"); + + b.Property("JacobContestId") + .HasColumnType("bigint"); + + b.Property("JacobDataId") + .HasColumnType("integer"); + + b.Property("MedalEarned") + .HasColumnType("integer"); + + b.Property("Position") + .HasColumnType("integer"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("JacobContestId"); + + b.HasIndex("JacobDataId"); + + b.HasIndex("ProfileMemberId"); + + b.ToTable("ContestParticipations"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Garden", b => + { + b.Property("ProfileId") + .HasMaxLength(36) + .HasColumnType("character varying(36)"); + + b.Property("CompletedVisitors") + .HasColumnType("integer"); + + b.Property("Composter") + .HasColumnType("jsonb"); + + b.Property("GardenExperience") + .HasColumnType("bigint"); + + b.Property("LastUpdated") + .HasColumnType("timestamp with time zone"); + + b.Property("UniqueVisitors") + .HasColumnType("integer"); + + b.Property("UnlockedPlots") + .HasColumnType("bigint"); + + b.Property>("Visitors") + .IsRequired() + .HasColumnType("jsonb"); + + b.HasKey("ProfileId"); + + b.ToTable("Gardens"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.JacobContest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("bigint"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Bronze") + .HasColumnType("integer"); + + b.Property("Crop") + .HasColumnType("integer"); + + b.Property("Diamond") + .HasColumnType("integer"); + + b.Property("Finnegan") + .HasColumnType("boolean"); + + b.Property("Gold") + .HasColumnType("integer"); + + b.Property("Participants") + .HasColumnType("integer"); + + b.Property("Platinum") + .HasColumnType("integer"); + + b.Property("Silver") + .HasColumnType("integer"); + + b.Property("Timestamp") + .HasColumnType("bigint"); + + b.HasKey("Id"); + + b.HasIndex("Timestamp"); + + b.ToTable("JacobContests"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.JacobData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ContestsLastUpdated") + .HasColumnType("bigint"); + + b.Property("FirstPlaceScores") + .HasColumnType("integer"); + + b.Property("Participations") + .HasColumnType("integer"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Stats") + .HasColumnType("jsonb"); + + b.HasKey("Id"); + + b.HasIndex("ProfileMemberId") + .IsUnique(); + + b.ToTable("JacobData"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.PlayerData", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DisplayName") + .HasColumnType("text"); + + b.Property("FirstLogin") + .HasColumnType("bigint"); + + b.Property("Karma") + .HasColumnType("bigint"); + + b.Property("LastLogin") + .HasColumnType("bigint"); + + b.Property("LastLogout") + .HasColumnType("bigint"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property("MonthlyPackageRank") + .HasColumnType("text"); + + b.Property("MonthlyRankColor") + .HasColumnType("text"); + + b.Property("MostRecentMonthlyPackageRank") + .HasColumnType("text"); + + b.Property("NetworkExp") + .HasColumnType("double precision"); + + b.Property("NewPackageRank") + .HasColumnType("text"); + + b.Property("Prefix") + .HasColumnType("text"); + + b.Property("Rank") + .HasColumnType("text"); + + b.Property("RankPlusColor") + .HasColumnType("text"); + + b.Property("RewardHighScore") + .HasColumnType("integer"); + + b.Property("RewardScore") + .HasColumnType("integer"); + + b.Property("RewardStreak") + .HasColumnType("integer"); + + b.Property("TotalDailyRewards") + .HasColumnType("integer"); + + b.Property("TotalRewards") + .HasColumnType("integer"); + + b.Property("Uuid") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("Uuid") + .IsUnique(); + + b.ToTable("PlayerData"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Profile", b => + { + b.Property("ProfileId") + .HasColumnType("text"); + + b.Property("BankBalance") + .HasColumnType("double precision"); + + b.Property>("CraftedMinions") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("GameMode") + .HasColumnType("text"); + + b.Property("IsDeleted") + .HasColumnType("boolean"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property("ProfileName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("ProfileId"); + + b.ToTable("Profiles"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ProfileMember", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property>("CollectionTiers") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Collections") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("IsSelected") + .HasColumnType("boolean"); + + b.Property("LastUpdated") + .HasColumnType("bigint"); + + b.Property>("Pets") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("PlayerUuid") + .IsRequired() + .HasColumnType("text"); + + b.Property("ProfileId") + .IsRequired() + .HasColumnType("text"); + + b.Property("ProfileName") + .HasColumnType("text"); + + b.Property("Purse") + .HasColumnType("double precision"); + + b.Property("SkyblockXp") + .HasColumnType("integer"); + + b.Property("Unparsed") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("WasRemoved") + .HasColumnType("boolean"); + + b.HasKey("Id"); + + b.HasIndex("PlayerUuid"); + + b.HasIndex("ProfileId"); + + b.ToTable("ProfileMembers"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Skills", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Alchemy") + .HasColumnType("double precision"); + + b.Property("Carpentry") + .HasColumnType("double precision"); + + b.Property("Combat") + .HasColumnType("double precision"); + + b.Property("Enchanting") + .HasColumnType("double precision"); + + b.Property("Farming") + .HasColumnType("double precision"); + + b.Property("Fishing") + .HasColumnType("double precision"); + + b.Property("Foraging") + .HasColumnType("double precision"); + + b.Property("Mining") + .HasColumnType("double precision"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Runecrafting") + .HasColumnType("double precision"); + + b.Property("Social") + .HasColumnType("double precision"); + + b.Property("Taming") + .HasColumnType("double precision"); + + b.HasKey("Id"); + + b.HasIndex("ProfileMemberId") + .IsUnique(); + + b.ToTable("Skills"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Images.Image", b => + { + b.Property("Id") + .HasMaxLength(48) + .HasColumnType("character varying(48)"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Description") + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("Hash") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property>("Metadata") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Order") + .HasColumnType("integer"); + + b.Property("Path") + .IsRequired() + .HasMaxLength(512) + .HasColumnType("character varying(512)"); + + b.Property("Title") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.HasKey("Id"); + + b.HasIndex("Path"); + + b.ToTable("Images"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.CosmeticImage", b => + { + b.Property("CosmeticId") + .HasColumnType("integer"); + + b.Property("ImageId") + .HasColumnType("character varying(48)"); + + b.HasKey("CosmeticId", "ImageId"); + + b.HasIndex("ImageId"); + + b.ToTable("CosmeticImage"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Entitlement", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Consumed") + .HasColumnType("boolean"); + + b.Property("Deleted") + .HasColumnType("boolean"); + + b.Property("EndDate") + .HasColumnType("timestamp with time zone"); + + b.Property("ProductId") + .HasColumnType("numeric(20,0)") + .HasAnnotation("Relational:JsonPropertyName", "sku_id"); + + b.Property("StartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("Target") + .HasColumnType("integer"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.ToTable("Entitlements"); + + b.HasDiscriminator("Target").HasValue(0); + + b.UseTphMappingStrategy(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Product", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("numeric(20,0)"); + + b.Property("Available") + .HasColumnType("boolean"); + + b.Property("Category") + .HasColumnType("integer"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("Features") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Flags") + .HasColumnType("numeric(20,0)"); + + b.Property("Icon") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(100) + .HasColumnType("character varying(100)"); + + b.Property("Price") + .HasColumnType("integer"); + + b.Property("Slug") + .IsRequired() + .HasMaxLength(128) + .HasColumnType("character varying(128)"); + + b.Property("ThumbnailId") + .HasMaxLength(48) + .HasColumnType("character varying(48)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ThumbnailId"); + + b.ToTable("Products"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductImage", b => + { + b.Property("ProductId") + .HasColumnType("numeric(20,0)"); + + b.Property("ImageId") + .HasColumnType("character varying(48)"); + + b.HasKey("ProductId", "ImageId"); + + b.HasIndex("ImageId"); + + b.ToTable("ProductImage"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductWeightStyle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ProductId") + .HasColumnType("numeric(20,0)"); + + b.Property("WeightStyleId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ProductId"); + + b.HasIndex("WeightStyleId"); + + b.ToTable("ProductCosmetics"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.WeightStyle", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Collection") + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Data") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Description") + .HasMaxLength(1024) + .HasColumnType("character varying(1024)"); + + b.Property("ImageId") + .HasColumnType("character varying(48)"); + + b.Property("Name") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("StyleFormatter") + .IsRequired() + .HasMaxLength(64) + .HasColumnType("character varying(64)"); + + b.Property("Type") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("ImageId"); + + b.HasIndex("Type"); + + b.ToTable("Cosmetics"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Timescale.CropCollection", b => + { + b.Property("Beetle") + .HasColumnType("integer"); + + b.Property("Cactus") + .HasColumnType("bigint"); + + b.Property("Carrot") + .HasColumnType("bigint"); + + b.Property("CocoaBeans") + .HasColumnType("bigint"); + + b.Property("Cricket") + .HasColumnType("integer"); + + b.Property("Earthworm") + .HasColumnType("integer"); + + b.Property("Fly") + .HasColumnType("integer"); + + b.Property("Locust") + .HasColumnType("integer"); + + b.Property("Melon") + .HasColumnType("bigint"); + + b.Property("Mite") + .HasColumnType("integer"); + + b.Property("Mosquito") + .HasColumnType("integer"); + + b.Property("Moth") + .HasColumnType("integer"); + + b.Property("Mouse") + .HasColumnType("integer"); + + b.Property("Mushroom") + .HasColumnType("bigint"); + + b.Property("NetherWart") + .HasColumnType("bigint"); + + b.Property("Potato") + .HasColumnType("bigint"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Pumpkin") + .HasColumnType("bigint"); + + b.Property("Rat") + .HasColumnType("integer"); + + b.Property("Seeds") + .HasColumnType("bigint"); + + b.Property("Slug") + .HasColumnType("integer"); + + b.Property("SugarCane") + .HasColumnType("bigint"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.Property("Wheat") + .HasColumnType("bigint"); + + b.HasIndex("ProfileMemberId"); + + b.ToTable("CropCollections"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Timescale.SkillExperience", b => + { + b.Property("Alchemy") + .HasColumnType("double precision"); + + b.Property("Carpentry") + .HasColumnType("double precision"); + + b.Property("Combat") + .HasColumnType("double precision"); + + b.Property("Enchanting") + .HasColumnType("double precision"); + + b.Property("Farming") + .HasColumnType("double precision"); + + b.Property("Fishing") + .HasColumnType("double precision"); + + b.Property("Foraging") + .HasColumnType("double precision"); + + b.Property("Mining") + .HasColumnType("double precision"); + + b.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b.Property("Runecrafting") + .HasColumnType("double precision"); + + b.Property("Social") + .HasColumnType("double precision"); + + b.Property("Taming") + .HasColumnType("double precision"); + + b.Property("Time") + .HasColumnType("timestamp with time zone"); + + b.HasIndex("ProfileMemberId"); + + b.ToTable("SkillExperiences"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("text"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("text"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("character varying(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + + b.HasData( + new + { + Id = "8270a1b1-5809-436a-ba1c-b712f4f55f67", + Name = "Admin", + NormalizedName = "ADMIN" + }, + new + { + Id = "3384aba1-5453-4787-81d9-0b7222225d81", + Name = "Moderator", + NormalizedName = "MODERATOR" + }, + new + { + Id = "d8c803c1-63a0-4594-8d68-aad7bd59df7d", + Name = "Support", + NormalizedName = "SUPPORT" + }, + new + { + Id = "ff4f5319-644e-4332-8bd5-2ec989ba5e7f", + Name = "Wiki", + NormalizedName = "WIKI" + }, + new + { + Id = "e99efab5-3fd2-416e-b8f5-93b0370892ac", + Name = "User", + NormalizedName = "USER" + }); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ClaimType") + .HasColumnType("text"); + + b.Property("ClaimValue") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("ProviderKey") + .HasColumnType("text"); + + b.Property("ProviderDisplayName") + .HasColumnType("text"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("RoleId") + .HasColumnType("text"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("text"); + + b.Property("LoginProvider") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Value") + .HasColumnType("text"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.MedalEvent", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.Event"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(4); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.WeightEvent", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.Event"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(1); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.MedalEventMember", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.EventMember"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(4); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.WeightEventMember", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Events.EventMember"); + + b.Property("Data") + .IsRequired() + .ValueGeneratedOnUpdateSometimes() + .HasColumnType("jsonb") + .HasColumnName("Data"); + + b.HasDiscriminator().HasValue(1); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.GuildEntitlement", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Monetization.Entitlement"); + + b.Property("GuildId") + .HasColumnType("numeric(20,0)"); + + b.HasIndex("GuildId"); + + b.HasDiscriminator().HasValue(1); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.UserEntitlement", b => + { + b.HasBaseType("EliteAPI.Models.Entities.Monetization.Entitlement"); + + b.Property("AccountId") + .HasMaxLength(22) + .HasColumnType("numeric(20,0)"); + + b.HasIndex("AccountId"); + + b.HasDiscriminator().HasValue(2); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.ApiUser", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.EliteAccount", "Account") + .WithMany() + .HasForeignKey("AccountId"); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.Badge", b => + { + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Image") + .WithMany() + .HasForeignKey("ImageId"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.EliteAccount", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.UserSettings", "UserSettings") + .WithMany() + .HasForeignKey("UserSettingsId"); + + b.Navigation("UserSettings"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.MinecraftAccount", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.EliteAccount", "EliteAccount") + .WithMany("MinecraftAccounts") + .HasForeignKey("AccountId"); + + b.Navigation("EliteAccount"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.UserBadge", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.Badge", "Badge") + .WithMany() + .HasForeignKey("BadgeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Accounts.MinecraftAccount", "MinecraftAccount") + .WithMany("Badges") + .HasForeignKey("MinecraftAccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Badge"); + + b.Navigation("MinecraftAccount"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.UserSettings", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.WeightStyle", "WeightStyle") + .WithMany() + .HasForeignKey("WeightStyleId"); + + b.Navigation("WeightStyle"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.Guild", b => + { + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Banner") + .WithMany() + .HasForeignKey("BannerId"); + + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Icon") + .WithMany() + .HasForeignKey("IconId"); + + b.Navigation("Banner"); + + b.Navigation("Icon"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildChannel", b => + { + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany("Channels") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildMember", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.ApiUser", "Account") + .WithMany("GuildMemberships") + .HasForeignKey("AccountId"); + + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany() + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.GuildRole", b => + { + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany("Roles") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.Event", b => + { + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Banner") + .WithMany() + .HasForeignKey("BannerId"); + + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany() + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Banner"); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.EventMember", b => + { + b.HasOne("EliteAPI.Models.Entities.Events.Event", "Event") + .WithMany() + .HasForeignKey("EventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithMany("EventEntries") + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Events.EventTeam", "Team") + .WithMany("Members") + .HasForeignKey("TeamId"); + + b.HasOne("EliteAPI.Models.Entities.Accounts.EliteAccount", "User") + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Event"); + + b.Navigation("ProfileMember"); + + b.Navigation("Team"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.EventTeam", b => + { + b.HasOne("EliteAPI.Models.Entities.Events.Event", "Event") + .WithMany("Teams") + .HasForeignKey("EventId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Event"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Farming.Farming", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithOne("Farming") + .HasForeignKey("EliteAPI.Models.Entities.Farming.Farming", "ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Farming.Pests", "Pests", b1 => + { + b1.Property("FarmingId") + .HasColumnType("integer"); + + b1.Property("Beetle") + .HasColumnType("integer"); + + b1.Property("Cricket") + .HasColumnType("integer"); + + b1.Property("Earthworm") + .HasColumnType("integer"); + + b1.Property("Fly") + .HasColumnType("integer"); + + b1.Property("Locust") + .HasColumnType("integer"); + + b1.Property("Mite") + .HasColumnType("integer"); + + b1.Property("Mosquito") + .HasColumnType("integer"); + + b1.Property("Moth") + .HasColumnType("integer"); + + b1.Property("Mouse") + .HasColumnType("integer"); + + b1.Property("Rat") + .HasColumnType("integer"); + + b1.Property("Slug") + .HasColumnType("integer"); + + b1.HasKey("FarmingId"); + + b1.ToTable("FarmingWeights"); + + b1.WithOwner() + .HasForeignKey("FarmingId"); + }); + + b.Navigation("Pests") + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ChocolateFactory", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithOne("ChocolateFactory") + .HasForeignKey("EliteAPI.Models.Entities.Hypixel.ChocolateFactory", "ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.ChocolateFactoryRabbits", "TotalRabbits", b1 => + { + b1.Property("ChocolateFactoryId") + .HasColumnType("integer"); + + b1.Property("Common") + .HasColumnType("integer"); + + b1.Property("Divine") + .HasColumnType("integer"); + + b1.Property("Epic") + .HasColumnType("integer"); + + b1.Property("Legendary") + .HasColumnType("integer"); + + b1.Property("Mythic") + .HasColumnType("integer"); + + b1.Property("Rare") + .HasColumnType("integer"); + + b1.Property("Uncommon") + .HasColumnType("integer"); + + b1.HasKey("ChocolateFactoryId"); + + b1.ToTable("ChocolateFactories"); + + b1.WithOwner() + .HasForeignKey("ChocolateFactoryId"); + }); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.ChocolateFactoryRabbits", "UniqueRabbits", b1 => + { + b1.Property("ChocolateFactoryId") + .HasColumnType("integer"); + + b1.Property("Common") + .HasColumnType("integer"); + + b1.Property("Divine") + .HasColumnType("integer"); + + b1.Property("Epic") + .HasColumnType("integer"); + + b1.Property("Legendary") + .HasColumnType("integer"); + + b1.Property("Mythic") + .HasColumnType("integer"); + + b1.Property("Rare") + .HasColumnType("integer"); + + b1.Property("Uncommon") + .HasColumnType("integer"); + + b1.HasKey("ChocolateFactoryId"); + + b1.ToTable("ChocolateFactories"); + + b1.WithOwner() + .HasForeignKey("ChocolateFactoryId"); + }); + + b.Navigation("ProfileMember"); + + b.Navigation("TotalRabbits") + .IsRequired(); + + b.Navigation("UniqueRabbits") + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ContestParticipation", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.JacobContest", "JacobContest") + .WithMany() + .HasForeignKey("JacobContestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.JacobData", null) + .WithMany("Contests") + .HasForeignKey("JacobDataId"); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithMany() + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("JacobContest"); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Garden", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.Profile", "Profile") + .WithOne("Garden") + .HasForeignKey("EliteAPI.Models.Entities.Hypixel.Garden", "ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.CropUpgrades", "Upgrades", b1 => + { + b1.Property("GardenProfileId") + .HasColumnType("character varying(36)"); + + b1.Property("Cactus") + .HasColumnType("smallint"); + + b1.Property("Carrot") + .HasColumnType("smallint"); + + b1.Property("CocoaBeans") + .HasColumnType("smallint"); + + b1.Property("Melon") + .HasColumnType("smallint"); + + b1.Property("Mushroom") + .HasColumnType("smallint"); + + b1.Property("NetherWart") + .HasColumnType("smallint"); + + b1.Property("Potato") + .HasColumnType("smallint"); + + b1.Property("Pumpkin") + .HasColumnType("smallint"); + + b1.Property("SugarCane") + .HasColumnType("smallint"); + + b1.Property("Wheat") + .HasColumnType("smallint"); + + b1.HasKey("GardenProfileId"); + + b1.ToTable("Gardens"); + + b1.WithOwner() + .HasForeignKey("GardenProfileId"); + }); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.MilestoneCrops", "Crops", b1 => + { + b1.Property("GardenProfileId") + .HasColumnType("character varying(36)"); + + b1.Property("Cactus") + .HasColumnType("bigint"); + + b1.Property("Carrot") + .HasColumnType("bigint"); + + b1.Property("CocoaBeans") + .HasColumnType("bigint"); + + b1.Property("Melon") + .HasColumnType("bigint"); + + b1.Property("Mushroom") + .HasColumnType("bigint"); + + b1.Property("NetherWart") + .HasColumnType("bigint"); + + b1.Property("Potato") + .HasColumnType("bigint"); + + b1.Property("Pumpkin") + .HasColumnType("bigint"); + + b1.Property("SugarCane") + .HasColumnType("bigint"); + + b1.Property("Wheat") + .HasColumnType("bigint"); + + b1.HasKey("GardenProfileId"); + + b1.ToTable("Gardens"); + + b1.WithOwner() + .HasForeignKey("GardenProfileId"); + }); + + b.Navigation("Crops") + .IsRequired(); + + b.Navigation("Profile"); + + b.Navigation("Upgrades") + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.JacobData", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithOne("JacobData") + .HasForeignKey("EliteAPI.Models.Entities.Hypixel.JacobData", "ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.EarnedMedalInventory", "EarnedMedals", b1 => + { + b1.Property("JacobDataId") + .HasColumnType("integer"); + + b1.Property("Bronze") + .HasColumnType("integer"); + + b1.Property("Diamond") + .HasColumnType("integer"); + + b1.Property("Gold") + .HasColumnType("integer"); + + b1.Property("Platinum") + .HasColumnType("integer"); + + b1.Property("Silver") + .HasColumnType("integer"); + + b1.HasKey("JacobDataId"); + + b1.ToTable("JacobData"); + + b1.WithOwner() + .HasForeignKey("JacobDataId"); + }); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.JacobPerks", "Perks", b1 => + { + b1.Property("JacobDataId") + .HasColumnType("integer"); + + b1.Property("DoubleDrops") + .HasColumnType("integer"); + + b1.Property("LevelCap") + .HasColumnType("integer"); + + b1.HasKey("JacobDataId"); + + b1.ToTable("JacobData"); + + b1.WithOwner() + .HasForeignKey("JacobDataId"); + }); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.MedalInventory", "Medals", b1 => + { + b1.Property("JacobDataId") + .HasColumnType("integer"); + + b1.Property("Bronze") + .HasColumnType("integer"); + + b1.Property("Gold") + .HasColumnType("integer"); + + b1.Property("Silver") + .HasColumnType("integer"); + + b1.HasKey("JacobDataId"); + + b1.ToTable("JacobData"); + + b1.WithOwner() + .HasForeignKey("JacobDataId"); + }); + + b.Navigation("EarnedMedals") + .IsRequired(); + + b.Navigation("Medals") + .IsRequired(); + + b.Navigation("Perks") + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.PlayerData", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.MinecraftAccount", "MinecraftAccount") + .WithOne("PlayerData") + .HasForeignKey("EliteAPI.Models.Entities.Hypixel.PlayerData", "Uuid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.SocialMediaLinks", "SocialMedia", b1 => + { + b1.Property("PlayerDataId") + .HasColumnType("integer"); + + b1.Property("Discord") + .HasColumnType("text"); + + b1.Property("Hypixel") + .HasColumnType("text"); + + b1.Property("Youtube") + .HasColumnType("text"); + + b1.HasKey("PlayerDataId"); + + b1.ToTable("PlayerData"); + + b1.WithOwner() + .HasForeignKey("PlayerDataId"); + }); + + b.Navigation("MinecraftAccount"); + + b.Navigation("SocialMedia") + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ProfileMember", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.MinecraftAccount", "MinecraftAccount") + .WithMany() + .HasForeignKey("PlayerUuid") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Hypixel.Profile", "Profile") + .WithMany("Members") + .HasForeignKey("ProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.OwnsOne("EliteAPI.Models.Entities.Hypixel.ApiAccess", "Api", b1 => + { + b1.Property("ProfileMemberId") + .HasColumnType("uuid"); + + b1.Property("Collections") + .HasColumnType("boolean"); + + b1.Property("Inventories") + .HasColumnType("boolean"); + + b1.Property("Museum") + .HasColumnType("boolean"); + + b1.Property("Skills") + .HasColumnType("boolean"); + + b1.Property("Vault") + .HasColumnType("boolean"); + + b1.HasKey("ProfileMemberId"); + + b1.ToTable("ProfileMembers"); + + b1.WithOwner() + .HasForeignKey("ProfileMemberId"); + }); + + b.Navigation("Api") + .IsRequired(); + + b.Navigation("MinecraftAccount"); + + b.Navigation("Profile"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Skills", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithOne("Skills") + .HasForeignKey("EliteAPI.Models.Entities.Hypixel.Skills", "ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.CosmeticImage", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.WeightStyle", "Cosmetic") + .WithMany() + .HasForeignKey("CosmeticId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Image") + .WithMany() + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Cosmetic"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Entitlement", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Product", b => + { + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Thumbnail") + .WithMany() + .HasForeignKey("ThumbnailId"); + + b.Navigation("Thumbnail"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductImage", b => + { + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Image") + .WithMany() + .HasForeignKey("ImageId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", "Product") + .WithMany() + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Image"); + + b.Navigation("Product"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.ProductWeightStyle", b => + { + b.HasOne("EliteAPI.Models.Entities.Monetization.Product", null) + .WithMany("ProductWeightStyles") + .HasForeignKey("ProductId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Monetization.WeightStyle", null) + .WithMany("ProductWeightStyles") + .HasForeignKey("WeightStyleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.WeightStyle", b => + { + b.HasOne("EliteAPI.Models.Entities.Images.Image", "Image") + .WithMany() + .HasForeignKey("ImageId"); + + b.Navigation("Image"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Timescale.CropCollection", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithMany() + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Timescale.SkillExperience", b => + { + b.HasOne("EliteAPI.Models.Entities.Hypixel.ProfileMember", "ProfileMember") + .WithMany() + .HasForeignKey("ProfileMemberId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ProfileMember"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("EliteAPI.Models.Entities.Accounts.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.ApiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.GuildEntitlement", b => + { + b.HasOne("EliteAPI.Models.Entities.Discord.Guild", "Guild") + .WithMany("Entitlements") + .HasForeignKey("GuildId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Guild"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.UserEntitlement", b => + { + b.HasOne("EliteAPI.Models.Entities.Accounts.EliteAccount", "Account") + .WithMany("Entitlements") + .HasForeignKey("AccountId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Account"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.ApiUser", b => + { + b.Navigation("GuildMemberships"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.EliteAccount", b => + { + b.Navigation("Entitlements"); + + b.Navigation("MinecraftAccounts"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Accounts.MinecraftAccount", b => + { + b.Navigation("Badges"); + + b.Navigation("PlayerData"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Discord.Guild", b => + { + b.Navigation("Channels"); + + b.Navigation("Entitlements"); + + b.Navigation("Roles"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.Event", b => + { + b.Navigation("Teams"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Events.EventTeam", b => + { + b.Navigation("Members"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.JacobData", b => + { + b.Navigation("Contests"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.Profile", b => + { + b.Navigation("Garden"); + + b.Navigation("Members"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Hypixel.ProfileMember", b => + { + b.Navigation("ChocolateFactory") + .IsRequired(); + + b.Navigation("EventEntries"); + + b.Navigation("Farming") + .IsRequired(); + + b.Navigation("JacobData") + .IsRequired(); + + b.Navigation("Skills") + .IsRequired(); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.Product", b => + { + b.Navigation("ProductWeightStyles"); + }); + + modelBuilder.Entity("EliteAPI.Models.Entities.Monetization.WeightStyle", b => + { + b.Navigation("ProductWeightStyles"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/EliteAPI/Data/Migrations/20250102201231_AddEventMemberEstimatedTime.cs b/EliteAPI/Data/Migrations/20250102201231_AddEventMemberEstimatedTime.cs new file mode 100644 index 0000000..6a5b019 --- /dev/null +++ b/EliteAPI/Data/Migrations/20250102201231_AddEventMemberEstimatedTime.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace EliteAPI.Data.Migrations +{ + /// + public partial class AddEventMemberEstimatedTime : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "EstimatedTimeActive", + table: "EventMembers", + type: "bigint", + nullable: false, + defaultValue: 0L); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "EstimatedTimeActive", + table: "EventMembers"); + } + } +} diff --git a/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs b/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs index 0b35e9f..1826526 100644 --- a/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs +++ b/EliteAPI/Data/Migrations/DataContextModelSnapshot.cs @@ -546,6 +546,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.Property("EndTime") .HasColumnType("timestamp with time zone"); + b.Property("EstimatedTimeActive") + .HasColumnType("bigint"); + b.Property("EventId") .HasColumnType("numeric(20,0)"); diff --git a/EliteAPI/Models/Entities/Events/EventMember.cs b/EliteAPI/Models/Entities/Events/EventMember.cs index 0eeceaf..238193c 100644 --- a/EliteAPI/Models/Entities/Events/EventMember.cs +++ b/EliteAPI/Models/Entities/Events/EventMember.cs @@ -24,6 +24,7 @@ [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)] public DateTimeOffset LastUpdated { get; set; } public DateTimeOffset StartTime { get; set; } public DateTimeOffset EndTime { get; set; } + public long EstimatedTimeActive { get; set; } [MaxLength(128)] public string? Notes { get; set; } diff --git a/EliteAPI/Parsers/Events/EventProgressParser.cs b/EliteAPI/Parsers/Events/EventProgressParser.cs index 063581a..46f8397 100644 --- a/EliteAPI/Parsers/Events/EventProgressParser.cs +++ b/EliteAPI/Parsers/Events/EventProgressParser.cs @@ -32,9 +32,12 @@ public static void LoadProgress(this EventMember eventMember, DataContext contex eventMember.Status = EventMemberStatus.Inactive; return; } - + + // Update estimated time active + // This isn't perfect as it uses the status from the last update + eventMember.UpdateEstimatedTimeActive(); eventMember.LastUpdated = currentTime; - + // Disqualify the member if they disabled API access during the event if (!member.Api.Collections || !member.Api.Inventories) { eventMember.Status = EventMemberStatus.Disqualified; @@ -52,9 +55,6 @@ public static void LoadProgress(this EventMember eventMember, DataContext contex return; } - - // Update the tool states and collection increases - // eventMember.UpdateToolsAndCollections(member); switch (@event.Type) { case EventType.None: @@ -78,4 +78,11 @@ public static void LoadProgress(this EventMember eventMember, DataContext contex context.Entry(eventMember).State = EntityState.Modified; } + + private static void UpdateEstimatedTimeActive(this EventMember eventMember) { + if (eventMember.Status != EventMemberStatus.Active) return; + + // Add difference in seconds to estimated time active + eventMember.EstimatedTimeActive += (long)(DateTimeOffset.UtcNow - eventMember.LastUpdated).TotalSeconds; + } } \ No newline at end of file diff --git a/EliteAPI/Parsers/Events/WeightEventProgressParser.cs b/EliteAPI/Parsers/Events/WeightEventProgressParser.cs index 00a1063..7bb46c9 100644 --- a/EliteAPI/Parsers/Events/WeightEventProgressParser.cs +++ b/EliteAPI/Parsers/Events/WeightEventProgressParser.cs @@ -7,9 +7,9 @@ namespace EliteAPI.Parsers.Events; public static class WeightEventProgressParser { /// - /// Cap mushrooms attributed to Mushroom Eater perk to 99% of 72,000 per hour, then assume players farm a maxiumum of 19/24 hours + /// Cap mushrooms attributed to Mushroom Eater perk to 95% of 72,000 per hour /// - private const int MaxMushroomEaterPerHour = (int)(72_000 * 0.99 * 19 / 24); + private const int MaxMushroomEaterPerHour = (int)(72_000 * 0.95); public static void UpdateFarmingWeight(this WeightEventMember eventMember, WeightEvent weightEvent, ProfileMember? member = null) { if (member is not null) { @@ -32,7 +32,7 @@ public static void UpdateFarmingWeight(this WeightEventMember eventMember, Weigh .GroupBy(t => t.Crop!.Value) .ToDictionary(g => g.Key, g => g.ToList()); - var mushroomEaterMushrooms = GetMushroomEaterMushrooms(weightEvent, collectionIncreases, toolsByCrop); + var mushroomEaterMushrooms = GetMushroomEaterMushrooms(eventMember, collectionIncreases, toolsByCrop); foreach (var (crop, tools) in toolsByCrop) { collectionIncreases.TryGetValue(crop, out var increasedCollection); @@ -80,7 +80,7 @@ public static void UpdateFarmingWeight(this WeightEventMember eventMember, Weigh /// /// Get maximum mushrooms attributed to Mushroom Eater perk /// - private static long GetMushroomEaterMushrooms(WeightEvent weightEvent, Dictionary collectionIncreases, + private static long GetMushroomEaterMushrooms(WeightEventMember eventMember, Dictionary collectionIncreases, Dictionary> toolsByCrop) { // Get unaccounted for mushroom collection for dealing with Mushroom Eater perk collectionIncreases.TryGetValue(Crop.Mushroom, out var increasedMushroom); @@ -88,9 +88,10 @@ private static long GetMushroomEaterMushrooms(WeightEvent weightEvent, Dictionar var farmedMushroom = toolsByCrop.TryGetValue(Crop.Mushroom, out var mushroomTools) ? mushroomTools.Sum(t => t.Cultivating.IncreaseFromInitial()) : 0; - var elapsedHours = (DateTimeOffset.UtcNow - weightEvent.StartTime).TotalHours; + var elapsedHours = eventMember.EstimatedTimeActive / 3600.0; var maxMushroomEater = (int)(elapsedHours * MaxMushroomEaterPerHour); var mushroomEaterMushrooms = Math.Min(Math.Max(increasedMushroom - farmedMushroom, 0), maxMushroomEater); + return mushroomEaterMushrooms; }