Перейти к публикации
Поиск в
  • Дополнительно...
Искать результаты, содержащие...
Искать результаты в...
  • Нужна помощь?

    Создайте тему в соответствующем разделе
    Не нужно писать всё в чат!
  • Загляните на торговую площадку

    Там вы можете купить
    всё что касается игровых серверов
  • Не хотите бан?

    Пожалуйста, ознакомьтесь с нашими правилами
    Не нарушайте порядок!
  • Продаёте или покупаете?

    Пользуйтесь услугами гаранта
    Мы сделаем вашу сделку безопасной
  • 0
123new

ParamsReadContext и ctx.Read( data ) в Enscript Mods

Возник вопрос нового плана.

Есть в авторском моде функция

void GlobalChat(CallType type, ref ParamsReadContext ctx, ref PlayerIdentity sender, ref Object target)
	{
		Param2< string, string > data;
        if ( !ctx.Read( data ) ) return;

		if( type == CallType.Server )	
        {
			string name = sender.GetName();
			string steamid = sender.GetPlainId();
			string bisid = sender.GetId();
			string idtable = sender.GetPlayerId().ToString();
			string log_date_time = ExpansionGetDateTime();

			string format = "[" + log_date_time + "] " + "[Chat]" + " " + name + "(steamid=" + steamid + ", bisid=" + bisid + ") " + data.param2;

			GetGame().AdminLog(format);

			GetRPCManager().SendRPC( "DayZExpansion", "GlobalChatServer", new Param2< string, string >(data.param1, data.param2) );	
		}
	}

Пишу в своем моде, который должен на стороне своего сервера ее дополнять через изменение имеющегося класса:

override void GlobalChat(CallType type, ref ParamsReadContext ctx, ref PlayerIdentity sender, ref Object target)
	{
		Print("ctx " + ctx);
		ParamsReadContext ctx_tmp = ctx;
		super.GlobalChat(type, ctx, sender, target);
		MyLogsGlobalChat(type, ctx_tmp, sender, target);
	}
	
	void MyLogsGlobalChat(CallType type, ref ParamsReadContext ctx, ref PlayerIdentity sender, ref Object target)
	{
		Print("12345");
		Print("ctx2 " + ctx);
		Param2< string, string > data;
		Print("data " + data);
		
        if ( !ctx.Read( data ) ) return;
		
		Print("1112131415");
		Print("data.param1 " + data.param1);
		Print("data.param2 " + data.param2);
		if( type == CallType.Server )	
        {
			string name = sender.GetName();
			string steamid = sender.GetPlainId();
			string bisid = sender.GetId();
			string idtable = sender.GetPlayerId().ToString();
			string log_date_time = GetExpansionChatBase().ExpansionGetDateTime();

			string format = "[" + log_date_time + "] " + "[Chat]" + " " + name + "(steamid=" + steamid + ", bisid=" + bisid + ") " + data.param2;

			Print(format);
		} 
	}

В логах после data NULL соответственно ничего не вижу.

Если меняю местами

Param2< string, string > data;
		Print("data " + data);

и

super.GlobalChat(type, ctx, sender, target);

то ситуация обратная, то что мне надо выполняется, а сама оригинальная функция нет, т.к. ломается на таком же коде в оригинальной функции.

Долгими вычислениями и тестами дошло, что ломается операция на строке

if ( !ctx.Read( data ) ) return;

в моем моде, которая вместо считывания данных в переменную возвращает false, ну и работа кода прирывается.

Понять не могу какова причина такого действия. Может кто просвятить что это за функция такая и по какой причине один раз эта функция обрабатывается как надо, а второй отказывается, и как должно быть? В родных скриптах сервера так ничего и не нашел поясняющего.

Разумеется, передать в виде другой переменной значение в родную функцию не могу, т.к. мод оригинальный авторский.

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


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

Рекомендованные сообщения

  • 0

