-
Posts
112 -
Joined
-
Last visited
-
Days Won
4 -
Отзыв
0%
Content Type
Profiles
Forums
Servers
DayZ Wiki
Updates
Downloads
Store
Joint Purchases
Everything posted by _MayHem_
-
Просмотр файла Server_manager bat -файл В преддверии обновления клиента и сервера игры DayZ. Выкладываю написанный мною .bat - файл для Server_manager. Сам пользуюсь для обновления модов до полследней версии. Не требует знаний по программированию и знания скриптинга. Интуитивно понятный и русифицированный интерфейс. In anticipation of the update of the DayZ game client and server. I 'm posting what I wrote .the bat file for Server_manager. I use it myself to update mods to the latest version. It does not require programming knowledge or scripting knowledge. Intuitive and Russified interface. Добавил _MayHem_ Добавлено 02.06.2025 Категория Программное обеспечение
-
Version 1.0.0
30 downloads
В преддверии обновления клиента и сервера игры DayZ. Выкладываю написанный мною .bat - файл для Server_manager. Сам пользуюсь для обновления модов до полследней версии. Не требует знаний по программированию и знания скриптинга. Интуитивно понятный и русифицированный интерфейс. In anticipation of the update of the DayZ game client and server. I 'm posting what I wrote .the bat file for Server_manager. I use it myself to update mods to the latest version. It does not require programming knowledge or scripting knowledge. Intuitive and Russified interface.Free -
itemEnt = player.GetInventory().CreateInInventory("Тут твоя бочка1"); itemBs = ItemBase.Cast(itemEnt); itemEnt = player.GetInventory().CreateInInventory("Тут твоя бочка2"); itemBs = ItemBase.Cast(itemEnt); itemEnt = player.GetInventory().CreateInInventory("Тут твоя бочка3"); itemBs = ItemBase.Cast(itemEnt);
-
1. Где Вы увидели, что я беру за это деньги? 2. Ссылку на аналоги в студию. 3. Код и отслеживание работает без нареканий, всю необхлдимую и исчерпывающую инфу выдает. З.Ы. Я проектом по Dayz занимаюсь всего 20 дней. Много не знаю. Но для себя некоторые выводы сделал касательно людей "мододелов" в Dayz
-
Значит не правильно выбрал стек.
-
Сугубо и решительно тоже осуждаю
-
список модов в студию)
-
Просмотр файла Чтение логов сервера и клиента игры Dayz Небольшой HTML файлик, (собственноручно написанный на коленке 😀) для удобного чтения логов сервера и клиента игры Dayz. - не требует установки в любом его проявлении. Скачиваете - запускаете в браузере - смотрите. - выдает возможные пути решения проблемы. - возможет поиск в интернете. - удобная система отображения информации. A small HTML file (handwritten on the knee 😀) for easy reading of the logs of the server and client of the Dayz game Добавил /img/icons/don.gif_MayHem_ Добавлено 29.05.2025 Категория Прочее
-
Version 1.0.0
52 downloads
Небольшой HTML файлик, (собственноручно написанный на коленке 😀) для удобного чтения логов сервера и клиента игры Dayz. - не требует установки в любом его проявлении. Скачиваете - запускаете в браузере - смотрите. - выдает возможные пути решения проблемы. - возможет поиск в интернете. - удобная система отображения информации. A small HTML file (handwritten on the knee 😀) for easy reading of the logs of the server and client of the Dayz gameFree -
Всем добра! Сделал кастомный слот персонажу. Создал на основе имеющегося жителе предмет. При помещении в кастомный слот все работает корректно весь инветарь виден но - на модельке персонаж жилет пропадает. При переносе этого жилета в ванильный слот - он виден на персонаже. Помогите разобраться. https://postimg.cc/K47DRP2q Код жилета class CfgVehicles { // РПС class Clothing_Base; class Clothing: Clothing_Base { }; class SmershVest_MOD: Clothing { scope=2; displayName="$STR_CfgVehicles_SmershVest0"; descriptionShort="$STR_CfgVehicles_SmershVest1"; model="\DZ\characters\vests\smersh_g.p3d"; attachments[]= { "VestBackpack", "VestGrenadeA" }; inventorySlot[]+= { "sample_RPS" }; itemInfo[]= { "Clothing", "Vest" }; itemSize[]={3,3}; itemsCargoSize[]={3,3}; quickBarBonus=2; varWetMax=0.49000001; heatIsolation=0.1; repairableWithKits[]={3}; // CLL_MODVanillaItemsBalance\DZ\characters\vests\config.cpp repairCosts[]={25}; visibilityModifier=0.69999999; hiddenSelections[]= { /* "camoGround", "camoMale", "camoFemale", "zbytek" */ }; hiddenSelectionsTextures[]= { "\dz\characters\vests\data\smersh_g_co.paa", "\dz\characters\vests\data\smersh_co.paa", "\dz\characters\vests\data\smersh_co.paa" }; class ClothingTypes { male="\DZ\characters\vests\smersh_m.p3d"; female="\DZ\characters\vests\smersh_f.p3d"; }; class DamageSystem { class GlobalHealth { class Health { hitpoints=110; transferToAttachmentsCoef=0.5; healthLevels[]= { { 1, { "DZ\characters\vests\Data\Smersh.rvmat" } }, { 0.69999999, { "DZ\characters\vests\Data\Smersh.rvmat" } }, { 0.5, { "DZ\characters\vests\Data\Smersh_damage.rvmat" } }, { 0.30000001, { "DZ\characters\vests\Data\Smersh_damage.rvmat" } }, { 0, { "DZ\characters\vests\Data\Smersh_destruct.rvmat" } } }; }; }; }; class AnimationSources { class Buttpack { source="user"; animPeriod=0.0099999998; initPhase=1; }; }; class AnimEvents { class SoundWeapon { class pickUpItem { soundSet="SmershVest_pickup_SoundSet"; id=797; }; class drop { soundset="SmershVest_drop_SoundSet"; id=898; }; }; }; }; class CfgNonAIVehicles { class ProxyAttachment; class Proxysmersh_g: ProxyAttachment { scope=2; inventorySlot[]= { "sample_RPS", "Slot_RPS" }; model="\DZ\characters\vests\smersh_g.p3d"; }; class Proxysample_RPS { scope=2; simulation="ProxyInventory"; inventorySlot="sample_RPS"; autocenter=0; animated=0; model="\DZ\characters\vests\smersh_g.p3d"; shadow=1; reversed=1; }; }; }; Код слота class CfgVehicles { class Man; class SurvivorBase: Man { attachments[]= { "Head", "Shoulder", "Melee", "Headgear", "Mask", "Eyewear", "Hands", "LeftHand", "Gloves", "Armband", "Vest", "Body", "Back", "Hips", "Legs", "Feet", "Splint_Right", "sample_Pouch", "sample_RPS" }; class InventoryEquipment { playerSlots[]= { "Slot_Shoulder", "Slot_Melee", "Slot_Vest", "Slot_Body", "Slot_Hips", "Slot_Legs", "Slot_Back", "Slot_Headgear", "Slot_Mask", "Slot_Eyewear", "Slot_Gloves", "Slot_Feet", "Slot_Armband", "Slot_sample_Pouch", "Slot_RPS" }; }; }; }; class CfgSlots { class Slot_sample_Pouch { name="sample_Pouch"; displayName="sample_Pouch"; selection = "torso"; ghostIcon="set:dayz_inventory image:pouches"; }; class Slot_RPS { name="sample_RPS"; displayName="sample_RPS"; selection = "torso"; ghostIcon="set:dayz_inventory image:pouches"; }; };
-
Делюсь базой мода, который пишу для своего сервера. Суть мода в наличии репутации игрока которая начисляется в зависимости от его действий (в базе действия 2 - убийство зомби и убийство игрока). В зависимости от репутации игроку при повторном респе выдается определенный лут (для теста использую яблоки и сливы) Древовидная структура архива и назначения файлов: scripts/4_World/reputation/ReputationManager.c — Менеджер логики репутации scripts/4_World/reputation/ReputationDefines.c — Константы, диапазоны репутации scripts/4_World/players/PlayerBase.c — Расширение класса PlayerBase c логикой репутации scripts/4_World/zombies/DayZInfected.c — Модификация для начисления очков за зомби config.cpp — Подключение скриптов, настройки мода scripts/4_World/reputation/ReputationManager.c class ReputationManager { static int GetReputationMode(int rep) { if (rep >= -25 && rep <= 25) return 0; // Нейтральная if (rep > 25 && rep <= 50) return 1; // Положительная if (rep < -25 && rep >= -50) return -1; // Отрицательная return 0; } } scripts/4_World/reputation/ReputationDefines.c const int REPUTATION_NEUTRAL_MIN = -25; const int REPUTATION_NEUTRAL_MAX = 25; const int REPUTATION_POSITIVE_MIN = 26; const int REPUTATION_POSITIVE_MAX = 50; const int REPUTATION_NEGATIVE_MIN = -50; const int REPUTATION_NEGATIVE_MAX = -26; const int REPUTATION_START = 0; const int REPUTATION_ZOMBIE_KILL = 5; const int REPUTATION_PLAYER_KILL = -25; scripts/4_World/players/PlayerBase.c modded class PlayerBase { int m_Reputation; override void OnInit() { super.OnInit(); m_Reputation = REPUTATION_START; } int GetReputation() { return m_Reputation; } void AddReputation(int value) { m_Reputation += value; ShowReputationToPlayer(); } void SetReputation(int value) { m_Reputation = value; ShowReputationToPlayer(); } void ShowReputationToPlayer() { string repText = string.Format("Ваша репутация: %1", m_Reputation); Param1 msgParam = new Param1(repText); GetGame().RPCSingleParam(this, 333, msgParam, true, GetIdentity()); } override void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx) { super.OnRPC(sender, rpc_type, ctx); if (rpc_type == 333) { Param1 repParam; if (ctx.Read(repParam)) { Param1 chatMsg = new Param1(repParam.param1); GetGame().Chat(chatMsg.param1); } } } override void StartingEquipSetup(PlayerBase player, bool clothesChosen) { super.StartingEquipSetup(player, clothesChosen); int rep = this.GetReputation(); if (rep >= 15 && rep <= 50) { player.GetInventory().CreateInInventory("Apple"); } else if (rep <= -50 && rep >= -150) { player.GetInventory().CreateInInventory("Plum"); } } override void EEKilled(Object killer) { super.EEKilled(killer); PlayerBase killerPlayer = PlayerBase.Cast(killer); if (killerPlayer && killerPlayer != this) { int victimReputation = this.GetReputation(); if ((victimReputation > 0) || (victimReputation < 0)) { killerPlayer.AddReputation(REPUTATION_PLAYER_KILL); } } } } scripts/4_World/zombies/DayZInfected.c modded class DayZInfected { override void EEHitBy(EntityAI attacker, int component, string ammo, vector pos, float energy, float dmg) { super.EEHitBy(attacker, component, ammo, pos, energy, dmg); if (IsAlive()) return; PlayerBase player = PlayerBase.Cast(attacker); if (player) { player.AddReputation(REPUTATION_ZOMBIE_KILL); } } } config.cpp class CfgPatches { class MyReputationMod { units[] = {}; weapons[] = {}; requiredAddons[] = {"DZ_Data"}; }; };
-
Много подобных объявление прочитал и не могу понять что конкретно вы продаете. Пак бесплатных модов, которые самому настроить можно очень легко (особенно если ты сумел установить сервер и запустить его.). Или "кастомные" платные моды которые нельзя продавать?
-
В данный момент времени занимаюсь написанием серверного античита для соственного сервера. Выкладываю на общее обозрение свою работа. Мод проверен в работе и работает корректно. Не дописал модуль игнорирования админов. Но это на будещее. Струтура AntiCheat/ ├── config.cpp └── scripts/ ├── 4_World/ │ └── AntiCheat.c AntiCheatLogger.c └── 5_Mission/ └── MissionServer.c AntiCheat.c class AntiCheat { protected ref array<ref PlayerData> m_PlayerData; protected float m_LastCheckTime; protected ref AntiCheatLogger m_Logger; protected const float CHECK_INTERVAL = 0.5; // 0.5 секунд protected const float MAX_SPEED = 7.0; // максимальная скрость в м/с protected const float WALLHACK_CHECK_DISTANCE = 50.0; // максимальная дистанция в метрах void AntiCheat() { m_PlayerData = new array<ref PlayerData>; m_LastCheckTime = 0; m_Logger = new AntiCheatLogger; GetDayZGame().Event_OnRPC.Insert(OnRPC); } void ~AntiCheat() { GetDayZGame().Event_OnRPC.Remove(OnRPC); if (m_Logger) { delete m_Logger; } } void OnRPC(PlayerIdentity sender, Object target, int rpc_type, ParamsReadContext ctx) { if (!sender) return; PlayerBase player = GetPlayerByIdentity(sender); if (!player) return; // обновление данных игрока UpdatePlayerData(player); // проверка CheckSpeedHack(player); CheckWallhack(player); } protected void UpdatePlayerData(PlayerBase player) { PlayerData data = GetPlayerData(player); if (!data) { data = new PlayerData; data.player = player; m_PlayerData.Insert(data); } vector currentPos = player.GetPosition(); float currentTime = GetGame().GetTime(); // расчет скорости if (data.lastPosition != vector.Zero) { float distance = vector.Distance(currentPos, data.lastPosition); float timeDiff = (currentTime - data.lastCheckTime) / 1000.0; // перевод в сек if (timeDiff > 0) { data.currentSpeed = distance / timeDiff; } } data.lastPosition = currentPos; data.lastCheckTime = currentTime; } protected void CheckSpeedHack(PlayerBase player) { PlayerData data = GetPlayerData(player); if (!data) return; // Проверка нахождения в вехикл if (player.IsInVehicle()) return; if (data.currentSpeed > MAX_SPEED) { string playerName = player.GetIdentity().GetName(); string details = string.Format("Speed: %1 m/s (Max allowed: %2 m/s)", data.currentSpeed, MAX_SPEED); // лоргирование m_Logger.LogViolation(playerName, "SPEED_HACK", details); // Notify in chat GetGame().ChatPlayer(1, "Possible speed hack detected: " + playerName); } } protected void CheckWallhack(PlayerBase player) { array<Object> objects = new array<Object>; GetGame().GetObjectsAtPosition(player.GetPosition(), WALLHACK_CHECK_DISTANCE, objects, null); foreach (Object obj : objects) { PlayerBase targetPlayer = PlayerBase.Cast(obj); if (!targetPlayer || targetPlayer == player) continue; vector direction = targetPlayer.GetPosition() - player.GetPosition(); direction.Normalize(); vector from = player.GetPosition(); vector to = targetPlayer.GetPosition(); if (!GetGame().IsBoxColliding(from, to)) { // Детект прохода через коллизии if (IsPlayerLookingAtTarget(player, targetPlayer)) { string playerName = player.GetIdentity().GetName(); string targetName = targetPlayer.GetIdentity().GetName(); string details = string.Format("Looking at player: %1 through wall", targetName); // лог m_Logger.LogViolation(playerName, "WALLHACK", details); // определние негодяя GetGame().ChatPlayer(1, "Possible wallhack detected: " + playerName); } } } } protected bool IsPlayerLookingAtTarget(PlayerBase player, PlayerBase target) { vector playerDir = player.GetDirection(); vector toTarget = target.GetPosition() - player.GetPosition(); toTarget.Normalize(); float dotProduct = playerDir.Dot(toTarget); return dotProduct > 0.9; // лок игрока } protected PlayerData GetPlayerData(PlayerBase player) { foreach (PlayerData data : m_PlayerData) { if (data.player == player) return data; } return null; } } class PlayerData { PlayerBase player; vector lastPosition; float lastCheckTime; float currentSpeed; } AntiCheatLogger.c class AntiCheatLogger { protected string m_LogFilePath; protected FileHandle m_LogFile; void AntiCheatLogger() { string date = GetGame().GetDate(); string time = GetGame().GetTime(); string timestamp = date + "_" + time; m_LogFilePath = "$profile:AntiCheat/logs/anticheat_" + timestamp + ".log"; // Создание дирректории логов if (!FileExist("$profile:AntiCheat/logs")) { MakeDirectory("$profile:AntiCheat/logs"); } // откр лог файл m_LogFile = OpenFile(m_LogFilePath, FileMode.WRITE); if (m_LogFile != 0) { FPrintln(m_LogFile, "=== AntiCheat Log Started ==="); FPrintln(m_LogFile, "Date: " + date); FPrintln(m_LogFile, "Time: " + time); FPrintln(m_LogFile, "==========================="); FPrintln(m_LogFile, ""); } } void ~AntiCheatLogger() { if (m_LogFile != 0) { FPrintln(m_LogFile, ""); FPrintln(m_LogFile, "=== AntiCheat Log Ended ==="); CloseFile(m_LogFile); } } void LogViolation(string playerName, string violationType, string details) { if (m_LogFile == 0) return; string timestamp = GetGame().GetDate() + " " + GetGame().GetTime(); string logEntry = string.Format("[%1] Player: %2 | Violation: %3 | Details: %4", timestamp, playerName, violationType, details); FPrintln(m_LogFile, logEntry); FlushFile(m_LogFile); } } MissionServer.c class MissionServer extends MissionServer { protected ref AntiCheat m_AntiCheat; void MissionServer() { m_AntiCheat = new AntiCheat; } void ~MissionServer() { if (m_AntiCheat) { delete m_AntiCheat; } } } Config.cpp class CfgPatches { class AntiCheat { units[] = {}; weapons[] = {}; requiredVersion = 0.1; requiredAddons[] = {"DZ_Data", "DZ_Scripts"}; }; }; class CfgMods { class AntiCheat { dir = "AntiCheat"; picture = ""; action = ""; hideName = 1; hidePicture = 1; name = "AntiCheat"; credits = "https://steamcommunity.com/profiles/76561199218849472/"; author = "https://steamcommunity.com/profiles/76561199218849472/"; authorID = "0"; version = "1.0"; extra = 0; type = "mod"; dependencies[] = {"Game", "World", "Mission"}; class defs { class gameScriptModule { value = ""; files[] = {"AntiCheat/scripts/3_Game"}; }; class worldScriptModule { value = ""; files[] = {"AntiCheat/scripts/4_World"}; }; class missionScriptModule { value = ""; files[] = {"AntiCheat/scripts/5_Mission"}; }; }; }; }; Вид логов === AntiCheat Log Started === Date: 2025-05-25 Time: 15:30:45 =========================== [2025-05-25 15:31:20] Player: Valanchik | Violation: SPEED_HACK | Details: Speed: 12.5 m/s (Max allowed: 7.0 m/s) [2025-05-25 15:32:15] Player: PoPuASS | Violation: WALLHACK | Details: Looking at player: Valanchik through wall P.S. Это тестовый вариант. Все что вы будите вносить можете публиковать тут. Мод подключать на стороне сервера. Особых просадок серверного ФПС я не увидел. Да и тестил всего несколько дней с помощью VPP
-
-
Немного структурированные знания по скриптингу в Dayz Введение Моддинг и скриптинг в DayZ Standalone — это процессы создания и изменения игрового контента с помощью внешних модификаций и программных скриптов. Моддинг позволяет добавить новые возможности, изменить баланс или добавить уникальный контент, а скриптинг — это инструмент расширения функционала игры за счёт написания кода на языке Enfusion Script. Существует несколько основных типов модов: Балансные моды — корректируют игровые параметры, например, урон оружия, здоровье персонажей или частоту появления ресурсов. Контентные моды — добавляют новые предметы, сущности, анимации или даже целые игровые механики, как кастомные рецепты крафта или уникальные задания. Серверные моды — расширяют возможности управления сервером, добавляют админ-команды, систему логирования или настройки экономики. Скриптинг необходим для реализации логики, которая не поддерживается стандартными средствами игры. Например, создание взаимодействия с окружением, динамический спавн лута, реализация уникальных действий для персонажа или разработка сложных игровых событий. Знания скриптинга важны как для начинающих, так и для опытных моддеров. Новички смогут создавать собственные простые моды, экспериментировать с игровыми механиками, а профессионалы — разрабатывать комплексные модификации, оптимизировать код и интегрировать новые функции в DayZ с максимальной гибкостью. Структура модов и файлов Стандартная структура мода для DayZ Standalone построена так, чтобы обеспечить удобство разработки, сборки и подключения модификаций как на клиентской, так и на серверной стороне. Рассмотрим подробно основные папки и ключевые файлы. Основные папки мода addons — содержит скомпилированные PBO-файлы, которые игра загружает как готовые модули. Это конечный формат мода для запуска. scripts — исходный код скриптов на Enfusion Script, включая логику игрового поведения, классы, функции и т.д. config — файлы конфигурации, такие как config.cpp, определяющие параметры сущностей, предметов, настройки мода. meta — метаданные, в том числе системные файлы, описывающие зависимости и структуру мода. Ключевые файлы конфигурации config.cpp — основной конфигурационный файл, содержащий описание классов, наследования, определение настроек объектов и скриптов. types.xml — определяет параметры лута и спавна предметов в мире игры: частоту появления, количество, зоны генерации. events.xml — задаёт группы событий со списком предметов, которые могут появляться при наступлении определённых условий. Процесс сборки и подключение мода Для упаковки мода создаётся PBO-файл — специальный архив, который содержит все важные файлы и папки. PBO формат используется движком DayZ для быстрого и упорядоченного доступа к ресурсам. Для создания PBO применяются инструменты: Addon Builder — официальный инструмент из Arma Tools для упаковки папки с модом в PBO. Community Tools — сторонние программы, например, PBO Manager, которые позволяют упаковывать и распаковывать PBO. После сборки мод помещается на сервер и/или клиент, подключается в конфигурационных файлах сервера (например, serverDZ.cfg) через параметр mods=. При запуске игры или сервера мод автоматически загружается и используется. Пример простой структуры модификации MyMod/ ├── scripts/ │ └── 4_World/ │ └── Entities/ │ └── MyCustomEntity.c ├── config.cpp ├── mod.cpp └── types.xml Основы Enfusion Script Enfusion Script — это специализированный скриптовый язык, разработанный компанией Bohemia Interactive для управления игровой логикой в DayZ Standalone. Он основан на синтаксисе, похожем на C++ и SQF, но адаптирован под особенности движка Enfusion, обеспечивая мощный и гибкий инструмент для моддинга. Переменные и типы данных В Enfusion Script поддерживаются основные типы данных: int — целочисленные значения float — числа с плавающей точкой bool — логические значения (true/false) string — текстовые строки ref — ссылки на объекты и классы В примере класс CustomPlayer наследует базовые свойства и методы PlayerBase, переопределяя метод OnPlayerHit с вызовом родительской реализации через super. Особенности языка Enfusion Script Строгая типизация — ошибки типов легко обнаруживаются на этапе компиляции. Поддержка событий и хуков для реакций на игровые действия. Интеграция с движком игры через специальные API для работы с объектами, игроками и окружением. Поддержка декларативных конфигураций файлов, таких как config.cpp, в тесной связке со скриптами. Знание этих основ критично для успешной работы с моддингом в DayZ, поскольку понимание структуры и возможностей Enfusion Script позволяет создавать не только простые корректировки, но и сложные игровые механики, интегрируя собственный код с базовой логикой игры. Объявление переменной происходит с явным указанием типа: int playerHealth = 100; float speed = 4.5; bool isAlive = true; string playerName = "Survivor"; Функции и методы Функции объявляются с использованием ключевого слова void или возвращаемого типа, если функция возвращает значение. Параметры передаются в круглых скобках: void PrintPlayerName(string name) { Print("Player: " + name); } int Add(int a, int b) { return a + b; } Наследование классов Enfusion Script поддерживает объектно-ориентированное программирование с наследованием. Для создания нового класса от существующего используется оператор :: class CustomPlayer : PlayerBase { override void OnPlayerHit(int damage) { super.OnPlayerHit(damage); Print("Custom damage reaction"); } } Работа с сущностями В DayZ ключевыми игровыми сущностями являются PlayerBase, ItemBase и AnimalBase. Эти базовые классы представляют игрока, предметы и животных соответственно. Создание и модификация сущностей позволяет добавлять новые игровые механики, расширять взаимодействия и изменять поведение объектов в мире. Основные классы сущностей PlayerBase — отвечает за логику и состояния персонажа: здоровье, инвентарь, движения, взаимодействия. ItemBase — базовый класс для всех предметов в игре, включая оружие, снаряжение, расходники. AnimalBase — класс, управляющий поведением дикой природы, включая передвижения, агрессивность и реакции. Создание кастомной сущности Для создания собственной сущности используется наследование из одного из базовых классов. Например, создадим новый предмет с дополнительной логикой: class CustomItem : ItemBase { void CustomItem() { Print("Создан кастомный предмет"); } override void OnUse() { super.OnUse(); Print("Использован кастомный предмет"); } } Здесь CustomItem наследуется от ItemBase, добавляет конструктор и переопределяет метод OnUse(), чтобы выполнить дополнительный код при использовании предмета. Модификация поведения сущностей Расширение классов позволяет изменять логику без переписывания всего кода. Например, для игрока можно добавить дополнительную реакцию на получение урона: class CustomPlayer : PlayerBase { override void OnHit(int damage, string source) { super.OnHit(damage, source); Print("Игрок получил " + damage + " урона от " + source); } } Особенности работы с сущностями Все кастомные классы необходимо прописывать в config.cpp для правильной регистрации игры. Взаимодействие с миром и лутом В DayZ спавн объектов и лута в игровом мире регулируется с помощью файлов types.xml и events.xml. Эти конфигурации определяют, какие предметы и с какой частотой появляются, а также в каких зонах и в каких условиях. Такой подход позволяет гибко настраивать генерацию ресурсов, настроить уникальные локации и события, влияющие на игровой процесс. Наследование позволяет переопределять методы, расширяя базовый функционал, сохраняя при этом совместимость. Используйте вызов super для вызова методов родительского класса, чтобы не потерять основную логику Файл types.xml В types.xml задаётся базовый список объектов для спавна — оружие, еда, медикаменты, бытовые предметы и многое другое. Каждая запись описывается с помощью параметров: name — идентификатор предмета; nominal — желаемое количество предметов на карте; lifetime — время существования объекта в секунду; restock — через сколько секунд после спавна объект может появиться вновь; min и quantmin — минимальное количество предметов и минимальный стэк; max и quantmax — максимальное количество и стек. Пример записи в types.xml для нового предмета: <type name="CustomBandage" nominal="20" lifetime="7200" restock="3600" min="1" max="3" quantmin="1" quantmax="1" /> Файл events.xml Файл events.xml описывает группы предметов, которые появляются вместе при определённых игровых событиях, например, в заброшенных складах или в лагере рейдеров. События помогают создавать больше живых и уникальных точек интереса, повышая реализм и разнообразие. Пример события, создающего набор лута: <event name="RaidersLoot" chance="0.2"> <item name="CustomBandage" count="2" /> <item name="Ammo_9mm" count="15" /> </event> Создание спавна через скрипты Кроме XML-конфигов, в DayZ можно создавать и управлять спавном объектов программно через Enfusion Script. Для этого используются методы создания объектов в мире, например: Entity SpawnCustomItem(vector position) { return GetGame().CreateObject("CustomBandage", position, false, true); } Данный код создаёт экземпляр объекта CustomBandage в указанной позиции без прикрепления к персонажу. Особенности событийного спавна Событийный спавн может быть привязан к определённым триггерам — началу миссии, достижению локации игроком, изменению игрового времени и другим условиям. Использование таких триггеров позволяет делать динамичный и адаптивный игровой мир, в который постоянно что-то происходит. Важно тщательно балансировать частоты и зону появления лута, чтобы сохранять интерес и вызов для игроков, не делая игру слишком простой или хаотичной. Обработка событий и хуки В DayZ Standalone жизненный цикл объектов охватывает три ключевых этапа: создание, обновление и уничтожение. Во время создания объект инициализируется с базовыми параметрами, на стадии обновления происходит обработка логики поведения, а при уничтожении — освобождение ресурсов и возможное выполнение завершающих действий. Для отслеживания важных игровых событий применяются хуки — специальные точки подключения к внутренним функциям движка, позволяющие моддерам вставлять свой код и расширять логику игры без изменения исходного кода. События игрока Рождение (OnPlayerSpawn) — инициализация состояния персонажа после входа в игру. Смерть (OnPlayerDeath) — момент обработки смерти для сохранения состояния или запуска дополнительных эффектов. Действия (например, OnItemUse, OnHit) — реакции на использование предметов, получение урона и другие игровые взаимодействия. Action-система Action-система отвечает за выполнение и обработку пользовательских действий (например, взятие предмета, открытие двери). Добавление нового действия требует создания класса-наследника ActionBase, определяющего логику, условия запуска и анимации. Пример простого добавления действия: class ActionCustom : ActionBase { override void OnStartClient(ActionData action_data) { super.OnStartClient(action_data); Print("Пользователь начал кастомное действие"); } } Пример подписки на событие и обработка Возьмём пример подписки на событие смерти игрока через хук: modded class PlayerBase { override void EEKilled(Object killer) { super.EEKilled(killer); Print("Игрок погиб, убийца: " + killer); // Дополнительная логика при смерти } } Здесь EEKilled — виртуальный метод, вызываемый в момент смерти. Использование ключевого слова override позволяет модифицировать поведение без уничтожения базовой логики, а вызов super.EEKilled(killer) гарантирует сохранение стандартной обработки. Благодаря хукам и системе событий в DayZ моддеры получают мощный инструмент для гибкого расширения и глубокой кастомизации игрового поведения. Пользовательские предметы и крафт Создание собственного предмета в DayZ требует последовательного подхода, включающего создание моделей, конфигурацию и добавление логики и рецептов крафта. Рассмотрим основные шаги. 1. Создание модели и текстур Первый этап — подготовка 3D-модели предмета в стороннем редакторе (например, Blender или 3ds Max) и экспорт в формат, поддерживаемый движком (обычно .p3d). Также необходимы текстуры в форматах .paa или .tga, которые создаются на основе исходных изображений. 2. Описание предмета в config.cpp В конфигурационном файле описывается класс предмета с указанием модели, информации для инвентаря и параметров взаимодействия. Пример: class CfgVehicles { class Inventory_Base; class CustomKnife : Inventory_Base { scope = 2; displayName = "Кастомный нож"; descriptionShort = "Острый нож, подходящий для выживания."; model = "\MyMod\Models\custom_knife.p3d"; weight = 500; itemSize[] = {2,1}; lootTag[] = {"Survival", "Weapon"}; }; }; 3. Добавление рецепта крафта в config.cpp и скрипты Чтобы игрок мог создавать новый предмет, следует описать рецепт крафта. Для этого в cfgRecipes (кастомном или существующем) задаются необходимые компоненты и количество. class CfgRecipes { class CraftCustomKnife { name = "Создать кастомный нож"; tools[] = {"Knife"}; inputs[] = { {"MetalPlate",1}, {"WoodenStick",1} }; output = "CustomKnife"; }; }; В скриптах можно дополнительно контролировать логику крафта, проверку условий или создавать кастомные действия. 4. Добавление анимаций и взаимодействий Анимации для новых предметов задаются в cfgMoves и связаны с Action-системой. Для кастомных взаимодействий обычно создают новые классы действий (ActionBase). Например, можно добавить уникальное использование ножа для добычи ресурсов или нанесения урона. Итоговый пример использования в скрипте class CustomKnife : Inventory_Base { void CustomKnife() { Print("Кастомный нож создан."); } override void OnUse() { super.OnUse(); Print("Использован кастомный нож."); // Дополнительная логика, например, нанесение урона } } Таким образом, создание предмета включает работу с моделью, описанием в конфиге, настройкой рецепта крафта и добавлением логики поведения и анимаций через скрипты и Action-систему для полноценного взаимодействия с игровым миром. Работа с инвентарём и характеристиками В DayZ Standalone управление инвентарём и характеристиками игрока осуществляется через сочетание скриптов и конфигурационных файлов. Моддеры могут изменять параметры здоровья, голода, жажды, а также добавлять, удалять или передавать предметы между персонажами и объектами. Изменение характеристик игрока Для изменения параметров состояния персонажа (здоровья, голода, жажды и др.) используются методы класса PlayerBase. Например, чтобы изменить здоровье игрока, доступен метод SetHealth, а для работы с голодом и жаждой — свойства, связанные с компонентом StaminaHandler или Stats. void SetPlayerHealth(PlayerBase player, float health) { player.SetHealth("", "", health); } void AddHunger(PlayerBase player, float amount) { float currentHunger = player.GetStatEnergy().Get(); player.GetStatEnergy().Add(amount); // Добавляет энергию, уменьшая голод } Работа с инвентарём: добавление и удаление предметов Взаимодействие с инвентарём реализуется через классы EntityAI и Inventory. Для выдачи предмета игроку используется метод GiveItem или создание объекта с последующим добавлением в инвентарь. // Создание и выдать предмет игроку void GiveItemToPlayer(PlayerBase player, string itemType) { EntityAI item = player.GetInventory().CreateInInventory(itemType); if (item) { Print("Предмет " + itemType + " выдан игроку."); } } // Удалить предмет из инвентаря void RemoveItemFromPlayer(PlayerBase player, string itemType) { array items = new array; player.GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER, items); foreach (EntityAI item : items) { if (item.GetType() == itemType) { player.GetInventory().DropEntity(item); item.Delete(); Print("Предмет " + itemType + " удалён."); break; } } } Передача предметов между игроками Для передачи предмета от одного игрока к другому предмет сначала удаляется из инвентаря донора и добавляется в инвентарь получателя: void TransferItem(PlayerBase fromPlayer, PlayerBase toPlayer, string itemType) { array items = new array; fromPlayer.GetInventory().EnumerateInventory(InventoryTraversalType.PREORDER, items); foreach (EntityAI item : items) { if (item.GetType() == itemType) { // Удаляем у донора fromPlayer.GetInventory().DropEntity(item); item.SetPosition(toPlayer.GetPosition()); // Добавляем в инвентарь получателя toPlayer.PredictiveTakeEntityToInventory(toPlayer, item); Print("Предмет передан игроку."); break; } } } Типичные задачи и решения Выдача стартового набора: при спавне игрока. Автоматическое лечение: изменение показателей здоровья через скрипты при использовании аптечек. Удаление нелегальных предметов: проверка инвентаря и удаление через цикл. Пользовательский интерфейс и HUD В DayZ Standalone пользовательский интерфейс (UI) создаётся с помощью встроенного UI API, позволяющего создавать окна, кнопки, текстовые поля и другие элементы для взаимодействия с игроком. Основу UI составляет система виджетов, которые можно размещать на экране и управлять ими через скрипты на Enfusion Script. Структура UI и взаимодействие со скриптом UI элементы создаются в виде классов, наследующих Widget или WidgetScript. Основная сцена HUD реализована в виде специального виджета, который отвечает за отображение информации поверх игрового мира. Для взаимодействия с игровым кодом UI использует события и методы на скриптовой стороне. Пример создания простого HUD Ниже пример создания простого HUD, выводящего здоровье игрока в левом верхнем углу экрана: class CustomHUD extends UIScriptedMenu { TextWidget healthText; override Widget Init() { layoutRoot = GetGame().GetWorkspace().CreateWidgets("MyMod/gui/layouts/customhud.layout"); healthText = TextWidget.Cast(layoutRoot.FindAnyWidget("HealthValue")); return layoutRoot; } override void Update() { PlayerBase player = PlayerBase.Cast(GetGame().GetPlayer()); if (player) { float health = player.GetHealth("", ""); healthText.SetText("Здоровье: " + Math.Floor(health).ToString()); } } } В данном примере создаётся класс CustomHUD, который инициализирует виджет из layout-файла и обновляет текст с текущим значением здоровья игрока каждое игровое обновление. Советы по отладке и оформлению UI Используйте встроенный Workspace Debugger для просмотра иерархий виджетов и свойств; Разделяйте логику и оформление: храните лейауты в .layout файлах, а логику — в скриптах; Минимизируйте количество обновлений: обновляйте UI только при изменении данных, чтобы снизить нагрузку; Проверяйте Null-ссылки: всегда убеждайтесь, что виджеты корректно инициализированы перед использованием; Используйте стили и шаблоны: для единообразия интерфейса и удобства поддержки кода. Серверная логика и администрирование В DayZ Standalone скрипты могут исполняться как на стороне клиента, так и на сервере. Разделение ролей важно для оптимизации и безопасности. Клиент отвечает за отображение, управление пользовательским интерфейсом и локальную логику, тогда как сервер обрабатывает важные игровые процессы, валидацию действий, управление состояниями и синхронизацию между игроками. Основные различия между серверным и клиентским кодом: Сервер: контролирует игровые правила, спавн объектов, обработку событий и действия игроков; все критичные вычисления выполняются здесь. Клиент: отвечает за визуализацию, анимации, интерфейс и локальный отклик на действия игрока. Админ-команды и их обработка Администрация сервера может использовать кастомные команды для управления игровым процессом, выдачи предметов или выполнения других операций. Для добавления админ-команды в Enfusion Script необходимо: Создать класс команды, реализующий интерфейс ChatCommandHandler или аналогичный. Зарегистрировать команду в системе через специальный менеджер команд. Обработать ввод и выполнить соответствующие действия. Пример простой админ-команды для выдачи предмета: class GiveItemCommand : ChatCommandHandler { override string GetCommandName() { return "give"; } override void Execute(PlayerIdentity sender, array params) { if (params.Count() != 2) { sender.SendDirectMessage("Использование: /give <player> <item>"); return; } string playerName = params[0]; string itemName = params[1]; PlayerBase targetPlayer = FindPlayerByName(playerName); if (!targetPlayer) { sender.SendDirectMessage("Игрок не найден."); return; } targetPlayer.GetInventory().CreateInInventory(itemName); sender.SendDirectMessage("Предмет " + itemName + " выдан игроку " + playerName + "."); } } Работа с логами сервера Логирование – важный инструмент для мониторинга работы сервера, отладки и аудита админских действий. В DayZ можно писать собственные сообщения в лог с помощью функции Print или специализированных методов сервера. Print("Сообщение") — выводит строку в общий лог сервера и консоль. Для разделения логов рекомендуется добавлять теги или префиксы, например: Print("[MyMod] Действие выполнено"). Для более сложной логики можно реализовать запись в отдельные файлы через API сервера или внешние плагины. Рекомендации по эффективному управлению сервером и модами Всегда разграничивайте серверный и клиентский код, минимизируя выполнение тяжелых операций на клиенте. Используйте проверки прав администратора перед выполнением команд, чтобы избежать злоупотреблений. Логируйте важные действия админов и критичные события для последующего анализа. Тестируйте моды в условиях, максимально приближенных к боевым, чтобы выявлять возможные ошибки и утечки производительности. Регулярно обновляйте и чистите логи, чтобы сервер не тормозил из-за больших файлов. Оптимизация и best practices Оптимизация кода и соблюдение лучших практик имеют решающее значение для создания стабильных, производительных и совместимых модификаций в DayZ Standalone. Ниже представлены ключевые рекомендации для моддеров любого уровня. Рекомендации по стилю и структуре кода Чёткая организация файлов: разделяйте логику по папкам и классам, используйте понятные имена для файлов и классов, чтобы упростить навигацию и поддержку. Комментирование: сопровождайте сложный или нестандартный код комментариями, чтобы облегчить понимание и последующую доработку. Избегайте дублирования кода: выносите часто повторяющиеся операции в функции или базовые классы, что улучшает читаемость и снижает вероятность ошибок. Типовые ошибки и их предотвращение Null-ссылки: всегда проверяйте объекты на >null< перед использованием, особенно при работе с инвентарём и сущностями. Неправильное наследование: при переопределении методов не забывайте вызывать super для сохранения базовой логики. Чрезмерная частота вызовов: минимизируйте вычисления в методах Update или на каждую итерацию, используйте события и таймеры. Совместимость и тестирование Тестируйте моды в изолированном окружении и на сервере с другими модификациями, чтобы выявить возможные конфликты. Используйте уникальные префиксы в именах классов и функций, чтобы избежать коллизий с другими модами. Регулярно обновляйте моды в соответствии с изменениями клиента и сервера, следя за актуальностью API и форматов конфигов. Советы по производительности Оптимизируйте циклы и алгоритмы — избегайте вложенных вызовов без необходимости. Используйте локальные переменные, где это возможно, для снижения нагрузки на память и уменьшения доступа к объектам. Минимизируйте количество создаваемых объектов и спавн объектов строго при необходимости. Профилируйте скрипты и анализируйте точки узкого места с помощью встроенных средств и логов. Примеры реализации В этом разделе представлены три законченных примера кода с подробным объяснением их работы и инструкциями по интеграции в игру DayZ Standalone 1.24+. 1. Кастомный игровой ивент с уникальным поведением Этот пример демонстрирует создание кастомного игрового ивента, который при активации спавнит группу врагов в радиусе от игрока. Ивент можно вызывать по триггеру или вручную из скрипта. class CustomEnemyEvent { void TriggerEvent(PlayerBase player) { vector pos = player.GetPosition(); int enemyCount = 5; for (int i = 0; i < enemyCount; i++) { vector spawnPos = pos + Vector(Math.RandomFloat(-10,10), 0, Math.RandomFloat(-10,10)); EnemyBase enemy = EnemyBase.Cast(GetGame().CreateObject("ZomBear", spawnPos, false, true)); enemy.SetAIBehaviour("Aggressive"); enemy.SetTarget(player); } Print("[CustomEnemyEvent] Спавн врагов у игрока: " + player.GetIdentity().GetName()); } } Интеграция: вызовите метод TriggerEvent, например, по выполнению определённого условия в игровом событии или через консоль. Ивент автоматически создаст врагов рядом с игроком и заставит их атаковать игрока. 2. Админ-команда для управления игроками на сервере Пример реализации простой админ-команды /kick, которая позволяет администратору выгнать игрока с сервера по имени. class KickPlayerCommand : ChatCommandHandler { override string GetCommandName() { return "kick"; } override void Execute(PlayerIdentity sender, array params) { if (params.Count() != 1) { sender.SendDirectMessage("Использование: /kick <имя_игрока>"); return; } string targetName = params[0]; PlayerBase target = FindPlayerByName(targetName); if (!target) { sender.SendDirectMessage("Игрок " + targetName + " не найден."); return; } target.GetPlayerAgent().Kick("Вы были кикнуты администратором."); sender.SendDirectMessage("Игрок " + targetName + " был кикнут."); Print("[KickPlayerCommand] Админ " + sender.GetName() + " кикнул игрока " + targetName); } } Использование: зарегистрируйте этот класс в системе команд серверного скрипта. Админы смогут вызвать команду в чате /kick JohnDoe, где JohnDoe — ник игрока. 3. Простой мод для изменения поведения животных Модификация, которая изменяет поведение стандартных животных, делая их более агрессивными и быстрее реагирующими на игрока. modded class AnimalBase { override void OnInitialize() { super.OnInitialize(); SetAggressionLevel(3); // Увеличение агрессии (1-5) SetReactionDistance(40); // Расстояние реакции на игрока в метрах } override void OnPlayerApproach(PlayerBase player) { super.OnPlayerApproach(player); if (player) { Print("Животное заметило игрока: " + player.GetIdentity().GetName()); } } } Интеграция: данный мод необходимо добавить в скрипты, перекрыв базовый класс AnimalBase. После этого все животные будут обладать улучшенными параметрами агрессивности и быстрее реагировать на подход игроков. КОМУ ПОМОГЛА ДАННАЯ СТАТЬЯ СТАВЬТЕ РЕКЦИИ😄
-
К сожалению таких я не знаю гайдов. Просто есть знание в ЯП и все. Видел канал такой. Но там основы основ - https://www.youtube.com/@DayZRussiaCommunity
-
Ты перепутал места спавна автомобилей и вероятно всего на место какого то лута)
-
Если ты делаешь механики используя ТОЛЬКО возможности игры, то в принципе можно делать и все на серверной стороне и кастить их на клиента.
-
Всем добра! Друзья, подскажите как сделать возможность намочить одежду используя фляжку с водой.
-
Можно ссылочку на Github
-
Возможные варианты решения, ибо ошибка связана с памятью в выделении стека: - Удалите кэш: C:\Users\ВАШ_ПОЛЬЗОВАТЕЛЬ\AppData\Local\DayZ Очистите папку "Документы\DayZ" - Антивирус/Брандмауэр Добавьте исключения для: DayZ_x64.exe Папки с игрой Папки %localappdata%\DayZ - В свойствах игры в Steam укажи: -noBenchmark -noPause -noLand -skipIntro
-
Этот код позволяет добавлять фейковых игроков в Steam-игры через модификацию памяти. Используйте на свой риск — в мультиплеерных играх это может привести к бану! #include <iostream> #include <windows.h> #include <stdexcept> #include <string> namespace SteamHack { // Конфигурация constexpr uintptr_t STEAM_CLIENT_OFFSET = 0x6FB703; constexpr const char* STEAM_CLIENT_MODULE = "steamclient64.dll"; constexpr size_t INSTRUCTION_SIZE = 6; // Безопасное получение модуля HMODULE GetSteamClientModule() { HMODULE hModule = GetModuleHandleA(STEAM_CLIENT_MODULE); if (!hModule) { throw std::runtime_error("Failed to find steamclient64.dll module"); } return hModule; } // Проверка адреса памяти bool IsValidMemoryAddress(void* addr) { if (!addr) return false; MEMORY_BASIC_INFORMATION mbi; return VirtualQuery(addr, &mbi, sizeof(mbi)) && (mbi.Protect & (PAGE_READONLY|PAGE_READWRITE|PAGE_EXECUTE_READ|PAGE_EXECUTE_READWRITE))); } // Основная функция void AddFakePlayers(BYTE playerCount) { if (playerCount == 0) { throw std::invalid_argument("Player count cannot be zero"); } uintptr_t base = reinterpret_cast<uintptr_t>(GetSteamClientModule()); uintptr_t addr = base + STEAM_CLIENT_OFFSET; if (!IsValidMemoryAddress(reinterpret_cast<void*>(addr))) { throw std::runtime_error("Invalid memory address"); } // Новые инструкции: add edx, playerCount + оригинальные байты unsigned char newInstructions[] = { 0x83, 0xC2, playerCount, 0x03, 0x5B, 0xD0 }; // Сохраняем оригинальные байты для возможного отката static unsigned char originalInstructions[INSTRUCTION_SIZE]; memcpy(originalInstructions, reinterpret_cast<void*>(addr), INSTRUCTION_SIZE); DWORD oldProtect; if (!VirtualProtect(reinterpret_cast<void*>(addr), INSTRUCTION_SIZE, PAGE_EXECUTE_READWRITE, &oldProtect)) { throw std::runtime_error("Failed to change memory protection"); } try { memcpy(reinterpret_cast<void*>(addr), newInstructions, INSTRUCTION_SIZE); } catch (...) { // В случае ошибки восстанавливаем оригинальные байты memcpy(reinterpret_cast<void*>(addr), originalInstructions, INSTRUCTION_SIZE); VirtualProtect(reinterpret_cast<void*>(addr), INSTRUCTION_SIZE, oldProtect, &oldProtect); throw; } // Восстанавливаем защиту if (!VirtualProtect(reinterpret_cast<void*>(addr), INSTRUCTION_SIZE, oldProtect, &oldProtect)) { throw std::runtime_error("Failed to restore memory protection"); } // Для отладки std::cout « "[DEBUG] Successfully patched memory at 0x" « std::hex « addr « " to add " « std::dec « static_cast<int>(playerCount) « " fake players\n"; } // Функция для отката изменений void RestoreOriginalCode() { uintptr_t base = reinterpret_cast<uintptr_t>(GetSteamClientModule()); uintptr_t addr = base + STEAM_CLIENT_OFFSET; if (!IsValidMemoryAddress(reinterpret_cast<void*>(addr))) { throw std::runtime_error("Invalid memory address for restore"); } DWORD oldProtect; if (!VirtualProtect(reinterpret_cast<void*>(addr), INSTRUCTION_SIZE, PAGE_EXECUTE_READWRITE, &oldProtect)) { throw std::runtime_error("Failed to change memory protection for restore"); } try { memcpy(reinterpret_cast<void*>(addr), originalInstructions, INSTRUCTION_SIZE); } catch (...) { throw std::runtime_error("Failed to restore original code"); } VirtualProtect(reinterpret_cast<void*>(addr), INSTRUCTION_SIZE, oldProtect, &oldProtect); } } BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { DisableThreadLibraryCalls(hModule); // Уменьшаем подозрительную активность switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: try { SteamHack::AddFakePlayers(10); // Добавляем 10 фейковых игроков } catch (const std::exception& e) { MessageBoxA(NULL, e.what(), "Steam Hack Error", MB_ICONERROR); return FALSE; } break; case DLL_PROCESS_DETACH: try { SteamHack::RestoreOriginalCode(); // Откатываем изменения при выгрузке } catch (...) { // Игнорируем ошибки при выгрузке } break; } return TRUE; } Как использовать этот улучшенный код для добавления фейковых игроков Этот код представляет собой DLL-инъекцию , которая модифицирует память `steamclient64.dll`, чтобы добавить фейковых игроков в игру. Вот пошаговая инструкция по его использованию. 1. Подготовка Что понадобится: - Компилятор C++ (Visual Studio 2022, MinGW, или другой) - Инжектор DLL (например, Cheat Engine , Process Hacker 2 , Extreme Injector ) - Игра, использующая Steam (например, CS:GO, Dota 2, Garry's Mod) - Административные права (для внедрения DLL) --- 2. Компиляция DLL 1. Создайте проект DLL в Visual Studio : - Откройте Visual Studio → Создать проект → Dynamic-Link Library (DLL) . - Вставьте улучшенный код в `main.cpp`. - Убедитесь, что выбрана конфигурация Release x64 (если игра 64-битная). 2. Настройки компиляции : - Включите многобайтовую кодировку (`Project → Properties → Configuration Properties → Advanced → Character Set → Use Multi-Byte Character Set`). - Отключите SDL checks (если есть ошибки). 3. Соберите проект ( Build → Build Solution ). - В папке `x64/Release/` появится файл `YourDllName.dll`. --- 3. Внедрение DLL в процесс игры Способ 1: Cheat Engine 1. Запустите игру и Cheat Engine . 2. В Cheat Engine: File → Open Process → выберите процесс игры (например, `csgo.exe`). 3. Перейдите в Tools → Inject DLL . 4. Выберите вашу DLL и нажмите Inject . Способ 2: Process Hacker 2 1. Запустите Process Hacker 2 от имени администратора. 2. Найдите процесс игры (например, `hl2.exe`). 3. ПКМ → Miscellaneous → Inject DLL . 4. Выберите вашу DLL и нажмите Inject . Способ 3: Extreme Injector (более скрытный) 1. Запустите Extreme Injector от имени администратора. 2. Выберите процесс игры. 3. Нажмите Add DLL и укажите путь к вашей DLL. 4. Включите Stealth Inject (если есть). 5. Нажмите Inject . --- 4. Проверка работы - Если всё прошло успешно, игра должна зарегистрировать 10 фейковых игроков (значение можно изменить в `AddFakePlayers(10)`). - Проверьте лобби или сервер, где должно отображаться больше игроков. --- 5. Дополнительные настройки Как изменить количество игроков? - В коде замените `AddFakePlayers(10)` на нужное число (например, `AddFakePlayers(50)`). Как отключить читинг? - Просто закройте игру — DLL выгрузится автоматически, и изменения откатятся (благодаря `RestoreOriginalCode` в `DLL_PROCESS_DETACH`). Как избежать бана? - Не используйте в VAC-защищённых играх (CS:GO, Dota 2) — могут забанить. - Тестируйте на оффлайн-серверах или пиратских версиях. - Меняйте сигнатуры кода , чтобы античиты не обнаружили инъекцию. --- 6. Возможные ошибки и решения | "Failed to find steamclient64.dll" | Убедитесь, что игра использует Steam. | | DLL не внедряется | Проверьте, что игра и инжектор x64 . | | Игра крашится | Возможно, код несовместим с текущей версией игры. | --- Вывод Этот код позволяет добавлять фейковых игроков в Steam-игры через модификацию памяти. ⚠️ Используйте на свой риск — в мультиплеерных играх это может привести к бану! Лучше тестировать в одиночных/пиратских версиях игр или на приватных серверах .
