123new

[DayZ 0.63] Создаем Сейвзону на сервере

22 сообщения в этой теме

В данной теме я распишу мой вариант установки сейвзоны, работающий на момент публикации статьи на версии сервера игры 0.63.149525.

 

Установка

1. Открываем 'init.c' в  'MpMissions' вашей.

2. Вверху файла добавляем 1 строкой:

#include "$CurrentDir:\\mpmissions\\dayzoffline.chernarusplus\\Scripts\safezone.c"
ref SafeZone_PlugIn SafeZone = new SafeZone_PlugIn();

Где 'dayzoffline.chernarusplus' - имя папки с активной 'MpMissions' вашей.

Пример:

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

3. В этом же файле находим блок начала класса 'CustomMission: MissionServer' и в его начале после открытия класса добавляем

	bool Activate_SafeZone_PlugIn = true; // safezone on (true) or off (false)
	
	override void TickScheduler(float timeslice)
    {
        GetGame().GetWorld().GetPlayerList(m_Players);
        if( m_Players.Count() == 0 ) return;
        for(int i = 0; i < SCHEDULER_PLAYERS_PER_TICK; i++)
        {
            if(m_currentPlayer >= m_Players.Count() )
            {
                m_currentPlayer = 0;
            }

            PlayerBase currentPlayer = PlayerBase.Cast(m_Players.Get(m_currentPlayer));
            if (Activate_SafeZone_PlugIn) { SafeZone_PlugIn.CheckingPosition(currentPlayer); } //Check if player is near safezone
            currentPlayer.OnTick();
            m_currentPlayer++;
        }
    }

Пример:

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

4. Создаем папку 'Scripts' в корне 'MpMissions' вашей, а в ней создаем файл с именем 'safezone.c' следующего содержания:

class SafeZone_PlugIn
{
	protected static vector SAFEZONE_LOACTION = "15145.1 32.9793 13919.0"; //Map coords (position of the safe zone)
	protected static float  SAFEZONE_RADIUS   = 100; //In meter
	protected static string SAFEZONE_ENTRY_MESSAGE     = "Welcome to The SafeZone! Godmode ENABLED!";
	protected static string SAFEZONE_EXIT_MESSAGE      = "You Have Left The SafeZone! Godmode DISABLED!";

	//Runs every tick (Stat time tick!) IMPORANT: Does reduce about 120 FPS when server is High-Full Pop!
	static void CheckingPosition(PlayerBase player)
	{
		private float SAFEZONE_distance;
		private string SAFEZONE_ZoneCheck, SAFEZONE_UID_PLAYER, SAFEZONE_NAME_PLAYER;
		SAFEZONE_NAME_PLAYER = player.GetIdentity().GetName(); 
		SAFEZONE_UID_PLAYER = player.GetIdentity().GetPlainId(); //Steam 64
		private Param1<string> SAFEZONE_Msgparam;		

		private vector SAFEZONE_pos_player = player.GetPosition();
		private vector SAFEZONE_LOCATION_FIXED = CorrectToGroundPosY(SAFEZONE_LOACTION);
		private string name_mesage_profile = "GodModeEnabledFor:" + SAFEZONE_UID_PLAYER;
		SAFEZONE_distance = vector.Distance(SAFEZONE_pos_player,SAFEZONE_LOCATION_FIXED);
		if (SAFEZONE_distance <= SAFEZONE_RADIUS) //Player Inside Zone
		{
			SAFEZONE_ZoneCheck = "";
			GetGame().GetProfileString(name_mesage_profile,SAFEZONE_ZoneCheck);
			if (SAFEZONE_ZoneCheck == "true") //Already in zone
			{
				return;
			}
			else
			{
				GetGame().SetProfileString(name_mesage_profile,"true");
				Print("[SafeZone] " + SAFEZONE_NAME_PLAYER + " (" + SAFEZONE_UID_PLAYER + ") Enter in safeZone in position: " + SAFEZONE_LOCATION_FIXED.ToString());
				SendPersonalMessage(SAFEZONE_ENTRY_MESSAGE, player);
			}
		}
		else if (SAFEZONE_distance > SAFEZONE_RADIUS) //Player Outside of Zone
		{
			SAFEZONE_ZoneCheck = "";
			GetGame().GetProfileString(name_mesage_profile,SAFEZONE_ZoneCheck);
			if (SAFEZONE_ZoneCheck == "false")
			{
				return;
			}
			else
			{
				if (SAFEZONE_ZoneCheck != "")
				{
					GetGame().SetProfileString(name_mesage_profile,"false");
					Print("[SafeZone] " + SAFEZONE_NAME_PLAYER + " (" + SAFEZONE_UID_PLAYER + ") Left safeZone in position: " + SAFEZONE_LOCATION_FIXED.ToString());
					SendPersonalMessage(SAFEZONE_EXIT_MESSAGE, player);
				} else
				{
					return;
				}
			}
		}
	}

