Загрузка данных
using System;
using System.IO;
using System.Reflection;
using System.Text;
using BepInEx;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using Il2CppInterop.Runtime.Injection;
using UnityEngine;
using UnityEngine.SceneManagement;
[BepInPlugin("my.cheatmenu", "CheatMenu", "1.2")]
public class Plugin : BasePlugin
{
public static ManualLogSource L;
public override void Load()
{
L = Log;
ClassInjector.RegisterTypeInIl2Cpp<MenuBehaviour>();
AddComponent<MenuBehaviour>();
Log.LogInfo("CheatMenu loaded, press Insert");
}
}
public class MenuBehaviour : MonoBehaviour
{
public MenuBehaviour(IntPtr ptr) : base(ptr) { }
bool open, fly, god, stamina;
float flySpeed = 15f;
Transform player;
CharacterController cc;
Rigidbody rb;
string filter = "";
int scenePage = 0;
float nextApply;
// режим шахеда
bool drone, exploding;
float droneSpeed = 30f, crashSpeed = 20f, spinSpeed = 360f;
float droneStartTime, respawnAt, flashStart;
Vector3 startPos;
GameObject flash;
AudioClip boomClip, buzzClip, musicClip;
AudioSource buzzSrc, musicSrc;
static readonly string[] HealthKeys = { "health", "hp" };
static readonly string[] StaminaKeys = { "stamina", "energy" };
static readonly string[] Bad = { "regen", "rate", "damage", "cost", "drain", "speed", "time", "delay", "max", "min", "percent", "ratio" };
void Start()
{
boomClip = LoadWav("boom.wav");
buzzClip = LoadWav("buzz.wav");
musicClip = LoadWav("music.wav");
}
AudioClip LoadWav(string name)
{
try
{
using (var s = Assembly.GetExecutingAssembly().GetManifestResourceStream(name))
{
if (s == null) { Plugin.L.LogInfo("No embedded sound: " + name); return null; }
var ms = new MemoryStream();
s.CopyTo(ms);
byte[] b = ms.ToArray();
int pos = 12, ch = 1, rate = 44100, bits = 16, fmt = 1, dataPos = -1, dataLen = 0;
while (pos + 8 <= b.Length)
{
string id = Encoding.ASCII.GetString(b, pos, 4);
int size = BitConverter.ToInt32(b, pos + 4);
if (id == "fmt ")
{
fmt = BitConverter.ToInt16(b, pos + 8);
ch = BitConverter.ToInt16(b, pos + 10);
rate = BitConverter.ToInt32(b, pos + 12);
bits = BitConverter.ToInt16(b, pos + 22);
}
else if (id == "data") { dataPos = pos + 8; dataLen = Math.Min(size, b.Length - dataPos); break; }
pos += 8 + size + (size % 2);
}
if (dataPos < 0 || fmt != 1 || bits != 16) { Plugin.L.LogInfo(name + ": need WAV 16-bit PCM"); return null; }
int samples = dataLen / 2;
var f = new float[samples];
for (int i = 0; i < samples; i++) f[i] = BitConverter.ToInt16(b, dataPos + i * 2) / 32768f;
var clip = AudioClip.Create(name, samples / ch, ch, rate, false);
clip.SetData(f, 0);
Plugin.L.LogInfo("Loaded sound: " + name);
return clip;
}
}
catch (Exception e) { Plugin.L.LogInfo("LoadWav error (" + name + "): " + e.Message); return null; }
}
AudioSource MakeLoopSource(string name, float volume)
{
var g = new GameObject(name);
UnityEngine.Object.DontDestroyOnLoad(g);
var src = g.AddComponent<AudioSource>();
src.loop = true;
src.spatialBlend = 0f;
src.volume = volume;
return src;
}
void StopDroneSounds()
{
if (buzzSrc != null) buzzSrc.Stop();
if (musicSrc != null) musicSrc.Stop();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Insert)) open = !open;
if (Input.GetKeyDown(KeyCode.F6)) SetFly(!fly);
if (Input.GetKeyDown(KeyCode.F8)) SetDrone(!drone);
if (open) { Cursor.visible = true; Cursor.lockState = CursorLockMode.None; }
// обычный полёт
if (fly && !drone && player != null && Camera.main != null && !open)
{
var cam = Camera.main.transform;
Vector3 dir = Vector3.zero;
if (Input.GetKey(KeyCode.W)) dir += cam.forward;
if (Input.GetKey(KeyCode.S)) dir -= cam.forward;
if (Input.GetKey(KeyCode.D)) dir += cam.right;
if (Input.GetKey(KeyCode.A)) dir -= cam.right;
if (Input.GetKey(KeyCode.Space)) dir += Vector3.up;
if (Input.GetKey(KeyCode.LeftControl)) dir -= Vector3.up;
float sp = Input.GetKey(KeyCode.LeftShift) ? flySpeed * 3f : flySpeed;
player.position += dir.normalized * sp * Time.deltaTime;
}
// режим шахеда
if (drone && !exploding && player != null && Camera.main != null && !open)
{
var cam = Camera.main.transform;
Vector3 dir = cam.forward;
if (Input.GetKey(KeyCode.W)) droneSpeed += 25f * Time.deltaTime;
if (Input.GetKey(KeyCode.S)) droneSpeed -= 25f * Time.deltaTime;
droneSpeed = Mathf.Clamp(droneSpeed, 5f, 80f);
float dist = droneSpeed * Time.deltaTime + 0.5f;
bool hit = false;
var hits = Physics.SphereCastAll(player.position, 0.5f, dir, dist);
foreach (var h in hits)
{
if (h.collider == null || h.collider.isTrigger) continue;
if (h.transform == player || h.transform.IsChildOf(player)) continue;
hit = true; break;
}
if (hit && Time.time - droneStartTime > 1.5f)
{
if (droneSpeed >= crashSpeed) Explode(player.position);
}
else
{
player.position += dir * droneSpeed * Time.deltaTime;
}
player.Rotate(dir, spinSpeed * Time.deltaTime, Space.World);
}
// вспышка взрыва
if (flash != null)
{
float k = (Time.time - flashStart) / 0.6f;
if (k >= 1f) { UnityEngine.Object.Destroy(flash); flash = null; }
else flash.transform.localScale = Vector3.one * (2f + k * 14f);
}
// возврат на старт после взрыва
if (exploding && Time.time >= respawnAt)
{
if (player != null) player.position = startPos;
exploding = false;
SetFly(false);
}
if ((god || stamina) && Time.time >= nextApply)
{
nextApply = Time.time + 0.25f;
ApplyStats(false);
}
}
void SetFly(bool value)
{
if (value == fly) return;
fly = value;
if (fly)
{
cc = FindObjectOfType<CharacterController>();
if (cc != null) { player = cc.transform; cc.enabled = false; }
else
{
var go = GameObject.FindWithTag("Player");
rb = go != null ? go.GetComponent<Rigidbody>() : null;
if (rb != null) { player = rb.transform; rb.isKinematic = true; }
}
if (player == null) fly = false;
}
else
{
drone = false;
StopDroneSounds();
if (cc != null) cc.enabled = true;
if (rb != null) rb.isKinematic = false;
}
}
void SetDrone(bool value)
{
if (value)
{
SetFly(true);
if (!fly || player == null) return;
startPos = player.position;
droneStartTime = Time.time;
exploding = false;
drone = true;
if (buzzClip != null)
{
if (buzzSrc == null) buzzSrc = MakeLoopSource("DroneBuzz", 1f);
buzzSrc.clip = buzzClip;
buzzSrc.Play();
}
if (musicClip != null)
{
if (musicSrc == null) musicSrc = MakeLoopSource("DroneMusic", 0.8f);
musicSrc.clip = musicClip;
musicSrc.Play();
}
}
else
{
drone = false;
StopDroneSounds();
}
}
void Explode(Vector3 pos)
{
exploding = true;
respawnAt = Time.time + 1.5f;
StopDroneSounds();
if (boomClip != null) AudioSource.PlayClipAtPoint(boomClip, pos, 1f);
flash = GameObject.CreatePrimitive(PrimitiveType.Sphere);
flash.transform.position = pos;
flash.transform.localScale = Vector3.one * 2f;
var col = flash.GetComponent<Collider>();
if (col != null) UnityEngine.Object.Destroy(col);
var rend = flash.GetComponent<Renderer>();
if (rend != null) rend.material.color = new Color(1f, 0.55f, 0.1f);
flashStart = Time.time;
var near = Physics.OverlapSphere(pos, 10f);
foreach (var c in near)
{
if (c == null) continue;
var body = c.attachedRigidbody;
if (body != null && body != rb) body.AddExplosionForce(800f, pos, 10f);
}
}
void ApplyStats(bool logOnly)
{
var all = UnityEngine.Object.FindObjectsOfType<MonoBehaviour>();
foreach (var mb in all)
{
if (mb == null) continue;
try
{
var t = mb.GetType();
if (t.Assembly.GetName().Name != "Assembly-CSharp") continue;
var props = t.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (var p in props)
{
if (!p.CanRead || !p.CanWrite) continue;
if (p.PropertyType != typeof(float) && p.PropertyType != typeof(int)) continue;
string n = p.Name.ToLower();
bool isBad = false;
foreach (var b in Bad) if (n.Contains(b)) { isBad = true; break; }
if (isBad) continue;
bool isH = false, isS = false;
foreach (var k in HealthKeys) if (n.Contains(k)) isH = true;
foreach (var k in StaminaKeys) if (n.Contains(k)) isS = true;
if (!isH && !isS) continue;
if (logOnly) { Plugin.L.LogInfo("FOUND: " + t.Name + "." + p.Name); continue; }
if (!(isH && god) && !(isS && stamina)) continue;
double target = 9999;
foreach (var q in props)
{
string qn = q.Name.ToLower();
bool maxMatch = qn.Contains("max") && (isH ? (qn.Contains("health") || qn.Contains("hp")) : (qn.Contains("stamina") || qn.Contains("energy")));
if (!maxMatch || !q.CanRead) continue;
object v = q.GetValue(mb);
if (v is float f) target = f; else if (v is int i) target = i;
break;
}
if (p.PropertyType == typeof(float)) p.SetValue(mb, (float)target);
else p.SetValue(mb, (int)target);
}
}
catch { }
}
}
void SpawnByName(string name)
{
var all = Resources.FindObjectsOfTypeAll<GameObject>();
foreach (var go in all)
{
if (go == null || go.name != name) continue;
Vector3 pos = Vector3.zero;
if (Camera.main != null) pos = Camera.main.transform.position + Camera.main.transform.forward * 3f;
var copy = UnityEngine.Object.Instantiate(go, pos, Quaternion.identity);
copy.SetActive(true);
return;
}
}
void OnGUI()
{
if (!open) return;
float x = 20, y = 20, w = 320, h = 28;
GUI.Box(new Rect(10, 10, w + 20, 800), "Cheat Menu (Insert)");
y += 20;
bool nf = GUI.Toggle(new Rect(x, y, w, h), fly, " Полёт / ноклип (F6)"); y += h;
if (nf != fly) SetFly(nf);
GUI.Label(new Rect(x, y, w, 20), "Скорость полёта: " + (int)flySpeed); y += 20;
flySpeed = GUI.HorizontalSlider(new Rect(x, y, w, 20), flySpeed, 3f, 100f); y += 28;
bool nd = GUI.Toggle(new Rect(x, y, w, h), drone, " Режим шахеда (F8)"); y += h;
if (nd != drone) SetDrone(nd);
GUI.Label(new Rect(x, y, w, 20), "Скорость дрона: " + (int)droneSpeed + " (W/S)"); y += 20;
droneSpeed = GUI.HorizontalSlider(new Rect(x, y, w, 20), droneSpeed, 5f, 80f); y += 24;
GUI.Label(new Rect(x, y, w, 20), "Порог взрыва: " + (int)crashSpeed); y += 20;
crashSpeed = GUI.HorizontalSlider(new Rect(x, y, w, 20), crashSpeed, 5f, 80f); y += 24;
GUI.Label(new Rect(x, y, w, 20), "Вращение: " + (int)spinSpeed + " град/с"); y += 20;
spinSpeed = GUI.HorizontalSlider(new Rect(x, y, w, 20), spinSpeed, 0f, 1080f); y += 28;
god = GUI.Toggle(new Rect(x, y, w, h), god, " Бессмертие"); y += h;
stamina = GUI.Toggle(new Rect(x, y, w, h), stamina, " Бесконечная стамина"); y += h;
if (GUI.Button(new Rect(x, y, w, h), "Найти поля health/stamina (в лог)")) ApplyStats(true);
y += h + 10;
GUI.Label(new Rect(x, y, w, h), "Сцены (индекс в билде):"); y += 22;
int count = SceneManager.sceneCountInBuildSettings;
for (int i = scenePage * 6; i < Math.Min(count, scenePage * 6 + 6); i++)
{
string path = SceneUtility.GetScenePathByBuildIndex(i);
string nm = Path.GetFileNameWithoutExtension(path);
if (GUI.Button(new Rect(x, y, w, 24), i + ": " + nm)) SceneManager.LoadScene(i);
y += 26;
}
if (GUI.Button(new Rect(x, y, 150, 24), "< Назад")) scenePage = Math.Max(0, scenePage - 1);
if (GUI.Button(new Rect(x + 170, y, 150, 24), "Вперёд >")) { if ((scenePage + 1) * 6 < count) scenePage++; }
y += 36;
GUI.Label(new Rect(x, y, w, h), "Спавн: введите часть имени"); y += 22;
filter = GUI.TextField(new Rect(x, y, w, 24), filter); y += 30;
if (filter.Length >= 2)
{
int shown = 0;
var all = Resources.FindObjectsOfTypeAll<GameObject>();
foreach (var go in all)
{
if (go == null || shown >= 6) break;
if (go.name.ToLower().Contains(filter.ToLower()))
{
if (GUI.Button(new Rect(x, y, w, 24), go.name)) SpawnByName(go.name);
y += 26; shown++;
}
}
}
}
}