Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • Нужна помощь?

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

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

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

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

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

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

Share this post


Link to post
Share on other sites

9 answers to this question

Recommended Posts

  • 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

 

Share this post


Link to post
Share on other sites



  • 0

ctx.Read( data);

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

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

 

Всеж просто

 

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

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

Share this post


Link to post
Share on other sites
  • 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-й раз не читаются.
Вот сижу и думаю, то ли я дурак и очевидного не понимаю, то ли игра кривая. Сам то тоже не шибко знаю с-подобные языки и их структуру

Share this post


Link to post
Share on other sites
  • 0

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

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

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

Share this post


Link to post
Share on other sites
  • 0

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

Share this post


Link to post
Share on other sites
  • 0

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

Share this post


Link to post
Share on other sites
  • 0

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

Share this post


Link to post
Share on other sites
  • 0

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

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

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

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

Important Information

By using this site, you automaticly agree to our Guidelines and Privacy Policy.
We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.