123new Это видел?

 

 \brief Initiate remote procedure call. When called on client, RPC is evaluated on server; When called on server, RPC is executed on all clients
	@param target object on which remote procedure is called, when NULL, RPC is evaluated by CGame as global
	@param rpc_type user defined identification of RPC
	@param params custom params array
	@param recipient specified client to send RPC to. If NULL, RPC will be send to all clients (specifying recipient increase security and decrease network traffic)
	@code
	const int RPC_LOW_BLOOD_PRESSURE_EFFECT = 0;
	...
	// on server side, after blood pressure of player is low...
	Param1<float> p = new Param1<float>(m_blood_pressure);
	array<param> params = new array<param>;
	params.Insert(p);
	GetGame().RPC(player, RPC_LOW_BLOOD_PRESSURE_EFFECT, params);
	// or shortcut
	GetGame().RPCSingleParam(player, RPC_LOW_BLOOD_PRESSURE_EFFECT, p);
	...
	// on client
	class PlayerBase
	{
		// override OnRPC function
		void OnRPC(PlayerIdentity sender, int rpc_type, ParamsReadContext ctx)
		{
			// dont forget to propagate this call trough class hierarchy!
			super.OnRPC(rpc_type, ctx);

			switch(rpc_type)
			{
				case RPC_LOW_BLOOD_PRESSURE_EFFECT:
					Param1<float> p = Param1<float>(0);
					if (ctx.Read(p))
					{
						float blood_pressure = p.param1;
						float effect_intensity = 1.0 - blood_pressure;
						ShowFancyScreenEffect(effect_intensity);
					}
				break;
			}
		}
	}
	@endcode

 

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


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

BorizzK не понял намека, где-то видимо туплю сильно

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


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

ctx.Read( data);

Вернет false если прочитать параметр в переменную не удалось

И true если удалось, и данные записались в переменную data

 

Всеж просто

 

А вот почему данные не всегда записываются

А vожет они и не передаются?

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


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

BorizzK ну это то я понял и так, мне вот любопытно почему первый раз при исполнении оно пишется, а второй раз нет. Да и что за переменная такая эта типа ParamsReadContext, функционала которой и описания я так и не нашел, кроме разве что родных примеров в скриптах богемии.
Причем не передаваться то не может, я эту переменную ParamsReadContext ctx проверил перед исполнением super.GlobalChat(type, ctx, sender, target); и после нее.
Оба раза она заполнена данными

SCRIPT       : ctx Serializer<89bcc0>
SCRIPT       : 12345
SCRIPT       : ctx2 Serializer<89bcc0>
SCRIPT       : data NULL
SCRIPT       : 0011: no data
override void GlobalChat(CallType type, ref ParamsReadContext ctx, ref PlayerIdentity sender, ref Object target)
	{
		Print("ctx " + ctx);
		super.GlobalChat(type, ctx, sender, target);
		MyLogsGlobalChat(type, ctx, sender, target);
	}
void MyLogsGlobalChat(CallType type, ParamsReadContext ctx, PlayerIdentity sender, Object target)
	{
		Print("12345");
		Print("ctx2 " + ctx);
		//Param2< string, string > data;
		Param2< string, string > data ;
		Print("data " + data);

		Param2<string, string> p1 = new Param2<string, string>("", "");
		if (ctx.Read(p1))
		{
		  Print("0: " + p1.param1);
		  Print("1: " + p1.param2);
		}
		else
		{
			Print("0011: " + "no data");
		}

        if ( !ctx.Read( data ) ) return;
		
		
		Print("1112131415");
		Print("data.param1 " + data.param1);
		Print("data.param2 " + data.param2);
		if( type == CallType.Server )	
        {
			string name = sender.GetName();
			string steamid = sender.GetPlainId();
			string bisid = sender.GetId();
			string idtable = sender.GetPlayerId().ToString();
			string log_date_time = GetExpansionChatBase().ExpansionGetDateTime();

			string format = "[" + log_date_time + "] " + "[Chat]" + " " + name + "(steamid=" + steamid + ", bisid=" + bisid + ") " + data.param2;

			Print(format);
		} 
	}

А вот в Data именно они 2-й раз не читаются.
Вот сижу и думаю, то ли я дурак и очевидного не понимаю, то ли игра кривая. Сам то тоже не шибко знаю с-подобные языки и их структуру

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


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

123new Си тут не при чем совершенно

Тут же не чистый си - тут все с прибабахом

Нужно логгировать и тестить-тестить-тестить

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


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

BorizzK да вот пытаюсь, пока прихожу к выводу что на строку ctx.Read( data ) все упирается в конечном итоге при 2-м выполнении

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


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

123new , всё достаточно просто. ctx в данном случае это serializer. Как только переменная этого типа считана через ctx.read, её содержимое обнуляется (сбрасывается указатель), поэтому дважды её считать не получится. Придётся костылить с разбором ctx на данные прямо в GlobalChat и совать в super.GlobalChat() новый указатель с копией данных, либо (что не есть хорошо) переписывать функцию целиком и обойтись без вызова super.GlobalChat()

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


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

Vaker а костылить с разбором как можно? есть примеры? Просто довольно сложно для понимания. Уже думал что можно его считать, и попытаться создать новый serializer, чтобы потом вогнать его в исходную функцию, но вот как...

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


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

