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

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

    Пользуйтесь услугами гаранта
    Мы сделаем вашу сделку безопасной
  • Не хотите БАН?

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

    Там вы можете продать или купить
    Всё что касается игровых серверов
  • 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

 

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


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


  • 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 Даж тут Богемия изобрела неведомую фигню

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

 

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


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

Присоединяйтесь к обсуждению

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

Гость
Ответить на вопрос...

×   Вставлено в виде отформатированного текста.   Восстановить форматирование

  Разрешено не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отобразить как ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставить изображения напрямую. Загрузите или вставьте изображения по ссылке.

Загрузка...

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

    • Автор: BorizzK
      Предлагаю все возможные гайды по enscript/моддингу публиковать в этой теме
      Ссылка на предыдущею версию темы по enscript версии 0.62 - там можно прочитать в общих чертах про этот язык
       
×
×
  • Создать...