Decompiled source of Divine Delivery v2.2.2
plugins/Divine Delivery/EndlessDelivery.Api.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Net; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Threading.Tasks; using EndlessDelivery.Api.Exceptions; using EndlessDelivery.Api.Requests; using EndlessDelivery.Common; using EndlessDelivery.Common.Communication.Scores; using EndlessDelivery.Common.ContentFile; using EndlessDelivery.Common.Inventory.Items; using Microsoft.CodeAnalysis; using Newtonsoft.Json; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("EndlessDelivery.Api")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b5dc0c560e2a25aa15f1eef619719550a062d078")] [assembly: AssemblyProduct("EndlessDelivery.Api")] [assembly: AssemblyTitle("EndlessDelivery.Api")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } public class BadRequestException : Exception { public BadRequestException(string reason) : base("Server rejected request as " + reason) { } } namespace EndlessDelivery.Api { public class ApiContext { private const string ProdUrl = "https://delivery.wafflethings.dev/api/"; public readonly Uri BaseUri; public readonly HttpClient Client; public string? Token; private readonly Func<string> _getTicket; public ApiContext(HttpClient client, Func<string> getTicket, Uri? baseUri = null) { Client = client; _getTicket = getTicket; if (baseUri != null && !baseUri.AbsoluteUri.EndsWith("/")) { baseUri = new Uri(baseUri.OriginalString + "/"); } BaseUri = ((baseUri == null) ? new Uri("https://delivery.wafflethings.dev/api/") : baseUri); } public async Task Login() { Token = await this.GetToken(_getTicket()); } public async Task AddAuth(HttpRequestMessage request) { try { if (Token == null) { throw new PermissionException("You must be logged in."); } request.Headers.Add("DeliveryToken", Token); } catch (InternalServerException ex) { await Task.FromException(ex); } } } } namespace EndlessDelivery.Api.Requests { public static class Api { private const string PingEndpoint = "ping"; private const string UpdateRequiredEndpoint = "update_required"; public static async Task<bool> ServerOnline(this ApiContext context) { return (await context.Client.GetAsync(context.BaseUri?.ToString() + "ping")).IsSuccessStatusCode; } public static async Task<bool> UpdateRequired(this ApiContext context) { string content = await (await context.Client.GetAsync(context.BaseUri?.ToString() + $"update_required")).Content.ReadAsStringAsync(); if (!bool.TryParse(content, out var result)) { throw new BadResponseException(content); } return result; } } public static class Authentication { private const string LoginEndpoint = "auth/steam/login"; public static async Task<string> GetToken(this ApiContext context, string ticket) { HttpResponseMessage response = await context.Client.PostAsync(context.BaseUri?.ToString() + "auth/steam/login", new StringContent(ticket)); if (!response.IsSuccessStatusCode) { throw new InternalServerException(); } return await response.Content.ReadAsStringAsync(); } } public static class Content { private const string CmsRoot = "cms/"; private const string UpdateRequiredEndpoint = "update_required?hash={0}"; private const string DownloadCmsEndpoint = "content"; public static async Task<bool> ContentUpdateRequired(this ApiContext context, string hash) { HttpResponseMessage response = await context.Client.GetAsync(context.BaseUri?.ToString() + "cms/" + $"update_required?hash={hash}"); if (response.IsSuccessStatusCode) { return false; } if (response.StatusCode != HttpStatusCode.UpgradeRequired) { throw new BadResponseException("CMS download error " + response.StatusCode); } return true; } public static async Task<Cms> DownloadCms(this ApiContext context) { string content = await (await context.Client.GetAsync(context.BaseUri?.ToString() + "cms/content")).Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<Cms>(content) ?? throw new BadResponseException(content); } } public static class Items { private const string ItemsRoot = "users/items/"; private const string BuyItemEndpoint = "buy_item"; private const string ActiveShopEndpoint = "active_shop"; private const string GetLoadoutEndpoint = "get_loadout?steamId={0}"; private const string SetLoadoutEndpoint = "set_loadout"; private const string GetInventoryEndpoint = "get_inventory?steamId={0}"; private const string ClaimDailyRewardEndpoint = "claim_daily_reward"; private const string GetClaimedRewardsEndpoint = "get_claimed_rewards"; public static async Task BuyItem(this ApiContext context, string itemId) { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, context.BaseUri?.ToString() + "users/items/buy_item"); await context.AddAuth(request); request.Content = new StringContent(itemId); HttpResponseMessage response = await context.Client.SendAsync(request); if (response.StatusCode == HttpStatusCode.BadRequest) { throw new BadRequestException(await response.Content.ReadAsStringAsync()); } } public static async Task<ShopRotation> GetActiveShop(this ApiContext context) { string content = await (await context.Client.GetAsync(context.BaseUri?.ToString() + "users/items/active_shop")).Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<ShopRotation>(content) ?? throw new BadResponseException(content); } public static async Task<CosmeticLoadout> GetLoadout(this ApiContext context, ulong steamId) { string content = await (await context.Client.GetAsync(context.BaseUri?.ToString() + "users/items/" + $"get_loadout?steamId={steamId}")).Content.ReadAsStringAsync(); CosmeticLoadout deserialized = JsonConvert.DeserializeObject<CosmeticLoadout>(content); return deserialized ?? throw new BadResponseException(content); } public static async Task SetLoadout(this ApiContext context, CosmeticLoadout loadout) { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, context.BaseUri?.ToString() + "users/items/set_loadout"); await context.AddAuth(request); request.Content = new StringContent(JsonConvert.SerializeObject((object)loadout)); HttpResponseMessage response = await context.Client.SendAsync(request); if (response.StatusCode == HttpStatusCode.BadRequest) { throw new BadRequestException(await response.Content.ReadAsStringAsync()); } } public static async Task<List<string>> GetInventory(this ApiContext context, ulong steamId) { HttpResponseMessage response = await context.Client.GetAsync(context.BaseUri?.ToString() + "users/items/" + $"get_inventory?steamId={steamId}"); if (response.StatusCode == HttpStatusCode.BadRequest) { throw new BadRequestException(await response.Content.ReadAsStringAsync()); } if (response.StatusCode == HttpStatusCode.InternalServerError) { throw new InternalServerException(); } string content = await response.Content.ReadAsStringAsync(); List<string> deserialized = JsonConvert.DeserializeObject<List<string>>(content); if (deserialized == null) { throw new BadResponseException(content); } return deserialized; } public static async Task ClaimDailyReward(this ApiContext context) { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, context.BaseUri?.ToString() + "users/items/claim_daily_reward"); await context.AddAuth(request); HttpResponseMessage response = await context.Client.SendAsync(request); if (response.StatusCode == HttpStatusCode.BadRequest) { throw new BadRequestException(await response.Content.ReadAsStringAsync()); } } public static async Task<List<string>> GetClaimedDailyRewards(this ApiContext context) { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, context.BaseUri?.ToString() + "users/items/get_claimed_rewards"); await context.AddAuth(request); HttpResponseMessage response = await context.Client.SendAsync(request); if (response.StatusCode == HttpStatusCode.BadRequest) { throw new BadRequestException(await response.Content.ReadAsStringAsync()); } string content = await response.Content.ReadAsStringAsync(); List<string> deserialized = JsonConvert.DeserializeObject<List<string>>(content); if (deserialized == null) { throw new BadResponseException(content); } return deserialized; } } public static class Scores { private const string ScoreRoot = "scores/"; private const string GetRangeEndpoint = "get_range?start={0}&count={1}"; private const string GetPositionEndpoint = "get_position?steamId={0}"; private const string GetScoreEndpoint = "get_score?steamId={0}"; private const string GetLengthEndpoint = "get_length"; private const string SubmitScoreEndpoint = "submit_score"; public static async Task<OnlineScore[]> GetScoreRange(this ApiContext context, int startIndex, int amount) { string content = await (await context.Client.GetAsync(context.BaseUri?.ToString() + "scores/" + $"get_range?start={startIndex}&count={amount}")).Content.ReadAsStringAsync(); return JsonConvert.DeserializeObject<OnlineScore[]>(content) ?? throw new BadResponseException(content); } public static async Task<int> GetLeaderboardPosition(this ApiContext context, ulong userId) { string content = await (await context.Client.GetAsync(context.BaseUri?.ToString() + "scores/" + $"get_position?steamId={userId}")).Content.ReadAsStringAsync(); if (!int.TryParse(content, out var pos)) { throw new BadResponseException(content); } return pos; } public static async Task<OnlineScore> GetLeaderboardScore(this ApiContext context, ulong userId) { HttpResponseMessage response = await context.Client.GetAsync(context.BaseUri?.ToString() + "scores/" + $"get_score?steamId={userId}"); if (response.StatusCode == HttpStatusCode.NotFound) { throw new NotFoundException(await response.Content.ReadAsStringAsync()); } string content = await response.Content.ReadAsStringAsync(); OnlineScore deserialized = JsonConvert.DeserializeObject<OnlineScore>(content); return deserialized ?? throw new BadResponseException(content); } public static async Task<int> GetLeaderboardLength(this ApiContext context) { string content = await (await context.Client.GetAsync(context.BaseUri?.ToString() + "scores/get_length")).Content.ReadAsStringAsync(); if (!int.TryParse(content, out var length)) { throw new BadResponseException(content); } return length; } public static async Task<OnlineScore> SubmitScore(this ApiContext context, SubmitScoreData scoreData) { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, context.BaseUri?.ToString() + "scores/submit_score"); await context.AddAuth(request); request.Content = new StringContent(JsonConvert.SerializeObject((object)scoreData)); string content = await (await context.Client.SendAsync(request)).Content.ReadAsStringAsync(); OnlineScore score = JsonConvert.DeserializeObject<OnlineScore>(content); return score ?? throw new BadResponseException(content); } } public static class Users { private const string UsersRoot = "users/"; private const string GetCurrencyAmountEndpoint = "get_currency_amount"; private const string GetAchievementsEndpoint = "get_achievements?steamId={0}"; private const string GrantAchievementEndpoint = "grant_achievement"; private const string GetUsernameEndpoint = "get_username?steamId={0}"; private const string LifetimeStatsEndpoint = "lifetime_stats?steamId={0}"; private const string GetBestScoreEndpoint = "get_best_score?steamId={0}"; public static async Task<int> GetCurrencyAmount(this ApiContext context) { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, context.BaseUri?.ToString() + "users/get_currency_amount"); await context.AddAuth(request); HttpResponseMessage response = await context.Client.SendAsync(request); if (response.StatusCode == HttpStatusCode.InternalServerError) { throw new InternalServerException(); } if (response.StatusCode == HttpStatusCode.BadRequest) { throw new BadRequestException(await response.Content.ReadAsStringAsync()); } string content = await response.Content.ReadAsStringAsync(); if (!int.TryParse(content, out var amount)) { throw new BadResponseException(content); } return amount; } public static async Task<List<OwnedAchievement>> GetAchievements(this ApiContext context, ulong userId) { HttpResponseMessage response = await context.Client.GetAsync(context.BaseUri?.ToString() + "users/" + $"get_achievements?steamId={userId}"); if (response.StatusCode == HttpStatusCode.NotFound) { throw new BadRequestException($"the user with ID {userId} was not found"); } if (response.StatusCode == HttpStatusCode.InternalServerError) { throw new InternalServerException(); } string content = await response.Content.ReadAsStringAsync(); List<OwnedAchievement> list = JsonConvert.DeserializeObject<List<OwnedAchievement>>(content); return list ?? throw new BadResponseException(content); } public static async Task<string> GetUsername(this ApiContext context, ulong userId) { HttpResponseMessage response = await context.Client.GetAsync(context.BaseUri?.ToString() + "users/" + $"get_username?steamId={userId}"); if (response.StatusCode == HttpStatusCode.NotFound) { throw new BadRequestException($"the user with ID {userId} was not found"); } return await response.Content.ReadAsStringAsync(); } public static async Task GrantAchievement(this ApiContext context, string achievementId) { HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, context.BaseUri?.ToString() + "users/grant_achievement"); await context.AddAuth(request); request.Content = new StringContent(achievementId); HttpResponseMessage response = await context.Client.SendAsync(request); if (response.StatusCode == HttpStatusCode.InternalServerError) { throw new InternalServerException(); } if (response.StatusCode == HttpStatusCode.BadRequest) { throw new BadRequestException(await response.Content.ReadAsStringAsync()); } } public static async Task<Score> GetLifetimeStats(this ApiContext context, ulong userId) { HttpResponseMessage response = await context.Client.GetAsync(context.BaseUri?.ToString() + "users/" + $"lifetime_stats?steamId={userId}"); if (response.StatusCode == HttpStatusCode.NotFound) { throw new BadRequestException($"the user with ID {userId} was not found"); } if (response.StatusCode == HttpStatusCode.InternalServerError) { throw new InternalServerException(); } string content = await response.Content.ReadAsStringAsync(); Score deserialized = JsonConvert.DeserializeObject<Score>(content); return deserialized ?? throw new BadResponseException(content); } public static async Task<OnlineScore> GetBestScore(this ApiContext context, ulong userId) { HttpResponseMessage response = await context.Client.GetAsync(context.BaseUri?.ToString() + "users/" + $"get_best_score?steamId={userId}"); if (response.StatusCode == HttpStatusCode.NotFound) { throw new BadRequestException($"the user with ID {userId} was not found"); } if (response.StatusCode == HttpStatusCode.InternalServerError) { throw new InternalServerException(); } string content = await response.Content.ReadAsStringAsync(); OnlineScore deserialized = JsonConvert.DeserializeObject<OnlineScore>(content); return deserialized ?? throw new BadResponseException(content); } } } namespace EndlessDelivery.Api.Exceptions { public class BadResponseException : Exception { public BadResponseException(string response) : base("Failed to parse response. Library may be out of date or server offline (\"" + response + "\").") { } } public class InternalServerException : Exception { public InternalServerException() : base("Internal server error.") { } } public class NotFoundException : Exception { public NotFoundException(string serverReason) : base("Not found - " + serverReason) { } } public class PermissionException : Exception { public PermissionException(string requirement = "") : base("The current user has insufficient permissions to perform this action. " + requirement) { } } }
plugins/Divine Delivery/EndlessDelivery.Common.dll
Decompiled 2 days agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using EndlessDelivery.Common.Communication.Scores; using EndlessDelivery.Common.Inventory.Items; using Microsoft.CodeAnalysis; using Newtonsoft.Json; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("EndlessDelivery.Common")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+b5dc0c560e2a25aa15f1eef619719550a062d078")] [assembly: AssemblyProduct("EndlessDelivery.Common")] [assembly: AssemblyTitle("EndlessDelivery.Common")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EndlessDelivery.Common { public class Achievement { public string Name; public string Id; public string Description; public ClientWebPair Icon; public string[] ItemGrants; public bool HideDetails; public bool Serverside; public bool Disabled = false; } public static class DdUtils { public static string IntToDifficulty(int diff) { if (1 == 0) { } string result = diff switch { 0 => "HARMLESS", 1 => "LENIENT", 2 => "STANDARD", 3 => "VIOLENT", 4 => "BRUTAL", 5 => "UKMD", _ => throw new Exception("Invalid difficulty."), }; if (1 == 0) { } return result; } public static string ToWordString(this TimeSpan timeSpan) { string text = string.Format("{0} minute{1}", timeSpan.Minutes, (timeSpan.Minutes == 1) ? string.Empty : "s"); if (timeSpan.Hours > 0) { text = string.Format("{0} hour{1}, ", timeSpan.Hours, (timeSpan.Hours == 1) ? string.Empty : "s") + text; } if (timeSpan.Days > 0) { text = string.Format("{0} day{1}, ", timeSpan.Days, (timeSpan.Days == 1) ? string.Empty : "s") + text; } return text; } } public class OwnedAchievement { public DateTime Achieved; public string Id; public OwnedAchievement(DateTime achieved, string id) { Achieved = achieved; Id = id; } public OwnedAchievement() { } } public class Score { public readonly int Rooms; public readonly int Kills; public readonly int Deliveries; public readonly float Time; public readonly int StartRoom; [JsonIgnore] public int MoneyGain => Deliveries / 4 * 10 + Kills / 5; private static bool IsLargerThanOtherScore(Score score, Score other) { if (score.Rooms != other.Rooms) { if (score.Rooms > other.Rooms) { return true; } return false; } if (score.Deliveries != other.Deliveries) { if (score.Deliveries > other.Deliveries) { return true; } return false; } if (score.Kills != other.Kills) { if (score.Kills > other.Kills) { return true; } return false; } if (score.Time != other.Time) { if (score.Time < other.Time) { return true; } return false; } return false; } public Score(int rooms, int kills, int deliveries, float time, int startRoom = 0) { Rooms = rooms; Kills = kills; Deliveries = deliveries; Time = time; StartRoom = startRoom; } public static Score operator +(Score a, Score b) { return new Score(a.Rooms + b.Rooms, a.Kills + b.Kills, a.Deliveries + b.Deliveries, a.Time + b.Time); } public static Score operator -(Score a, Score b) { return new Score(a.Rooms - b.Rooms, a.Kills - b.Kills, a.Deliveries - b.Deliveries, a.Time - b.Time); } public static bool operator >(Score a, Score b) { return IsLargerThanOtherScore(a, b); } public static bool operator <(Score a, Score b) { return IsLargerThanOtherScore(b, a); } public override string ToString() { return $"[Score {Rooms} {Kills} {Deliveries} {Time}]"; } } } namespace EndlessDelivery.Common.Inventory.Items { public class Banner : Item { public ClientWebPair Asset; public Banner(ClientWebPair asset, ItemDescriptor descriptor) : base(descriptor) { Asset = asset; } public Banner() { } } [Serializable] public class ClientWebPair { public string AssetUri; public string AddressablePath; } public class CosmeticLoadout { public static readonly List<string> DefaultItems = new List<string>(10) { "revolver_default", "altrevolver_default", "shotgun_default", "altshotgun_default", "nailgun_default", "altnailgun_default", "railcannon_default", "rocket_default", "banner_default", "present_default" }; public string BannerId; public string PresentId; public List<string> RevolverIds = new List<string>(); public List<string> AltRevolverIds = new List<string>(); public List<string> ShotgunIds = new List<string>(); public List<string> AltShotgunIds = new List<string>(); public List<string> NailgunIds = new List<string>(); public List<string> AltNailgunIds = new List<string>(); public List<string> RailcannonIds = new List<string>(); public List<string> RocketIds = new List<string>(); public static CosmeticLoadout Default => new CosmeticLoadout { BannerId = "banner_default", PresentId = "present_default", RevolverIds = new List<string>(3) { "revolver_default", "revolver_default", "revolver_default" }, AltRevolverIds = new List<string>(3) { "altrevolver_default", "altrevolver_default", "altrevolver_default" }, ShotgunIds = new List<string>(3) { "shotgun_default", "shotgun_default", "shotgun_default" }, AltShotgunIds = new List<string>(3) { "altshotgun_default", "altshotgun_default", "altshotgun_default" }, NailgunIds = new List<string>(3) { "nailgun_default", "nailgun_default", "nailgun_default" }, AltNailgunIds = new List<string>(3) { "altnailgun_default", "altnailgun_default", "altnailgun_default" }, RailcannonIds = new List<string>(3) { "railcannon_default", "railcannon_default", "railcannon_default" }, RocketIds = new List<string>(3) { "rocket_default", "rocket_default", "rocket_default" } }; } public abstract class Item { public ItemDescriptor Descriptor; public Item(ItemDescriptor descriptor) { Descriptor = descriptor; } protected Item() { } } public class ItemDescriptor { public StoreItemType Type; public string Id; public string Name; public int ShopPrice; public ClientWebPair Icon; public ItemDescriptor(string id, string name, ClientWebPair icon, StoreItemType type, int shopPrice = 0) { Id = id; Name = name; Icon = icon; Type = type; ShopPrice = shopPrice; } public ItemDescriptor() { } } public enum StoreItemType { Banner, Revolver, Shotgun, Nailgun, Rail, Rocket, Present, AltRevolver, AltShotgun, AltNailgun } public class WeaponSkinItem : Item { } public enum GunType { Revolver, AltRevolver, Shotgun, AltShotgun, Nailgun, AltNailgun, Railcannon, RocketLauncher } } namespace EndlessDelivery.Common.ContentFile { public class CalendarReward { public bool IsLastDay; public DateTime Date; public string Name; public string Description; public string Subtitle; public ClientWebPair Icon; public string Id; public bool HasItem; public string ItemId; public bool HasCurrency; public int CurrencyAmount; } public class Cms { public List<DatedRoomPool> RoomPools = new List<DatedRoomPool>(); public Dictionary<string, CalendarReward> CalendarRewards = new Dictionary<string, CalendarReward>(); public Dictionary<string, Achievement> Achievements = new Dictionary<string, Achievement>(); public Dictionary<string, Banner> Banners = new Dictionary<string, Banner>(); public Dictionary<string, WeaponSkinItem> Revolvers = new Dictionary<string, WeaponSkinItem>(); public Dictionary<string, WeaponSkinItem> AltRevolvers = new Dictionary<string, WeaponSkinItem>(); public Dictionary<string, WeaponSkinItem> Shotguns = new Dictionary<string, WeaponSkinItem>(); public Dictionary<string, WeaponSkinItem> AltShotguns = new Dictionary<string, WeaponSkinItem>(); public Dictionary<string, WeaponSkinItem> Nailguns = new Dictionary<string, WeaponSkinItem>(); public Dictionary<string, WeaponSkinItem> AltNailguns = new Dictionary<string, WeaponSkinItem>(); public Dictionary<string, WeaponSkinItem> Railcannons = new Dictionary<string, WeaponSkinItem>(); public Dictionary<string, WeaponSkinItem> Rockets = new Dictionary<string, WeaponSkinItem>(); public Dictionary<string, WeaponSkinItem> Presents = new Dictionary<string, WeaponSkinItem>(); public List<ShopRotation> ShopRotations = new List<ShopRotation>(); public Dictionary<string, string> Strings = new Dictionary<string, string>(); public Dictionary<string, string> BannedMods = new Dictionary<string, string>(); [JsonIgnore] public string Hash { get { using MD5 mD = MD5.Create(); string s = JsonConvert.SerializeObject((object)this, (Formatting)0); byte[] bytes = Encoding.UTF8.GetBytes(s); byte[] array = mD.ComputeHash(bytes); return BitConverter.ToString(array).Replace("-", "").ToLowerInvariant(); } } [JsonIgnore] public CalendarReward CurrentCalendarReward => CalendarRewards.FirstOrDefault((KeyValuePair<string, CalendarReward> x) => x.Value.Date == DateTime.UtcNow.Date).Value; [JsonIgnore] public ShopRotation ActiveShopRotation { get { foreach (ShopRotation shopRotation in ShopRotations) { if (shopRotation.Start > DateTime.UtcNow || shopRotation.Start + shopRotation.Length < DateTime.UtcNow) { continue; } return shopRotation; } return null; } } [JsonIgnore] public DatedRoomPool? CurrentRoomPool { get { DatedRoomPool datedRoomPool = null; foreach (DatedRoomPool roomPool in RoomPools) { if (datedRoomPool == null || (roomPool.After > datedRoomPool.After && roomPool.After <= DateTime.UtcNow)) { datedRoomPool = roomPool; } } return datedRoomPool; } } public string GetString(string id) { return Strings.ContainsKey(id) ? Strings[id] : id; } public bool TryGetItem(string id, out Item item) { if (Banners.TryGetValue(id, out var value)) { item = value; return true; } Dictionary<string, WeaponSkinItem>[] array = new Dictionary<string, WeaponSkinItem>[9] { Revolvers, AltRevolvers, Shotguns, AltShotguns, Nailguns, AltNailguns, Railcannons, Rockets, Presents }; Dictionary<string, WeaponSkinItem>[] array2 = array; foreach (Dictionary<string, WeaponSkinItem> dictionary in array2) { if (dictionary.TryGetValue(id, out var value2)) { item = value2; return true; } } item = null; return false; } } public class DatedRoomPool { public DateTime After; public string AssetPath; } public class ShopRotation { public List<string> ItemIds; public DateTime Start; public TimeSpan Length; [JsonIgnore] public DateTime End => Start + Length; } } namespace EndlessDelivery.Common.Communication.Scores { public class OnlineScore { public ulong SteamId { get; set; } public Score Score { get; set; } public int Index { get; set; } public int CountryIndex { get; set; } public short Difficulty { get; set; } public DateTime Date { get; set; } } public class SubmitScoreData { public Score Score; public short Difficulty; public SubmitScoreData(Score score, short difficulty) { Score = score; Difficulty = difficulty; } } } namespace EndlessDelivery.Common.Achievements { public class BestRoomAchievement : ServerSideAchievement { private string _id; private int _room; public override string Id => _id; public override bool ShouldGrant(OnlineScore score, OnlineScore bestScore, Score lifetimeStats) { return bestScore.Score.Rooms >= _room; } public BestRoomAchievement(string id, int room) { _id = id; _room = room; } } public class LifetimeRoomsAchievement : ServerSideAchievement { private string _id; private int _rooms; public override string Id => _id; public override bool ShouldGrant(OnlineScore score, OnlineScore bestScore, Score lifetimeStats) { return lifetimeStats.Rooms >= _rooms; } public LifetimeRoomsAchievement(string id, int rooms) { _id = id; _rooms = rooms; } } public class MoneyAchievement : ServerSideAchievement { private string _id; private float _money; public override string Id => _id; public override bool ShouldGrant(OnlineScore score, OnlineScore bestScore, Score lifetimeStats) { return (float)score.Score.MoneyGain > _money; } public MoneyAchievement(string id, int money) { _id = id; _money = money; } } public class PlaytimeAchievement : ServerSideAchievement { private string _id; private float _seconds; public override string Id => _id; public override bool ShouldGrant(OnlineScore score, OnlineScore bestScore, Score lifetimeStats) { return lifetimeStats.Time >= _seconds; } public PlaytimeAchievement(string id, TimeSpan time) { _id = id; _seconds = (float)time.TotalSeconds; } } public abstract class ServerSideAchievement { public static ServerSideAchievement[] AllAchievements = new ServerSideAchievement[10] { new BestRoomAchievement("first_place_ach", 60), new BestRoomAchievement("ach_top25", 45), new BestRoomAchievement("ach_top50", 30), new LifetimeRoomsAchievement("ach_100rooms", 100), new LifetimeRoomsAchievement("ach_500rooms", 500), new LifetimeRoomsAchievement("ach_1000rooms", 1000), new PlaytimeAchievement("ach_2hours", TimeSpan.FromHours(2.0)), new PlaytimeAchievement("ach_10hours", TimeSpan.FromHours(10.0)), new PlaytimeAchievement("ach_20hours", TimeSpan.FromHours(20.0)), new MoneyAchievement("ach_money1", 300) }; public abstract string Id { get; } public abstract bool ShouldGrant(OnlineScore score, OnlineScore bestScore, Score lifetimeStats); } }
plugins/Divine Delivery/EndlessDelivery.dll
Decompiled 2 days ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Threading.Tasks; using AtlasLib.Saving; using AtlasLib.Utils; using AtlasLib.Weapons; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Logging; using Discord; using EndlessDelivery.Achievements; using EndlessDelivery.Anticheat; using EndlessDelivery.Api; using EndlessDelivery.Api.Exceptions; using EndlessDelivery.Api.Requests; using EndlessDelivery.Assets; using EndlessDelivery.Common; using EndlessDelivery.Common.Achievements; using EndlessDelivery.Common.Communication.Scores; using EndlessDelivery.Common.ContentFile; using EndlessDelivery.Common.Inventory.Items; using EndlessDelivery.Components; using EndlessDelivery.Config; using EndlessDelivery.Cosmetics; using EndlessDelivery.Cosmetics.Skins; using EndlessDelivery.Gameplay; using EndlessDelivery.Gameplay.EnemyGeneration; using EndlessDelivery.Gameplay.Firework; using EndlessDelivery.Gameplay.SpecialWaves; using EndlessDelivery.Gameplay.Ward; using EndlessDelivery.Online; using EndlessDelivery.ScoreManagement; using EndlessDelivery.UI; using EndlessDelivery.Utils; using HarmonyLib; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using ProjectProphet; using Steamworks; using Steamworks.Data; using TMPro; using UltraTweaker; using UltraTweaker.Tweaks; using UnityEngine; using UnityEngine.AddressableAssets; using UnityEngine.Audio; using UnityEngine.Events; using UnityEngine.ResourceManagement.AsyncOperations; using UnityEngine.SceneManagement; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.0", FrameworkDisplayName = ".NET Standard 2.0")] [assembly: AssemblyCompany("EndlessDelivery")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+85640807997ab32ab5c7711cdfca7086974d6d8e")] [assembly: AssemblyProduct("EndlessDelivery")] [assembly: AssemblyTitle("EndlessDelivery")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace EndlessDelivery { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("waffle.ultrakill.christmasdelivery", "Divine Delivery", "2.2.2")] public class Plugin : BaseUnityPlugin { public static ManualLogSource Log; public const string Name = "Divine Delivery"; public const string Version = "2.2.2"; public const string Guid = "waffle.ultrakill.christmasdelivery"; private void Start() { //IL_0033: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Log.LogInfo((object)"Divine Delivery has started !!"); AssetManager.LoadCatalog(); AssetManager.LoadDataFile(); OnlineFunctionality.Init(); new Harmony("waffle.ultrakill.christmasdelivery").PatchAll(); } } } namespace EndlessDelivery.Utils { public enum Axis { X, Y, Z } public static class MathsExtensions { public static IEnumerable<T> Shuffle<T>(this IEnumerable<T> source) { Random rng = new Random(); T[] elements = source.ToArray(); for (int i = elements.Length - 1; i >= 0; i--) { int swapIndex = rng.Next(i + 1); yield return elements[swapIndex]; elements[swapIndex] = elements[i]; } } public static List<T> ShuffleAndToList<T>(this IEnumerable<T> source) { List<T> list = new List<T>(); Random random = new Random(); T[] array = source.ToArray(); for (int num = array.Length - 1; num >= 0; num--) { int num2 = random.Next(num + 1); list.Add(array[num2]); array[num2] = array[num]; } return list; } public static T Pick<T>(this T[] array) { if (array.Length == 0) { return (T)(object)null; } return array[Random.Range(0, array.Length)]; } public static T Pick<T>(this List<T> list) { if (list.Count == 0) { return (T)(object)null; } return list[Random.Range(0, list.Count)]; } public static Vector3 Only(this Vector3 vector, params Axis[] axes) { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Unknown result type (might be due to invalid IL or missing references) return new Vector3(axes.Contains(Axis.X) ? vector.x : 0f, axes.Contains(Axis.Y) ? vector.y : 0f, axes.Contains(Axis.Z) ? vector.z : 0f); } } public static class TimeUtils { public static string Formatted(this TimeSpan span) { return span.ToString("mm\\:ss\\:fff", new CultureInfo("en-US")); } } } namespace EndlessDelivery.UI { [HarmonyPatch] public class AchievementHud : MonoSingleton<AchievementHud> { private static GameObject? s_asset; [SerializeField] private AudioSource? _soundEffect; [SerializeField] private GameObject? _holder; [SerializeField] private TMP_Text? _name; [SerializeField] private TMP_Text? _desc; [SerializeField] private Image? _icon; private bool _canShowNextAchievement = true; private Queue<Achievement> _achievements = new Queue<Achievement>(); public void AddAchievement(Achievement achievement) { _achievements.Enqueue(achievement); } private void Update() { if (_canShowNextAchievement && _achievements.Count != 0) { ((MonoBehaviour)this).StartCoroutine(ShowCoroutine(_achievements.Dequeue())); _canShowNextAchievement = false; } } private IEnumerator ShowCoroutine(Achievement achievement) { if ((Object)(object)_holder == (Object)null || (Object)(object)_name == (Object)null || (Object)(object)_desc == (Object)null || (Object)(object)_icon == (Object)null) { Plugin.Log.LogWarning((object)"AchievementHud has _holder, _name, _desc, or _icon null! Returning."); _canShowNextAchievement = true; yield break; } TMP_Text? name = _name; Cms? lastFetchedContent = OnlineFunctionality.LastFetchedContent; name.text = ((lastFetchedContent != null) ? lastFetchedContent.GetString(achievement.Name) : null) ?? achievement.Name; TMP_Text? desc = _desc; Cms? lastFetchedContent2 = OnlineFunctionality.LastFetchedContent; desc.text = ((lastFetchedContent2 != null) ? lastFetchedContent2.GetString(achievement.Description) : null) ?? achievement.Description; AsyncOperationHandle<Sprite> spriteLoad = Addressables.LoadAssetAsync<Sprite>((object)achievement.Icon.AddressablePath); yield return (object)new WaitUntil((Func<bool>)(() => spriteLoad.IsDone)); AudioSource? soundEffect = _soundEffect; if (soundEffect != null) { soundEffect.Play(); } _icon.sprite = spriteLoad.Result; _holder.SetActive(true); yield return (object)new WaitForSecondsRealtime(3f); Vector3 oldScale = _holder.transform.localScale; while (!_holder.transform.localScale.x.Equals(0f)) { _holder.transform.localScale = Vector3.MoveTowards(_holder.transform.localScale, new Vector3(0f, _holder.transform.localScale.y), Time.unscaledDeltaTime * 20f); yield return null; } _holder.SetActive(false); _holder.transform.localScale = oldScale; _canShowNextAchievement = true; } [HarmonyPatch(typeof(CanvasController), "Awake")] [HarmonyPostfix] private static void AddSelf(CanvasController __instance) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (s_asset == null) { s_asset = Addressables.LoadAssetAsync<GameObject>((object)"Assets/Delivery/Prefabs/HUD/Achievement UI.prefab").WaitForCompletion(); } Object.Instantiate<GameObject>(s_asset, ((Component)__instance).transform); } } public class AchievementTerminal : MonoBehaviour { [SerializeField] private TMP_Text _achievementNameText; [SerializeField] private TMP_Text _achievementDescText; [SerializeField] private TMP_Text _achievementUnlocksText; [SerializeField] private GameObject _buttonTemplate; [SerializeField] private Transform _achievementHolder; private void Awake() { SetAchievement(null); ((MonoBehaviour)this).StartCoroutine(PopulateAchievements()); } private IEnumerator PopulateAchievements() { ((Component)_achievementHolder).gameObject.SetActive(false); Task<Cms> cmsTask = OnlineFunctionality.GetContent(); Task<List<OwnedAchievement>> achievementsTask = Users.GetAchievements(OnlineFunctionality.Context, SteamId.op_Implicit(SteamClient.SteamId)); yield return (object)new WaitUntil((Func<bool>)(() => cmsTask.IsCompleted && achievementsTask.IsCompleted)); Cms cms = cmsTask.Result; List<string> ownedAchievementIds = achievementsTask.Result.Select((OwnedAchievement x) => x.Id).ToList(); foreach (Achievement achievement in cms.Achievements.Values.OrderBy((Achievement x) => !ownedAchievementIds.Contains(x.Id))) { if (!achievement.Disabled) { AddAchievement(achievement, ownedAchievementIds.Contains(achievement.Id)); } } ((Component)_achievementHolder).gameObject.SetActive(true); } private void AddAchievement(Achievement achievement, bool isOwned) { Object.Instantiate<GameObject>(_buttonTemplate, _achievementHolder).GetComponent<AchievementTerminalButton>().SetUp(this, achievement, isOwned); } public void SetAchievement(Achievement? achievement) { Cms cms = OnlineFunctionality.LastFetchedContent; _achievementNameText.text = ((achievement == null) ? "-" : cms.GetString(achievement.Name)); _achievementDescText.text = ((achievement == null) ? "-" : (achievement.HideDetails ? cms.GetString("game_ui.hidden_achievement") : cms.GetString(achievement.Description))); if (achievement == null) { _achievementUnlocksText.text = "-"; return; } List<Item> list = new List<Item>(); string[] itemGrants = achievement.ItemGrants; Item item = default(Item); foreach (string text in itemGrants) { if (cms.TryGetItem(text, ref item)) { list.Add(item); } } string @string = cms.GetString("game_ui.achievement_unlocks_nothing"); string individualTemplate = cms.GetString("game_ui.achievement_unlock_individual"); string arg = ((list.Count != 0) ? string.Join(", ", list.Select(delegate(Item x) { string arg2 = cms.GetString("category." + ((object)(StoreItemType)(ref x.Descriptor.Type)).ToString().ToLower()).ToLower(); string string2 = cms.GetString(x.Descriptor.Name); return string.Format(individualTemplate, string2, arg2); })) : cms.GetString(@string)); _achievementUnlocksText.text = string.Format(cms.GetString("game_ui.achievement_unlocks"), arg); } } public class AchievementTerminalButton : MonoBehaviour { [SerializeField] private Image _iconImage; [SerializeField] private Button _button; [SerializeField] private Image _buttonImage; [SerializeField] private Color _buttonAchievedColour; [SerializeField] private Color _buttonNotAchievedColour; private AchievementTerminal _parentTerminal; public void SetUp(AchievementTerminal parentTerminal, Achievement achievement, bool isOwned) { _parentTerminal = parentTerminal; ((MonoBehaviour)parentTerminal).StartCoroutine(SetUpCoroutine(achievement, isOwned)); } private IEnumerator SetUpCoroutine(Achievement achievement, bool isOwned) { Achievement achievement2 = achievement; ((Component)this).gameObject.SetActive(false); AsyncOperationHandle<Sprite> spriteLoad = Addressables.LoadAssetAsync<Sprite>((object)achievement2.Icon.AddressablePath); yield return (object)new WaitUntil((Func<bool>)(() => spriteLoad.IsDone)); _iconImage.sprite = spriteLoad.Result; ((Graphic)_buttonImage).color = (isOwned ? _buttonAchievedColour : _buttonNotAchievedColour); ((UnityEvent)_button.onClick).AddListener((UnityAction)delegate { _parentTerminal.SetAchievement(achievement2); }); ((Component)this).gameObject.SetActive(true); } } public class AdventCalendar : MonoBehaviour { private static readonly string[] s_buttonOrder = new string[25] { "day15_2024", "day16_2024", "day4_2024", "day25_2024", "day8_2024", "day22_2024", "day24_2024", "day18_2024", "day10_2024", "day20_2024", "day6_2024", "day13_2024", "day23_2024", "day3_2024", "day17_2024", "day7_2024", "day19_2024", "day14_2024", "day12_2024", "day1_2024", "day5_2024", "day9_2024", "day21_2024", "day2_2024", "day11_2024" }; [SerializeField] private GameObject _templateButton; [SerializeField] private Transform _buttonHolder; [SerializeField] private GameObject _claimPage; [SerializeField] private Image _iconImage; [SerializeField] private TMP_Text _nameTitle; [SerializeField] private TMP_Text _descriptionText; [SerializeField] private TMP_Text _subtitleText; [SerializeField] private Button _claimButton; [SerializeField] private TMP_Text _claimButtonText; [SerializeField] private TMP_Text _timeRemainingText; [SerializeField] private MoneyCounter _moneyCounter; private List<string> _ownedDays = new List<string>(); private List<GameObject> _buttons = new List<GameObject>(); private string _timeRemainingString = "{0}"; private DateTime _endTime; private Item? _selectedItem; private bool _rewardIsToday; private int _cachedCurrencyAmount; public void Claim() { CalendarReward todayReward = OnlineFunctionality.LastFetchedContent.CurrentCalendarReward; if (_rewardIsToday) { _ownedDays.Add(todayReward.Id); } _claimButtonText.text = OnlineFunctionality.LastFetchedContent.GetString("game_ui.calendar_claimed"); ((Selectable)_claimButton).interactable = false; Task.Run(async delegate { if (_rewardIsToday) { await Items.ClaimDailyReward(OnlineFunctionality.Context); if (todayReward.HasCurrency) { _cachedCurrencyAmount += todayReward.CurrencyAmount; } } else { Plugin.Log.LogInfo((object)("buying item " + _selectedItem.Descriptor.Id)); try { _cachedCurrencyAmount -= _selectedItem.Descriptor.ShopPrice; await Items.BuyItem(OnlineFunctionality.Context, _selectedItem.Descriptor.Id); } catch (Exception ex2) { Exception ex = ex2; Plugin.Log.LogError((object)ex.ToString()); } } await CosmeticManager.FetchLoadout(); _moneyCounter.RefreshMoney(_cachedCurrencyAmount); }); } public void EnableClaimUi(string dayId) { ((MonoBehaviour)this).StartCoroutine(EnableClaimUiCoroutine(dayId)); } private IEnumerator EnableClaimUiCoroutine(string dayId) { Cms cms = OnlineFunctionality.LastFetchedContent; CalendarReward reward = cms.CalendarRewards[dayId]; if ((!cms.TryGetItem(reward.ItemId, ref _selectedItem) || _selectedItem == null) && reward.HasItem) { Plugin.Log.LogWarning((object)(reward.ItemId + " has no item despite HasItem being true, calendar not showing (how has this happened)")); yield break; } AsyncOperationHandle<Sprite> loadIcon = Addressables.LoadAssetAsync<Sprite>((object)reward.Icon.AddressablePath); Task<int> getCurrency = Users.GetCurrencyAmount(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => loadIcon.IsDone && getCurrency.IsCompleted)); _cachedCurrencyAmount = getCurrency.Result; _moneyCounter.SetValue(_cachedCurrencyAmount); _iconImage.sprite = loadIcon.Result; _nameTitle.text = cms.GetString(reward.Name); _descriptionText.text = cms.GetString(reward.Description); _subtitleText.text = cms.GetString(reward.Subtitle); bool isClaimed = _ownedDays.Contains(dayId) || (_selectedItem != null && CosmeticManager.AllOwned.Contains(_selectedItem.Descriptor.Id)); _rewardIsToday = dayId == cms.CurrentCalendarReward?.Id; ((Selectable)_claimButton).interactable = !isClaimed && (_rewardIsToday || (reward.HasItem && _selectedItem.Descriptor.ShopPrice <= _cachedCurrencyAmount)); string missedString = (reward.HasItem ? string.Format(cms.GetString("game_ui.calendar_buy"), _selectedItem.Descriptor.ShopPrice) : cms.GetString("game_ui.calendar_missed")); string unclaimedString = (_rewardIsToday ? "game_ui.calendar_unclaimed" : missedString); _claimButtonText.text = cms.GetString(isClaimed ? "game_ui.calendar_claimed" : unclaimedString); _claimPage.SetActive(true); } private void Awake() { _timeRemainingString = OnlineFunctionality.LastFetchedContent.GetString("game_ui.shop_remaining_time"); ((MonoBehaviour)this).StartCoroutine(Refresh()); } private void FixedUpdate() { _timeRemainingText.text = string.Format(_timeRemainingString, DdUtils.ToWordString(_endTime - DateTime.UtcNow)); if (DateTime.UtcNow > _endTime) { ((MonoBehaviour)this).StartCoroutine(Refresh()); _endTime = DateTime.MaxValue; } } private IEnumerator Refresh() { CalendarReward next = OnlineFunctionality.LastFetchedContent.CurrentCalendarReward; bool hasNextDay = next != null && !next.IsLastDay; _endTime = ((!hasNextDay) ? DateTime.MaxValue : (next.Date + TimeSpan.FromDays(1.0))); ((Component)_timeRemainingText).gameObject.SetActive(hasNextDay); foreach (GameObject oldButton in _buttons) { Object.Destroy((Object)(object)oldButton); } Task<Cms> contentTask = OnlineFunctionality.GetContent(); yield return (object)new WaitUntil((Func<bool>)(() => contentTask.IsCompleted)); ((MonoBehaviour)this).StartCoroutine(CreateButtons()); } private IEnumerator CreateButtons() { Task<List<string>> getClaimedTask = Items.GetClaimedDailyRewards(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => getClaimedTask.IsCompleted)); _ownedDays = getClaimedTask.Result; string[] array = s_buttonOrder; foreach (string dayId in array) { if (!OnlineFunctionality.LastFetchedContent.CalendarRewards.ContainsKey(dayId)) { Plugin.Log.LogWarning((object)("Missing day ID " + dayId)); continue; } GameObject button = Object.Instantiate<GameObject>(_templateButton, _buttonHolder); _buttons.Add(button); button.GetComponent<AdventCalendarButton>().SetUp(this, OnlineFunctionality.LastFetchedContent.CalendarRewards[dayId]); } } } public class AdventCalendarButton : MonoBehaviour { [SerializeField] private TMP_Text _numberText; [SerializeField] private Button _button; [SerializeField] private Image _image; [SerializeField] private Color _todayColour; [SerializeField] private Color _beforeTodayColour; [SerializeField] private Color _afterTodayColour; public void SetUp(AdventCalendar parent, CalendarReward reward) { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Unknown result type (might be due to invalid IL or missing references) //IL_00ca: Unknown result type (might be due to invalid IL or missing references) AdventCalendar parent2 = parent; CalendarReward reward2 = reward; _numberText.text = reward2.Date.Day.ToString(); ((UnityEvent)_button.onClick).AddListener((UnityAction)delegate { parent2.EnableClaimUi(reward2.Id); }); Color color = _todayColour; if (reward2.Date.Date < DateTime.UtcNow.Date) { color = _beforeTodayColour; } if (reward2.Date.Date > DateTime.UtcNow.Date) { ((Selectable)_button).interactable = false; color = _afterTodayColour; } ((Graphic)_image).color = color; } } [HarmonyPatch] public class AltPresentHud : MonoBehaviour { public TMP_Text[] PresentTexts; public TMP_Text TimerText; public TMP_Text RoomText; public Color TimerColour; public Color TimerDangerColour; public void Update() { //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) if (MonoSingleton<GameManager>.Instance.GameStarted) { TimerText.text = TimeSpan.FromSeconds(MonoSingleton<GameManager>.Instance.TimeLeft).Formatted(); RoomText.text = MonoSingleton<GameManager>.Instance.RoomsComplete.ToString(); if (MonoSingleton<GameManager>.Instance.TimeLeft < 10f) { ((Graphic)TimerText).color = TimerDangerColour; } else { ((Graphic)TimerText).color = TimerColour; } int num = 0; Room currentRoom = MonoSingleton<GameManager>.Instance.CurrentRoom; TMP_Text[] presentTexts = PresentTexts; foreach (TMP_Text val in presentTexts) { val.text = $"{currentRoom.AmountDelivered[(WeaponVariant)num]}/{currentRoom.PresentColourAmounts[num]}"; num++; } } } [HarmonyPatch(typeof(HudController), "Start")] [HarmonyPostfix] private static void AddSelf(HudController __instance) { //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) if (__instance.altHud && !MapInfoBase.InstanceAnyType.hideStockHUD && AssetManager.InSceneFromThisMod) { GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"Assets/Delivery/Prefabs/HUD/Classic Present Hud.prefab").WaitForCompletion(); Object.Instantiate<GameObject>(val, UnityUtils.GetChild(((Component)__instance).gameObject, "Filler").transform); } } } public class CheatsFoundScreen : MonoBehaviour { [SerializeField] private TMP_Text _reasonsText; private void Awake() { if (!EndlessDelivery.Anticheat.Anticheat.HasIllegalMods(out List<string> reasons)) { ((Component)this).gameObject.SetActive(false); return; } DisablePlayer(); _reasonsText.text = string.Join("; ", reasons); ((Component)this).gameObject.SetActive(true); } private void Update() { Cursor.visible = true; Cursor.lockState = (CursorLockMode)2; ((Behaviour)MonoSingleton<NewMovement>.Instance).enabled = false; ((Behaviour)MonoSingleton<GunControl>.Instance).enabled = false; ((Behaviour)MonoSingleton<FistControl>.Instance).enabled = false; Time.timeScale = 0f; } private void DisablePlayer() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown GameStateManager.Instance.RegisterState(new GameState("pause_cheatscreen", (GameObject[])(object)new GameObject[1] { ((Component)this).gameObject }) { cursorLock = (LockMode)2, cameraInputLock = (LockMode)1, playerInputLock = (LockMode)1 }); ((Behaviour)MonoSingleton<NewMovement>.Instance).enabled = false; ((Behaviour)MonoSingleton<GunControl>.Instance).enabled = false; ((Behaviour)MonoSingleton<FistControl>.Instance).enabled = false; Time.timeScale = 0f; } public void ReenablePlayer() { ((Behaviour)MonoSingleton<NewMovement>.Instance).enabled = true; ((Behaviour)MonoSingleton<GunControl>.Instance).enabled = true; ((Behaviour)MonoSingleton<FistControl>.Instance).enabled = true; MonoSingleton<TimeController>.Instance.RestoreTime(); } } public class ColourSetter : MonoBehaviour { public int Colour; private void Start() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) Color colour = ConfigFile.Instance.Data.GetColour(Colour); Text val = default(Text); if (((Component)this).TryGetComponent<Text>(ref val)) { ((Graphic)val).color = colour; } TMP_Text val2 = default(TMP_Text); if (((Component)this).TryGetComponent<TMP_Text>(ref val2)) { ((Graphic)val2).color = colour; } Image val3 = default(Image); if (((Component)this).TryGetComponent<Image>(ref val3)) { ((Graphic)val3).color = colour; } } } [HarmonyPatch] public class DeliveryButton { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__0_0; internal void <AddButton>b__0_0() { ((MonoBehaviour)CoroutineRunner.Instance).StartCoroutine(LoadWhenLogged()); } } [HarmonyPatch(typeof(CanvasController), "Awake")] [HarmonyPostfix] private static void AddButton(CanvasController __instance) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Expected O, but got Unknown GameObject child = UnityUtils.GetChild(((Component)__instance).gameObject, "Chapter Select"); if ((Object)(object)child == (Object)null) { return; } GameObject child2 = UnityUtils.GetChild(child, "The Cyber Grind"); RectTransform component = child2.GetComponent<RectTransform>(); component.sizeDelta -= new Vector2(55f, 0f); ((Transform)component).position = ((Transform)component).position - new Vector3(27.5f, 0f, 0f); GameObject val = Object.Instantiate<GameObject>(Addressables.LoadAssetAsync<GameObject>((object)"Assets/Delivery/Prefabs/HUD/Jolly Chapter Select Button.prefab").WaitForCompletion(), child.transform); ButtonClickedEvent onClick = val.GetComponent<Button>().onClick; object obj = <>c.<>9__0_0; if (obj == null) { UnityAction val2 = delegate { ((MonoBehaviour)CoroutineRunner.Instance).StartCoroutine(LoadWhenLogged()); }; <>c.<>9__0_0 = val2; obj = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj); } private static IEnumerator LoadWhenLogged() { Task<bool> isOnlineTask = Api.ServerOnline(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => isOnlineTask.IsCompleted)); yield return (object)new WaitUntil((Func<bool>)(() => OnlineFunctionality.LoggedIn || !isOnlineTask.Result)); AssetManager.LoadSceneUnsanitzed("Assets/Delivery/Scenes/Game Scene.unity"); } } [HarmonyPatch] public class EndScreen : MonoSingleton<EndScreen> { public GameObject[] ToAppear; public GameObject AudioObject; public Image HighscoreFlash; public float Delay = 0.25f; public float SkippingDelay = 0.05f; [Space(10f)] public ReachValueText Rooms; public ReachValueText Kills; public ReachValueText Deliveries; public ReachValueText TimeElapsed; [Space(10f)] public Text BestRooms; public Text BestKills; public Text BestDeliveries; public Text BestTimeElapsed; [Space(10f)] public ReachValueText MoneyGainText; [Space(10f)] public GameObject Leaderboard; public GameObject EverythingButLeaderboard; [HideInInspector] public bool NewBest; [HideInInspector] public ReachValueText CurrentText; [HideInInspector] public Score PreviousHighscore; private int _currentIndex; private float _timeSinceComplete; private bool _appearedSelf; private bool _complete; private bool _leaderboardShown; public bool Skipping => MonoSingleton<InputManager>.Instance.InputSource.Fire1.WasPerformedThisFrame || MonoSingleton<InputManager>.Instance.InputSource.Jump.WasPerformedThisFrame; private void Awake() { GameObject[] toAppear = ToAppear; foreach (GameObject val in toAppear) { val.SetActive(false); } } public void Appear() { SetPanelValues(MonoSingleton<GameManager>.Instance.CurrentScore, Rooms, Kills, Deliveries, TimeElapsed); SetPanelValues(NewBest ? PreviousHighscore : ScoreManager.CurrentDifficultyHighscore, BestRooms, BestKills, BestDeliveries, BestTimeElapsed); MoneyGainText.Target = MonoSingleton<GameManager>.Instance.CurrentScore.MoneyGain; ((MonoBehaviour)this).StartCoroutine(AppearCoroutine()); } private IEnumerator AppearCoroutine() { TimeController timeController = MonoSingleton<TimeController>.Instance; timeController.controlTimeScale = false; while (timeController.timeScale > 0f) { timeController.timeScale = Mathf.MoveTowards(timeController.timeScale, 0f, Time.unscaledDeltaTime * (timeController.timeScale + 0.01f)); Time.timeScale = timeController.timeScale * timeController.timeScaleModifier; MonoSingleton<AudioMixerController>.Instance.allSound.SetFloat("allPitch", timeController.timeScale); MonoSingleton<AudioMixerController>.Instance.allSound.SetFloat("allVolume", 0.5f + timeController.timeScale / 2f); MonoSingleton<AudioMixerController>.Instance.musicSound.SetFloat("allPitch", timeController.timeScale); MonoSingleton<MusicManager>.Instance.volume = 0.5f + timeController.timeScale / 2f; yield return null; } ShowNext(); _appearedSelf = true; MonoSingleton<MusicManager>.Instance.forcedOff = true; MonoSingleton<MusicManager>.Instance.StopMusic(); AudioObject.SetActive(true); } private void SetPanelValues(Score score, ReachValueText rooms, ReachValueText kills, ReachValueText deliveries, ReachValueText time) { rooms.Target = score.Rooms; kills.Target = score.Kills; deliveries.Target = score.Deliveries; time.Target = score.Time; } private void SetPanelValues(Score score, Text rooms, Text kills, Text deliveries, Text time) { int rooms2 = score.Rooms; rooms.text = rooms2.ToString(); rooms2 = score.Kills; kills.text = rooms2.ToString(); rooms2 = score.Deliveries; deliveries.text = rooms2.ToString(); time.text = TimeSpan.FromSeconds(score.Time).Formatted(); } private void Update() { if (_appearedSelf) { ReachValueText currentText = CurrentText; if (currentText == null || currentText.Done) { _timeSinceComplete += Time.unscaledDeltaTime; } if ((_timeSinceComplete >= ((!Skipping) ? Delay : SkippingDelay) && _currentIndex != ToAppear.Length) || Skipping) { ShowNext(); _timeSinceComplete = 0f; } } } private void ShowNext() { if (_currentIndex == ToAppear.Length) { if (!_leaderboardShown) { Leaderboard.SetActive(true); EverythingButLeaderboard.SetActive(false); _leaderboardShown = true; } else { MonoSingleton<NewMovement>.Instance.hp = 0; _complete = true; } } else { ToAppear[_currentIndex++].SetActive(true); } } public void DoFlashIfApplicable() { if (NewBest) { SetPanelValues(ScoreManager.CurrentDifficultyHighscore, BestRooms, BestKills, BestDeliveries, BestTimeElapsed); ((MonoBehaviour)this).StartCoroutine(DoHighscoreFlash()); } } private IEnumerator DoHighscoreFlash() { ((Graphic)HighscoreFlash).color = new Color(1f, 1f, 1f, 1f); ((Component)HighscoreFlash).GetComponent<AudioSource>().Play(); while (((Graphic)HighscoreFlash).color.a != 0f) { ((Graphic)HighscoreFlash).color = new Color(1f, 1f, 1f, Mathf.MoveTowards(((Graphic)HighscoreFlash).color.a, 0f, Time.unscaledDeltaTime)); yield return null; } } [HarmonyPatch(typeof(CanvasController), "Awake")] [HarmonyPostfix] private static void CreateSelf() { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Object.Instantiate<GameObject>(Addressables.LoadAssetAsync<GameObject>((object)"Assets/Delivery/Prefabs/HUD/Delivery End Screen.prefab").WaitForCompletion()); } } public class EndScreenLeaderboards : MonoBehaviour { public Text[] ConnectingToServerText; public Transform TopLeaderboardContainer; public Transform NearbyLeaderboardContainer; public GameObject EntryTemplate; public void OnEnable() { DoStuff(); } private async Task DoStuff() { if (MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0) < 3) { Text[] connectingToServerText = ConnectingToServerText; foreach (Text text3 in connectingToServerText) { text3.text = "LEADERBOARDS ARE ONLY ON VIOLENT AND ABOVE"; } return; } if (!(await Api.ServerOnline(OnlineFunctionality.Context))) { Text[] connectingToServerText2 = ConnectingToServerText; foreach (Text text2 in connectingToServerText2) { text2.text = "FAILED TO CONNECT :^("; } return; } int ownPosition = await Scores.GetLeaderboardPosition(OnlineFunctionality.Context, SteamId.op_Implicit(SteamClient.SteamId)); OnlineScore[] nearScores = await Scores.GetScoreRange(OnlineFunctionality.Context, Mathf.Max(ownPosition - 5, 0), 10); OnlineScore[] topScores = await Scores.GetScoreRange(OnlineFunctionality.Context, 0, 10); OnlineScore[] array = nearScores; foreach (OnlineScore scoreResult in array) { Object.Instantiate<GameObject>(EntryTemplate, NearbyLeaderboardContainer).GetComponent<LeaderboardEntry>().SetValuesAndEnable((MonoBehaviour)(object)this, scoreResult); } OnlineScore[] array2 = topScores; foreach (OnlineScore scoreResult2 in array2) { Object.Instantiate<GameObject>(EntryTemplate, TopLeaderboardContainer).GetComponent<LeaderboardEntry>().SetValuesAndEnable((MonoBehaviour)(object)this, scoreResult2); } Text[] connectingToServerText3 = ConnectingToServerText; foreach (Text text in connectingToServerText3) { ((Component)text).gameObject.SetActive(false); } } } public class JollyTerminal : MonoBehaviour { public GameObject[] DisableIfNotOnHighscoreDifficulty; private void OnEnable() { bool active = MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0) >= 3; GameObject[] disableIfNotOnHighscoreDifficulty = DisableIfNotOnHighscoreDifficulty; foreach (GameObject val in disableIfNotOnHighscoreDifficulty) { val.SetActive(active); } } } public class JollyTerminalLeaderboards : MonoBehaviour { public Button[] PageButtons; public Button JumpToSelfButton; public LeaderboardEntry[] Entries; public LeaderboardEntry OwnEntry; public TMP_Text PageText; private OnlineScore[] _pageScores; private int _page; private int? _pageAmount = null; private Coroutine? _lastRefresh; private OnlineScore? _ownScore; private async Task SetStuff() { if (await Api.ServerOnline(OnlineFunctionality.Context)) { _pageAmount = Mathf.CeilToInt((float)(await Scores.GetLeaderboardLength(OnlineFunctionality.Context)) / (float)Entries.Length); RefreshPageText(); try { _ownScore = await Scores.GetLeaderboardScore(OnlineFunctionality.Context, SteamId.op_Implicit(SteamClient.SteamId)); } catch (NotFoundException) { _ownScore = null; } OwnEntry.SetValuesAndEnable((MonoBehaviour)(object)this, _ownScore); if (_ownScore == null) { ((Selectable)JumpToSelfButton).interactable = false; } } } public void OnEnable() { LeaderboardEntry[] entries = Entries; foreach (LeaderboardEntry leaderboardEntry in entries) { ((Component)leaderboardEntry).gameObject.SetActive(false); } _lastRefresh = ((MonoBehaviour)this).StartCoroutine(RefreshPage()); } public void ScrollPage(int amount) { if (_page + amount >= 0 && !(_page + amount > _pageAmount - 1)) { RefreshPageText(); SetPage(_page + amount); } } public void SetPage(int page) { _page = page; _lastRefresh = ((MonoBehaviour)this).StartCoroutine(RefreshPage()); } private void RefreshPageText() { PageText.text = _page + 1 + " / " + ((!_pageAmount.HasValue) ? "-" : _pageAmount.ToString()); } public void JumpToSelf() { if (_ownScore == null) { Plugin.Log.LogWarning((object)"JumpToSelf with null _ownScore - should be impossible"); return; } int page = Mathf.FloorToInt((float)_ownScore.Index / (float)Entries.Length); SetPage(page); } private static async Task<OnlineScore[]> GetPage(int pageIndex, int pageSize) { int scoreCount = await Scores.GetLeaderboardLength(OnlineFunctionality.Context); int startIndex = pageIndex * pageSize; int amount = Mathf.Min(scoreCount - startIndex, pageSize); return await Scores.GetScoreRange(OnlineFunctionality.Context, pageIndex * pageSize, amount); } public void OpenWebsite() { Application.OpenURL(OnlineFunctionality.LastFetchedContent.GetString("constants.website")); } public void JoinDiscord() { Application.OpenURL(OnlineFunctionality.LastFetchedContent.GetString("constants.discord")); } private IEnumerator RefreshPage() { if (_lastRefresh != null) { ((MonoBehaviour)this).StopCoroutine(_lastRefresh); } Task<bool> onlineTask = Api.ServerOnline(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => onlineTask.IsCompleted)); if (!onlineTask.Result) { MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Server offline!", "", "", 0, false); ((Component)this).gameObject.SetActive(false); yield break; } bool jumpToSelfWasEnabled = ((Selectable)JumpToSelfButton).interactable; Button[] pageButtons = PageButtons; foreach (Button button in pageButtons) { ((Selectable)button).interactable = false; } Task<OnlineScore[]> scoreTask = GetPage(_page, Entries.Length); Task setStuff = SetStuff(); yield return (object)new WaitUntil((Func<bool>)(() => scoreTask.IsCompleted && setStuff.IsCompleted)); _pageScores = scoreTask.Result; for (int i = 0; i < Entries.Length; i++) { if (i < _pageScores.Length) { Entries[i].SetValuesAndEnable((MonoBehaviour)(object)this, _pageScores[i]); } else { ((Component)Entries[i]).gameObject.SetActive(false); } } Button[] pageButtons2 = PageButtons; foreach (Button button2 in pageButtons2) { ((Selectable)button2).interactable = true; } if (!jumpToSelfWasEnabled) { ((Selectable)JumpToSelfButton).interactable = jumpToSelfWasEnabled; } } } public class JollyTerminalShop : MonoBehaviour { [SerializeField] private GameObject _templatePanel; [SerializeField] private Transform _panelHolder; [SerializeField] private AudioSource _buySound; [SerializeField] private AudioSource _buyError; [SerializeField] private TMP_Text _timeRemainingText; [SerializeField] private MoneyCounter _moneyCounter; private List<ShopItemPanel> _panels = new List<ShopItemPanel>(); private bool _hasInitialized = false; private int _totalMoney = 0; private DateTime _endTime; private string _timeRemainingString = "{0}"; private void OnEnable() { ((MonoBehaviour)this).StartCoroutine(InitializeIfOnline()); } private void FixedUpdate() { if (!(_endTime == default(DateTime))) { _timeRemainingText.text = string.Format(_timeRemainingString, DdUtils.ToWordString(_endTime - DateTime.UtcNow)); if (DateTime.UtcNow > _endTime) { ((MonoBehaviour)this).StartCoroutine(RefreshShop()); _endTime = DateTime.MaxValue; } } } private IEnumerator InitializeIfOnline() { Task<bool> onlineTask = Api.ServerOnline(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => onlineTask.IsCompleted)); if (!onlineTask.Result) { MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Server offline!", "", "", 0, false); yield break; } ((MonoBehaviour)this).StartCoroutine(SetInitialMoneyCoroutine()); ((MonoBehaviour)this).StartCoroutine(RefreshShop()); } private IEnumerator RefreshShop() { foreach (ShopItemPanel panel in _panels) { if (!((Object)(object)panel == (Object)null) && !((Object)(object)((Component)panel).gameObject == (Object)null)) { Object.Destroy((Object)(object)((Component)panel).gameObject); } } _panels.Clear(); Task<ShopRotation> shopTask = Items.GetActiveShop(OnlineFunctionality.Context); Task<Cms> cmsTask = OnlineFunctionality.GetContent(); yield return (object)new WaitUntil((Func<bool>)(() => shopTask.IsCompleted && cmsTask.IsCompleted)); _timeRemainingString = cmsTask.Result.GetString("game_ui.shop_remaining_time"); _endTime = shopTask.Result.End; Item item = default(Item); foreach (string itemId in shopTask.Result.ItemIds) { if (!cmsTask.Result.TryGetItem(itemId, ref item)) { Plugin.Log.LogWarning((object)("Shop rotation contains missing item: " + item.Descriptor.Id)); continue; } AddItem(item.Descriptor); item = null; } } private IEnumerator SetInitialMoneyCoroutine() { Task<int> moneyTask = Users.GetCurrencyAmount(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => moneyTask.IsCompleted)); _totalMoney = moneyTask.Result; _moneyCounter.SetValue(moneyTask.Result); _hasInitialized = true; } private void AddItem(ItemDescriptor item) { GameObject val = Object.Instantiate<GameObject>(_templatePanel, _panelHolder); val.SetActive(false); ShopItemPanel component = val.GetComponent<ShopItemPanel>(); _panels.Add(component); component.SetUp(this, item); } public void BuyItem(ItemDescriptor item) { if (item.ShopPrice > _totalMoney) { _buyError.Play(); return; } foreach (ShopItemPanel panel in _panels) { panel.Disable(); } ((MonoBehaviour)this).StartCoroutine(BuyItemCoroutine(item)); } private IEnumerator BuyItemCoroutine(ItemDescriptor item) { Task buyTask = Items.BuyItem(OnlineFunctionality.Context, item.Id); Task loadoutTask = CosmeticManager.FetchLoadout(); yield return (object)new WaitUntil((Func<bool>)(() => buyTask.IsCompleted && loadoutTask.IsCompleted)); Task refreshTask = CosmeticManager.FetchLoadout(); yield return (object)new WaitUntil((Func<bool>)(() => refreshTask.IsCompleted)); _buySound.Play(); _totalMoney -= item.ShopPrice; _moneyCounter.RefreshMoney(_totalMoney); foreach (ShopItemPanel itemPanel in _panels) { itemPanel.Enable(); } } } public class JollyTerminalStartPickButton : MonoBehaviour { [SerializeField] private Button _button; [SerializeField] private TMP_Text _text; public void Setup(JollyTerminalStartPicker picker, int startWave) { //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Expected O, but got Unknown JollyTerminalStartPicker picker2 = picker; StartTimes.StartTime currentTimes = ((SaveFile<StartTimes>)(object)StartTimes.Instance).Data.CurrentTimes; _text.text = startWave.ToString(); if (!currentTimes.UnlockedStartTimes.Contains(startWave)) { ((Selectable)_button).interactable = false; return; } ((UnityEvent)_button.onClick).AddListener((UnityAction)delegate { picker2.SetWave(startWave); }); } } public class JollyTerminalStartPicker : MonoBehaviour { [SerializeField] private TMP_Text? _timeDisplayText; [SerializeField] private GameObject? _buttonPrefab; [SerializeField] private Transform? _buttonHolder; private bool _hasPopulated; private void OnEnable() { if (!_hasPopulated) { Populate(); SetWave(((SaveFile<StartTimes>)(object)StartTimes.Instance).Data.CurrentTimes.SelectedWave); } } private void Populate() { if ((Object)(object)_buttonPrefab == (Object)null || (Object)(object)_buttonHolder == (Object)null) { throw new Exception("StartPicker Button prefab or button holder is null"); } int[] startableWaves = StartTimes.StartTime.StartableWaves; foreach (int startWave in startableWaves) { Object.Instantiate<GameObject>(_buttonPrefab, _buttonHolder).GetComponent<JollyTerminalStartPickButton>().Setup(this, startWave); } _hasPopulated = true; } public void SetWave(int wave) { StartTimes.StartTime currentTimes = ((SaveFile<StartTimes>)(object)StartTimes.Instance).Data.CurrentTimes; currentTimes.SelectedWave = wave; if ((Object)(object)_timeDisplayText == (Object)null) { Plugin.Log.LogWarning((object)"Time display text on start picker is null"); return; } string arg = TimeSpan.FromSeconds(currentTimes.GetRoomTime(wave)).ToString("mm\\:ss\\.fff", new CultureInfo("en-US")); _timeDisplayText.text = $"<size=20><color=orange>ROOM {wave}\n<size=15><color=#999999>TIME: {arg}"; } } public class LeaderboardEntry : MonoBehaviour { [Header("All monobehaviours here should implement IText")] public MonoBehaviour RankNumber; public MonoBehaviour Username; public MonoBehaviour Rooms; public MonoBehaviour Difficulty; public Image ProfileActual; public Image Banner; [SerializeField] private Sprite _loadingPfp; private Coroutine? _lastPfpSetter; private Coroutine? _lastBannerSetter; private Coroutine? _lastUsernameSetter; private Friend _user; private OnlineScore? _score; public void SetValuesAndEnable(MonoBehaviour coroutineRunner, OnlineScore? onlineScore) { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_0131: Unknown result type (might be due to invalid IL or missing references) if (onlineScore == null) { SetNullValues(); return; } _score = onlineScore; _user = new Friend(SteamId.op_Implicit(onlineScore.SteamId)); ((IText)RankNumber).SetText((onlineScore.Index + 1).ToString()); IText obj = (IText)Rooms; int rooms = onlineScore.Score.Rooms; obj.SetText(rooms.ToString()); ((IText)Difficulty).SetText(DdUtils.IntToDifficulty((int)onlineScore.Difficulty)); if (_lastUsernameSetter != null) { coroutineRunner.StopCoroutine(_lastUsernameSetter); } _lastUsernameSetter = coroutineRunner.StartCoroutine(SetUsername(_user)); if (_lastPfpSetter != null) { coroutineRunner.StopCoroutine(_lastPfpSetter); } _lastPfpSetter = coroutineRunner.StartCoroutine(SetAvatar(_user)); if ((Object)(object)Banner != (Object)null) { if (_lastBannerSetter != null) { coroutineRunner.StopCoroutine(_lastBannerSetter); } _lastBannerSetter = coroutineRunner.StartCoroutine(SetBanner(_user)); } ((Component)this).gameObject.SetActive(true); } public void SetNullValues() { ((IText)RankNumber).SetText("#-"); ((IText)Username).SetText("-"); ((IText)Rooms).SetText("-"); ((IText)Difficulty).SetText("(-)"); ProfileActual.sprite = _loadingPfp; ((Component)this).gameObject.SetActive(true); } private IEnumerator SetUsername(Friend user) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) Task<string> usernameTask = Users.GetUsername(OnlineFunctionality.Context, SteamId.op_Implicit(user.Id)); yield return (object)new WaitUntil((Func<bool>)(() => usernameTask.IsCompleted)); string username = usernameTask.Result; if (_score.SteamId == SteamId.op_Implicit(SteamClient.SteamId)) { username = "<color=orange>" + username + "</color>"; } ((IText)Username).SetText(username); } private IEnumerator SetAvatar(Friend user) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) ProfileActual.sprite = _loadingPfp; Task<Image?> imageTask = ((Friend)(ref user)).GetMediumAvatarAsync(); yield return (object)new WaitUntil((Func<bool>)(() => imageTask.IsCompleted)); Texture2D texture2D = new Texture2D((int)imageTask.Result.Value.Width, (int)imageTask.Result.Value.Height, (TextureFormat)4, false); texture2D.LoadRawTextureData(imageTask.Result.Value.Data); texture2D.Apply(); ProfileActual.sprite = Sprite.Create(texture2D, new Rect(0f, 0f, (float)((Texture)texture2D).width, (float)((Texture)texture2D).height), Vector2.one / 2f); } private IEnumerator SetBanner(Friend user) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) ((Component)Banner).gameObject.SetActive(false); Task<CosmeticLoadout> loadoutTask = Items.GetLoadout(OnlineFunctionality.Context, SteamId.op_Implicit(user.Id)); Task<Cms> cmsTask = OnlineFunctionality.GetContent(); yield return (object)new WaitUntil((Func<bool>)(() => cmsTask.IsCompleted && loadoutTask.IsCompleted)); if (cmsTask.Result.Banners.TryGetValue(loadoutTask.Result.BannerId, out var banner)) { AsyncOperationHandle<Sprite?> bannerLoadTask = Addressables.Instance.LoadAssetAsync<Sprite>((object)banner.Asset.AddressablePath); yield return (object)new WaitUntil((Func<bool>)(() => bannerLoadTask.IsDone)); if (!((Object)(object)bannerLoadTask.Result == (Object)null)) { Banner.sprite = bannerLoadTask.Result; ((Component)Banner).gameObject.SetActive(true); } } } public void OpenProfile() { //IL_0016: Unknown result type (might be due to invalid IL or missing references) Application.OpenURL(string.Format(OnlineFunctionality.LastFetchedContent.GetString("constants.website_users"), _user.Id)); } } public class LoadoutHud : MonoBehaviour { private static readonly Dictionary<StoreItemType, StoreItemType> s_alternateSwapDict = new Dictionary<StoreItemType, StoreItemType> { { (StoreItemType)1, (StoreItemType)7 }, { (StoreItemType)2, (StoreItemType)8 }, { (StoreItemType)3, (StoreItemType)9 }, { (StoreItemType)7, (StoreItemType)1 }, { (StoreItemType)8, (StoreItemType)2 }, { (StoreItemType)9, (StoreItemType)3 } }; [SerializeField] private TMP_Text _itemNameText; [SerializeField] private TMP_Text _categoryTitle; [SerializeField] private GameObject _page; [SerializeField] private GameObject _templateItemButton; [SerializeField] private Transform _itemButtonHolder; [SerializeField] private GameObject _alternateButton; [SerializeField] private Button _equipButton; [SerializeField] private TMP_Text _equipButtonText; [SerializeField] private LoadoutHudVariantButton[] _variantButtons; [SerializeField] private GameObject _presentConfigButton; private List<GameObject> _currentItemButtons = new List<GameObject>(); private Item? _selectedItem; private StoreItemType _currentItemType; public bool HasNoVariations(StoreItemType itemType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Invalid comparison between Unknown and I4 if ((int)itemType == 0 || (int)itemType == 6) { return true; } return false; } public bool HasAlternates(StoreItemType itemType) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) return s_alternateSwapDict.ContainsKey(itemType); } private void Awake() { SelectItemType(1); } private void OnEnable() { ((MonoBehaviour)this).StartCoroutine(FetchLoadoutBeforeEnable()); } private IEnumerator FetchLoadoutBeforeEnable() { _page.SetActive(false); Task loadoutTask = CosmeticManager.FetchLoadout(); yield return (object)new WaitUntil((Func<bool>)(() => loadoutTask.IsCompleted)); _page.SetActive(true); } private void OnDisable() { CosmeticManager.UpdateLoadout(); } public void SelectItemType(int itemType) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) _currentItemType = (StoreItemType)itemType; ((MonoBehaviour)this).StartCoroutine(SetSlotPage()); } public void SwapToAlt() { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_004d: Expected I4, but got Unknown //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (!HasAlternates(_currentItemType)) { Plugin.Log.LogWarning((object)$"SwapToAlt called with unsupported item {_currentItemType} - shouldn't happen."); } else { SelectItemType((int)s_alternateSwapDict[_currentItemType]); } } private IEnumerator SetSlotPage() { _page.SetActive(false); Task<bool> onlineTask = Api.ServerOnline(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => onlineTask.IsCompleted)); if (!onlineTask.Result) { MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Server offline!", "", "", 0, false); yield break; } Task<Cms> cmsTask = OnlineFunctionality.GetContent(); yield return (object)new WaitUntil((Func<bool>)(() => cmsTask.IsCompleted)); Cms cms = cmsTask.Result; _categoryTitle.text = cms.GetString("category." + ((object)(StoreItemType)(ref _currentItemType)).ToString().ToLower()); List<Item> itemList = new List<Item>(); Item item3 = default(Item); foreach (string itemId in CosmeticManager.AllOwned) { if (cms.TryGetItem(itemId, ref item3) && item3.Descriptor.Type == _currentItemType) { itemList.Add(item3); item3 = null; } } foreach (GameObject oldItemButton in _currentItemButtons) { Object.Destroy((Object)(object)oldItemButton); } IEnumerable<Item> orderedList = itemList.OrderBy((Item x) => CosmeticLoadout.DefaultItems.Contains(x.Descriptor.Id) ? string.Empty : cms.GetString(x.Descriptor.Name)); foreach (Item item2 in orderedList) { AddItem(item2); } string targetId; if (HasNoVariations(_currentItemType)) { targetId = GetEquippedItemId(_currentItemType); } else { targetId = GetEquippedItemId(_currentItemType, 0); } if (targetId != null) { SetItem(orderedList.FirstOrDefault((Func<Item, bool>)((Item item) => item.Descriptor.Id == targetId))); } else { SetItem(null); } _alternateButton.SetActive(HasAlternates(_currentItemType)); _presentConfigButton.SetActive((int)_currentItemType == 6); _page.SetActive(true); } private void AddItem(Item item) { GameObject val = Object.Instantiate<GameObject>(_templateItemButton, _itemButtonHolder); val.GetComponent<LoadoutHudItemButton>().SetUp(this, item); _currentItemButtons.Add(val); } public void SetItem(Item? item) { _itemNameText.text = ((item != null) ? OnlineFunctionality.LastFetchedContent.GetString(item.Descriptor.Name) : "-"); _selectedItem = item; UpdateEquipButtons(item); } private void UpdateEquipButtons(Item? item) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) if (HasNoVariations(_currentItemType)) { EnableSingleEquipButton(item); } else { EnableVariationEquipButtons(item); } } private void EnableSingleEquipButton(Item? item) { //IL_0047: Unknown result type (might be due to invalid IL or missing references) LoadoutHudVariantButton[] variantButtons = _variantButtons; foreach (LoadoutHudVariantButton loadoutHudVariantButton in variantButtons) { ((Component)loadoutHudVariantButton).gameObject.SetActive(false); } ((Component)_equipButton).gameObject.SetActive(true); if (item != null) { string text = ((GetEquippedItemId(_currentItemType) == item.Descriptor.Id) ? "equipped" : "unequipped"); _equipButtonText.text = OnlineFunctionality.LastFetchedContent.GetString("shop." + text); ((Selectable)_equipButton).interactable = true; } else { _equipButtonText.text = OnlineFunctionality.LastFetchedContent.GetString("shop.unequipped"); ((Selectable)_equipButton).interactable = false; } } private void EnableVariationEquipButtons(Item? item) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) ((Component)_equipButton).gameObject.SetActive(false); LoadoutHudVariantButton[] variantButtons = _variantButtons; foreach (LoadoutHudVariantButton loadoutHudVariantButton in variantButtons) { ((Component)loadoutHudVariantButton).gameObject.SetActive(true); if (item != null) { loadoutHudVariantButton.SetState(GetEquippedItemId(_currentItemType, loadoutHudVariantButton.VariationIndex) == item.Descriptor.Id); loadoutHudVariantButton.SetInteractable(interactable: true); } else { loadoutHudVariantButton.SetState(on: false); loadoutHudVariantButton.SetInteractable(interactable: false); } } } public string? GetEquippedItemId(StoreItemType itemType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) if ((int)itemType != 0) { if ((int)itemType == 6) { return CosmeticManager.Loadout.PresentId; } Plugin.Log.LogWarning((object)$"Item type {_currentItemType} is not supported for GetEquippedItemId(StoreItemType)"); return null; } return CosmeticManager.Loadout.BannerId; } public string? GetEquippedItemId(StoreItemType itemType, int variation) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Unknown result type (might be due to invalid IL or missing references) List<string> loadoutSlotList = GetLoadoutSlotList(_currentItemType); if (loadoutSlotList == null) { Plugin.Log.LogWarning((object)$"{_currentItemType} loadoutSlotList was null."); return string.Empty; } if (loadoutSlotList.Count <= variation) { Plugin.Log.LogWarning((object)$"{variation} out of range of slot {itemType}."); return string.Empty; } return loadoutSlotList[variation]; } public List<string>? GetLoadoutSlotList(StoreItemType itemType) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Expected I4, but got Unknown //IL_00a6: Unknown result type (might be due to invalid IL or missing references) switch (itemType - 1) { case 0: return CosmeticManager.Loadout.RevolverIds; case 6: return CosmeticManager.Loadout.AltRevolverIds; case 1: return CosmeticManager.Loadout.ShotgunIds; case 7: return CosmeticManager.Loadout.AltShotgunIds; case 2: return CosmeticManager.Loadout.NailgunIds; case 8: return CosmeticManager.Loadout.AltNailgunIds; case 3: return CosmeticManager.Loadout.RailcannonIds; case 4: return CosmeticManager.Loadout.RocketIds; default: Plugin.Log.LogWarning((object)$"Item type {_currentItemType} is not supported for GetLoadoutSlotList"); return null; } } public void EquipForVariation(int variationIndex) { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0022: Unknown result type (might be due to invalid IL or missing references) List<string> loadoutSlotList = GetLoadoutSlotList(_currentItemType); if (loadoutSlotList == null) { Plugin.Log.LogWarning((object)$"{_currentItemType} loadoutSlotList was null."); return; } while (loadoutSlotList.Count < 3) { loadoutSlotList.Add(string.Empty); } loadoutSlotList[variationIndex] = _selectedItem.Descriptor.Id; UpdateEquipButtons(_selectedItem); } public void EquipNoVariation() { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Invalid comparison between Unknown and I4 //IL_0058: Unknown result type (might be due to invalid IL or missing references) StoreItemType currentItemType = _currentItemType; StoreItemType val = currentItemType; if ((int)val != 0) { if ((int)val != 6) { Plugin.Log.LogWarning((object)$"Item type {_currentItemType} is not supported for EquipNoVariation"); return; } CosmeticManager.Loadout.PresentId = _selectedItem.Descriptor.Id; } else { CosmeticManager.Loadout.BannerId = _selectedItem.Descriptor.Id; } UpdateEquipButtons(_selectedItem); } } public class LoadoutHudItemButton : MonoBehaviour { [SerializeField] private Button _button; [SerializeField] private Image _iconImage; public void SetUp(LoadoutHud loadoutHud, Item item) { ((MonoBehaviour)loadoutHud).StartCoroutine(SetUpCoroutine(loadoutHud, item)); } private IEnumerator SetUpCoroutine(LoadoutHud loadoutHud, Item item) { LoadoutHud loadoutHud2 = loadoutHud; Item item2 = item; ((Component)this).gameObject.SetActive(false); AsyncOperationHandle<Sprite?> iconLoad = Addressables.LoadAssetAsync<Sprite>((object)item2.Descriptor.Icon.AddressablePath); yield return (object)new WaitUntil((Func<bool>)(() => iconLoad.IsDone)); if ((Object)(object)iconLoad.Result == (Object)null) { Plugin.Log.LogWarning((object)("Couldn't load icon for item " + item2.Descriptor.Id + ". Not showing button")); } _iconImage.sprite = iconLoad.Result; ((UnityEvent)_button.onClick).AddListener((UnityAction)delegate { loadoutHud2.SetItem(item2); }); ((Component)this).gameObject.SetActive(true); } } public class LoadoutHudVariantButton : MonoBehaviour { public int VariationIndex; [SerializeField] private LoadoutHud _parentHud; [SerializeField] private ColorBlindGet[] _colourGetters; [SerializeField] private Button _button; [SerializeField] private GameObject _check; private void OnEnable() { ColorBlindGet[] colourGetters = _colourGetters; foreach (ColorBlindGet val in colourGetters) { val.variationNumber = VariationIndex; val.UpdateColor(); } } private void Awake() { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected O, but got Unknown ((UnityEvent)_button.onClick).AddListener((UnityAction)delegate { _parentHud.EquipForVariation(VariationIndex); }); } public void SetState(bool on) { _check.SetActive(on); } public void SetInteractable(bool interactable) { ((Selectable)_button).interactable = interactable; } } public class MoneyCounter : MonoBehaviour { [SerializeField] private AudioSource _moneyDecreaseTick; [SerializeField] private float _moneyTickInterval; [SerializeField] private float _moneyDecreaseInterval; [SerializeField] private TMP_Text _moneyCounter; private Coroutine? _lastMoneyRefresher; private int _counterMoney = 0; public void SetValue(int amount) { _counterMoney = amount; _moneyCounter.text = amount.ToString(); } public void RefreshMoney(int targetMoney) { if (_lastMoneyRefresher != null) { ((MonoBehaviour)this).StopCoroutine(_lastMoneyRefresher); } _lastMoneyRefresher = ((MonoBehaviour)this).StartCoroutine(RefreshMoneyCoroutine(targetMoney)); } private IEnumerator RefreshMoneyCoroutine(int targetMoney) { float timeSinceTick = 0f; float timeSinceDecrease = 0f; while (_counterMoney != targetMoney) { timeSinceTick += Time.deltaTime; timeSinceDecrease += Time.deltaTime; if (timeSinceTick > _moneyTickInterval) { _moneyDecreaseTick.Play(); timeSinceTick = 0f; } if (timeSinceDecrease > _moneyDecreaseInterval) { SetValue(--_counterMoney); } yield return null; } } } public class Podium : MonoBehaviour { [SerializeField] private MeshRenderer[] _pfpRenderers; [SerializeField] private TMP_Text[] _nameTexts; private void Awake() { ((MonoBehaviour)this).StartCoroutine(SetValues()); } private IEnumerator SetValues() { Task<OnlineScore[]> scoresTask = Scores.GetScoreRange(OnlineFunctionality.Context, 0, 3); yield return (object)new WaitUntil((Func<bool>)(() => scoresTask.IsCompleted)); int index = 0; OnlineScore[] result = scoresTask.Result; foreach (OnlineScore score in result) { ((MonoBehaviour)this).StartCoroutine(SetPfp(score.SteamId, index)); ((MonoBehaviour)this).StartCoroutine(SetUsername(score.SteamId, index)); index++; } } private IEnumerator SetUsername(ulong steamId, int index) { Task<string> usernameTask = Users.GetUsername(OnlineFunctionality.Context, steamId); yield return (object)new WaitUntil((Func<bool>)(() => usernameTask.IsCompleted)); _nameTexts[index].text = $"#{index + 1} - " + usernameTask.Result.ToUpperInvariant(); } private IEnumerator SetPfp(ulong steamId, int index) { Friend val = new Friend(SteamId.op_Implicit(steamId)); Task<Image?> imageTask = ((Friend)(ref val)).GetLargeAvatarAsync(); float startTime = Time.time; yield return (object)new WaitUntil((Func<bool>)(() => imageTask == null || imageTask.IsCompleted || imageTask.IsFaulted || imageTask.IsCanceled || startTime - Time.time > 10f)); if (imageTask?.Result.HasValue ?? false) { Texture2D texture2D = new Texture2D((int)imageTask.Result.Value.Width, (int)imageTask.Result.Value.Height, (TextureFormat)4, false); texture2D.LoadRawTextureData(imageTask.Result.Value.Data); texture2D.Apply(); Material[] materialArray = ((Renderer)_pfpRenderers[index]).materials; materialArray[1].mainTextureScale = new Vector2(1f, -1f); materialArray[1].mainTexture = (Texture)(object)texture2D; ((Renderer)_pfpRenderers[index]).materials = materialArray; } } } public class PresentColourPicker : MonoBehaviour { [SerializeField] private PresentColourUi _parent; [SerializeField] private int _colourIndex; [SerializeField] private Slider[] _sliders; [SerializeField] private Image _image; private void Awake() { for (int i = 0; i < _sliders.Length; i++) { int currentIndex = i; ((UnityEvent<float>)(object)_sliders[i].onValueChanged).AddListener((UnityAction<float>)delegate(float value) { _parent.SliderChanged(_colourIndex, currentIndex, value); UpdateSelf(); }); } UpdateSelf(); } public void UpdateSelf() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_004c: Unknown result type (might be due to invalid IL or missing references) Color colour = ConfigFile.Instance.Data.GetColour(_colourIndex); for (int i = 0; i < _sliders.Length; i++) { _sliders[i].SetValueWithoutNotify(((Color)(ref colour))[i]); } ((Graphic)_image).color = colour; } } public class PresentColourUi : MonoBehaviour { public static readonly List<SerializableColour> DefaultColours = new List<SerializableColour>(4) { new SerializableColour(0f, 0.91f, 1f, 1f), new SerializableColour(0.27f, 1f, 0.27f, 1f), new SerializableColour(1f, 0.24f, 0.24f, 1f), new SerializableColour(1f, 0.88f, 0.24f, 1f) }; public void SliderChanged(int colourIndex, int rgbIndex, float value) { Plugin.Log.LogMessage((object)$"Colour {colourIndex} [{rgbIndex}] = {value}"); List<SerializableColour> presentColours = ConfigFile.Instance.Data.PresentColours; SerializableColour serializableColour = presentColours[colourIndex]; serializableColour[rgbIndex] = value; presentColours[colourIndex] = serializableColour; } public void ResetColour(int colourIndex) { ConfigFile.Instance.Data.PresentColours[colourIndex] = DefaultColours[colourIndex]; } } [HarmonyPatch] public class PresentTimeHud : MonoSingleton<PresentTimeHud> { public const float DangerTime = 10f; public Image[] PresentImages; public TMP_Text Timer; public TMP_Text CompleteRooms; public Color TimerColour; public Color TimerDangerColour; private float _lastSetSeconds; private float _lerpProgress; private float _originalFontSize; private Vector3 _timerStartPos; public void Start() { //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) _originalFontSize = Timer.fontSize; _timerStartPos = Timer.transform.localPosition; } private void Update() { //IL_01d1: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) if (!MonoSingleton<GameManager>.Instance.GameStarted) { return; } if (MonoSingleton<GameManager>.Instance.TimerActive) { Timer.text = TimeSpan.FromSeconds(MonoSingleton<GameManager>.Instance.TimeLeft).ToString("mm\\:ss\\.fff", new CultureInfo("en-US")); Timer.fontSize = Mathf.MoveTowards(Timer.fontSize, _originalFontSize, 75f * Time.deltaTime); _lastSetSeconds = MonoSingleton<GameManager>.Instance.TimeLeft; _lerpProgress = 0f; } else { if (MonoSingleton<GameManager>.Instance.TimeLeft > 10f) { MonoSingleton<CameraController>.Instance.StopShake(); } float num = Mathf.Lerp(_lastSetSeconds, MonoSingleton<GameManager>.Instance.TimeLeft, _lerpProgress); Timer.text = TimeSpan.FromSeconds(num).Formatted(); Timer.fontSize = _originalFontSize * (1f + _lerpProgress * 0.15f); _lerpProgress += Time.deltaTime / 0.5f; } if (MonoSingleton<GameManager>.Instance.TimeLeft <= 10f) { ((Graphic)Timer).color = TimerDangerColour; Timer.transform.localPosition = _timerStartPos + new Vector3((float)Random.Range(-1, 1), (float)Random.Range(-1, 1), 0f); MonoSingleton<CameraController>.Instance.CameraShake((10f - MonoSingleton<GameManager>.Instance.TimeLeft) / 50f); } else { ((Graphic)Timer).color = TimerColour; Timer.transform.localPosition = _timerStartPos; } if ((Object)(object)MonoSingleton<GameManager>.Instance.CurrentRoom != (Object)null) { for (int i = 0; i < 4; i++) { PresentImages[i].fillAmount = FindFill((WeaponVariant)i); } } CompleteRooms.text = MonoSingleton<GameManager>.Instance.RoomsComplete.ToString(); } private float FindFill(WeaponVariant colour) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) float num = MonoSingleton<GameManager>.Instance.CurrentRoom.PresentColourAmounts[colour]; return 1f - (float)MonoSingleton<GameManager>.Instance.CurrentRoom.AmountDelivered[colour] / num; } [HarmonyPatch(typeof(HudController), "Start")] [HarmonyPostfix] private static void AddSelf(HudController __instance) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) if (!__instance.altHud && !MapInfoBase.InstanceAnyType.hideStockHUD) { GameObject val = Addressables.LoadAssetAsync<GameObject>((object)"Assets/Delivery/Prefabs/HUD/Present Panel.prefab").WaitForCompletion(); GameObject val2 = Object.Instantiate<GameObject>(val, ((Component)__instance.hudpos).transform); val2.transform.localPosition = val.transform.localPosition; val2.gameObject.SetActive(false); } } } public class ReachValueText : MonoBehaviour { public enum IntOrFloat { Int, Float } public IntOrFloat Type; public Text Text; public float Target; public string Format; public string StartValue; public float ChangePerSecond; public bool IsTimestamp; private float _timeElapsed; private AudioSource _audio; private float _currentValue; [HideInInspector] public bool Done; private void OnEnable() { MonoSingleton<EndScreen>.Instance.CurrentText = this; Text.text = StartValue; _audio = ((Component)this).GetComponent<AudioSource>(); AudioSource audio = _audio; if (audio != null) { audio.Play(); } } private void Update() { if (MonoSingleton<EndScreen>.Instance.Skipping) { _currentValue = Target; SetText(); } if (Target == _currentValue) { SetText(); Done = true; ((Behaviour)this).enabled = false; AudioSource audio = _audio; if (audio != null) { audio.Stop(); } } else { _timeElapsed += Time.unscaledDeltaTime; _currentValue = Mathf.MoveTowards(_currentValue, Target, ChangePerSecond * Time.unscaledDeltaTime); SetText(); } } private void SetText() { float num = ((Type == IntOrFloat.Int) ? Mathf.Floor(_currentValue) : _currentValue); Text.text = ((!IsTimestamp) ? string.Format(Format, num) : TimeSpan.FromSeconds(num).Formatted()); } } public class ShopItemPanel : MonoBehaviour { [SerializeField] private Button _button; [SerializeField] private TMP_Text _itemName; [SerializeField] private TMP_Text _itemCost; [SerializeField] private TMP_Text _itemType; [SerializeField] private Image _iconImage; [SerializeField] private Image _moneyIcon; private JollyTerminalShop _parentShop; private ItemDescriptor _itemDescriptor; private string _ownedString; public void SetUp(JollyTerminalShop parentShop, ItemDescriptor itemDescriptor) { ((Component)this).gameObject.SetActive(false); _itemDescriptor = itemDescriptor; _parentShop = parentShop; ((MonoBehaviour)parentShop).StartCoroutine(SetUpCoroutine()); } private IEnumerator SetUpCoroutine() { Task<Cms> cmsTask = OnlineFunctionality.GetContent(); yield return (object)new WaitUntil((Func<bool>)(() => cmsTask.IsCompleted)); Cms cms = cmsTask.Result; _ownedString = cms.GetString("shop.owned"); _itemName.text = cms.GetString(_itemDescriptor.Name); _itemCost.text = _itemDescriptor.ShopPrice.ToString(); _itemType.text = cms.GetString("category." + ((object)(StoreItemType)(ref _itemDescriptor.Type)).ToString().ToLower()); if (CosmeticManager.AllOwned.Contains(_itemDescriptor.Id)) { SetOwned(); } AsyncOperationHandle<Sprite> iconCoroutine = Addressables.LoadAssetAsync<Sprite>((object)_itemDescriptor.Icon.AddressablePath); yield return (object)new WaitUntil((Func<bool>)(() => iconCoroutine.IsDone)); _iconImage.sprite = iconCoroutine.Result; ((Component)this).gameObject.SetActive(true); } public void Buy() { _parentShop.BuyItem(_itemDescriptor); } public void Enable() { if (CosmeticManager.AllOwned.Contains(_itemDescriptor.Id)) { SetOwned(); } else { ((Selectable)_button).interactable = true; } } public void Disable() { ((Selectable)_button).interactable = false; } private void SetOwned() { _itemCost.text = _ownedString; Disable(); ((Component)_moneyIcon).gameObject.SetActive(false); } } [HarmonyPatch] public class TabMenu : MonoBehaviour { private static GameObject? s_menuObject; [SerializeField] private TMP_Text _map; [SerializeField] private TMP_Text _time; [SerializeField] private TMP_Text _kills; private int _roomEnemyCount; private int _killsOnEnter; private void Awake() { MonoSingleton<GameManager>.Instance.RoomStarted += delegate(Room room) { if (!((Object)(object)room.Arena == (Object)null) && !((Object)(object)MonoSingleton<StatsManager>.Instance == (Object)null)) { _roomEnemyCount = room.Arena.enemies.Length; _killsOnEnter = MonoSingleton<StatsManager>.Instance.kills; } }; } private void Update() { if (!((Object)(object)MonoSingleton<GameManager>.Instance == (Object)null) && !((Object)(object)MonoSingleton<GameManager>.Instance.CurrentRoomData == (Object)null)) { _map.text = MonoSingleton<GameManager>.Instance.CurrentRoomData.Name; _time.text = TimeSpan.FromSeconds(MonoSingleton<GameManager>.Instance.TimeElapsed).ToString("mm':'ss'.'ff"); _kills.text = (_roomEnemyCount - (MonoSingleton<StatsManager>.Instance.kills - _killsOnEnter)).ToString(); } } [HarmonyPatch(typeof(LevelStatsEnabler), "Start")] [HarmonyPostfix] private static void AddSelf(LevelStatsEnabler __instance) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Unknown result type (might be due to invalid IL or missing references) if (AssetManager.InSceneFromThisMod) { if (s_menuObject == null) { s_menuObject = Addressables.LoadAssetAsync<GameObject>((object)"Assets/Delivery/Prefabs/HUD/Game Stats.prefab").WaitForCompletion(); } ((Component)__instance).gameObject.SetActive(true); __instance.levelStats = Object.Instantiate<GameObject>(s_menuObject, ((Component)__instance).transform); __instance.levelStats.SetActive(false); } } } public interface IText { void SetText(string text); } public class TmpText : MonoBehaviour, IText { private TMP_Text _text; public void SetText(string text) { if ((Object)(object)_text == (Object)null) { _text = ((Component)this).GetComponent<TMP_Text>(); } _text.text = text; } } public class UnityText : MonoBehaviour, IText { private Text _text; public void SetText(string text) { if ((Object)(object)_text == (Object)null) { _text = ((Component)this).GetComponent<Text>(); } _text.text = text; } } public class UpdateScreen : MonoBehaviour { private void Awake() { ((Component)this).gameObject.SetActive(false); ((MonoBehaviour)CoroutineRunner.Instance).StartCoroutine(EnableIfNeeded()); } private void Update() { ((Behaviour)MonoSingleton<NewMovement>.Instance).enabled = false; ((Behaviour)MonoSingleton<GunControl>.Instance).enabled = false; ((Behaviour)MonoSingleton<FistControl>.Instance).enabled = false; Time.timeScale = 0f; } private IEnumerator EnableIfNeeded() { Task<bool> onlineTask = Api.ServerOnline(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => onlineTask.IsCompleted)); if (onlineTask.Result) { Task<bool> updateRequiredTask = Api.UpdateRequired(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => updateRequiredTask.IsCompleted)); if (updateRequiredTask.Result) { ((Component)this).gameObject.SetActive(true); GameStateManager.Instance.RegisterState(new GameState("pause_updscreen", (GameObject[])(object)new GameObject[1] { ((Component)this).gameObject }) { cursorLock = (LockMode)2, cameraInputLock = (LockMode)1, playerInputLock = (LockMode)1 }); ((Behaviour)MonoSingleton<NewMovement>.Instance).enabled = false; ((Behaviour)MonoSingleton<GunControl>.Instance).enabled = false; ((Behaviour)MonoSingleton<FistControl>.Instance).enabled = false; Time.timeScale = 0f; } } } public void ReenablePlayer() { ((Behaviour)MonoSingleton<NewMovement>.Instance).enabled = true; ((Behaviour)MonoSingleton<GunControl>.Instance).enabled = true; ((Behaviour)MonoSingleton<FistControl>.Instance).enabled = true; MonoSingleton<TimeController>.Instance.RestoreTime(); } public void OpenThunderstore() { Application.OpenURL("https://thunderstore.io/c/ultrakill/p/Waff1e/Divine_Delivery/"); } } } namespace EndlessDelivery.ScoreManagement { public class ScoreManager { public static SaveFile<Dictionary<int, Score>> LocalHighscores = SaveFile.RegisterFile<Dictionary<int, Score>>(new SaveFile<Dictionary<int, Score>>("local_scores.json", "Divine Delivery", new Dictionary<int, Score>())); public static Score CurrentDifficultyHighscore { get { //IL_002c: Unknown result type (might be due to invalid IL or missing references) Score value; return (Score)(LocalHighscores.Data.TryGetValue(MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0), out value) ? ((object)value) : ((object)new Score(0, 0, 0, 0f, 0))); } } public static bool CanSubmit() { List<string> reasons; return CanSubmit(out reasons); } public static bool CanSubmit(out List<string> reasons) { return !EndlessDelivery.Anticheat.Anticheat.HasIllegalMods(out reasons) && !MonoSingleton<CheatsController>.Instance.cheatsEnabled; } public static bool CanSubmitOnline() { List<string> reasons; return CanSubmit(out reasons) && MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0) >= 3; } public static async Task<OnlineScore?> SubmitScore(Score score, short difficulty) { if (!CanSubmitOnline()) { return null; } if (await Api.UpdateRequired(OnlineFunctionality.Context)) { return null; } if (score > CurrentDifficultyHighscore) { LocalHighscores.Data[difficulty] = score; } try { OnlineScore submittedScore = await Scores.SubmitScore(OnlineFunctionality.Context, new SubmitScoreData(score, difficulty)); AchievementManager.CheckOnline(submittedScore, await Users.GetBestScore(OnlineFunctionality.Context, SteamId.op_Implicit(SteamClient.SteamId)), await Users.GetLifetimeStats(OnlineFunctionality.Context, SteamId.op_Implicit(SteamClient.SteamId))); return submittedScore; } catch (Exception ex) { MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage($"Score submit error!\nUpdate or upload your logs. {ex.GetType()}.", "", "", 0, false); Plugin.Log.LogError((object)ex.ToString()); return null; } } } } namespace EndlessDelivery.Online { [HarmonyPatch] public static class DiscordRpc { [HarmonyPatch(typeof(DiscordController), "SendActivity")] [HarmonyPrefix] private static void UpdateActivity(DiscordController __instance) { if (AssetManager.InSceneFromThisMod) { SetActivity(ref __instance.cachedActivity); } } private static void SetActivity(ref Activity activity) { activity.Assets.LargeImage = GetUrl(MonoSingleton<GameManager>.Instance.CurrentRoomData); activity.Assets.LargeText = "DIVINE DELIVERY"; activity.Details = $"ROOMS: {MonoSingleton<GameManager>.Instance.RoomsComplete}"; } private static string GetUrl(RoomData? data) { return "https://delivery.wafflethings.dev/Resources/DiscordIcons/" + (data?.Id ?? "startroom") + ".png"; } } public static class OnlineFunctionality { public static readonly ApiContext Context = new ApiContext(new HttpClient(), (Func<string>)GetTicket, (Uri)null); private static SaveFile<Cms?> s_cmsData = SaveFile.RegisterFile<Cms>(new SaveFile<Cms>("content.json", "Divine Delivery", (Cms)null)); public static bool LoggedIn { get; private set; } public static Cms? LastFetchedContent => s_cmsData.Data; public static void Init() { Plugin.Log.LogMessage((object)"Init called!"); ((MonoBehaviour)CoroutineRunner.Instance).StartCoroutine(InitWhenSteamReady()); } private static IEnumerator InitWhenSteamReady() { while (!SteamClient.IsValid) { yield return null; } Context.Client.DefaultRequestHeaders.Add("DdVersion", "2.2.2"); Context.Client.DefaultRequestHeaders.Add("DdMods", string.Join(",", Chainloader.PluginInfos.Values.Select((PluginInfo x) => x.Metadata.GUID.Replace(",", string.Empty)))); Task loginTask = Task.Run((Func<Task?>)Context.Login); yield return (object)new WaitUntil((Func<bool>)(() => loginTask.IsCompleted)); LoggedIn = true; Task.Run((Func<Task<Cms>?>)GetContent); Task.Run((Func<Task?>)CosmeticManager.FetchLoadout); } public static string GetTicket() { //IL_0003: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) AuthTicket authSessionTicket = SteamUser.GetAuthSessionTicket(default(NetIdentity)); return BitConverter.ToString(authSessionTicket.Data, 0, authSessionTicket.Data.Length).Replace("-", string.Empty); } public static async Task<Cms> GetContent() { ApiContext context = Context; Cms data = s_cmsData.Data; if (await Content.ContentUpdateRequired(context, ((data != null) ? data.Hash : null) ?? string.Empty)) { Cms downloaded = await Content.DownloadCms(Context); if (downloaded == null) { throw new Exception("CMS download failed!"); } s_cmsData.Data = downloaded; } return s_cmsData.Data ?? throw new Exception("Couldn't get content and no old content cached."); } } } namespace EndlessDelivery.Gameplay { [HarmonyPatch] public class GameManager : MonoSingleton<GameManager> { public delegate void RoomEvent(Room room); public delegate void EnemyEvent(EnemyIdentifier enemy); private static SpecialWave[] s_specialWaves = new SpecialWave[3] { new Radiant(), new FireworkWave(), new WardWave() }; public const float StartTime = 45f; public const float TimeAddLength = 0.5f; public const float MaxTime = 90f; public const int SpecialWaveStart = 20; public const int SpecialWaveInterval = 5; public AudioSource TimeAddSound; public RoomPool RoomPool; [SerializeField] private Vector3 _baseRoomPosition = new Vector3(0f, 0f, 100f); private Coroutine _pauseCoroutine; private List<RoomData> _remainingRooms = new List<RoomData>(); private List<SpecialWave> _remainingSpecialWaves = new List<SpecialWave>(); private const int StartingPoints = 10; private const int MaxPointGain = 15; public bool GameStarted { get; private set; } public float TimeLeft { get; private set; } public float TimeElapsed { get; private set; } public int DeliveredPresents { get; set; } public int RoomsComplete { get; private set; } public Room CurrentRoom { get; private set; } public RoomData CurrentRoomData { get; private set; } public Room PreviousRoom { get; private set; } public bool TimerActive { get; private set; } public int PointsPerWave { get; private set; } public Score CurrentScore => new Score(RoomsComplete, MonoSingleton<StatsManager>.Instance.kills, DeliveredPresents, TimeElapsed, ((SaveFile<StartTimes>)(object)StartTimes.Instance).Data.CurrentTimes.SelectedWave); public event RoomEvent? RoomStarted; public event RoomEvent? RoomCleared; public event RoomEvent? RoomComplete; public event EnemyEvent? EnemySpawned; public static int GetRoomPoints(int roomNumber) { int num = 10; for (int i = 0; i < roomNumber; i++) { num += Mathf.Min(3 + (i + 1) / 3, 15); } return num; } private void Awake() { EnemyHack.AddToPools(EnemyGroup.Groups[DeliveryEnemyClass.Projectile], EnemyGroup.Groups[DeliveryEnemyClass.Uncommon], EnemyGroup.Groups[DeliveryEnemyClass.Special], EnemyGroup.Groups[DeliveryEnemyClass.Melee]); } private void SetRoomPool() { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) DatedRoomPool currentRoomPool = OnlineFunctionality.LastFetchedContent.CurrentRoomPool; if (currentRoomPool == null) { Plugin.Log.LogWarning((object)"Pool was null, using fallback"); return; } string assetPath = OnlineFunctionality.LastFetchedContent.CurrentRoomPool.AssetPath; RoomPool roomPool = Addressables.LoadAssetAsync<RoomPool>((object)assetPath).WaitForCompletion(); if ((Object)(object)roomPool == (Object)null) { Plugin.Log.LogWarning((object)("Loaded pool at " + assetPath + " was null, using fallback")); } else { RoomPool = roomPool; } } private void Update() { if (GameStarted && MonoSingleton<GunControl>.Instance.activated) { TimeLeft = Mathf.MoveTowards(TimeLeft, 0f, Time.deltaTime); TimeElapsed += Time.deltaTime; if (TimeLeft == 0f) { EndGame(); } if (!CurrentRoom.RoomCleared && CurrentRoom.RoomActivated && CurrentRoom.AllEnemiesSpawned && MonoSingleton<EnemyTracker>.Instance.enemies.All((EnemyIdentifier enemy) => enemy.dead)) { CurrentRoom.RoomCleared = true; MonoSingleton<MusicManager>.Instance.PlayCleanMusic(); this.RoomCleared?.Invoke(CurrentRoom); AddTime(6f, "<color=orange>FULL CLEAR</color>"); } } } public void RegisterEnemySpawned(EnemyIdentifier enemy) { CurrentRoom.Enemies.Add(enemy); this.EnemySpawned?.Invoke(enemy); } public SpecialWave PickSpecialWave() { if (_remainingSpecialWaves.Count == 0) { _remainingSpecialWaves.AddRange(s_specialWaves); } return _remainingSpecialWaves.Pick(); } public void AddTime(float seconds, string reason) { if (TimeLeft + seconds > 90f) { seconds = Mathf.Round(90f - TimeLeft); } AudioSource timeAddSound = TimeAddSound; if (timeAddSound != null) { timeAddSound.Play(); } TimerActive = false; if (_pauseCoroutine != null) { ((MonoBehaviour)this).StopCoroutine(_pauseCoroutine); } _pauseCoroutine = ((MonoBehaviour)this).StartCoroutine(UnpauseTimer()); MonoSingleton<StyleHUD>.Instance.AddPoints(5, $"{reason} <size=20>({seconds}s)</size>", (GameObject)null, (EnemyIdentifier)null, -1, "", ""); TimeLeft += seconds; } public void SilentAddTime(float seconds) { TimeLeft += seconds; } private IEnumerator UnpauseTimer() { yield return (object)new WaitForSeconds(0.5f); TimerActive = true; } private Room GenerateNewRoom() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) CurrentRoomData = GetRandomRoom(); return Object.Instantiate<GameObject>(CurrentRoomData.Prefab, _baseRoomPosition + Vector3.right * (float)(RoomsComplete % 3) * 200f, Quaternion.identity).GetComponent<Room>(); } private RoomData GetRandomRoom() { if (_remainingRooms.Count == 0) { _remainingRooms.AddRange(RoomPool.Rooms); } RoomData roomData = _remainingRooms.Pick(); _remainingRooms.Remove(roomData); return roomData; } public void RoomEnd() { this.RoomComplete?.Invoke(CurrentRoom); RoomsComplete++; if (CurrentRoom.RoomHasGameplay) { AddTime(8f, "<color=orange>ROOM CLEAR</color>"); PointsPerWave += Mathf.Min(3 + RoomsComplete / 3, 10); ((SaveFile<StartTimes>)(object)StartTimes.Instance).Data.UpdateAllLowerDifficulty(RoomsComplete, TimeLeft); MonoSingleton<NewMovement>.Instance.ResetHardDamage(); MonoSingleton<NewMovement>.Instance.GetHealth(100, true, false); MonoSingleton<NewMovement>.Instance.FullStamina(); } else if (!GameStarted) { StartGame(); } SetRoom(GenerateNewRoom()); } public void SetRoom(Room room) { if ((Object)(object)CurrentRoom != (Object)(object)room) { PreviousRoom = CurrentRoom; CurrentRoom = room; room.Initialize(); } if (room.RoomHasGameplay && !room.RoomAlreadyVisited) { room.RoomAlreadyVisited = true; } this.RoomStarted?.Invoke(CurrentRoom); } public void StartGame() { if (!GameStarted) { SetRoomPool(); ((Component)MonoSingleton<PresentTimeHud>.Instance).gameObject.SetActive(true); ((Component)((Component)MonoSingleton<StatsManager>.Instance).GetComponentInChildren<MusicManager>(true)).gameObject.SetActive(true); MonoSingleton<MusicManager>.Instance.StartMusic(); RoomsComplete = ((SaveFile<StartTimes>)(object)StartTimes.Instance).Data.CurrentTimes.SelectedWave; PointsPerWave = GetRoomPoints(RoomsComplete); TimeLeft = ((SaveFile<StartTimes>)(object)StartTimes.Instance).Data.CurrentTimes.GetRoomTime(RoomsComplete); TimerActive = true; GameStarted = true; } } public void EndGame() { if (!GameStarted) { return; } if (!MonoSingleton<NewMovement>.Instance.dead) { MonoSingleton<NewMovement>.Instance.GetHurt(1000, false, 1f, false, false, 0.35f, false); } ((Component)MonoSingleton<NewMovement>.Instance.blackScreen).gameObject.SetActive(false); MonoSingleton<NewMovement>.Instance.hp = 100; GameStarted = false; int @int = MonoSingleton<PrefsManager>.Instance.GetInt("difficulty", 0); if (ScoreManager.CanSubmit(out List<string> reasons)) { if (!ScoreManager.LocalHighscores.Data.ContainsKey(@int) || CurrentScore > ScoreManager.LocalHighscores.Data[@int]) { MonoSingleton<EndScreen>.Instance.PreviousHighscore = ScoreManager.CurrentDifficultyHighscore; MonoSingleton<EndScreen>.Instance.NewBest = true; } ((MonoBehaviour)this).StartCoroutine(ShowAfterSubmit(@int)); } else { MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Score not submitting due to other mods, or cheats enabled. " + string.Join(", ", reasons), "", "", 0, false); MonoSingleton<EndScreen>.Instance.Appear(); } } private IEnumerator ShowAfterSubmit(int difficulty) { Task<bool> onlineTask = Api.ServerOnline(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => onlineTask.IsCompleted)); if (onlineTask.Result) { Task<bool> updateRequiredTask = Api.UpdateRequired(OnlineFunctionality.Context); yield return (object)new WaitUntil((Func<bool>)(() => updateRequiredTask.IsCompleted)); if (!updateRequiredTask.Result) { Task submitTask = ScoreManager.SubmitScore(CurrentScore, (short)difficulty); yield return (object)new WaitUntil((Func<bool>)(() => submitTask.IsCompleted)); } else { MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Update required to submit scores!", "", "", 0, false); } } else { MonoSingleton<HudMessageReceiver>.Instance.SendHudMessage("Server offline!", "", "", 0, false); } MonoSingleton<EndScreen>.Instance.Appear(); } [HarmonyPatch(typeof(SeasonalHats), "Start")] [HarmonyPrefix] private static void EnableHats(SeasonalHats __instance) { if (AssetManager.InSceneFromThisMod) { __instance.easter.SetActive(false); __instance.halloween.SetActive(false); __instance.christmas.SetActive(true); } } [HarmonyPatch(typeof(NewMovement), "GetHurt")] [HarmonyPostfix] private static void CustomDeath(NewMovement __instance) { if (__instance.dead && AssetManager.InSceneFromThisMod) { MonoSingleton<GameManager>.Instance.EndGame(); } } } public static class GenerationEquations { public static int PresentAmount(int wave) { int num = Mathf.CeilToInt(Mathf.Log((float)wave, 6.5f) * 3f); num = Mathf.Clamp(num, 4, 10); Plugin.Log.LogInfo((object)$"{wave} presents: {num}"); return num; } public static int[] DistributeBetween(int amount, int number) { int[] array = new int[amount]; int num = 0; while (number >= 1) { array[num]++; number--; num++; if (num > amount - 1) { num = 0; } } return array; } } public class PlayerChimneyFixer : MonoSingleton<PlayerChimneyFixer> { private bool _isInChimney; private Chimney _currentChimney; public void EnterChimney(Chimney chimney) { _isInChimney = true; _currentChimney = chimney; } public void Exit() { _isInChimney = false; } private void Update() { //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_0090: Unknown result type