update for "carnival"

This commit is contained in:
Hao Feng
2025-10-13 16:05:56 +11:00
parent ccffaf352f
commit e01dd26d6f
9 changed files with 686 additions and 666 deletions

View File

@@ -4,10 +4,13 @@ using System.Threading.Tasks;
using Il2CppPhoton.Bolt;
using UnityEngine;
using Il2Cpp;
using System;
using System.Collections;
using System.Collections.Generic;
namespace DevourClient
{
public class ClientMain : MonoBehaviour
public class ClientMain : MonoBehaviour, IDisposable
{
public ClientMain(IntPtr ptr)
: base(ptr)
@@ -25,7 +28,7 @@ namespace DevourClient
Players = 6
}
static Rect windowRect = new Rect(Settings.Settings.x + 10, Settings.Settings.y + 10, 700, 700);
static Rect windowRect = new Rect(Settings.Settings.x + 10, Settings.Settings.y + 10, 800, 750);
static CurrentTab current_tab = CurrentTab.Visuals;
static bool flashlight_toggle = false;
@@ -34,13 +37,12 @@ namespace DevourClient
static bool azazel_esp_colorpick = false;
static bool spoofLevel = false;
static float spoofLevelValue = 0;
static bool change_server_name = false;
static bool change_steam_name = false;
// UI variables
static bool fly = false;
static float fly_speed = 5;
static bool fastMove = false;
static float _PlayerSpeedMultiplier = 1;
public static float lobbySize = 4;
public static bool _IsAutoRespawn = false;
public static bool unlimitedUV = false;
public static bool exp_modifier = false;
@@ -53,7 +55,6 @@ namespace DevourClient
static bool azazel_esp = false;
static bool azazel_skel_esp = false;
static bool azazel_snapline = false;
static bool spam_message = false;
static bool item_esp = false;
static bool goat_rat_esp = false;
static bool demon_esp = false;
@@ -64,46 +65,40 @@ namespace DevourClient
static bool should_show_start_message = true;
static Texture2D crosshairTexture = default!;
private static string spamMessageText = "Deez Nutz";
private static string steamNameText = "patate";
private static string serverNameText = "patate on top !";
private static float spamMessageInterval = 5f; // Default send interval in seconds
private static float spamMessageTimer = 0f; // Timer
private static int frameCount = 0;
private static int lastMemoryLog = 0;
private const int GC_GEN0_INTERVAL = 300;
private const int GC_FULL_INTERVAL = 3600;
private const int MEMORY_LOG_INTERVAL = 1800;
public void Start()
{
MelonLogger.Msg("For the Queen !");
Hacks.Misc.ShowMessageBox("For the Queen !");
MelonLogger.Warning("Made with <3 by patate and Jadis.");
Hacks.Misc.ShowMessageBox("Made with <3 by patate and Jadis.");
MelonLogger.Warning("Github : https://github.com/ALittlePatate/DevourClient");
Hacks.Misc.ShowMessageBox("Github : https://github.com/ALittlePatate/DevourClient");
MelonLogger.Warning("Note : if you payed for this you most likely got scammed.");
Hacks.Misc.ShowMessageBox("Note : if you payed for this you most likely got scammed.");
long startMemory = GC.GetTotalMemory(false);
MelonLogger.Msg($"[Memory Monitor] Startup managed memory: {startMemory / 1024 / 1024} MB");
crosshairTexture = Helpers.GUIHelper.GetCircularTexture(5, 5);
// Start all coroutines using new coroutine management mechanism
Helpers.Entities.StartAllCoroutines();
}
public void OnDestroy()
{
// Stop all coroutines when component is destroyed
Helpers.Entities.StopAllCoroutines();
// Clean up other resources
if (crosshairTexture != null)
{
UnityEngine.Object.Destroy(crosshairTexture);
crosshairTexture = null;
}
}
public void OnApplicationQuit()
{
// Stop all coroutines when application quits
Helpers.Entities.StopAllCoroutines();
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetLocalPlayer()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetGoatsAndRats()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetSurvivalInteractables()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetKeys()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetDemons()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetSpiders()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetGhosts()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetBoars()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetCorpses()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetCrows()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetLumps()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetAzazels()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetAllPlayers()));
Helpers.Entities.RegisterCoroutine(MelonCoroutines.Start(Helpers.Entities.GetMonkeys()));
}
public void Update()
@@ -159,31 +154,13 @@ namespace DevourClient
}
else
{
if (crosshair && in_game_cache)
{
in_game_cache = false;
}
}
if (spam_message)
{
spamMessageTimer += Time.deltaTime;
if (spamMessageTimer >= spamMessageInterval)
{
Hacks.Misc.MessageSpam(spamMessageText);
spamMessageTimer = 0f; // Reset timer
}
}
else
{
spamMessageTimer = 0f; // Reset timer when disabled
}
if (spoofLevel)
{
Hacks.Misc.SetRank((int)spoofLevelValue);
}
if (Input.GetKeyDown(Settings.Settings.flyKey))
{
fly = !fly;
@@ -237,7 +214,30 @@ namespace DevourClient
{
Helpers.Entities.LocalPlayer_.p_GameObject.GetComponent<Il2CppOpsive.UltimateCharacterController.Character.UltimateCharacterLocomotion>().TimeScale = _PlayerSpeedMultiplier;
}
catch { return; }
catch { return; }
}
frameCount++;
if (frameCount % GC_GEN0_INTERVAL == 0)
{
GC.Collect(0, GCCollectionMode.Optimized);
}
if (frameCount % GC_FULL_INTERVAL == 0)
{
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
frameCount = 0;
}
if (frameCount - lastMemoryLog >= MEMORY_LOG_INTERVAL)
{
long memoryUsed = GC.GetTotalMemory(false);
MelonLogger.Msg($"[Memory Monitor] Current managed memory: {memoryUsed / 1024 / 1024} MB | Frame: {frameCount}");
lastMemoryLog = frameCount;
}
}
@@ -249,72 +249,37 @@ namespace DevourClient
should_show_start_message = false;
}
// Update error message display time
if (Settings.Settings.showErrorMessage)
// 保存原始GUI状态
Color originalBackgroundColor = GUI.backgroundColor;
GUISkin originalSkin = GUI.skin;
try
{
Settings.Settings.errorMessageDisplayTime += Time.deltaTime;
if (Settings.Settings.errorMessageDisplayTime >= Settings.Settings.errorMessageMaxDisplayTime)
{
Settings.Settings.showErrorMessage = false;
}
}
GUI.backgroundColor = Color.grey;
// Render error message box
if (Settings.Settings.showErrorMessage)
{
// Set message box style
GUIStyle errorBoxStyle = new GUIStyle(GUI.skin.box);
errorBoxStyle.normal.background = GUIHelper.MakeTex(2, 2, new Color(0.8f, 0.2f, 0.2f, 0.9f));
errorBoxStyle.normal.textColor = Color.white;
errorBoxStyle.fontSize = 14;
errorBoxStyle.padding = new RectOffset(10, 10, 10, 10);
errorBoxStyle.wordWrap = true;
errorBoxStyle.clipping = TextClipping.Overflow;
// 设置按钮样式
GUI.skin.button.normal.background = GUIHelper.MakeTex(2, 2, Color.black);
GUI.skin.button.normal.textColor = Color.white;
GUI.skin.button.hover.background = GUIHelper.MakeTex(2, 2, Color.green);
GUI.skin.button.hover.textColor = Color.black;
// Calculate message box position (bottom center)
float boxWidth = 400f;
float boxHeight = 60f;
float boxX = (Screen.width - boxWidth) / 2f;
float boxY = Screen.height - boxHeight - 20f;
// 设置切换按钮样式
GUI.skin.toggle.onNormal.textColor = Color.yellow;
// Draw message box
GUI.Box(new Rect(boxX, boxY, boxWidth, boxHeight), Settings.Settings.errorMessage, errorBoxStyle);
}
// 设置文本框样式 - 这是关键修复
GUI.skin.textField.normal.background = GUIHelper.MakeTex(2, 2, new Color(0.2f, 0.2f, 0.2f, 0.8f));
GUI.skin.textField.normal.textColor = Color.white;
GUI.skin.textField.focused.background = GUIHelper.MakeTex(2, 2, new Color(0.3f, 0.3f, 0.3f, 0.9f));
GUI.skin.textField.focused.textColor = Color.yellow;
GUI.skin.textField.border = new RectOffset(2, 2, 2, 2);
GUI.backgroundColor = Color.grey;
// 设置标签样式
GUI.skin.label.normal.textColor = Color.white;
// Set button style
var buttonStyle = new GUIStyle(GUI.skin.button);
buttonStyle.normal.background = GUIHelper.MakeTex(2, 2, Color.black);
buttonStyle.normal.textColor = Color.white;
buttonStyle.border = new RectOffset(2, 2, 2, 2);
GUI.skin.button = buttonStyle;
// 设置滑块样式
GUI.skin.horizontalSlider.normal.background = GUIHelper.MakeTex(2, 2, new Color(0.3f, 0.3f, 0.3f, 0.8f));
GUI.skin.horizontalSliderThumb.normal.background = GUIHelper.MakeTex(2, 2, Color.white);
// Set label style
var labelStyle = new GUIStyle(GUI.skin.label);
labelStyle.normal.textColor = Color.white;
labelStyle.border = new RectOffset(2, 2, 2, 2);
GUI.skin.label = labelStyle;
// Set text field style
var textFieldStyle = new GUIStyle(GUI.skin.textField);
textFieldStyle.normal.textColor = Color.white;
textFieldStyle.border = new RectOffset(2, 2, 2, 2);
GUI.skin.textField = textFieldStyle;
// Set slider style
var sliderStyle = new GUIStyle(GUI.skin.horizontalSlider);
sliderStyle.border = new RectOffset(2, 2, 2, 2);
GUI.skin.horizontalSlider = sliderStyle;
// Set toggle style
var toggleStyle = new GUIStyle(GUI.skin.toggle);
toggleStyle.normal.textColor = Color.white;
toggleStyle.border = new RectOffset(2, 2, 2, 2);
toggleStyle.onNormal.textColor = Color.yellow;
GUI.skin.toggle = toggleStyle;
//from https://www.unknowncheats.me/forum/unity/437277-mono-internal-optimisation-tips.html
if (UnityEngine.Event.current.type == EventType.Repaint)
{
if (player_esp || player_snapline || player_skel_esp)
@@ -432,6 +397,13 @@ namespace DevourClient
Render.Render.DrawNameESP(lump.transform.position, "Lump", new Color(1.0f, 0.0f, 0.0f, 1.0f));
}
}
foreach (Il2Cpp.MonkeyBehaviour monkey in Helpers.Entities.Monkeys)
{
if (monkey != null)
{
Render.Render.DrawNameESP(monkey.transform.position, "Monkey", new Color(1.0f, 0.0f, 0.0f, 1.0f));
}
}
}
if (azazel_esp || azazel_snapline || azazel_skel_esp)
@@ -450,7 +422,7 @@ namespace DevourClient
}
}
if (crosshair && in_game_cache) //&& !Player.IsPlayerCrawling())
if (crosshair && in_game_cache)
{
const float crosshairSize = 4;
@@ -466,11 +438,21 @@ namespace DevourClient
}
}
if (Settings.Settings.menu_enable) //Si on appuie sur INSERT
if (Settings.Settings.menu_enable)
{
windowRect = GUI.Window(0, windowRect, (GUI.WindowFunction)Tabs, "DevourClient");
}
}
catch (System.Exception ex)
{
MelonLogger.Msg($"OnGUI Error: {ex.Message}");
}
finally
{
// 恢复原始GUI状态
GUI.backgroundColor = originalBackgroundColor;
GUI.skin = originalSkin;
}
}
public static void Tabs(int windowID)
@@ -557,7 +539,7 @@ namespace DevourClient
{
flashlight_colorpick = !flashlight_colorpick;
MelonLogger.Msg("Flashlight color picker : " + flashlight_colorpick.ToString());
Hacks.Misc.ShowMessageBox("Flashlight color picker : " + flashlight_colorpick.ToString());
}
if (flashlight_colorpick)
@@ -580,7 +562,6 @@ namespace DevourClient
{
Hacks.Misc.TPItems();
MelonLogger.Msg("TP Items!");
Hacks.Misc.ShowMessageBox("TP Items!");
}
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 110, 130, 30), "Freeze azazel"))
@@ -590,8 +571,6 @@ namespace DevourClient
GUI.Label(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 150, 120, 30), "Azazel & Demons");
// azazel
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 180, 60, 25), "Sam") && Player.IsInGameOrLobby() && BoltNetwork.IsServer)
{
Hacks.Misc.SpawnAzazel((PrefabId)BoltPrefabs.AzazelSam);
@@ -622,7 +601,10 @@ namespace DevourClient
BoltNetwork.Instantiate(BoltPrefabs.AzazelApril, Player.GetPlayer().transform.position, Quaternion.identity);
}
// demon
if (GUI.Button(new Rect(Settings.Settings.x + 430, Settings.Settings.y + 180, 60, 25), "Kai") && Player.IsInGameOrLobby() && BoltNetwork.IsServer)
{
BoltNetwork.Instantiate(BoltPrefabs.AzazelKai, Player.GetPlayer().transform.position, Quaternion.identity);
}
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 220, 60, 25), "Ghost") && Player.IsInGameOrLobby() && BoltNetwork.IsServer)
{
@@ -659,7 +641,10 @@ namespace DevourClient
BoltNetwork.Instantiate(BoltPrefabs.ManorLump, Player.GetPlayer().transform.position, Quaternion.identity);
}
// Animal
if (GUI.Button(new Rect(Settings.Settings.x + 500, Settings.Settings.y + 220, 60, 25), "Monkey") && BoltNetwork.IsServer && Player.IsInGameOrLobby())
{
BoltNetwork.Instantiate(BoltPrefabs.Monkey, Player.GetPlayer().transform.position, Quaternion.identity);
}
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 260, 60, 25), "Rat"))
{
@@ -712,7 +697,6 @@ namespace DevourClient
{
Hacks.Misc.InstantWin();
MelonLogger.Msg("EZ Win");
Hacks.Misc.ShowMessageBox("EZ Win");
}
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 110, 150, 30), "Burn a ritual object"))
@@ -747,7 +731,6 @@ namespace DevourClient
catch
{
MelonLogger.Msg("Azazel not found !");
Hacks.Misc.ShowMessageBox("Azazel not found !");
}
}
@@ -768,7 +751,6 @@ namespace DevourClient
catch
{
MelonLogger.Msg("Azazel not found !");
Hacks.Misc.ShowMessageBox("Azazel not found !");
}
}
@@ -789,7 +771,6 @@ namespace DevourClient
catch
{
MelonLogger.Msg("Azazel not found !");
Hacks.Misc.ShowMessageBox("Azazel not found !");
}
}
@@ -816,7 +797,6 @@ namespace DevourClient
catch
{
MelonLogger.Msg("Azazel not found !");
Hacks.Misc.ShowMessageBox("Azazel not found !");
}
}
@@ -838,7 +818,6 @@ namespace DevourClient
catch
{
MelonLogger.Msg("Azazel not found !");
Hacks.Misc.ShowMessageBox("Azazel not found !");
}
}
@@ -865,7 +844,6 @@ namespace DevourClient
catch
{
MelonLogger.Msg("Azazel not found !");
Hacks.Misc.ShowMessageBox("Azazel not found !");
}
}
@@ -888,7 +866,6 @@ namespace DevourClient
if (realm == null)
{
MelonLogger.Warning("realm was null.");
Hacks.Misc.ShowMessageBox("realm was null.");
return;
}
@@ -920,7 +897,6 @@ namespace DevourClient
if (realm == null)
{
MelonLogger.Warning("realm was null.");
Hacks.Misc.ShowMessageBox("realm was null.");
return;
}
@@ -945,41 +921,66 @@ namespace DevourClient
infinite_mirrors = GUI.Toggle(new Rect(Settings.Settings.x + 370, Settings.Settings.y + 150, 150, 20), infinite_mirrors, "Infinite mirrors");
break;
case "Carnival":
if (GUI.Button(new Rect(Settings.Settings.x + 190, Settings.Settings.y + 70, 150, 30), "TP to Azazel"))
{
try
{
Il2Cpp.NolanBehaviour nb = Player.GetPlayer();
nb.TeleportTo(Helpers.Map.GetAzazel().transform.position, Quaternion.identity);
}
catch
{
MelonLogger.Msg("Azazel not found !");
}
}
if (GUI.Button(new Rect(Settings.Settings.x + 190, Settings.Settings.y + 110, 150, 30), "Despawn Monkeys"))
{
Hacks.Misc.DespawnMonkeys();
}
break;
}
// load map
GUI.Label(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 210, 100, 30), "Load Map: ");
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 240, 100, 30), "Farmhouse") && BoltNetwork.IsServer)
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 240, 90, 30), "Farmhouse") && BoltNetwork.IsServer)
{
Helpers.Map.LoadMap("Devour");
}
if (GUI.Button(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 240, 100, 30), "Asylum") && BoltNetwork.IsServer)
if (GUI.Button(new Rect(Settings.Settings.x + 110, Settings.Settings.y + 240, 90, 30), "Asylum") && BoltNetwork.IsServer)
{
Helpers.Map.LoadMap("Molly");
}
if (GUI.Button(new Rect(Settings.Settings.x + 230, Settings.Settings.y + 240, 100, 30), "Inn") && BoltNetwork.IsServer)
if (GUI.Button(new Rect(Settings.Settings.x + 210, Settings.Settings.y + 240, 90, 30), "Inn") && BoltNetwork.IsServer)
{
Helpers.Map.LoadMap("Inn");
}
if (GUI.Button(new Rect(Settings.Settings.x + 340, Settings.Settings.y + 240, 100, 30), "Town") && BoltNetwork.IsServer)
if (GUI.Button(new Rect(Settings.Settings.x + 310, Settings.Settings.y + 240, 90, 30), "Town") && BoltNetwork.IsServer)
{
Helpers.Map.LoadMap("Town");
}
if (GUI.Button(new Rect(Settings.Settings.x + 450, Settings.Settings.y + 240, 100, 30), "Slaughterhouse") && BoltNetwork.IsServer)
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 280, 90, 30), "Slaughterhouse") && BoltNetwork.IsServer)
{
Helpers.Map.LoadMap("Slaughterhouse");
}
if (GUI.Button(new Rect(Settings.Settings.x + 560, Settings.Settings.y + 240, 100, 30), "Manor") && BoltNetwork.IsServer)
if (GUI.Button(new Rect(Settings.Settings.x + 110, Settings.Settings.y + 280, 90, 30), "Manor") && BoltNetwork.IsServer)
{
Helpers.Map.LoadMap("Manor");
}
if (GUI.Button(new Rect(Settings.Settings.x + 210, Settings.Settings.y + 280, 90, 30), "Carnival") && BoltNetwork.IsServer)
{
Helpers.Map.LoadMap("Carnival");
}
}
private static void EspTab()
@@ -1136,7 +1137,7 @@ namespace DevourClient
}
}
if (GUILayout.Button("Shovel"))
if (GUILayout.Button("Spade"))
{
if (BoltNetwork.IsServer && !Player.IsInGame())
{
@@ -1159,6 +1160,29 @@ namespace DevourClient
Hacks.Misc.CarryObject("SurvivalCake");
}
}
if (GUILayout.Button("MusicBox"))
{
if (BoltNetwork.IsServer && !Player.IsInGame())
{
BoltNetwork.Instantiate(BoltPrefabs.SurvivalMusicBox, Player.GetPlayer().transform.position, Quaternion.identity);
}
else
{
Hacks.Misc.CarryObject("MusicBox-Idle");
}
}
if (GUILayout.Button("Coin"))
{
if (BoltNetwork.IsServer && !Player.IsInGame())
{
BoltNetwork.Instantiate(BoltPrefabs.SurvivalCoin, Player.GetPlayer().transform.position, Quaternion.identity);
}
else
{
Hacks.Misc.CarryObject("SurvivalCoin");
}
}
GUILayout.EndScrollView();
GUILayout.EndVertical();
@@ -1231,27 +1255,38 @@ namespace DevourClient
}
}
if (GUILayout.Button("Dirty head"))
{
if (BoltNetwork.IsServer && !Player.IsInGame())
{
BoltNetwork.Instantiate(BoltPrefabs.SurvivalHead, Player.GetPlayer().transform.position, Quaternion.identity);
}
else
{
Hacks.Misc.CarryObject("SurvivalHead");
}
}
// if (GUILayout.Button("Dirty head"))
// {
// if (BoltNetwork.IsServer && !Player.IsInGame())
// {
// BoltNetwork.Instantiate(BoltPrefabs.SurvivalHead, Player.GetPlayer().transform.position, Quaternion.identity);
// }
// else
// {
// Hacks.Misc.CarryObject("SurvivalHead");
// }
// }
if (GUILayout.Button("Clean head"))
// if (GUILayout.Button("Clean head"))
// {
// if (BoltNetwork.IsServer && !Player.IsInGame())
// {
// BoltNetwork.Instantiate(BoltPrefabs.SurvivalCleanHead, Player.GetPlayer().transform.position, Quaternion.identity);
// }
// else
// {
// Hacks.Misc.CarryObject("SurvivalCleanHead");
// }
// }
if (GUILayout.Button("Doll Head"))
{
if (BoltNetwork.IsServer && !Player.IsInGame())
{
BoltNetwork.Instantiate(BoltPrefabs.SurvivalCleanHead, Player.GetPlayer().transform.position, Quaternion.identity);
BoltNetwork.Instantiate(BoltPrefabs.SurvivalDollHead, Player.GetPlayer().transform.position, Quaternion.identity);
}
else
{
Hacks.Misc.CarryObject("SurvivalCleanHead");
Hacks.Misc.CarryObject("SurvivalDollHead");
}
}
@@ -1545,105 +1580,67 @@ namespace DevourClient
private static void MiscTab()
{
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 70, 150, 30), "Unlock Achievements"))
// === 游戏功能按钮区域 (左上) ===
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 70, 140, 25), "Unlock Achievements"))
{
Thread AchievementsThread = new Thread(new ThreadStart(Hacks.Unlock.Achievements));
AchievementsThread.Start();
MelonLogger.Msg("Achievements Unlocked!");
Hacks.Misc.ShowMessageBox("Achievements Unlocked!");
MelonLogger.Msg("Achievements unlocked!");
Hacks.Misc.ShowMessageBox("Achievements unlocked!");
}
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 110, 150, 30), "Unlock Doors"))
if (GUI.Button(new Rect(Settings.Settings.x + 160, Settings.Settings.y + 70, 140, 25), "Unlock Doors"))
{
Hacks.Unlock.Doors();
MelonLogger.Msg("Doors Unlocked!");
Hacks.Misc.ShowMessageBox("Doors Unlocked!");
MelonLogger.Msg("Doors unlocked!");
Hacks.Misc.ShowMessageBox("Doors unlocked!");
}
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 150, 150, 30), "TP Keys") && Player.IsInGame())
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 105, 140, 25), "Teleport Keys") && Player.IsInGame())
{
Hacks.Misc.TPKeys();
MelonLogger.Msg("Here are your keys!");
Hacks.Misc.ShowMessageBox("Here are your keys!");
MelonLogger.Msg("Keys teleported!");
Hacks.Misc.ShowMessageBox("Keys teleported!");
}
if (GUI.Button(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 190, 150, 30), "Make Random Noise"))
if (GUI.Button(new Rect(Settings.Settings.x + 160, Settings.Settings.y + 105, 140, 25), "Play Random Sound"))
{
Hacks.Misc.PlaySound();
MelonLogger.Msg("Playing a random sound!");
Hacks.Misc.ShowMessageBox("Playing a random sound!");
MelonLogger.Msg("Playing random sound!");
Hacks.Misc.ShowMessageBox("Playing random sound!");
}
spam_message = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 240, 140, 30), spam_message, "Chat spam");
if (spam_message)
{
spamMessageText = GUI.TextField(new Rect(Settings.Settings.x + 160, Settings.Settings.y + 240, 200, 30), spamMessageText);
GUI.Label(new Rect(Settings.Settings.x + 370, Settings.Settings.y + 240, 60, 30), "Send Interval(s):");
spamMessageInterval = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 440, Settings.Settings.y + 240, 100, 30), spamMessageInterval, 1f, 30f);
GUI.Label(new Rect(Settings.Settings.x + 550, Settings.Settings.y + 240, 60, 30), ((int)spamMessageInterval).ToString());
}
// === 基础开关区域 (左中) ===
_walkInLobby = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 150, 140, 20), _walkInLobby, "Walk In Lobby");
_IsAutoRespawn = GUI.Toggle(new Rect(Settings.Settings.x + 160, Settings.Settings.y + 150, 140, 20), _IsAutoRespawn, "Auto Respawn");
change_steam_name = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 270, 140, 30), change_steam_name, "Change Steam Name");
if (change_steam_name)
{
steamNameText = GUI.TextField(new Rect(Settings.Settings.x + 160, Settings.Settings.y + 270, 200, 30), steamNameText);
if (GUI.Button(new Rect(Settings.Settings.x + 370, Settings.Settings.y + 270, 60, 30), "Apply"))
{
Hacks.Misc.SetSteamName(steamNameText);
}
}
change_server_name = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 300, 140, 30), change_server_name, "Change Server Name");
if (change_server_name)
{
serverNameText = GUI.TextField(new Rect(Settings.Settings.x + 160, Settings.Settings.y + 300, 200, 30), serverNameText);
if (GUI.Button(new Rect(Settings.Settings.x + 370, Settings.Settings.y + 300, 60, 30), "Apply"))
{
Hacks.Misc.SetServerName(serverNameText);
}
}
_walkInLobby = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 330, 140, 30), _walkInLobby, "Walk In Lobby");
_IsAutoRespawn = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 360, 140, 30), _IsAutoRespawn, "Auto Respawn");
fly = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 400, 40, 20), fly, "Fly");
if (GUI.Button(new Rect(Settings.Settings.x + 60, Settings.Settings.y + 400, 40, 20), Settings.Settings.flyKey.ToString()))
// === 飞行控制区域 (左中下) ===
fly = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 180, 40, 20), fly, "Fly");
if (GUI.Button(new Rect(Settings.Settings.x + 60, Settings.Settings.y + 180, 50, 20), Settings.Settings.flyKey.ToString()))
{
Settings.Settings.flyKey = Settings.Settings.GetKey();
}
GUI.Label(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 180, 80, 20), "Speed:");
fly_speed = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 170, Settings.Settings.y + 185, 80, 10), fly_speed, 5f, 20f);
GUI.Label(new Rect(Settings.Settings.x + 260, Settings.Settings.y + 180, 40, 20), ((int)fly_speed).ToString());
fly_speed = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 430, 100, 10), fly_speed, 5f, 20f);
GUI.Label(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 425, 100, 30), ((int)fly_speed).ToString());
// === 等级欺骗区域 (左下) ===
spoofLevel = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 210, 100, 20), spoofLevel, "Spoof Level");
spoofLevelValue = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 215, 80, 10), spoofLevelValue, 0f, 666f);
GUI.Label(new Rect(Settings.Settings.x + 210, Settings.Settings.y + 210, 50, 20), ((int)spoofLevelValue).ToString());
// === 经验修改区域 (左下) ===
exp_modifier = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 240, 100, 20), exp_modifier, "Exp Modifier");
exp = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 245, 80, 10), exp, 1000f, 6000f);
GUI.Label(new Rect(Settings.Settings.x + 210, Settings.Settings.y + 240, 50, 20), ((int)exp).ToString());
spoofLevel = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 470, 150, 20), spoofLevel, "Spoof Level");
spoofLevelValue = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 500, 100, 10), spoofLevelValue, 0f, 666f);
GUI.Label(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 495, 100, 30), ((int)spoofLevelValue).ToString());
// === 速度修改区域 (左下) ===
fastMove = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 270, 100, 20), fastMove, "Player Speed");
_PlayerSpeedMultiplier = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 275, 80, 10), _PlayerSpeedMultiplier, (int)1f, (int)10f);
GUI.Label(new Rect(Settings.Settings.x + 210, Settings.Settings.y + 270, 50, 20), ((int)_PlayerSpeedMultiplier).ToString());
exp_modifier = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 540, 150, 20), exp_modifier, "EXP Modifier");
exp = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 570, 100, 10), exp, 1000f, 6000f);
GUI.Label(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 565, 100, 30), ((int)exp).ToString());
fastMove = GUI.Toggle(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 610, 150, 20), fastMove, "Player Speed");
_PlayerSpeedMultiplier = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 10, Settings.Settings.y + 640, 100, 10), _PlayerSpeedMultiplier, (int)1f, (int)10f);
GUI.Label(new Rect(Settings.Settings.x + 120, Settings.Settings.y + 635, 100, 30), ((int)_PlayerSpeedMultiplier).ToString());
GUI.Label(new Rect(Settings.Settings.x + 295, Settings.Settings.y + 70, 150, 30), "Max players");
lobbySize = GUI.HorizontalSlider(new Rect(Settings.Settings.x + 295, Settings.Settings.y + 90, 100, 10), lobbySize, (int)0f, (int)30f);
GUI.Label(new Rect(Settings.Settings.x + 405, Settings.Settings.y + 85, 100, 30), ((int)lobbySize).ToString());
if (GUI.Button(new Rect(Settings.Settings.x + 285, Settings.Settings.y + 110, 150, 30), "Create server"))
{
MelonLogger.Msg("Creating the server...");
Hacks.Misc.ShowMessageBox("Creating the server...");
Hacks.Misc.CreateCustomizedLobby((int)lobbySize);
MelonLogger.Msg("Done !");
Hacks.Misc.ShowMessageBox("Done !");
}
}
private static void PlayersTab()
@@ -1657,7 +1654,6 @@ namespace DevourClient
if (bp == null || bp.Name == "")
{
MelonLogger.Warning("players is null");
Hacks.Misc.ShowMessageBox("players is null");
continue;
}
@@ -1710,5 +1706,69 @@ namespace DevourClient
}
}
private void OnDestroy()
{
try
{
base.StopAllCoroutines();
Dispose();
}
catch (Exception ex)
{
MelonLogger.Error($"Error in OnDestroy: {ex.Message}");
}
}
private void OnApplicationQuit()
{
try
{
Dispose();
}
catch (Exception ex)
{
MelonLogger.Error($"Error in OnApplicationQuit: {ex.Message}");
}
}
public void Dispose()
{
try
{
MelonLogger.Msg("Starting ClientMain cleanup...");
long memoryBeforeCleanup = GC.GetTotalMemory(false);
MelonLogger.Msg($"[Memory Monitor] Pre-cleanup managed memory: {memoryBeforeCleanup / 1024 / 1024} MB");
Helpers.Entities.StopAllCoroutines();
if (crosshairTexture != null)
{
UnityEngine.Object.DestroyImmediate(crosshairTexture);
crosshairTexture = null;
}
Helpers.GUIHelper.Cleanup();
Helpers.Entities.CleanupCachedObjects();
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
long memoryAfterCleanup = GC.GetTotalMemory(true);
long memoryFreed = memoryBeforeCleanup - memoryAfterCleanup;
MelonLogger.Msg($"[Memory Monitor] Post-cleanup managed memory: {memoryAfterCleanup / 1024 / 1024} MB");
MelonLogger.Msg($"[Memory Monitor] Memory freed: {memoryFreed / 1024 / 1024} MB");
MelonLogger.Msg("ClientMain disposed successfully.");
}
catch (Exception ex)
{
MelonLogger.Error($"Error disposing ClientMain: {ex.Message}");
}
}
}
}

