Jump to content
Search In
  • More options...
Find results that contain...
Find results in...
  • Need help?

    Create a topic in the appropriate section
    Don't write everything in the chat!
  • Take a look at the marketplace

    There you can buy
    everything related to game servers
  • Don't want a ban?

    Please read our rules
    Don't disturb the order!
  • Sell or buy?

    Use services of the guarantor
    We will make your deal safe
  • 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 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) } } } } };  
    • By Troy1
      Всем привет. Подскжите ну или помогите пожалуйста решить вопрос.
      Вопрос звучит так. На сервере есть трейдер зоны и базы игроков. 
      Если в течение определённого времени, на пример 1 - 2 часа с машиной не кто не взаимодействует и машина не находится в зоне трейдера или на теретории базы, то машина отлетает в гараж или на штраф стоянку.
      На сервере используется TraderPlus.
       
      Есть такие решения у кого?
      За ранние благодарю.
    • By Troy1
      Всем привет. Подскжите ну или помогите пожалуйста решить вопрос.
      Вопрос звучит так. Нужно сделать так, что бы на всей карте был запрет на строительство. 
      Если нужно построить например базу с палатками, то нужно установить верстак или флаг, который установит зону для строительства с радиусом примерно 20-25 метров от центра и желательно что бы зона была квадратной.
      Есть такие решения у кого?
      За ранние благодарю.
    • By Troy1
      Всем доброго времени. У меня непонятно как появилась проблема с подключение к серверу с главного меню игры.
      При подключение с лаунчера, на сервер захожу без проблем.
      После нажатия на кнопку ESC находясь на сервере и нажимаю на кнопку выйти, меня перебрасывает в главное меню игры.
       
      Вот и сама проблема --> Когда я нажимаю кнопку играть, при подключение к серверу начинается отсчёт таймера, таймер зависает и игра крашится (Иногда краш игры до появления таймера).
      Пробовал переустанавливать сервер и клиент, отключать моды и всё вроде-бы нормально становилось, но стоит подключить моды которые требуют зависимость мода CF то проблема снова начинает проявляться.
      Моды которым не требуется зависимость мода CF с ними всё работает нормально и при повторном подключение игра не крашится.
      Пробовал на другие сервера заходить и пере подключаться с главного меню, всё нормально работает и игра не вылетает.
       
      Помогите ПЛЗ.
      За ранние благодарю.
    • By BorizzK
      Предлагаю все возможные гайды по enscript/моддингу публиковать в этой теме
      Ссылка на предыдущею версию темы по enscript версии 0.62 - там можно прочитать в общих чертах про этот язык
       
  • Our picks

×
×
  • 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.