using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
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 BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using Febucci.UI;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using Steamworks;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("DailyKnuckle")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("0.6.0.0")]
[assembly: AssemblyInformationalVersion("0.6.0")]
[assembly: AssemblyProduct("DailyKnuckle")]
[assembly: AssemblyTitle("DailyKnuckle")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("0.6.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;
}
}
internal static class IsExternalInit
{
}
}
namespace DailyKnuckle
{
public class DisableTargetsIfEnabled : MonoBehaviour
{
public List<GameObject> targets = new List<GameObject>();
private void OnEnable()
{
if (targets.Count <= 0)
{
return;
}
foreach (GameObject target in targets)
{
target.SetActive(false);
}
}
private void OnDisable()
{
if (targets.Count <= 0)
{
return;
}
foreach (GameObject target in targets)
{
target.SetActive(true);
}
}
}
public class ModifierTooltipHandler : MonoBehaviour
{
public TMP_Text target;
public GUISkin skin;
public Texture2D background;
private void Awake()
{
target = ((Component)this).GetComponent<TMP_Text>();
}
private void OnGUI()
{
//IL_0101: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_003d: Unknown result type (might be due to invalid IL or missing references)
//IL_016f: Unknown result type (might be due to invalid IL or missing references)
//IL_0176: Expected O, but got Unknown
//IL_0182: Unknown result type (might be due to invalid IL or missing references)
//IL_0187: Unknown result type (might be due to invalid IL or missing references)
//IL_0189: Unknown result type (might be due to invalid IL or missing references)
//IL_0193: Unknown result type (might be due to invalid IL or missing references)
//IL_01a1: Unknown result type (might be due to invalid IL or missing references)
//IL_01ac: Unknown result type (might be due to invalid IL or missing references)
//IL_01b3: Unknown result type (might be due to invalid IL or missing references)
//IL_01ba: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)skin == (Object)null)
{
background = new Texture2D(1, 1, (TextureFormat)20, false);
background.SetPixel(0, 0, new Color(0f, 0f, 0f, 0.85f));
background.Apply();
skin = Object.Instantiate<GUISkin>(GUI.skin);
skin.box.font = target.font.sourceFontFile;
skin.font = target.font.sourceFontFile;
skin.box.fontSize = 22;
skin.box.richText = true;
skin.box.normal.background = background;
skin.label.font = target.font.sourceFontFile;
}
int num = TMP_TextUtilities.FindIntersectingLink(target, Input.mousePosition, (Camera)null);
if (num == -1)
{
return;
}
string linkID = ((TMP_LinkInfo)(ref target.textInfo.linkInfo[num])).GetLinkID();
if (Patches.Modifiers.TryGetValue(linkID?.Replace("modifier:", ""), out var value))
{
string tooltip = value.Tooltip;
if (!Utility.IsNullOrWhiteSpace(tooltip))
{
GUI.skin = skin;
GUIContent val = new GUIContent(tooltip);
Vector2 val2 = GUI.skin.box.CalcSize(val);
GUI.Box(new Rect(Input.mousePosition.x - val2.x, (float)Screen.height - Input.mousePosition.y, val2.x, val2.y), val, skin.box);
}
}
}
}
public class SeedableBehavior : MonoBehaviour, Seedable
{
public int setSeed;
public void SetSeed(int seed)
{
setSeed = seed;
}
public int GetCurrentSeed()
{
return setSeed;
}
}
public class Patches
{
public static M_Gamemode dailyMode;
public static M_Gamemode weeklyMode;
public static SeedResponse latestDaily;
public static SeedResponse latestWeekly;
public static Dictionary<string, SeedModifier> Modifiers = new Dictionary<string, SeedModifier>();
public static bool HasCompetedInDaily { get; private set; } = false;
public static SeedResponse CurrentSeed
{
get
{
if (!IsWeeklyOrDaily())
{
return null;
}
if (!((Object)(object)CL_GameManager.gamemode == (Object)(object)dailyMode))
{
return latestWeekly;
}
return latestDaily;
}
}
public static async Task<SeedResponse> FetchSeed(bool daily = true)
{
using HttpResponseMessage response = await Plugin.http.GetAsync(daily ? "latestdaily" : "latestweekly");
response.EnsureSuccessStatusCode();
return JsonConvert.DeserializeObject<SeedResponse>(StringUtility.ReplaceMultiple(await response.Content.ReadAsStringAsync(), new HashSet<char> { '[', ']' }, '\0'));
}
public static async Task<List<SQLLeaderboardEntry>> FetchLeaderboardEntries(int seed_id, bool daily, int count = 10, bool time = false)
{
using HttpResponseMessage response = await Plugin.http.GetAsync(string.Format("statsforseed?leaderboard={0}&seed_id={1}&count={2}{3}", daily ? "daily" : "weekly", seed_id, count, time ? "&sorttime=1" : ""));
response.EnsureSuccessStatusCode();
return JsonConvert.DeserializeObject<List<SQLLeaderboardEntry>>(await response.Content.ReadAsStringAsync());
}
public static async Task<List<SQLLeaderboardEntry>> FetchNearbyLeaderboardEntries(int seed_id, bool daily, int count = 10, string steamid = "", bool time = false)
{
using HttpResponseMessage response = await Plugin.http.GetAsync(string.Format("statsnearplayer?leaderboard={0}&seed_id={1}&count={2}&steamid={3}{4}", daily ? "daily" : "weekly", seed_id, count, steamid, time ? "&sorttime=1" : ""));
response.EnsureSuccessStatusCode();
return JsonConvert.DeserializeObject<List<SQLLeaderboardEntry>>(await response.Content.ReadAsStringAsync());
}
public static async void UploadScore(bool daily = true, float score = 0f, float time = 0f)
{
if ((Object)(object)CL_GameManager.gamemode == (Object)(object)dailyMode && HasCompetedInDaily)
{
return;
}
using StringContent jsonContent = new StringContent(JsonConvert.SerializeObject((object)new Dictionary<string, object>
{
{
"steamid",
SteamClient.SteamId.Value.ToString()
},
{
"score",
Mathf.FloorToInt(Mathf.Clamp(score, 0f, 2.1474836E+09f))
},
{
"seed_id",
daily ? latestDaily.id : latestWeekly.id
},
{
"leaderboard",
daily ? "daily" : "weekly"
},
{
"time",
Mathf.FloorToInt(Mathf.Clamp(time, 0f, 2.1474836E+09f))
}
}, (Formatting)0), Encoding.UTF8, "application/json");
HttpResponseMessage obj = await Plugin.http.PostAsync("sign", jsonContent);
obj.EnsureSuccessStatusCode();
string content = await obj.Content.ReadAsStringAsync();
(await Plugin.http.PostAsync("uploadscore", new StringContent(content))).EnsureSuccessStatusCode();
}
public static async Task<List<SQLLeaderboardEntry>> FetchLeaderboardEntry(int seed_id, bool daily, string steamid = "")
{
using HttpResponseMessage response = await Plugin.http.GetAsync(string.Format("leaderboardentryforuser?leaderboard={0}&seedid={1}&steamid={2}", daily ? "daily" : "weekly", seed_id, steamid));
response.EnsureSuccessStatusCode();
return JsonConvert.DeserializeObject<List<SQLLeaderboardEntry>>(await response.Content.ReadAsStringAsync());
}
public static async Task<bool> HasCompetedIn(int seed_id, string steamid, bool daily)
{
return (await FetchLeaderboardEntry(seed_id, daily, steamid)).Count > 0;
}
[HarmonyPatch(typeof(CL_AssetManager), "InitializeAssetManager")]
[HarmonyPostfix]
[HarmonyWrapSafe]
public static void AssetEntry(CL_AssetManager __instance)
{
WKAssetDatabase db = CL_AssetManager.GetBaseAssetDatabase();
M_Gamemode cloneTarget;
if (!db.gamemodeAssets.Any((M_Gamemode gm) => ((Object)gm).name == "GM_Daily"))
{
cloneTarget = db.gamemodeAssets.First((M_Gamemode gm) => ((Object)gm).name == "GM_Campaign");
MakeGameMode(ref dailyMode, "Daily", "Daily Run");
MakeGameMode(ref weeklyMode, "Weekly", "Weekly Run");
PopulateMutators();
}
void MakeGameMode(ref M_Gamemode target, string name, string displayName)
{
//IL_0082: Unknown result type (might be due to invalid IL or missing references)
target = Object.Instantiate<M_Gamemode>(cloneTarget);
((Object)target).name = "GM_" + name;
target.capsuleName = name;
target.allowLeaderboardScoring = false;
target.useCustomCapsuleName = true;
target.allowCheatedScores = false;
target.scoreLeaderboardIronKnuckle = false;
target.scoreLeaderboardHard = false;
target.allowCheats = false;
target.showBankAmount = false;
target.gamemodeName = displayName;
target.introText = "COMPETE";
target.capsuleName = "GO";
target.timeMeasure = (TimeScoreMeasure)1;
db.gamemodeAssets.Add(target);
}
}
internal static void PopulateMutators()
{
if (Modifiers.Count > 0)
{
return;
}
foreach (Type item in from type in typeof(SeedModifier).Assembly.GetTypes()
where type.IsSubclassOf(typeof(SeedModifier))
select type)
{
SeedModifier seedModifier = Activator.CreateInstance(item) as SeedModifier;
Modifiers.Add(seedModifier.Key, seedModifier);
seedModifier.Setup();
}
}
[HarmonyPatch(typeof(UI_PlayPane), "Start")]
[HarmonyPostfix]
[HarmonyWrapSafe]
public static async void MakeButton(UI_PlayPane __instance)
{
Transform val = ((Component)__instance).transform.Find("Tab Objects/Play Pane - Scroll View Tab - Custom");
Transform val2 = Object.Instantiate<Transform>(val, val.parent);
((Object)val2).name = "Play Pane - Scroll View Tab - Competitive";
Transform obj = ((Component)__instance).transform.Find("Tabs/Tab Buttons/ModeButton_Challenge");
Transform val3 = Object.Instantiate<Transform>(obj, obj.parent);
((Object)val3).name = "ModeButton_DailyWeekly";
TMP_Text componentInChildren = ((Component)val3).GetComponentInChildren<TMP_Text>(true);
componentInChildren.text = "Competitive";
((Component)((Component)__instance).transform.Find("Tabs")).GetComponent<UI_TabGroup>().tabs.Add(new Tab
{
name = "dailyweekly",
tabObject = ((Component)val2).gameObject,
button = ((Component)val3).GetComponent<Button>(),
firstSelect = null,
buttonText = componentInChildren
});
Transform dailyTabContent = val2.Find("Viewport/Content");
Transform sectionBreakTemplate = val.Find("Viewport/Content/Mode - Major Section Break - Endless");
Transform buttonTemplate = val.Find("Viewport/Content/Mode Selection Button - Endless");
DisableTargetsIfEnabled disableTargetsIfEnabled = ComponentHolderProtocol.AddComponent<DisableTargetsIfEnabled>((Object)(object)val2);
foreach (Transform item in dailyTabContent)
{
Object.Destroy((Object)(object)((Component)item).gameObject);
}
foreach (Transform item2 in ((Component)__instance).transform.Find("Mutators"))
{
Transform val4 = item2;
if (((Object)((Component)val4).gameObject).name.Contains("Toggle") && ((Component)val4).gameObject.activeSelf)
{
disableTargetsIfEnabled.targets.Add(((Component)val4).gameObject);
}
}
await MakeDailyWeekly();
await MakeDailyWeekly(daily: false);
((Component)dailyTabContent).GetComponent<RectTransform>().SetSizeWithCurrentAnchors((Axis)0, 1450f);
async Task MakeDailyWeekly(bool daily = true)
{
Transform val5 = Object.Instantiate<Transform>(sectionBreakTemplate, dailyTabContent);
Transform val6 = Object.Instantiate<Transform>(buttonTemplate, dailyTabContent);
M_Gamemode modeTarget = (daily ? dailyMode : weeklyMode);
foreach (Transform item3 in dailyTabContent)
{
((Component)item3).gameObject.SetActive(true);
}
foreach (Transform item4 in val5.Find("Section Title"))
{
Transform val7 = item4;
if (((Object)val7).name.Contains("Roach Counter"))
{
Object.Destroy((Object)(object)((Component)val7).gameObject);
}
}
Transform val8 = val5.Find("Section Title/Mode Name");
((Component)val8).GetComponent<TMP_Text>().text = (daily ? "DAILY" : "WEEKLY");
((Object)val5).name = "Mode - Major Section Break";
((Component)val6).GetComponent<UI_CapsuleButton>().unlockAchievement = modeTarget.unlockAchievement;
((Component)val6.Find("Lock Image/Unlock Requirement")).GetComponent<TMP_Text>().text = modeTarget.unlockHint;
((Component)val6.Find("Mode Name")).GetComponent<TMP_Text>().text = "GO";
UI_Gamemode_Button playUIButton = ((Component)val6).GetComponent<UI_Gamemode_Button>();
Transform label1 = Object.Instantiate<Transform>(val8, dailyTabContent);
TMP_Text label1Text = ((Component)label1).GetComponent<TMP_Text>();
label1.rotation = Quaternion.identity;
((Component)label1).GetComponent<RectTransform>().SetSizeWithCurrentAnchors((Axis)0, 500f);
label1Text.text = "Fetching data... If you still see this something is wrong. Check log";
List<string> modNameList = new List<string>();
SeedResponse seedTarget;
try
{
seedTarget = ((!daily) ? (latestWeekly = await FetchSeed(daily: false)) : (latestDaily = await FetchSeed()));
if (seedTarget.modifiers != null)
{
foreach (SeedModifier modifier in GetModifiers(seedTarget.modifiers))
{
modNameList.Add("<link=\"modifier:" + modifier.Key + "\">" + modifier.DisplayName + "</link>");
}
}
}
catch (Exception ex)
{
if (daily)
{
latestDaily = null;
}
else
{
latestWeekly = null;
}
Plugin.Logger.LogError((object)ex);
label1Text.text = ex.Message + ": " + ex.InnerException?.Message;
return;
}
string oneShotMessage = "<br><b>You only have one shot.</b>";
if (daily)
{
try
{
HasCompetedInDaily = await HasCompetedIn(latestDaily.id, SteamClient.SteamId.Value.ToString(), daily: true);
}
catch (Exception ex2)
{
Plugin.Logger.LogError((object)ex2);
return;
}
if (HasCompetedInDaily)
{
oneShotMessage = "<br><i>You had one shot.</i><br>You may only view your score.";
}
}
DateTime dateTime = DateTime.UnixEpoch.AddMilliseconds(long.Parse(seedTarget.timecreated));
label1Text.alignment = (TextAlignmentOptions)4097;
label1Text.text = string.Format("\r\n{0} run #{1}\r\nCreated: {2}\r\nSeed: {3}\r\nModifiers: {4}{5}", daily ? "Daily" : "Weekly", seedTarget.id, dateTime, seedTarget.seed, modNameList.AsEnglish(), daily ? oneShotMessage : "");
ComponentHolderProtocol.AddComponent<ModifierTooltipHandler>((Object)(object)label1);
((UnityEventBase)((Component)((Component)playUIButton).transform).GetComponent<Button>().onClick).RemoveAllListeners();
playUIButton.gamemode = modeTarget;
playUIButton.initialized = false;
}
}
[HarmonyPatch(typeof(WorldLoader), "Awake")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static void WL_Awake(WorldLoader __instance)
{
UndoModifiers();
if (!IsWeeklyOrDaily())
{
return;
}
SeedResponse seedResponse = (((Object)(object)CL_GameManager.gamemode == (Object)(object)dailyMode) ? latestDaily : latestWeekly);
__instance.seed = seedResponse.seed;
__instance.startingSeed = __instance.seed;
SettingsManager.settings.g_hard = false;
SettingsManager.settings.g_competitive = false;
foreach (SeedModifier modifier in GetModifiers(seedResponse.modifiers))
{
modifier.PreWorldLoader(__instance);
}
}
[HarmonyPatch(typeof(CL_GameManager), "LoadIn")]
[HarmonyPostfix]
[HarmonyWrapSafe]
public static void GM_PostLoad(CL_GameManager __instance)
{
if (!IsWeeklyOrDaily())
{
return;
}
foreach (SeedModifier modifier in GetModifiers((((Object)(object)CL_GameManager.gamemode == (Object)(object)dailyMode) ? latestDaily : latestWeekly).modifiers))
{
modifier.AfterLoadedIn(__instance);
}
}
[HarmonyPatch(typeof(M_Gamemode), "Finish")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static bool Gamemode_Finish(M_Gamemode __instance, float time, bool hasFinished = false)
{
if (!IsWeeklyOrDaily())
{
return true;
}
__instance.gamemodeModule.OnFinish(hasFinished);
bool flag = (!__instance.allowCheatedScores && CommandConsole.hasCheated) || (!__instance.allowCheatedScores && !CL_GameManager.AreAchievementsAllowed());
UploadScore((Object)(object)CL_GameManager.gamemode == (Object)(object)dailyMode, (!flag) ? __instance.GetPlayerScore(hasFinished) : 0f, time);
return false;
}
public static List<SeedModifier> GetModifiers(string mods)
{
List<SeedModifier> list = new List<SeedModifier>();
if (string.IsNullOrWhiteSpace(mods))
{
return list;
}
string[] array = mods.Split('|', StringSplitOptions.RemoveEmptyEntries);
foreach (string key in array)
{
if (Modifiers.ContainsKey(key))
{
list.Add(Modifiers[key]);
continue;
}
throw new InvalidOperationException("Please update your mod or report this bug if it persists.");
}
return list;
}
public static void UndoModifiers()
{
Plugin.modifierHarmony.UnpatchSelf();
}
[HarmonyPatch(typeof(Leaderboard_Panel), "UpdateScore")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static bool LP_ScoreFetchPatch(Leaderboard_Panel __instance)
{
if (!IsWeeklyOrDaily())
{
return true;
}
try
{
OutOfPatchLeaderboardFetch(__instance);
}
catch (Exception ex)
{
Plugin.Logger.LogError((object)ex);
}
return false;
}
public static async Task OutOfPatchLeaderboardFetch(Leaderboard_Panel __instance)
{
List<Leaderboard_Score> scoreObjects = __instance.scoreObjects;
for (int j = 0; j < scoreObjects.Count; j++)
{
((Component)scoreObjects[j]).gameObject.SetActive(false);
}
bool useTime = (int)__instance.scoreType == 1;
List<SQLLeaderboardEntry> scores = null;
if ((int)__instance.defaultType == 0)
{
scores = await FetchLeaderboardEntries(CurrentSeed.id, (Object)(object)CL_GameManager.gamemode == (Object)(object)dailyMode, __instance.scoresToPull, useTime);
}
else if ((int)__instance.defaultType == 2 || (int)__instance.defaultType == 1)
{
scores = await FetchNearbyLeaderboardEntries(CurrentSeed.id, (Object)(object)CL_GameManager.gamemode == (Object)(object)dailyMode, __instance.scoresToPull / 2, SteamClient.SteamId.Value.ToString(), useTime);
if (scores == null)
{
scores = await FetchLeaderboardEntries(CurrentSeed.id, (Object)(object)CL_GameManager.gamemode == (Object)(object)dailyMode, __instance.scoresToPull, useTime);
}
}
Friend val = default(Friend);
for (int i = 0; i < scoreObjects.Count; i++)
{
if (i >= scores.Count)
{
((Component)scoreObjects[i]).gameObject.SetActive(false);
continue;
}
SteamId id = new SteamId
{
Value = Convert.ToUInt64(scores[i].steamid)
};
((Friend)(ref val))..ctor(id);
((Component)scoreObjects[i]).gameObject.SetActive(true);
scoreObjects[i].positionText.text = $"<mspace=''>{scores[i].rank}</mspace>";
scoreObjects[i].nameText.text = ((Friend)(ref val)).Name ?? "";
if (!useTime)
{
scoreObjects[i].scoreText.text = $"{scores[i].score}";
}
else
{
TimeSpan timeSpan = TimeSpan.FromSeconds(scores[i].time.Value);
scoreObjects[i].scoreText.text = $"{timeSpan:hh\\:mm\\:ss}";
}
Texture2D texture = SteamManager.ConvertSteamIcon((await ((Friend)(ref val)).GetMediumAvatarAsync()).Value);
scoreObjects[i].profile.texture = (Texture)(object)texture;
if (SteamClient.SteamId.Value == id.Value)
{
((Graphic)scoreObjects[i].positionText).color = __instance.isMeColor;
((Graphic)scoreObjects[i].nameText).color = __instance.isMeColor;
((Graphic)scoreObjects[i].scoreText).color = __instance.isMeColor;
}
else
{
((Graphic)scoreObjects[i].positionText).color = Color.white;
((Graphic)scoreObjects[i].nameText).color = Color.white;
((Graphic)scoreObjects[i].scoreText).color = Color.white;
}
}
}
public static bool IsWeeklyOrDaily()
{
if (!((Object)(object)CL_GameManager.gamemode == (Object)(object)dailyMode))
{
return (Object)(object)CL_GameManager.gamemode == (Object)(object)weeklyMode;
}
return true;
}
[HarmonyPatch(typeof(UI_GamemodeScreen), "LoadGamemode")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static bool UI_GamemodeScreen_LoadGamemode()
{
if ((Object)(object)CL_GameManager.gamemode != (Object)(object)dailyMode)
{
return true;
}
return !HasCompetedInDaily;
}
[HarmonyPatch(typeof(SpawnSettings), "CheckStat")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static bool SpawnSettings_CheckStat(ref bool __result, StatCheck check)
{
if (!IsWeeklyOrDaily() || check.session)
{
return true;
}
__result = true;
return false;
}
[HarmonyPatch(typeof(SpawnSettings), "RandomCheck")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static void SpawnSettings_RandomCheck(SpawnSettings __instance)
{
Random.InitState((int)DateTime.Now.Ticks);
if (IsWeeklyOrDaily())
{
Random.InitState(CurrentSeed.seed);
}
}
[HarmonyPatch(typeof(ENV_VendingMachine), "GenerateOptions")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static void ENV_VendingMachine_GenerateOptions(ENV_VendingMachine __instance)
{
Random.InitState((int)DateTime.Now.Ticks);
if (IsWeeklyOrDaily())
{
int localSeed = __instance.localSeed;
Random.InitState((localSeed == 0) ? CurrentSeed.seed : localSeed);
}
}
[HarmonyPatch(typeof(CL_ProgressionManager), "HasProgressionUnlock")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static bool CL_ProgressionManager_HasProgressionUnlock(ref bool __result, SpawnSettings __instance)
{
if (!IsWeeklyOrDaily())
{
return true;
}
__result = true;
return false;
}
[HarmonyPatch(typeof(M_Level), "CanSpawn")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static bool MLevel_CanSpawn(ref bool __result)
{
if (!IsWeeklyOrDaily())
{
return true;
}
__result = true;
return false;
}
[HarmonyPatch(typeof(CL_GameManager), "GrabSavedRoaches")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static bool CL_GameManager_GrabSavedRoaches()
{
if (!IsWeeklyOrDaily())
{
return true;
}
CL_GameManager.roaches = ((!SettingsManager.settings.g_competitive) ? 20 : 0);
return false;
}
[HarmonyPatch(typeof(StatManager), "SaveStats")]
[HarmonyPrefix]
[HarmonyWrapSafe]
public static void StatManager_SaveStats()
{
IsWeeklyOrDaily();
CL_GameManager.gMan.allowScores = false;
}
}
public record SeedResponse(int id, int seed, string timecreated = null, string modifiers = null);
public record SQLLeaderboardEntry(string steamid = null, int? score = null, int? rank = null, int? time = null);
[BepInPlugin("DailyKnuckle", "DailyKnuckle", "0.6.0")]
public class Plugin : BaseUnityPlugin
{
public static ManualLogSource Logger;
public static ConfigEntry<string> dkServer;
public static HttpClient http = new HttpClient();
public static Harmony modifierHarmony = new Harmony("dailyknuckle.modifiers");
private void Awake()
{
Logger = ((BaseUnityPlugin)this).Logger;
dkServer = ((BaseUnityPlugin)this).Config.Bind<string>("Connection", "ServerUri", "http://ec2-13-49-224-141.eu-north-1.compute.amazonaws.com:5000", "Server to retrieve dailies from");
http.BaseAddress = new Uri(dkServer.Value);
http.Timeout = TimeSpan.FromSeconds(5.0);
Harmony.CreateAndPatchAll(typeof(Patches), (string)null);
}
}
public static class Extensions
{
public static void AddTag(this GameObject gameObject, string tag)
{
if (!string.IsNullOrEmpty(tag))
{
ObjectTagger orAddComponent = ComponentHolderProtocol.GetOrAddComponent<ObjectTagger>((Object)(object)gameObject);
if (!orAddComponent.tags.Contains(tag))
{
orAddComponent.tags.Add(tag);
}
}
}
public static bool HasTag(this GameObject gameObject, string tag)
{
ObjectTagger component = gameObject.GetComponent<ObjectTagger>();
if ((Object)(object)component == (Object)null || !component.tags.Contains(tag))
{
return false;
}
return true;
}
public static string AsEnglish(this List<string> input, string nothing = "none", string and = " and ", string comma = ", ")
{
int count = input.Count;
switch (count)
{
case 0:
return nothing;
case 1:
return input[0];
case 2:
return input[0] + and + input[1];
default:
{
string text = "";
int i;
for (i = 0; i < count - 1; i++)
{
text = text + input[i] + comma;
}
return text + and + input[i];
}
}
}
}
public class SeedModifier
{
public virtual string DisplayName { get; }
public virtual string Key { get; }
public virtual string Tooltip { get; }
public virtual void Setup()
{
}
public virtual void PreWorldLoader(WorldLoader loader)
{
}
public virtual void AfterLoadedIn(CL_GameManager manager)
{
}
}
public class IronKnuckleMod : SeedModifier
{
public override string DisplayName => "<color=\"yellow\">Iron Knuckle</color>";
public override string Key => "IK";
public override string Tooltip => "<color=\"yellow\">No Perks, Or Starting Roaches</color>";
public override void PreWorldLoader(WorldLoader loader)
{
SettingsManager.settings.g_competitive = true;
}
}
public class HardMod : SeedModifier
{
public override string DisplayName => "<color=\"red\">Hard Mode</color>";
public override string Key => "HM";
public override string Tooltip => "<color=\"red\">Good Luck</color>";
public override void PreWorldLoader(WorldLoader loader)
{
SettingsManager.settings.g_hard = true;
}
}
public class AllFragilesMod : SeedModifier
{
private class ModifierPatches
{
[HarmonyPatch(typeof(HandholdManager), "LoadHandholds")]
[HarmonyPrefix]
[HarmonyWrapSafe]
private static void Patch(GameObject g)
{
//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
//IL_00eb: Unknown result type (might be due to invalid IL or missing references)
//IL_0103: Unknown result type (might be due to invalid IL or missing references)
//IL_010d: Unknown result type (might be due to invalid IL or missing references)
//IL_011e: Unknown result type (might be due to invalid IL or missing references)
//IL_012a: Unknown result type (might be due to invalid IL or missing references)
//IL_012f: Unknown result type (might be due to invalid IL or missing references)
//IL_013b: Unknown result type (might be due to invalid IL or missing references)
//IL_0155: Unknown result type (might be due to invalid IL or missing references)
//IL_0175: Unknown result type (might be due to invalid IL or missing references)
Transform[] componentsInChildren = g.GetComponentsInChildren<Transform>();
RaycastHit val3 = default(RaycastHit);
foreach (Transform val in componentsInChildren)
{
if (!((Object)val).name.Contains("handhold:basic:") || ((Object)val).name.Contains("ventHole") || ((Object)val).name.Contains("edge") || ((Object)val).name.Contains("rod") || ((Object)val).name.Contains("edge") || ((Object)val).name.Contains(":bar"))
{
continue;
}
MeshFilter component = ((Component)val).GetComponent<MeshFilter>();
if (!((Object)(object)component != (Object)null) || component.mesh.vertexCount <= 128)
{
GameObject val2 = Object.Instantiate<GameObject>(BreakableHandhold, val.parent);
val2.transform.position = ((Component)val).transform.position;
val2.transform.rotation = ((Component)val).transform.rotation;
val2.transform.Translate(val2.transform.up * 0.2f);
if (Physics.Raycast(val2.transform.position, -val2.transform.up, ref val3, 1.5f, LayerMask.op_Implicit(hitMask)))
{
val2.transform.position = ((RaycastHit)(ref val3)).point;
val2.transform.Rotate(new Vector3(90f, 0f, 0f));
Object.Destroy((Object)(object)((Component)val).gameObject);
}
else
{
Object.Destroy((Object)(object)val2);
}
}
}
}
}
public static GameObject BreakableHandhold;
public static LayerMask hitMask = LayerMask.op_Implicit(-1);
public override string DisplayName => "Fragile Handholds";
public override string Key => "FHOLDS";
public override string Tooltip => "Makes most handholds fragile.\nIt is <b>not possible</b> to do it 100% accurately, so expect bugs.";
public override void PreWorldLoader(WorldLoader WL)
{
//IL_0035: 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_008e: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)BreakableHandhold == (Object)null)
{
BreakableHandhold = ((Component)((Component)CL_AssetManager.GetLevelAsset("M3_Habitation_Shaft_01", "")).transform.Find("Handholds/Handhold_Breakable_Basic_02")).gameObject;
}
if (LayerMask.op_Implicit(hitMask) == -1)
{
hitMask = ((Component)CL_AssetManager.GetBaseAssetDatabase().itemPrefabs.First((GameObject p) => ((Object)p).name == "Item_Piton").GetComponent<Item_Object>().itemData.handItemAsset).gameObject.GetComponent<HandItem_Piton>().hitMask;
}
Plugin.modifierHarmony.PatchAll(typeof(ModifierPatches));
}
}
public class NoGravityMod : SeedModifier
{
private class ModifierPatches
{
[HarmonyPatch(typeof(ENV_Rope), "Start")]
[HarmonyPrefix]
[HarmonyWrapSafe]
private static void Patch(ENV_Rope __instance)
{
__instance.gravity = 0f;
}
}
public static GameObject BreakableHandhold;
public override string DisplayName => "No Gravity";
public override string Key => "NOGRAV";
public override string Tooltip => "No gravity. <i>Duh.</i>";
public override void AfterLoadedIn(CL_GameManager manager)
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
ENT_Player.playerObject.SetGravity(false);
ENT_Player.playerObject.gravity = 0f;
CL_GameManager.gMan.gravity = 0f;
Physics.gravity = new Vector3(0f, 0f, 0f);
Plugin.modifierHarmony.PatchAll(typeof(ModifierPatches));
}
}
public class LessItemsMod : SeedModifier
{
private class ModifierPatches
{
private static readonly WeightedDict chanceDict = new WeightedDict
{
{ "item_beans", 90f },
{ "item_piton", 100f },
{ "item_rebar", 90f },
{ "item_rebar_explosive", 45f },
{ "item_rebarrope", 75f },
{ "item_injector", 45f },
{ "denizen_sluggrub", 45f },
{ "item_autopiton", 50f },
{ "item_pillbottle", 45f },
{ "item_food_bar", 65f }
};
[HarmonyPatch(typeof(M_Level), "OnSpawn")]
[HarmonyPrefix]
[HarmonyWrapSafe]
private static void Patch(M_Level __instance)
{
Item_Object[] componentsInChildren = ((Component)__instance).gameObject.GetComponentsInChildren<Item_Object>();
foreach (Item_Object val in componentsInChildren)
{
if (!((Object)((Component)val).gameObject).name.ToLower().Contains("flashlight") && !((Object)((Component)val).gameObject).name.ToLower().Contains("flaregun"))
{
Object.Destroy((Object)(object)((Component)val).gameObject);
}
}
}
[HarmonyPatch(typeof(M_Level), "OnEnter")]
[HarmonyPostfix]
[HarmonyWrapSafe]
private static void Patch3(M_Level __instance)
{
//IL_00df: Unknown result type (might be due to invalid IL or missing references)
//IL_00e4: 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)
if (((Component)__instance).gameObject.HasTag("scarceitems-visited"))
{
return;
}
((Component)__instance).gameObject.AddTag("scarceitems-visited");
if (((Object)((Component)__instance).gameObject).name.Contains("M1_Intro_01"))
{
return;
}
List<string> list = new List<string>();
Random.InitState(__instance.GetLevelSeed());
int num = 1 + ((Random.Range(0, 101) < 50) ? 1 : 0);
for (int j = 0; j < num; j++)
{
Random.InitState(__instance.GetLevelSeed() + j * 128);
string result = chanceDict.GetRandomResult<string>();
Random.InitState((int)DateTime.Now.Ticks);
Item clone = CL_AssetManager.GetBaseAssetDatabase().entityPrefabs.First((GameObject i) => ((Object)i).name.ToLower() == result).GetComponent<Item_Object>().itemData.GetClone();
Inventory inventory = ENT_Player.GetInventory();
Vector3 val = new Vector3(0f, -1f, 1f);
inventory.AddItemToInventoryScreen(((Vector3)(ref val)).normalized, clone, true, false);
list.Add(clone.itemName);
}
CL_UIManager.instance.tipHeader.ShowText("Given items: " + list.AsEnglish());
}
[HarmonyPatch(typeof(ENV_VendingMachine), "GenerateOptions")]
[HarmonyPostfix]
[HarmonyWrapSafe]
private static void Patch2(ENV_VendingMachine __instance)
{
VendingButton[] buttons = __instance.buttons;
for (int i = 0; i < buttons.Length; i++)
{
buttons[i].available = false;
}
__instance.UpdateButtons();
}
}
public override string DisplayName => "One Item Per Room";
public override string Key => "OPROOM";
public override string Tooltip => "No items will normally spawn in a room.\nYou will get a random item from a certain set after you clear a room.";
public override void PreWorldLoader(WorldLoader WL)
{
Plugin.modifierHarmony.PatchAll(typeof(ModifierPatches));
}
}
public class NoHandholdsMod : SeedModifier
{
private class ModifierPatches
{
[HarmonyPatch(typeof(HandholdManager), "LoadHandholds")]
[HarmonyPrefix]
[HarmonyWrapSafe]
private static void Patch(GameObject g)
{
M_Level component = g.GetComponent<M_Level>();
bool flag = ((Object)g).name.Contains("Pipeworks_Organ") || ((Object)g).name.Contains("M3_Campaign_Transition_Pipeworks_To_Habitation") || ((Object)g).name.Contains("Habitation_Lab");
Transform[] componentsInChildren = g.GetComponentsInChildren<Transform>();
foreach (Transform val in componentsInChildren)
{
if (((Object)val).name.Contains("handhold:") && !((Object)val).name.Contains("edge"))
{
Random.InitState(component.GetLevelSeed());
if (!flag || Random.Range(0, 101) >= 40)
{
Random.InitState((int)DateTime.Now.Ticks);
Object.Destroy((Object)(object)((Component)val).gameObject);
}
}
}
}
}
public override string DisplayName => "Almost No Handholds";
public override string Key => "NOHOLDS";
public override string Tooltip => "Makes most handholds disappear.";
public override void PreWorldLoader(WorldLoader WL)
{
Plugin.modifierHarmony.PatchAll(typeof(ModifierPatches));
}
}
public class OnlyClimbMod : SeedModifier
{
private class ModifierPatches
{
[HarmonyPatch(typeof(App_PerkPage), "GenerateCards")]
[HarmonyPostfix]
[HarmonyWrapSafe]
private static void Patch(App_PerkPage __instance)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0007: Invalid comparison between Unknown and I4
if ((int)__instance.perkPageType != 1)
{
return;
}
__instance.fullfilled = true;
foreach (App_PerkPage_Card card in __instance.cards)
{
card.DisableCard();
card.LockCard();
card.UpdateCard();
}
}
}
public class TimeLimitMod : SeedModifier
{
private class ModifierPatches
{
private static TMP_Text timerHeader;
private static float timeLeft = 0f;
private static float greenLerp = 0f;
private static readonly string[] safeAreas = new string[3] { "M1_Silos_SafeArea_01(Clone)", "M3_Habitation_Shaft_Intro(Clone)", "M1_Campaign_Transition_Silo_To_Pipeworks_01(Clone)" };
[HarmonyPatch(typeof(CL_GameManager), "Start")]
[HarmonyPostfix]
[HarmonyWrapSafe]
private static void Patch(CL_GameManager __instance)
{
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
timeLeft = 15f;
greenLerp = 0f;
GameObject gameObject = ((Component)CL_UIManager.instance.header).gameObject;
timerHeader = Object.Instantiate<GameObject>(gameObject, gameObject.transform.parent).GetComponent<TMP_Text>();
timerHeader.transform.Translate(new Vector3(0f, 48f, 0f));
TMP_Text obj = timerHeader;
obj.fontSize += 8f;
Object.Destroy((Object)(object)((Component)timerHeader).GetComponent<UT_TextScrawl>());
Object.Destroy((Object)(object)((Component)timerHeader).GetComponent<TypewriterByCharacter>());
Object.Destroy((Object)(object)((Component)timerHeader).GetComponent<TextAnimator_TMP>());
timerHeader.renderMode = (TextRenderFlags)255;
}
[HarmonyPatch(typeof(CL_GameManager), "Update")]
[HarmonyPostfix]
[HarmonyWrapSafe]
private static void Patch2(CL_GameManager __instance)
{
//IL_000a: Unknown result type (might be due to invalid IL or missing references)
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Unknown result type (might be due to invalid IL or missing references)
//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
if (timerHeader.transform.localScale.x > 1f)
{
timerHeader.transform.localScale = new Vector3(Mathf.Max(1f, timerHeader.transform.localScale.x - Time.deltaTime * 0.75f), timerHeader.transform.localScale.y, timerHeader.transform.localScale.z);
}
if (greenLerp > 0f)
{
greenLerp = Mathf.Max(0f, greenLerp -= Time.deltaTime);
}
((Graphic)timerHeader).color = Color.Lerp(Color.grey, Color.green, greenLerp);
if (CL_GameManager.gMan.IsReviving())
{
timeLeft = 15f;
timerHeader.text = "PAUSED";
return;
}
if (CL_GameManager.IsSafe() || safeAreas.Contains(((Object)((Component)CL_EventManager.currentLevel).gameObject).name))
{
timerHeader.text = "PAUSED";
return;
}
timeLeft -= Time.deltaTime;
TimeSpan timeSpan = TimeSpan.FromSeconds(timeLeft);
string text = $"{timeSpan.Minutes:D2}:{timeSpan.Seconds:D2}.{timeSpan.Milliseconds:D3}";
timerHeader.text = ((timeLeft < 5f) ? ("<color=\"red\">" + text) : text);
if (timeLeft <= 0f && !CL_GameManager.isDead())
{
((GameEntity)ENT_Player.playerObject).Kill("");
((Component)timerHeader).gameObject.SetActive(false);
}
}
[HarmonyPatch(typeof(M_Level), "OnEnter")]
[HarmonyPostfix]
[HarmonyWrapSafe]
private static void Patch3(M_Level __instance)
{
//IL_0122: Unknown result type (might be due to invalid IL or missing references)
//IL_0136: Unknown result type (might be due to invalid IL or missing references)
//IL_0140: Unknown result type (might be due to invalid IL or missing references)
if (((Component)__instance).gameObject.HasTag("attack-visited"))
{
return;
}
((Component)__instance).gameObject.AddTag("attack-visited");
string name = ((Object)((Component)__instance).gameObject).name;
if (!name.Contains("M1_Intro_01"))
{
if (name.Contains("M3_Campaign_Transition_Pipeworks_To_Habitation"))
{
timeLeft += 165f;
}
else if (name.Contains("Habitation_Pier"))
{
timeLeft += 120f;
}
else if (name.StartsWith("M2"))
{
timeLeft += 30f;
}
else if ((name.StartsWith("M3") && !name.Contains("Habitation_Shaft")) || name.Contains("Silos_Air_07"))
{
timeLeft += 60f;
}
else
{
timeLeft += 17.5f;
}
timeLeft = Mathf.Clamp(timeLeft, 0f, 300f);
greenLerp = 1f;
timerHeader.transform.localScale = new Vector3(1.5f, timerHeader.transform.localScale.y, timerHeader.transform.localScale.z);
}
}
}
public override string DisplayName => "Time Attack";
public override string Key => "TIMELM";
public override string Tooltip => "You have a timer that tracks how long you have to live.\nGet extra time by clearing rooms, depending on room and region.\nThe timer will pause in breakrooms.";
public override void PreWorldLoader(WorldLoader WL)
{
Plugin.modifierHarmony.PatchAll(typeof(ModifierPatches));
}
}
public override string DisplayName => "Only Climbing";
public override string Key => "PERKOC";
public override string Tooltip => "You start with the <b>Only Climb</b> perk.\n<b>Disables the silos experimental perk machine.</b>";
public override void AfterLoadedIn(CL_GameManager manager)
{
ENT_Player.playerObject.AddPerk(new string[1] { "perk_u_t1_onlyclimbing" });
Plugin.modifierHarmony.PatchAll(typeof(ModifierPatches));
}
}
public class WeightedDict : IDictionary<object, float>, ICollection<KeyValuePair<object, float>>, IEnumerable<KeyValuePair<object, float>>, IEnumerable
{
private readonly Dictionary<object, float> _dict = new Dictionary<object, float>();
public float this[object key]
{
get
{
return _dict[key];
}
set
{
_dict[key] = value;
}
}
public float RatioSum => _dict.Sum((KeyValuePair<object, float> p) => p.Value);
public ICollection<object> Keys => _dict.Keys;
public ICollection<float> Values => _dict.Values;
public int Count => _dict.Count;
public bool IsReadOnly => false;
public void Add(object key, float value)
{
_dict.Add(key, value);
}
public void Add(KeyValuePair<object, float> item)
{
_dict.Add(item.Key, item.Value);
}
public void Clear()
{
_dict.Clear();
}
public bool Contains(KeyValuePair<object, float> item)
{
return _dict.Contains(item);
}
public bool ContainsKey(object key)
{
return _dict.ContainsKey(key);
}
public void CopyTo(KeyValuePair<object, float>[] array, int arrayIndex)
{
throw new NotImplementedException();
}
public IEnumerator<KeyValuePair<object, float>> GetEnumerator()
{
return _dict.GetEnumerator();
}
public object GetRandomResult()
{
float num = Random.Range(0f, 0.99f) * RatioSum;
foreach (KeyValuePair<object, float> item in _dict)
{
num -= item.Value;
if (num <= 0f)
{
return item.Key;
}
}
return null;
}
public T GetRandomResult<T>()
{
return (T)GetRandomResult();
}
public bool Remove(object key)
{
return _dict.Remove(key);
}
public bool Remove(KeyValuePair<object, float> item)
{
return _dict.Remove(item.Key);
}
public bool TryGetValue(object key, out float value)
{
return _dict.TryGetValue(key, out value);
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "DailyKnuckle";
public const string PLUGIN_NAME = "DailyKnuckle";
public const string PLUGIN_VERSION = "0.6.0";
}
}