View File

@@ -12,4 +12,78 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<WarningLevel>0</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="0Harmony">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\net6\0Harmony.dll</HintPath>
</Reference>
<Reference Include="Assembly-CSharp">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Assembly-CSharp.dll</HintPath>
</Reference>
<Reference Include="Il2CppBehaviorDesigner.Runtime">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2CppBehaviorDesigner.Runtime.dll</HintPath>
</Reference>
<Reference Include="Il2Cppbolt">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppbolt.dll</HintPath>
</Reference>
<Reference Include="Il2Cppbolt.user">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppbolt.user.dll</HintPath>
</Reference>
<Reference Include="Il2Cppcom.rlabrecque.steamworks.net">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppcom.rlabrecque.steamworks.net.dll</HintPath>
</Reference>
<Reference Include="Il2CppInterop.Runtime">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\net6\Il2CppInterop.Runtime.dll</HintPath>
</Reference>
<Reference Include="Il2Cppmscorlib">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppmscorlib.dll</HintPath>
</Reference>
<Reference Include="Il2CppOpsive.UltimateCharacterController">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2CppOpsive.UltimateCharacterController.dll</HintPath>
</Reference>
<Reference Include="Il2Cppudpkit">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppudpkit.dll</HintPath>
</Reference>
<Reference Include="Il2Cppudpkit.common">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppudpkit.common.dll</HintPath>
</Reference>
<Reference Include="Il2Cppudpkit.platform.photon">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Il2Cppudpkit.platform.photon.dll</HintPath>
</Reference>
<Reference Include="MelonLoader">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\net6\MelonLoader.dll</HintPath>
</Reference>
<Reference Include="UnityEngine">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.AnimationModule">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.AnimationModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.CoreModule">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.CoreModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.HotReloadModule">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.HotReloadModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.IMGUIModule">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.IMGUIModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.InputLegacyModule">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.InputLegacyModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.InputModule">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.InputModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.PhysicsModule">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.PhysicsModule.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UI">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.UI.dll</HintPath>
</Reference>
<Reference Include="UnityEngine.UIModule">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\UnityEngine.UIModule.dll</HintPath>
</Reference>
<Reference Include="Unity.TextMeshPro">
<HintPath>E:\SteamLibrary\steamapps\common\Devour\MelonLoader\Il2CppAssemblies\Unity.TextMeshPro.dll</HintPath>
</Reference>
</ItemGroup>
</Project>