Vaker Даж тут Богемия изобрела неведомую фигню

Ибо Сериализация и ДеСериализация это вообще как бы о другом (применительно к другим языкам)

 

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


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

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

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

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

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

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

Войти

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

Войти сейчас

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

    • Автор: Troy1
      Всем привет. Суть в чём, пишу мод на событие и когда происходит событие, параллельно должна меняться скорость ветра, не могу понять как заставить скрипт управлять силой ветра. Понижать силу ветра получилось сделать, а вот повышать не как. Только после перезагрузки сервера сила ветра задаётся в нужном значение.
      Как сделать, что бы по вызову функции менялась сила ветра в большую или в меньшую сторону?
      protected void SetWind(float wind, float time) { if (!g_Game) return; Weather m_Weather = g_Game.GetWeather(); if (!m_Weather) return; m_Weather.SetWindMaximumSpeed(wind); m_Weather.SetWind(Vector(1/Math.Sqrt(3), 1/Math.Sqrt(3), 1/Math.Sqrt(3)) * wind); m_Weather.SetWindSpeed(wind); m_Weather.SetWindFunctionParams(1.0, 1.0, -1); } Это скрипт на понижение силы ветра.
      Работает понижение силы ветра в том случае, если до этого сила ветра была выше.
      Пример:
      Изначально на сервере сила ветра = 20 m/s А нужно понизить до 10 m/s
      Только в этом случае сработает скрипт который я приложил выше.
      Помогите пожалуйста решить этот вопрос.
      За ранние благодарю.
    • Автор: Troy1
      Всем привет. Помогите пожалуйста со скриптом.
      Суть. Я пытаюсь сделать синхранизацию сервера с клиентом передавая c конфига время разделки животного.
      В родных скриптах есть class UATimeSpent с константами и там есть константа SKIN.
      Мне нужно её перезаписать на своё значение и мне выдаёт ошибку: Trying to modify write protected variable 'SKIN' в переводе на Русский Попытка изменить защищенную от записи переменную «SKIN».
      Функция скрипта: Когда игрок запускает клиент, идёт запрос на серверную часть и получает в ответ время разделки.
      Задача: Нужно перезаписать константу SKIN на новое значение и всё.
      Сам скрипт.
      class timeToComplete extends UATimeSpent { protected ref UATimeSpent m_UATimeSpent; void timeToComplete() { GetDayZGame().Event_OnRPC.Insert(OnRPC); CheckUATimeSpent(); } void ~timeToComplete() { GetDayZGame().Event_OnRPC.Remove(OnRPC); } void CheckUATimeSpent() { GetGame().RPCSingleParam(NULL, SOC_TIME_RPCs.SOC_GT, NULL, true); } void OnRPC(PlayerIdentity sender, Object target, int rpc_type, ParamsReadContext ctx) { if (rpc_type == SOC_TIME_RPCs.SOC_RT) { Param1<float> soc_srt; if (ctx.Read(soc_srt)) { if (soc_srt.param1!= 0) { m_UATimeSpent.SKIN = soc_srt.param1; Print("Пришёл ответ от сервера в m_UATimeSpent.SKIN - " + m_UATimeSpent.SKIN) } } } } };  
    • Автор: Troy1
      Всем привет. Подскжите ну или помогите пожалуйста решить вопрос.
      Вопрос звучит так. На сервере есть трейдер зоны и базы игроков. 
      Если в течение определённого времени, на пример 1 - 2 часа с машиной не кто не взаимодействует и машина не находится в зоне трейдера или на теретории базы, то машина отлетает в гараж или на штраф стоянку.
      На сервере используется TraderPlus.
       
      Есть такие решения у кого?
      За ранние благодарю.
    • Автор: Troy1
      Всем привет. Подскжите ну или помогите пожалуйста решить вопрос.
      Вопрос звучит так. Нужно сделать так, что бы на всей карте был запрет на строительство. 
      Если нужно построить например базу с палатками, то нужно установить верстак или флаг, который установит зону для строительства с радиусом примерно 20-25 метров от центра и желательно что бы зона была квадратной.
      Есть такие решения у кого?
      За ранние благодарю.
  • Наш выбор

×
×
  • Создать...

Важная информация

Используя этот сайт, вы автоматически обязуетесь соблюдать наши Правила и Политика конфиденциальности.
Чтобы сделать этот веб-сайт лучше, мы разместили cookies на вашем устройстве. Вы можете изменить свои настройки cookies, в противном случае мы будем считать, что вы согласны с этим.

Поддержка