	static vector CorrectToGroundPosY(vector pos)
	{
		private float pos_x = pos[0];
		private float pos_z = pos[2];
		private float pos_y = GetGame().SurfaceY(pos_x, pos_z);
		private vector tmp_pos = Vector(pos_x, pos_y, pos_z);
		return tmp_pos;
	}
	static void SendPersonalMessage(string message, PlayerBase casted_player) 
	{
		Man player; 
		Class.CastTo(player, casted_player);
		if(( player ) && (message != ""))
		{
			Param1<string> m_GlobalMessage = new Param1<string>(message); 
			GetGame().RPCSingleParam(player, ERPCs.RPC_USER_ACTION_MESSAGE, m_GlobalMessage, true, player.GetIdentity()); 
		}
	}
}

Ну или скачиваем его отсюда в готовом виде:

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

Здесь:

 'SAFEZONE_LOACTION' - координаты точки центра сейвзоны.

'SAFEZONE_RADIUS' - радиус от указанного центра севзоны, на котором действует защита

'ENTRY_MESSAGE' - сообщение о входе в зону (не рекоммендуется указывать русский язык, может не отображаться)
'EXIT_MESSAGE' - сообщение о выходе из зоны (не рекоммендуется указывать русский язык, может не отображаться)
5. Распаковываем в папку с сервером в корень вот этот архив:

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

6. В параметры запуска сервера добавляем:

-mod=ModdedScripts

7. Запускаем сервер и проверяем.

 

Для совсем ленивых готовая миссия сервера с настроенной сейвзоной. 

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

  Пункты 5-7 из инструкции выше после этого необходимо повторить, иначе годмод работать не будет!!!

 

P.S. Если у вас в корне сервера лежала папка scripts и она читалась сервером, после этого она может перестать считываться!

P.P.S. Да, да, за основу взята сборка от DaOne, и по тому же принципу сделана и safe-zone с незначительными изменениями. За что ему огромное спасибо. Более корректной реализации метода God-Mode не встречал.

Изменено пользователем 123new (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
Забронировать это рекламное место


mastaZz проверь)) По сути годмод в чистом смысле мод-костыль, взятый из сборки админки от DaOne, его корректность в разных ситуациях еще изучать надо, и не известно как оно работать после обновы будет еще. Но зомбики вроде как не убивают, на большем проверить не мог.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

123new там смысл в восстановлении ущерба, это еще до даона сделали и я делал

 

 