View File

@@ -91,12 +91,11 @@ namespace DevourClient.Hacks
if (burnAll)
{
_slaughterhouseAltarController.SkipToGoat(10);
_slaughterhouseAltarController.BurnGoat();
}
else
{
_slaughterhouseAltarController.BurnGoat();
_slaughterhouseAltarController.SkipToGoat(10);
}
break;
@@ -163,13 +162,11 @@ namespace DevourClient.Hacks
else
{
MelonLogger.Error("azazelBehaviour is null!");
Hacks.Misc.ShowMessageBox("azazelBehaviour is null!");
}
}
else
{
MelonLogger.Error("azazel is null!");
Hacks.Misc.ShowMessageBox("azazel is null!");
}
}
}
@@ -233,26 +230,6 @@ namespace DevourClient.Hacks
_menu.ShowCanvasGroup(_menu.mainMenuCanvasGroup, false);
}
public static void SetSteamName(string name)
{
Il2CppHorror.Menu Menu_ = UnityEngine.Object.FindObjectOfType<Il2CppHorror.Menu>();
if (Menu_ == null)
{
return;
}
Menu_.steamName = name;
}
public static void SetServerName(string name)
{
Il2CppHorror.Menu Menu_ = UnityEngine.Object.FindObjectOfType<Il2CppHorror.Menu>();
if (Menu_ == null)
{
return;
}
Menu_.serverNameText.text = name;
}
public static void BigFlashlight(bool reset)
{
@@ -379,23 +356,6 @@ namespace DevourClient.Hacks
NolanRank.SetRank(rank);
}
public static void MessageSpam(string message)
{
//TOFIX : not spamming anymore :/
if (Helpers.Player.IsInGame())
{
Il2Cpp.GameUI game_ui_class = UnityEngine.Object.FindObjectOfType<Il2Cpp.GameUI>();
game_ui_class.textChatInput.text = message;
game_ui_class.OnChatMessageSubmit();
}
else
{
Il2CppHorror.Menu menu_class = UnityEngine.Object.FindObjectOfType<Il2CppHorror.Menu>();
menu_class.textChatInput.text = message;
menu_class.OnChatMessageSubmit();
}
}
public static void DespawnDemons()
{
@@ -474,13 +434,26 @@ namespace DevourClient.Hacks
}
}
public static void DespawnMonkeys()
{
foreach (Il2Cpp.MonkeyBehaviour monkey in Helpers.Entities.Monkeys)
{
if (monkey != null)
{
monkey.Despawn();
}
}
}
public static int ShowMessageBox(string message)
{
Settings.Settings.errorMessage = message;
Settings.Settings.errorMessageDisplayTime = 0f;
Settings.Settings.showErrorMessage = true;
return 0;
}
//not used, might be useful, some day
Il2CppHorror.Menu menu = UnityEngine.Object.FindObjectOfType<Il2CppHorror.Menu>();
if (menu == null)
return 1;
menu.ShowMessageModal(message);
return 0;
}
public static void PlaySound()
{

View File

@@ -22,7 +22,9 @@ namespace DevourClient.Hacks
}
MelonLoader.MelonLogger.Warning("You need to restart your game for the achievements to be unlocked !!!");
Hacks.Misc.ShowMessageBox("You need to restart your game for the achievements to be unlocked !!!");
MelonLoader.MelonLogger.Warning("You need to restart your game for the achievements to be unlocked !!!");
MelonLoader.MelonLogger.Warning("You need to restart your game for the achievements to be unlocked !!!");
MelonLoader.MelonLogger.Warning("You need to restart your game for the achievements to be unlocked !!!");
}
public static void Doors()