Изменено пользователем BorizzK (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

BorizzK угу, иного варианта пока не придумано. Просто вынес это добро отдельно, дабы не прыгали желающие по темам в просьбах 'как вытащить из такой то сборке это то'. Ну и маленько скрипт переработал-подправил по своим соображениям.

Изменено пользователем 123new (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

У меня на сервере с большим онлайном ,давольно большие проблемы , иногда крашми сервер.

Как-то можно с оттуда достать год мод , и сделать обычную оповещалку ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Sancezz063 откуда достать? сборка DaOne? А не проще просто готовый гайд использовать, а не заниматься извлечением того же самого из чужой сборки?

Изменено пользователем 123new (история изменений)

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

123new Я говорю достать оповещалку в заданном радиусе, так-как этот год мод при большом количестве игроков крашит сервер. Вот я и говорю из данной сейв зоны достать оповещалку в заданном радиусе.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Sancezz063 то что в гайде у меня пишется в mpmissions - и есть оповещался. Сам обработчик годмода в pbo как мод серверу зашит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

123new хочу вставить твою сейф зону в иник вот этой админки https://github.com/Malotruu/DayZ-0.63-Malotru

но выдает ошибку.

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

123new удаляю весь этот блок и все работает. на что это влияет 

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

belenkiy2 tick sheduler - операция, выполняемая для каждого игрока постоянно, пока он играет. т.е. обновление статы персонажа и т.п. Ну если не ошибаюсь, конечно, я сам не эксперт.
Над имеющимся у тебя блоком tick sheduler добавь

bool Activate_SafeZone_PlugIn = true; // safezone on (true) or off (false)

и уже в нем (в самом блоке tick sheduler) после

if(m_currentPlayer >= m_Players.Count() )
            {
                m_currentPlayer = 0;
            }
PlayerBase player = PlayerBase.Cast(m_Players.Get(m_currentPlayer));

добавь

if (Activate_SafeZone_PlugIn) { SafeZone_PlugIn.CheckingPosition(player); } //Check if player is near safezone

тогда проблема с твоего скриншота отпадет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
1 час назад, 123new сказал:

belenkiy2 tick sheduler - операция, выполняемая для каждого игрока постоянно, пока он играет. т.е. обновление статы персонажа и т.п. Ну если не ошибаюсь, конечно, я сам не эксперт.
Над имеющимся у тебя блоком tick sheduler добавь

bool Activate_SafeZone_PlugIn = true; // safezone on (true) or off (false)

и уже в нем (в самом блоке tick sheduler) после

if(m_currentPlayer >= m_Players.Count() )
            {
                m_currentPlayer = 0;
            }
PlayerBase player = PlayerBase.Cast(m_Players.Get(m_currentPlayer));

добавь

if (Activate_SafeZone_PlugIn) { SafeZone_PlugIn.CheckingPosition(player); } //Check if player is near safezone

тогда проблема с твоего скриншота отпадет.

У тебя получается вот так вот 

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

belenkiy2 тогда сотри ту что мою добавлял

bool Activate_SafeZone_PlugIn = true; // safezone on (true) or off (false)

видимо она в твоей сборке уже есть и называется также

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах
6 часов назад, 123new сказал:

belenkiy2 тогда сотри ту что мою добавлял

bool Activate_SafeZone_PlugIn = true; // safezone on (true) or off (false)

видимо она в твоей сборке уже есть и называется также

 

17 часов назад, belenkiy2 сказал:

123new хочу вставить твою сейф зону в иник вот этой админки https://github.com/Malotruu/DayZ-0.63-Malotru

но выдает ошибку.

Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

та же ошибка 

Поделиться сообщением


Ссылка на сообщение
Поделиться на других сайтах

Создайте аккаунт или войдите в него для комментирования

Вы должны быть пользователем, чтобы оставить комментарий

Создать аккаунт

Зарегистрируйтесь для получения аккаунта. Это просто!


Зарегистрировать аккаунт

Войти

Уже зарегистрированы? Войдите здесь.


Войти сейчас

  • Похожие публикации

    • Автор: 123new
      Нам понадобится:
      1. Сервер DayZ Standalone (см. тему вот эту)
      2. Notepad++: бесплатно на оф. сайте
      3. Немного времени и настойчивости (обычно бывает в комплекте и так)
       
      И так, начинаем:
      1. Открываем блокнотом mpmissions\dayzOffline.chernarusplus\init.c
      P.S. Имя папки dayzOffline.chernarusplus у вас может отличаться, будьте внимательны
      2. В начале файла добавляем:
      static int time_repeat_info_players = 10; //in seconds static string file_name_info_players = "$profile:PlayersLogFile.txt"; static void WriteFile(string file_name, string text) { private FileHandle fhandle; if ( !FileExist(file_name) ) { fhandle = OpenFile(file_name, FileMode.WRITE); } else { fhandle = OpenFile(file_name, FileMode.APPEND); } if ( fhandle == 0 ) { Print("[#Запись_в_файл]: Не удалось открыть файл для записи: " + file_name); Print("[#Запись_в_файл]: [Запись]: " + text); return; } FPrintln(fhandle, text); CloseFile(fhandle); } static void WritePlayersInfo() { array<Man> players = new array<Man>; Man player; Man player_test; GetGame().GetPlayers( players ); if (players.Count() > 0) { if ( FileExist(file_name_info_players) ) { DeleteFile(file_name_info_players); } for ( int i = 0; i < players.Count(); ++i ) { player_test = players.Get(i); if( player_test ) { PlayerIdentity p_identity = player_test.GetIdentity(); private string coord_pl = player_test.GetPosition().ToString(); private string Name_P = p_identity.GetName(); private string UID_P = p_identity.GetPlainId(); WriteFile(file_name_info_players, "User name: " + Name_P + " UID: " + UID_P + " Coords: " + coord_pl); } } } else { if ( FileExist(file_name_info_players) ) { DeleteFile(file_name_info_players); } } } Где 'PlayersLogFile.txt' меняем на нужное вам имя файла, а в 'time_repeat_info_players' настраиваем время повтора проверки списка игроков для перезаписи файла
      3. Находим в файле блок 'void main()' и в его конце перед закрывающей '}', поумолчанию это строка
      weather.SetWindFunctionParams(0.1, 0.3, 50); добавляем ниже строку:
      GetGame().GetCallQueue(CALL_CATEGORY_GAMEPLAY).CallLater(WritePlayersInfo, (time_repeat_info_players * 1000), true); 4. Готово, если не допустили ошибок, при наличии хотя бы 1 игрока на сервере ваш файл с данными по игрокам будет присутствовать и заполняться информацией, а в случае их отсутствия удаляться.
    • Автор: 123new
      В данной теме я распишу возможность создания серверного мода для сервера на свобственном примере и объясню как его собрать.Работающий на момент публикации статьи на версии сервера игры 1.4.152050.
       
      Нам понадобятся:
      1. Сервер игры актуальной версии, не ниже патча 1.04. Как установить можно узнать тут:
      До версии 1.04 параметра servermod у сервера игры не существовало!!!
      2. Программа 'PBO manager' с состава инструментария армы из сети: https://www.armaholic.com/page.php?id=16369
      Зеркало: https://yadi.sk/d/_gmzoNSDpNJTt
      Еще зеркало:
      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.

      4. Notepad++ https://notepad-plus-plus.org/download P.S. Вместо 'PBO manager' можно использовать DayZ Tools, но как им пользоваться разбираемся сами ;)
       
      И так, приступим:
      1. Предположим, что у нас имеется свой некий набор скриптов, который необходимо добавить серверу, но не на уровне миссии сервера, а на более ранних уровнях его загрузки. Например, добавить свой killfeed, модифицировать или изменить какой-либо из родных скриптов сервера игры, либо вовсе модификации, подключенной у вас.
      Для примера в этой теме и данного гайда я взял вот этот набор скриптов, собранный непосредственно для данной темы за 5 минут, и не изменяющий в сервере ровным счетом ничего. Он может послужить базой для создания своих модов, функций, переменных или классов. Данный гайд будем описывать, исходя из этого архива.
      Архив:
      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
      2. Создаем папку с нашим модом. Для примера, это будет папка '@My_Server_Mod'. В созданной нами папке создаем папку 'Addons', а в ней папку 'My_Server_Mod'.
      3. Помещаем содержимое распакованного архива в папку 'My_Server_Mod'. Должно получиться так:

      4. В папке 'My_Server_Mod' создаем файлик 'config.cpp' и заполняем его следующими данными (советую использовать Notepad++ для этого):
      class CfgPatches // требуется обязательно { class My_Server_Mod // требуется обязательно, совпадает с именем мода { units[]={}; // may be not worked weapons[]={}; // may be not worked requiredVersion=0.1; // may be not worked requiredAddons[]={}; /* requiredAddons[]= { "DZ_Data", // Перечисляем требуемые и используемые модом аддоны (pbo-файлы игры и модов по их внутренним скриптовым именам) }; */ }; }; class CfgMods // // требуется обязательно, совпадает с именем мода { // https://community.bistudio.com/wiki/DayZ:Modding_Structure#Mod_presentation class My_Server_Mod { dir = "My_Server_Mod"; // Имя папки мода, совпадает с именем мода picture = ""; // Картинка в описании мода action = ""; // Ссылка, например вот так: action = "https://dayz.com/"; hideName = 1; // Не уверен, что этот параметр работает hidePicture = 1; // Не уверен, что этот параметр работает name = "My_Server_Mod"; // Имя мода (а также его внутреннее скриптовое имя) logoSmall = "Mods/TestMod/modlogosmall.tga"; // значок рядом с именем мода, если описание не развернуто logo = "Mods/TestMod/modlogo.tga"; // логотип под меню игры logoOver = "Mods/TestMod/modlogohover.tga"; // при наведении курсора мыши на логотип tooltip = "tooltip"; // подсказка при наведении курсора мыши overview = "My Server Mod"; // Описание credits = "123new"; // credits author = "123new"; // author authorID = "0"; // author steam ID version = "1.0"; // version extra = 0; // Не уверен, что этот параметр работает type = "mod"; // требуется обязательно, остается неизменным // inputs = "mods\testmod\inputs\my_new_inputs.xml"; // необязательно, при использовании пользовательских inputs dependencies[]={"Core","GameLib","Game","World","Mission"}; // необязательно, если необходимо установить зависимость класса class defs { class engineScriptModule { value=""; // если значение пустое, используется функция ввода по умолчанию files[]={"My_Server_Mod/scripts/1_Core"}; // вы можете добавить любое количество файлов или каталогов, и они будут скомпилированы вместе с оригинальными скриптами игрового модуля }; class gameLibScriptModule { value=""; files[]={"My_Server_Mod/scripts/2_GameLib"}; }; class gameScriptModule { //value="CreateGameMod"; // когда значение заполнено, имя функции ввода модуля скрипта по умолчанию перезаписывается им value = ""; files[]={"My_Server_Mod/scripts/3_Game"}; }; class worldScriptModule { value=""; files[]={"My_Server_Mod/scripts/4_World"}; }; class missionScriptModule { value=""; files[]={"My_Server_Mod/scripts/5_Mission"}; }; }; // Если какой-то из разделов скриптинга вам не нужен и вы не сибираетесь его паковать, сотрите необходимый блок с ним выше и в массиве dependencies }; }; Пояснения в файле оставил. Файл готовый:
      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
      Как видите, в 'deffs' названия классов и путей соответствуют родным из 'scripts.pbo', но с допиской имени мода. Имя мода в данном случае и есть идентификатор для обращения к своему моду извне. А в 'dependencies' перечисляются используемые классы оригинальных скриптов без дописки номера секции. Количество используемых 'dependencies' и блоков 'deffs' должно быть идентично.
      Пояснения есть также и в официальной документации от разработчика: https://community.bistudio.com/wiki/DayZ:Modding_Structure#Mod_presentation
      5. Запаковываем нашу папку 'My_Server_Mod' в pbo-файл 'My_Server_Mod.pbo' через 'PBO manager', как на скриншоте ниже:

      Можно использовать и другие способы запаковки, если знаете их или привычны вам.
      6. Добавляем в параметры запуска сервера параметр:
      "[email protected]_Server_Mod;" -FilePatching 7. Радуемся, наш серверный мод готов. Пример готового серверного мода:
      Пожалуйста, Войдите или Зарегистрируйтесь, чтобы увидеть это: Вложение.
      P.S. Создавать bikey файл для мода и bisign подписи для него не требуется, иначе это может привести к неработоспособности серверной модификации (возможно, недоработка сервера игры разработчиком)
       
      Отмечу сразу, что данный способ подходит для модификации и переписывания оригинальных классов скриптов сервера от разработчиков и модификации чужих модов с помощью моддинга, применяется исключительно на стороне сервера игры и клиент игры не затрагивает. Распространять такой мод игрокам НЕ НУЖНО!
      Изменение оригинальных скриптов, для которых не предусмотрена операция 'modded class' в движке игры, а также классов и функций, которые защищены языком и движком игры от такого рода действий через серверные моды не получится. Если вы столкнулись с этим, вам проще распаковать scripts.pbo и поместить папку scripts в корень сервера игры, добавить в параметры запуска сервера параметр -FilePatching и изменять напрямую в папке необходимые вам файлы. (правда из-за ошибки разработчиков на патче 1.04 данный метод не работает корректно)
       
      P.P.S. Процедура создания своего собственного клиент-серверного мода на основе скриптов работает таким же образом. В случае создания такого мода, файл 'config.cpp' может быть для стандартного мода более разнообразным, а также после требуется обязательная подпись такого мода в bisign и создание bikey файлов. Более подробно это освещать требуется отдельно!
    • Автор: 123new
      Собственно, в шапке темы написано все. Давайте в этой теме обсуждать вопрос создания 'нормальной' (привычной для всех, в том числе и для редактирования) базы данных персонажей сервера. Возможно, даже с возможностью мультисерверной работы (что крайне лишним не было бы).