View File

@@ -1,27 +1,120 @@
using UnityEngine;
using MelonLoader;
using System.Collections.Generic;
namespace DevourClient.Helpers
{
public static class GUIHelper
class GUIHelper
{
private static Texture2D previewTexture;
private static GUIStyle boxStyle;
private static float R;
private static float G;
private static float B;
private static Texture2D previewTexture = null;
private static Dictionary<Color, Texture2D> colorTextureCache = new Dictionary<Color, Texture2D>();
private static Dictionary<int, Texture2D> circularTextureCache = new Dictionary<int, Texture2D>();
private static Color lastPreviewColor = Color.clear;
private static GUIStyle cachedBoxStyle = null;
public static void Initialize()
public static Color ColorPick(string title, Color color)
{
if (previewTexture == null)
GUI.Label(new Rect(Settings.Settings.x + 195, Settings.Settings.y + 70, 250, 30), title);
R = GUI.VerticalSlider(new Rect(Settings.Settings.x + 240, Settings.Settings.y + 100, 30, 90), color.r, 0f, 1f);
G = GUI.VerticalSlider(new Rect(Settings.Settings.x + 270, Settings.Settings.y + 100, 30, 90), color.g, 0f, 1f);
B = GUI.VerticalSlider(new Rect(Settings.Settings.x + 300, Settings.Settings.y + 100, 30, 90), color.b, 0f, 1f);
GUI.Label(new Rect(Settings.Settings.x + 240, Settings.Settings.y + 190, 30, 30), "R");
GUI.Label(new Rect(Settings.Settings.x + 270, Settings.Settings.y + 190, 30, 30), "G");
GUI.Label(new Rect(Settings.Settings.x + 300, Settings.Settings.y + 190, 30, 30), "B");
color = new Color(R, G, B, 1);
void DrawPreview(Rect position, Color color_to_draw)
{
previewTexture = new Texture2D(1, 1);
boxStyle = new GUIStyle(GUI.skin.box);
if (previewTexture == null || lastPreviewColor != color_to_draw)
{
if (previewTexture == null)
{
previewTexture = new Texture2D(1, 1);
}
previewTexture.SetPixel(0, 0, color_to_draw);
previewTexture.Apply();
lastPreviewColor = color_to_draw;
}
if (cachedBoxStyle == null)
{
cachedBoxStyle = new GUIStyle(GUI.skin.box);
}
cachedBoxStyle.normal.background = previewTexture;
GUI.Box(position, GUIContent.none, cachedBoxStyle);
}
DrawPreview(new Rect(Settings.Settings.x + 195, Settings.Settings.y + 100, 20, 90), color);
return color;
}
public static Texture2D MakeTex(int width, int height, Color col)
{
if (colorTextureCache.TryGetValue(col, out Texture2D cachedTexture))
{
if (cachedTexture != null)
{
return cachedTexture;
}
}
Color[] pix = new Color[width * height];
for (int i = 0; i < pix.Length; ++i)
{
pix[i] = col;
}
Texture2D result = new Texture2D(width, height);
result.SetPixels(pix);
result.Apply();
colorTextureCache[col] = result;
return result;
}
public static Texture2D GetCircularTexture(int width, int height)
{
int cacheKey = width;
if (circularTextureCache.TryGetValue(cacheKey, out Texture2D cachedTexture))
{
if (cachedTexture != null)
{
return cachedTexture;
}
}
Texture2D texture = new Texture2D(width, height);
for (int x = 0; x < texture.width; x++)
{
for (int y = 0; y < texture.height; y++)
{
if (Vector2.Distance(new Vector2(x, y), new Vector2(texture.width / 2, texture.height / 2)) <= texture.width / 2)
{
texture.SetPixel(x, y, Color.white);
}
else
{
texture.SetPixel(x, y, Color.clear);
}
}
}
texture.Apply();
circularTextureCache[cacheKey] = texture;
return texture;
}
public static void Cleanup()
{
@@ -49,114 +142,5 @@ namespace DevourClient.Helpers
}
circularTextureCache.Clear();
}
private static float R;
private static float G;
private static float B;
public static Color ColorPick(string title, Color color)
{
Initialize();
GUILayout.BeginArea(new Rect(Settings.Settings.x + 195, Settings.Settings.y + 70, 250, 250));
GUILayout.Label(title);
GUILayout.Space(10);
GUILayout.BeginHorizontal();
GUILayout.Label("R", GUILayout.Width(20));
R = GUILayout.HorizontalSlider(color.r, 0f, 1f, GUILayout.Width(150));
GUILayout.Label(((int)(R * 255)).ToString(), GUILayout.Width(30));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("G", GUILayout.Width(20));
G = GUILayout.HorizontalSlider(color.g, 0f, 1f, GUILayout.Width(150));
GUILayout.Label(((int)(G * 255)).ToString(), GUILayout.Width(30));
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("B", GUILayout.Width(20));
B = GUILayout.HorizontalSlider(color.b, 0f, 1f, GUILayout.Width(150));
GUILayout.Label(((int)(B * 255)).ToString(), GUILayout.Width(30));
GUILayout.EndHorizontal();
GUILayout.Space(10);
void DrawPreview(Color color_to_draw)
{
if (previewTexture == null)
{
previewTexture = new Texture2D(1, 1);
}
previewTexture.SetPixel(0, 0, color_to_draw);
previewTexture.Apply();
boxStyle.normal.background = previewTexture;
GUILayout.Box(GUIContent.none, boxStyle, GUILayout.Height(30));
}
DrawPreview(new Color(R, G, B, 1));
GUILayout.EndArea();
return new Color(R, G, B, 1);
}
public static Texture2D MakeTex(int width, int height, Color col)
{
string cacheKey = $"{width}x{height}_{col.r}_{col.g}_{col.b}";
if (colorTextureCache.TryGetValue(col, out Texture2D cachedTexture))
{
return cachedTexture;
}
Texture2D result = new Texture2D(width, height);
Color[] pix = new Color[width * height];
for (int i = 0; i < pix.Length; ++i)
{
pix[i] = col;
}
result.SetPixels(pix);
result.Apply();
colorTextureCache[col] = result;
return result;
}
public static Texture2D GetCircularTexture(int width, int height)
{
int size = Mathf.Max(width, height);
if (circularTextureCache.TryGetValue(size, out Texture2D cachedTexture))
{
return cachedTexture;
}
Texture2D texture = new Texture2D(width, height);
for (int x = 0; x < texture.width; x++)
{
for (int y = 0; y < texture.height; y++)
{
if (Vector2.Distance(new Vector2(x, y), new Vector2(texture.width / 2, texture.height / 2)) <= texture.width / 2)
{
texture.SetPixel(x, y, Color.white);
}
else
{
texture.SetPixel(x, y, Color.clear);
}
}
}
texture.Apply();
circularTextureCache[size] = texture;
return texture;
}
}
}

View File

@@ -11,7 +11,7 @@
{
switch (sceneName)
{
case "Devour":
case "Anna":
return "Farmhouse";
case "Molly":
return "Asylum";
@@ -23,6 +23,8 @@
return "Slaughterhouse";
case "Manor":
return "Manor";
case "Carnival":
return "Carnival";
default:
return "Menu";
}
@@ -40,12 +42,10 @@
Il2CppPhoton.Bolt.BoltNetwork.LoadScene(mapName);
MelonLoader.MelonLogger.Warning("Please press the button only once, it may take some time for the map to load.");
Hacks.Misc.ShowMessageBox("Please press the button only once, it may take some time for the map to load.");
}
else
{
MelonLoader.MelonLogger.Warning("You must be the host to use this command!");
Hacks.Misc.ShowMessageBox("You must be the host to use this command!");
}
}
}

View File

@@ -12,14 +12,32 @@ namespace DevourClient.Render
{
public static GUIStyle StringStyle { get; set; } = new GUIStyle(GUI.skin.label);
private static GUIContent cachedContent = new GUIContent();
private static Dictionary<string, Vector2> sizeCache = new Dictionary<string, Vector2>();
private static int frameCacheClearCounter = 0;
private const int CACHE_CLEAR_INTERVAL = 1800;
public static void DrawString(Vector2 position, Color color, string label, bool centered = true)
{
var content = new GUIContent(label);
var size = StringStyle.CalcSize(content);
cachedContent.text = label;
if (!sizeCache.TryGetValue(label, out Vector2 size))
{
size = StringStyle.CalcSize(cachedContent);
sizeCache[label] = size;
frameCacheClearCounter++;
if (frameCacheClearCounter >= CACHE_CLEAR_INTERVAL)
{
sizeCache.Clear();
frameCacheClearCounter = 0;
}
}
var upperLeft = centered ? position - size / 2f : position;
Color color2 = GUI.color;
GUI.color = color;
GUI.Label(new Rect(upperLeft, size), content);
GUI.Label(new Rect(upperLeft, size), cachedContent);
GUI.color = color2;
}
@@ -63,7 +81,7 @@ namespace DevourClient.Render
}
public static void DrawBones(Transform bone1, Transform bone2, Color c)
{
if (!Camera.main) //fix the crash maybe
if (!Camera.main)
{
return;
}

View File

@@ -40,7 +40,8 @@ namespace DevourClient.Helpers
Il2Cpp.NolanBehaviour nb = p_GameObject.GetComponent<Il2Cpp.NolanBehaviour>();
Il2Cpp.SurvivalReviveInteractable _reviveInteractable = UnityEngine.Object.FindObjectOfType<Il2Cpp.SurvivalReviveInteractable>();
_reviveInteractable.Interact(nb.gameObject);
if (_reviveInteractable.CanInteract(nb.gameObject) == true) { _reviveInteractable.Interact(nb.gameObject); }
}
public void Jumpscare()
@@ -48,7 +49,6 @@ namespace DevourClient.Helpers
if (!BoltNetwork.IsServer)
{
MelonLogger.Msg("You need to be server !");
Hacks.Misc.ShowMessageBox("You need to be server !");
return;
}
@@ -66,9 +66,6 @@ namespace DevourClient.Helpers
sab.OnPickedUpPlayer(sab.gameObject, p_GameObject, false);
MelonLogger.Msg(Name);
Hacks.Misc.ShowMessageBox(Name);
/*
MelonLogger.Msg(Name);
Il2Cpp.JumpScare _jumpscare = UnityEngine.Object.FindObjectOfType<Il2Cpp.JumpScare>();
@@ -114,7 +111,6 @@ namespace DevourClient.Helpers
else
{
MelonLogger.Error("Azazel not found!");
Hacks.Misc.ShowMessageBox("Azazel not found!");
return;
}
}
@@ -124,7 +120,6 @@ namespace DevourClient.Helpers
if (!BoltNetwork.IsServer)
{
MelonLogger.Msg("You need to be server !");
Hacks.Misc.ShowMessageBox("You need to be server !");
return;
}
@@ -180,9 +175,6 @@ namespace DevourClient.Helpers
public class Entities
{
private static bool isRunning = true; // Control coroutine running state
private static List<object> activeCoroutines = new List<object>(); // Track active coroutines
public static int MAX_PLAYERS = 4; //will change by calling CreateCustomizedLobby
public static BasePlayer LocalPlayer_ = new BasePlayer();
@@ -198,106 +190,28 @@ namespace DevourClient.Helpers
public static Il2Cpp.CorpseBehaviour[] Corpses = default!;
public static Il2Cpp.CrowBehaviour[] Crows = default!;
public static Il2Cpp.ManorLumpController[] Lumps = default!;
public static Il2Cpp.MonkeyBehaviour[] Monkeys = default!;
// Method to stop all coroutines
public static void StopAllCoroutines()
{
isRunning = false;
foreach (var coroutine in activeCoroutines)
{
if (coroutine != null)
{
MelonCoroutines.Stop(coroutine);
}
}
activeCoroutines.Clear();
// Clean up all cached objects
CleanupCachedObjects();
}
// Clean up cached objects
private static void CleanupCachedObjects()
{
if (Players != null)
{
foreach (var player in Players)
{
if (player != null)
{
player.p_GameObject = null;
}
}
Players = null;
}
LocalPlayer_.p_GameObject = null;
GoatsAndRats = null;
SurvivalInteractables = null;
Keys = null;
Demons = null;
Spiders = null;
Ghosts = null;
Azazels = null;
Boars = null;
Corpses = null;
Crows = null;
Lumps = null;
}
// Method to start all coroutines
public static void StartAllCoroutines()
{
isRunning = true;
activeCoroutines.Clear();
// Start all coroutines and save references
activeCoroutines.Add(MelonCoroutines.Start(GetLocalPlayer()));
activeCoroutines.Add(MelonCoroutines.Start(GetAllPlayers()));
activeCoroutines.Add(MelonCoroutines.Start(GetGoatsAndRats()));
activeCoroutines.Add(MelonCoroutines.Start(GetSurvivalInteractables()));
activeCoroutines.Add(MelonCoroutines.Start(GetKeys()));
activeCoroutines.Add(MelonCoroutines.Start(GetDemons()));
activeCoroutines.Add(MelonCoroutines.Start(GetSpiders()));
activeCoroutines.Add(MelonCoroutines.Start(GetGhosts()));
activeCoroutines.Add(MelonCoroutines.Start(GetBoars()));
activeCoroutines.Add(MelonCoroutines.Start(GetCorpses()));
activeCoroutines.Add(MelonCoroutines.Start(GetCrows()));
activeCoroutines.Add(MelonCoroutines.Start(GetLumps()));
activeCoroutines.Add(MelonCoroutines.Start(GetAzazels()));
}
// 协程生命周期管理
private static List<object> activeCoroutines = new List<object>();
private static bool isRunning = false;
public static IEnumerator GetLocalPlayer()
{
while (isRunning)
{
try
GameObject[] currentPlayers = GameObject.FindGameObjectsWithTag("Player");
for (int i = 0; i < currentPlayers.Length; i++)
{
GameObject[] currentPlayers = GameObject.FindGameObjectsWithTag("Player");
if (currentPlayers != null)
if (currentPlayers[i].GetComponent<Il2Cpp.NolanBehaviour>().entity.IsOwner)
{
for (int i = 0; i < currentPlayers.Length; i++)
{
if (currentPlayers[i].GetComponent<Il2Cpp.NolanBehaviour>().entity.IsOwner)
{
// Clean up old references before updating
if (LocalPlayer_.p_GameObject != currentPlayers[i])
{
LocalPlayer_.p_GameObject = currentPlayers[i];
}
break;
}
}
LocalPlayer_.p_GameObject = currentPlayers[i];
break;
}
}
catch (System.Exception e)
{
string err = $"GetLocalPlayer coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
@@ -306,70 +220,46 @@ namespace DevourClient.Helpers
{
while (isRunning)
{
try
{
GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
GameObject[] players = GameObject.FindGameObjectsWithTag("Player");
Players = new BasePlayer[players.Length];
// Clean up old array before creating new one
if (Players != null)
int i = 0;
foreach (GameObject p in players)
{
string player_name = "";
string player_id = "-1";
Il2Cpp.DissonancePlayerTracking dpt = p.gameObject.GetComponent<Il2Cpp.DissonancePlayerTracking>();
if (dpt != null)
{
foreach (var player in Players)
{
if (player != null)
{
player.p_GameObject = null;
}
}
player_name = dpt.state.PlayerName;
player_id = dpt.state.PlayerId;
}
// Create new array
Players = new BasePlayer[players.Length];
for (int i = 0; i < players.Length; i++)
if (Players[i] == null)
{
if (Players[i] == null)
{
Players[i] = new BasePlayer();
}
Players[i].p_GameObject = players[i];
Il2Cpp.DissonancePlayerTracking dpt = players[i].GetComponent<Il2Cpp.DissonancePlayerTracking>();
if (dpt != null)
{
Players[i].Name = dpt.state.PlayerName;
Players[i].Id = dpt.state.PlayerId;
}
Players[i] = new BasePlayer();
}
}
catch (System.Exception e)
{
string err = $"GetAllPlayers coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
Players[i].Id = player_id;
Players[i].Name = player_name;
Players[i].p_GameObject = p;
i++;
}
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
public static IEnumerator GetGoatsAndRats()
{
while (isRunning)
{
try
{
GoatsAndRats = Il2Cpp.GoatBehaviour.FindObjectsOfType<Il2Cpp.GoatBehaviour>();
}
catch (System.Exception e)
{
string err = $"GetGoatsAndRats coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
GoatsAndRats = Il2Cpp.GoatBehaviour.FindObjectsOfType<Il2Cpp.GoatBehaviour>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
@@ -378,18 +268,9 @@ namespace DevourClient.Helpers
{
while (isRunning)
{
try
{
SurvivalInteractables = Il2Cpp.SurvivalInteractable.FindObjectsOfType<Il2Cpp.SurvivalInteractable>();
}
catch (System.Exception e)
{
string err = $"GetSurvivalInteractables coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
SurvivalInteractables = Il2Cpp.SurvivalInteractable.FindObjectsOfType<Il2Cpp.SurvivalInteractable>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
@@ -398,18 +279,9 @@ namespace DevourClient.Helpers
{
while (isRunning)
{
try
{
Keys = Il2Cpp.KeyBehaviour.FindObjectsOfType<Il2Cpp.KeyBehaviour>();
}
catch (System.Exception e)
{
string err = $"GetKeys coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
Keys = Il2Cpp.KeyBehaviour.FindObjectsOfType<Il2Cpp.KeyBehaviour>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
@@ -418,18 +290,9 @@ namespace DevourClient.Helpers
{
while (isRunning)
{
try
{
Demons = Il2Cpp.SurvivalDemonBehaviour.FindObjectsOfType<Il2Cpp.SurvivalDemonBehaviour>();
}
catch (System.Exception e)
{
string err = $"GetDemons coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
Demons = Il2Cpp.SurvivalDemonBehaviour.FindObjectsOfType<Il2Cpp.SurvivalDemonBehaviour>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
@@ -438,18 +301,9 @@ namespace DevourClient.Helpers
{
while (isRunning)
{
try
{
Spiders = Il2Cpp.SpiderBehaviour.FindObjectsOfType<Il2Cpp.SpiderBehaviour>();
}
catch (System.Exception e)
{
string err = $"GetSpiders coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
Spiders = Il2Cpp.SpiderBehaviour.FindObjectsOfType<Il2Cpp.SpiderBehaviour>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
@@ -458,18 +312,9 @@ namespace DevourClient.Helpers
{
while (isRunning)
{
try
{
Ghosts = Il2Cpp.GhostBehaviour.FindObjectsOfType<Il2Cpp.GhostBehaviour>();
}
catch (System.Exception e)
{
string err = $"GetGhosts coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
Ghosts = Il2Cpp.GhostBehaviour.FindObjectsOfType<Il2Cpp.GhostBehaviour>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
@@ -478,18 +323,9 @@ namespace DevourClient.Helpers
{
while (isRunning)
{
try
{
Boars = Il2Cpp.BoarBehaviour.FindObjectsOfType<Il2Cpp.BoarBehaviour>();
}
catch (System.Exception e)
{
string err = $"GetBoars coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
Boars = Il2Cpp.BoarBehaviour.FindObjectsOfType<Il2Cpp.BoarBehaviour>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
@@ -498,18 +334,9 @@ namespace DevourClient.Helpers
{
while (isRunning)
{
try
{
Corpses = Il2Cpp.CorpseBehaviour.FindObjectsOfType<Il2Cpp.CorpseBehaviour>();
}
catch (System.Exception e)
{
string err = $"GetCorpses coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
Corpses = Il2Cpp.CorpseBehaviour.FindObjectsOfType<Il2Cpp.CorpseBehaviour>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
@@ -518,18 +345,9 @@ namespace DevourClient.Helpers
{
while (isRunning)
{
try
{
Crows = Il2Cpp.CrowBehaviour.FindObjectsOfType<Il2Cpp.CrowBehaviour>();
}
catch (System.Exception e)
{
string err = $"GetCrows coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
Crows = Il2Cpp.CrowBehaviour.FindObjectsOfType<Il2Cpp.CrowBehaviour>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
@@ -538,39 +356,135 @@ namespace DevourClient.Helpers
{
while (isRunning)
{
try
{
Lumps = Il2Cpp.ManorLumpController.FindObjectsOfType<Il2Cpp.ManorLumpController>();
}
catch (System.Exception e)
{
string err = $"GetLumps coroutine encountered an error: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
}
Lumps = Il2Cpp.ManorLumpController.FindObjectsOfType<Il2Cpp.ManorLumpController>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
public static IEnumerator GetMonkeys()
{
while (isRunning)
{
Monkeys = Il2Cpp.MonkeyBehaviour.FindObjectsOfType<Il2Cpp.MonkeyBehaviour>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
public static IEnumerator GetAzazels()
{
/*
* ikr AzazelS, because in case we spawn multiple we want the esp to render all of them
*/
while (isRunning)
{
try
Azazels = Il2Cpp.SurvivalAzazelBehaviour.FindObjectsOfType<Il2Cpp.SurvivalAzazelBehaviour>();
// Wait 5 seconds before caching objects again.
yield return new WaitForSeconds(5f);
}
}
/// <summary>
/// 启动所有协程
/// </summary>
public static void StartAllCoroutines()
{
isRunning = true;
}
/// <summary>
/// 停止所有协程并清理协程引用
/// </summary>
public static void StopAllCoroutines()
{
try
{
// 设置标志,让所有协程循环自然退出
isRunning = false;
// 停止所有记录的协程
foreach (var coroutine in activeCoroutines)
{
Azazels = Il2Cpp.SurvivalAzazelBehaviour.FindObjectsOfType<Il2Cpp.SurvivalAzazelBehaviour>();
}
catch (System.Exception e)
{
string err = $"Error in GetAzazels coroutine: {e.Message}";
MelonLogger.Error(err);
DevourClient.Settings.Settings.errorMessage = err;
DevourClient.Settings.Settings.showErrorMessage = true;
if (coroutine != null)
{
MelonCoroutines.Stop(coroutine);
}
}
yield return new WaitForSeconds(5f);
// 清空协程引用列表
activeCoroutines.Clear();
// 清理缓存对象
CleanupCachedObjects();
MelonLogger.Msg("All coroutines stopped and cleaned up successfully.");
}
catch (System.Exception ex)
{
MelonLogger.Error($"Error stopping coroutines: {ex.Message}");
}
}
/// <summary>
/// 清理所有缓存的游戏对象引用
/// </summary>
public static void CleanupCachedObjects()
{
try
{
// 清理玩家对象引用
if (Players != null)
{
foreach (var player in Players)
{
if (player != null)
{
player.p_GameObject = null;
}
}
}
// 将所有实体数组设为null释放对游戏对象的引用
Players = null;
GoatsAndRats = null;
SurvivalInteractables = null;
Keys = null;
Demons = null;
Spiders = null;
Ghosts = null;
Azazels = null;
Boars = null;
Corpses = null;
Crows = null;
Lumps = null;
Monkeys = null;
// 清理本地玩家引用
if (LocalPlayer_ != null)
{
LocalPlayer_.p_GameObject = null;
}
MelonLogger.Msg("Cached objects cleaned up successfully.");
}
catch (System.Exception ex)
{
MelonLogger.Error($"Error cleaning up cached objects: {ex.Message}");
}
}
/// <summary>
/// 注册协程引用用于后续管理
/// </summary>
public static void RegisterCoroutine(object coroutine)
{
if (coroutine != null && !activeCoroutines.Contains(coroutine))
{
activeCoroutines.Add(coroutine);
}
}
}

View File

@@ -13,17 +13,12 @@ namespace DevourClient.Settings
public static Color player_esp_color = new Color(0.00f, 1.00f, 0.00f, 1);
public static Color azazel_esp_color = new Color(1.00f, 0.00f, 0.00f, 1);
public static float speed = 1f;
public const string message_to_spam = "Deez Nutz";
public static KeyCode flyKey = KeyCode.None;
public static Vector2 itemsScrollPosition = Vector2.zero;
public static Vector2 rituelObjectsScrollPosition = Vector2.zero;
public static Vector2 stuffsScrollPosition = Vector2.zero;
// Error message box settings
public static bool showErrorMessage = false;
public static string errorMessage = "";
public static float errorMessageDisplayTime = 0f;
public static float errorMessageMaxDisplayTime = 4f; // Maximum display time for error messages (in seconds)
public static KeyCode GetKey()
{
Thread.Sleep(50); //TOFIX tried using anyKeydown, no success