Перейти к контенту

Скриптование


Svoboда

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

@AndreySol, не нужно оправдывать по сути чепуху(!). Если ты коллбэком на выход в онлайн ставишь требуемое значение состояния предмета, тем самым ПЕРЕКРЫВАЯ любые ранее заданные значения для серверного объекта, то на кой заморочка с нет-пакетами?!  :crazy:

Твоя оправдалка может относиться только к случаю, когда ты тот же артефакт спавнишь куда-то на другую локацию, и он конечно же не выйдет в онлайн в текущей игре, а при переходе на его локацию - состояние будет "заводским"... Ну так и нужно различать, что если спавнишь предмет на текущей локации - то изменять нужно (можно) коллбэком на спавн, а если нет - то net-пакетами.

Также, допускают ошибку, когда сначало спавнят предмет, например в то же инвентарь, а через некоторое время, а не сразу же в цикле спавна, net-пакетом пытаются изменить параметр(ы)... естественно, пока предмет не уйдет в оффлайн и не вернется в онлайн (вот он сэйв-лоад!) - то ничего не меняется.

Ну и, есть конечно некоторые параметры у некоторых предметов (например у КПК), которые требуют особого подхода, но тут уж именно только нет-пакетами и спавн не в инвентарь, а с последующим трансфером...

 

В общем, в данном случае с противогазами актора нет никакого смысла в дублировании net-пакетами!

 

@Akella-96 aka SvD, кратко про амк-таймеры помянул выше. Расписывать неизвестный мне  скрипт 'awrp_cop' не имею возможности и желания.

По оригиналному скрипту от амк - воспользуйся поиском по многочисленным ресурсам в сети по моддингу. А еще лучше - замени на нормальные таймеры...

А вообще, скрипт (script) - это сценарий, в котором все и описано, и тебе нужно бы почитать мануалы по Lua, чтобы читать и понимать то, что в скрипт кто-то когда-то написал и как это нужно/можно применять (раз уж используешь не свое).

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@AndreySol, если искать себе искуственные заморочки - то их всегда можно найти!  :crazy:

Вот только зачем их искать и навешивать шоры себе же и другим?

Раз спавним актору в рюкзак, то и используем простейшее:

local sobj = alife():create("af_medusa", vector(), 0, 0, db.actor:id())
local func_callback = function(item_cond, id, obj) obj:set_condition(item_cond) end
level.client_spawn_manager():add(sobj.id, db.actor:id(), func_callback, 0.55)

 - открываем и видим покоцанную медузу...
Ну а для твоей заморочки могу посоветовать - а подумай ка и ответь, а твой артефакт вообще то вышел в онлайн в полном смысле? Тебя не смущает то, что предмет, попав сразу же в рюкзак, так и не был полностью "увиден" игрою?! Вот и не переданы параметры от серверного клиентскому.
Или можно отправить твоего перса (раз это не актор), вместе со всем своим хабаром в оффлайн и обратно - и будет смена состояния предмета.
Ну а если актор и если уж хочешь заморачиваться с нет-пакетами, то спавни рядом с актором и транфери предмет по тому же коллбэку выхода в онлайн, без set_condition - и получишь то же самое!
Суть: не нужно пытаться микроскопом забивать гвозди, когда для этого имеется молоток.
 
Ну а по "работает с CoP" - это ясно из контекста, но таймеры - они и в африке таймеры. ;-)
Изменено пользователем Artos
  • Нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Saruman, а с чего ты решил что "но помоему sid не задается", Если ты не покорежил функции net-пакетов, то все прекрасно задается.

И, при установке SID'а в момент спавна объекта не требуются манипуляции с off-on-лайнами, т.е. значение заданное параметру доступно сразу (для клиентского объекта - по выходу его в онлайн).

 

Только особенность проверки свеже-добавленного SIDa в базе движка имеет нюанс и не стОит использовать alife():story_object(SID) до перезапуска игры или манипуляций с off-on-лайнами.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Saruman, следует все же различать собственно  наличие сида у объекта и наличие этого сида в базе алайфа  (в игре).

По заданию сида объекту - выше уже все сказано и никаких непоняток или "не задается" не существует. А вот попадание в базу алайфа, чтобы по требуемому сиду можно было бы проверить наличие объекта с этим сидом в игре - это уже без перезапуска игры (или без правки движка) не получится. Не помогут и манипуляции с отправками в оффлайн и обратно. Т.е. или сразу спавни свой объект через алл.спавн, задав ему требуемый сид, или не ориентируй свои скрипты на проверку сида без перезагрузки игры.

Вообще, немало и других способов "искать" требуемый объект в игре... чем тебе (для ТЧ) тот же поиск заспавненного объекта по имени не подходит alife():object("my_obj_name") ? Может и не так "красив" как по сиду, но не менее эффективен и дает тот же результат. ;-)

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Stalkersof, мусорил бы ты "по теме", т.е. в топике по ковыряниям ТЧ... и заглянул бы в топик "Справочник по функциям и классам", дабы не гадать как нужно вызывать ту иль иную функцию.

Для ТЧ пространство 'relation_registry' сильно ограничено и доступно только семейство функций "community_goodwill", которые оперируют именем группировки и идентификатором персоналии, относительно которого и работают. Ну а изменять в игре отношения целых группировок - это тебе не ЧН/ЗП...

И если "изменяешь" что-то, то чтобы говорить об изменениях или их отсутствии - приводят все же нечто, с чем можно сравнивать.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение
но это теория.

Ни к теории, ни к практике это не имеет никакого отношения! Это пустые погадалки на кофейной гуще.  :crazy: , как будто-то от "перемены мест" изменится сумма...

Не пора ли завязывать с подобными "советами", не имеющими никакого отношения ни к скриптам, ни к программированию?! Почему бы самим "советчикам" не опробовать на своей шкуре, потратив свое время, а не писать в публичный топик, засоряя и топик и мозги...

 

Про формулу уже писалось (тут):

Загляни в этот файл. config/creatures/game_relations.ltx Там в комментах разрабы написали полную формулу и там же все таблички, по которым вычисляются части этой формулы.

Изменено пользователем Artos
  • Не нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Dennis_Chikin, ответ может быть относительно простым: а) уборщик мусора в Lua ассинхронен и б) "клиентский объект" - объект движка, а коллбэки, о которых ты упоминаешь, это методы/свойства иного объекта - объекта биндера (это уже Lua, т.е. дочерний от "клиентского"). Т.о. если программист движка, который писал коды для обработчиков коллбэков, не озаботился синхронизацией с порожденными Lua-объектами, то ... "Хочешь чтобы не воняло - спускай в туалете за собою, не дожидаясь что это сделает уборщица."

Можно и более пространно порассуждать, но тут уже потребуется каждый коллбэк (его алгоритм) рассматривать по-отдельности, и... что-то можно отнести к рудиментам, а что-то потребует долгих рассуждений и пояснений, но никак не может быть отнесено к рудиментам. Иными словами, даже однократного срабатывания "ненужного/забытого" коллбэка может быть достаточно для фатальной ошибки (вылета).

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Zander_driver, в исходном скрипте (se_stor.script) уже заложен вывод информации о кол-ве элементов хранения (cnt_elm):

 log("Save Storehouse: size(%d)=[%d], ...", cnt_elm, cnt_bytes, ...

поэтому не стОит дублировать одно и то же...

 

Ну а по сути сообщения, то (ИМХО):

1. Конечно можно вслепую уменьшить полезный объем каждого элемента хранилища и успокоиться, если не возникнет в игре ошибок... Однако, если не ясна причина возникновения ошибки, то никто не гарантирует, что при некотором изменении в игре, ошибка все же не возникнет. Исправлять нужно причину. а не пытаться подстраиваться под ситуацию. А вот для этого ты поленился даже строки лога об ошибке указать.

2. Уверен, что если тебе приходится сохранять "строки по 90-130 байт ... порядка нескольких тысяч штук." - то с оптимизацией в твоем моде явно нелады. В сэйве обычно хранят эксклюзивную информацию, которая характеризует именно текущее состояние в игре, а не абы все и вся, что зачем-то захотелось записывать.

  • Нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Dennis_Chikin, просто у @Zander_driver'а  некорректно построенна фраза.

Вероятно данные в исходной таблице имели структуру вложенных таблиц. Объем данных в таблице таков, что в сумме превышает (или может) ~8 кБ ,

и поэтому исходная таблица по-элементно переводилась в строки... (каждая субтаблица в свою строку), чтобы запоминать по частям.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@sapsan, скрипт хранилища позволяет сохранять и табличные типы данных (и др.), но(!) если кол-во (кило)байт после перевода таблици в строку (и даже с компрессией) превысит 8 кБ - то скрипт не будет автоматом разрезать эту таблицу на куски, а ругнется в лог и пропустит эту таблицу.

Т.о. если у модмейкера есть подозрения, что его таблица не влезет в один stor-элемент, то именно ему требуется озаботиться либо разбиением таблицы на несколько (что я бы рекомендовал), либо самому разбивать свою большую таблицу на нужные ему куски и их сохранять.

 

"Удобства использования" все же имеют границы, за пределами которых начинаются неудобства.  :crazy:  Вот тут и нужно вспоминать про оптимизацию... и выбирать критерии.

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Dennis_Chikin, что-то ты брякнул, что и мне сложновато понять...  :crazy:

Во-первых, скрипт хранилища как раз и выполняет все "непосредственно в save_all/load_all".

Во-вторых, полностью согласен, что в пакете актора по сути то хранить можно "копейки", но как раз в рассматриваемом случае потребно целую "кучу" где-то, но сохранять.


@sapsan, тебе же уже не раз написано, что исходная таблица в данном случае содержит такое кол-во данных, что при переводе в строку (сериализации) кол-во байт строки превышает 8 кБ. А это уже не просто "удобства", а ограничение движка игры!

Т.о. если хочешь использовать "удобное хранение" - потрудись не превышать размер строки в 8 кБ или же сохраняй/дроби сам как тебе вздумается.

 

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

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Dennis_Chikin, ты "тихо сам с собою" иль как?  :crazy:

Исходное сообщение Zander_driver'а о том, что при сохранении большой таблицы у него со скриптом se_stor.script возникает ошибка переполнения.

Способы конвертирования таблицы в строку (иль иной тип данных) давным давно известны, применяются и в данном случае не рассматриваются (пока).

Ты спросил: "Зачем переводить в строку", на что дан ответ: "Чтобы разрезать таблицу на части, т.к. строка всей таблицы превышает допустимый размер!".

Ну и что же ты с чем собрался скрещивать, предлагая очередной (с ошибками и сильно ограниченный) вариант сериализации "аля xStream" при тех же самых 8-ми кило на пакет?!   :crazy:

 

 

 

Где это написано ?

Автор исходного сообщения пишет об одной таблице, мною (в ответ на заданный вопрос о переводе в строки) дано пояснение (единственно возможное в данной ситуации)...

Оставляю вас далее строить свои домысли и погадалки... Вот только что и кому вы пытаетесь показать иль объяснить?  :wub:

 

P.S. Вот только троллить, переходя на личности, не стОит... Теперь просто вас начну игнорировать.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение
Неужели я неясно выразился.

Как можно видеть из возникших вопросов - недостаточно ясно..., а точнее для любителей шарад или гаданий.

@Zander_driver, какова цель твоего исходного поста #5414?

Сообщить о возможной ситуации, когда в скрипте (неизвестном для многих) у тебя возникает ошибка? А кому, кроме тебя иль меня это интересно? Да и для меня, без технической информации, это просто пустой оффтопик, а тебе ".. было лень  :) поэтому просто уменьшил предельный размер пакета..".

Даже на мой ответ и фразу о необходимости хотя бы лога(!), ты продолжаешь пустые предполагалки и "если так уж необходим, могу воспроизвести,...".

Судя по твоим описаниям, действительно ошибка может происходить из-за некорректного определения границы объема пакета, однако без конкретных строк лога и/или твоего кода не вижу возможности найти причину и исправить. Вслепую снижать границу для мнимого исчезновения вероятности ошибки(?) - уже писал, что не считаю это правильным вариантом (тем более на моих кодах ошибка не проявляется).

 

Ну а по оптимизации, не стОит из меня делать Кашпировского... Я все же не экстрасенс и не любитель гадать на кофейной гуще, чтобы по куцым и завуалированным фразам в личке строить догадки и тем более соображать зачем это кому-то.

Ну а пока мне все же непонятны такие "тысячи записей из строк" - остаюсь прежнего мнения о  не оптимальности  принятых для сохранения данных. Что-то не верится, что эти несколько тысяч записей возникают в следствии игры и именно эксклюзивны, а не воспроизводимы вновь. (ну да это как говорится: "хозяин барин")

 

 

 

Полагаю ошибка где то в алгоритме "когда надо переключаться на следующий объект".

Хм, судя по описаниям, ошибка НЕ в алгоритме, а в конкретном числе для границы пакета. Если это так, то я бы предпочел перепроверить и определить причину, чтобы установить безопасную границу, а не гадать в слепую...

 

P.S. Кстати, ты так и не ответил на заданный вопрос:

[q]Условия возникновения: имея кучу всяких данных в таблице, которые хотелось бы сохранить, перевожу таблицу в строку.[/q] Кстати, а зачем ?

 

 

...

и, просто предположение, не из-за "ручного" ли перевода возникает проблема?

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

 

 

Про ошибки хочу подробностей.

Хотеть не вредно, но лучше их попросить...  :crazy:

После того как посмотрел топик по разработкам в солянке, стал понятен твой интерес к этой теме. Ошибки бывают (и у тебя присутствуют) различного типа:

1. Ошибка применения необъявленной переменной: в строке 

else abort( "pstor_save_all, not registered type: %s, k: %s", t, k, _util.to_str( npc ) ) 

используется необъявленная переменная (t вместо p), что приведет к потере информации в функции прерывания игры о причине предыдущей ошибки.

2. Ошибочно предлагать "простейшую модификацию оригинала" для использования типа данных "userdata" при том, что не оговоривается обязательность наличия в таких данных неких v.classname и v:save, коих в оригинальных объектах в игре практически не встречается или имеются только в классах типа биндеров. 

Подобное без ограничений применения просто напросто будет вызывать ошибки при попытках модмейкеров сохранить, например, вектор позиции иль гейм-таймер (CTime) иль подобное..., а с ограничением - см.фразу о "сильно ограничивает".

3. Можно и далее продолжить разбор "простейшей модификации", но не вижу пока надобности, т.к. имеются более продвинутые варианты записи различных данных в сэйв(ы). Если есть желание сравнить и порассуждать - нет проблем, но тогда тебе придется ознакомиться с уже имеющимися вариантами (хотя бы с тем, о котором речь в исходном посте).

 

 

 

 

А модифицируется это в дальнейшем, если бы оно было зачем-то надо, просто тупо проверкой размера нетпакета после записи очередной переменной, и если больше максимально разрешенного размера - создаем другое хранилище, и продолжаем писать уже в него.
Именно "тупо"! К твоему сведению если ты в нет-пакет что-то записал, то что-то проверять после записи уже поздно будет... т.к. если переполнение, то придется уже "выкидывать" этот нет-пакет и все перезаписывать заново. Именно на этом этапе и пишет про ошибку Zander_driver, и именно тут имеется некая неопределенность: то ли выбранная граница максимума для записи велика, то ли имеется ошибка перевода в строки и их запись в сэйв...

 

По "преобразованию таблиц в строки" нам пока рано (иль поздно) говорить.

1. Моя позиция проста: "Любая таблица для записи в сэйв НЕ должна превышать 8 кБ! Если превышает - модмейкер должен заранее позаботиться о разделении на приемлемые части." Именно на этом основан алгоритм скрипта общего хранилища, т.е. любые строки/таблицы более 8 кБ просто игнорируются с сообщением об этом в лог.

Если  тебе или кому-то хочется на лету делить автоматом строки/таблицы и распределять по разным объектам с последующими слияниями - нет проблем, пишите свои варианты (с string.sub() иль иным).  ;)

2. Варианты сериализации и даже с компрессией давно уже есть и никакого чудовищного оверхеда не наблюдается. Если организовать данные и писать их в сэйв с умом(!) то даже при записи чисел строками можно выиграть в объемах! Но все конечно зависит от контента и огульно все сваливать в кучу - ошибочно!

Кстати, это еще один тип ошибки (не оптимальность) в твоем варианте записи pstor'ов.

 

 

 

 

Но поскольку это происходит уже не в скрипте - это будет всяко быстрее.
Позвольте поинтересоваться: "не в скрипте" - это где? где это будет быстрее и по какой такой причине?  :crazy:

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Zander_driver, никто и не гонит и не требует сразу же реагировать на реплики, как и вообще писать посты без необходимой информации. 

Нужны логИ, по строкам которых можно было бы понять причину сбоя/ошибки.

Если по какой-то причине сбой именно из-за "переполнения", то нужен лог записи, в котором были бы указаны объемы записи в каждый элемент и соответственно строки лога чтения из этих элементов из сэйва. В скрипте вывод этой информации предусмотрен.

Так же, нет подозрений на превышение какой-то отдельной строки более чем 8 кБ, а есть подозрение, что или сама строка после "ручного" перевода своей таблички оказалась "странной" или еще какой-то неясный сбой при сохранении цепочки строк (пересечение имен, недопустимые символы в именах, ...)

В общем не гадать нужно, а анализировать информацию (которая отсутствует)!

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Zander_driver, все же по-аккуратнее и по-понятнее стОит формулировать вопросы/посты.

1. Нет в оригинальных играх серии Сталкера объектов с сидами 'smartterrain', а есть для 'smart_terrain' (clsid.smart_terrain). Этот же сид регистрируется и в class_registrator.script.

2. Как можно сменить то, чего нет? Нет для смарт-террейнов такого понятия 'комьюнити'. Имеется возможность задать параметр 'accepted_communities' - табличку в которой перечислены допустимые/разрешенные для гулага группировки.

Можно было бы net-пакетами менять в кастомдате значения для этого параметра, но... пока нет стабильных вариантов для этого класса.

Но не сложно в игре в нужное время менять эту табличку (accepted_communities) по своему разумению, естественно дополнительно написав свои изменяющие функции.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Zander_driver, и вновь очень неаккуратно излагаешь...

В алл.спавне задается параметр 'communities', который относится к гулагу для этого смарттерейна и который как раз и считывается в 'accepted_communities'.

В net-пакете этот параметр, как уже выше указал, нужно искать в кастомдате, и конечно же под тем же именем (communities), который и указан в алл.спавне.

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

@Zander_driver, зачем же свои предполагалки мне приписывать? С самого начало было сказано:

 

Имеется возможность задать параметр 'accepted_communities' - табличку в которой перечислены допустимые/разрешенные для гулага группировки.

- т.е. было сказано, что этот параметр может быть добавлен к серверному объекту смарттерейна. А про нет-пакет, как и про кастом-дату, говорилось именно о 'communities'.

И как раз(!), этот параметр ('accepted_communities'), отсутствующий у движкового объекта(!), объявляется из параметра 'communities', берущегося скриптом из кастомдаты объекта (т.е. может быть прочитан и нет-пакетом). Т.о. ответ на твой вопрос "как изменить" уже и был дан ранее...

Примечание: Прямое изменение параметра 'obj.accepted_communities' конечно возможно, но(!) будет действовать только на текущей локации, т.е. после перезапуска игры все вернется к значению 'communities' из кастомдаты(net-пакета).

Изменено пользователем Artos

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение

Информация в контексте вопроса о максимальном объеме net-пакета (см. #5412 и далее):

(по некоторым причинам... излагать приходится несколько косноязычно... но вроде как достаточно понятно ;) )

Имеется значение NET_PacketSizeLimit = 8192; //16384

Т.е. для ТЧ (SHoC) размер net-пакета должен быть не более 8192 байт, а для ЧН/ЗП соответственно 16384, однако(!) допустимые значения меньше объявленных/указанных. Это обусловлено тем, что для "склеивания в сэйв" - при обработке net-пакетов каждого игрового объекта для включения его данных в общий сэйв используются аналогичные функции имеющие те же ограничения и расходуются доп.байты...

Эмпирическим путем определено, что расходуется порядка 512 байт (или менее). Т.о. при расчете допустимых размеров для элементов универсальных хранилищ (и вообще как ограничение для всех других объектов) следует использовать следующие значения:

 

SHoC: NET_PacketSizeLimit = 8192 - 512 = 7680 bytes

CS|CoP: NET_PacketSizeLimit = 2x8192 - 512 = 15872 bytes

 

 

Примечание: Признаком переполнения net-пакета(ов) является зависание или фатальное прерывание игры на стадии записи сэйва игры. При этом лог-файл пуст(!), т.е. в лог-файле отсутствует какая-либо информация. В продвинутых способах записи в лог последней строкою будет упоминание о начале сохранений '* Saving objects':

$ DBG: se_stor:save_storehouse: size(1)=[7951]+[0]

$ DBG: se_stor:save_storehouse: size(2)=[7976]+[7951]

$ DBG: se_stor:save_storehouse: size(3)=[7967]+[15927]
...

$ DBG: se_stor:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

$ DBG: se_stor:Save Storehouse: size(5)=[31442], keys=[1882] 
$ DBG: se_stor:~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Saving spawns...
* Saving objects...

 

 

 

а вот дебаг-движок игры дополнительно к выше указанной записи ругнулся бы фатальной ошибкою:

FATAL ERROR

[error]Expression    : assertion failed
[error]Function      : NET_Packet::w
[error]File          : ../../xrNetServer/net_utils.h
[error]Line          : 47
[error]Description   : B.count + count < NET_PacketSizeLimit

 

 

Резюме: При необходимости контролируйте максимальный размер записанного в net-пакеты игровых объектов по указанным выше значениям.

 

В скрипте se_stor.script можно изменить так:

--/#!# лимит (bytes) на один stor-объект (мах.длина строк)
local MAX_PACKET_LENGHT = 8192 - 512 --/ for SHoC
if iSSVer > 7 then MAX_PACKET_LENGHT = MAX_PACKET_LENGHT + 8192 end --/ for CS&CoP!

 

 

Изменено пользователем Artos
  • Нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение
То есть, если трогать, то надо разбираться, как же оно все-таки работает, и зачем ?

Если захотелось трогать, то нужно разбираться не столь с "как работает", а "как должно работать", т.е. что же скрипт (заложенный в него алгоритм) должен выполнять с заданной ему строкою в конфиге...

Функция 'parse_syn_data' в цикле должна разбивать строку по маске-символу '|' и из первой ее части (подстроки) брать данные о звуке для статуса, разбивая подстроку по маске-символу '@'. И т.о. все что после '|?' (если имеется) - откладывается для разбора в следующем подцикле итерации по строке...

 

если он по ошибке таки получит что-нибудь, реально начинающееся на | ?

Вот и должен конфигер писать в конфиге для логики не абы-что, а то, что требуется и должно быть прочитано и "понято" скриптом! Т.е. чтобы начиналось не просто с "реального", а с реально значимого.

function parse_data(oNPC,sStr)
  local tRet = {}
  if sStr and sStr ~= '' then
    local sField,sDist,sState,sSound,tDat
    for sField in sStr:gmatch("(%|*%d+%|[^%|]+)%p*") do
      sDist,sState,sSound = sField:match('^%s*([^| ]+)%|*([^|@ ]*)@*(%S*)')
      if not (tonumber(sDist) and sState) or sState == '' then
        log("parse_data:NPC=[%s],dist=[%s]=[%s][%s]:f[%s]:<%s>", oNPC and oNPC:name(), sDist, sState, sSound, sField, "Info") --/#~#
      end
      tDat = {dist = tonumber(sDist)}
      if sState then
        if sState ~= '' then
          tDat.state = xr_logic.parse_condlist(oNPC, sDist, sState, sState)
        else
          tDat.state = {}
        end
      end
      if sSound and sSound ~= '' then
        tDat.sound = xr_logic.parse_condlist(oNPC, sDist, sSound, sSound)
      end
      table.insert(tRet, tDat)
    end
  end
--  log("parse_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~#
  --table.print(tRet,"parse_data|"..(oNPC and oNPC:name()) or '') --/#~#
  return tRet --/>
end

function parse_zone_data(oNPC,sStr)
  local tRet = {}
  if sStr and sStr ~= '' then
    local sField,sZone,sState,sSound,tDat
    for sField in sStr:gmatch("(%|*[^%|]+%|[^%|]+)%p*") do
      sZone,sState,sSound = sField:match('^%s*([^| ]+)%|*([^|@ ]*)@*(%S*)')
      if not (sZone and sState) or sState == '' then
        log("parse_zone_data:NPC=[%s]<~zone=[%s]=[%s][%s]:f[%s]:<%s>", oNPC and oNPC:name(), sZone, sState, sSound, sField, "Info") --/#~#
      end
      tDat = {zone = sZone}
      if sState then
        if sState ~= '' then
          tDat.state = xr_logic.parse_condlist(oNPC, sDist, sState, sState)
        else
          tDat.state = {}
        end
      end
      if sSound and sSound ~= '' then
        tDat.sound = xr_logic.parse_condlist(oNPC, sZone, sSound, sSound)
      end
      table.insert(tRet, tDat)
    end
  end
--  log("parse_zone_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~#
  --table.print(tRet,"parse_zone_data|"..(oNPC and oNPC:name()) or '') --/#~#
  return tRet --/>
end

function parse_syn_data(oNPC,sStr)
  local tRet = {}
  if sStr and sStr ~= '' then
    local sField,sState,sSound
    for sField in sStr:gmatch("(%|*[^%|]+%|*)%p*") do
      sState,sSound = sField:match('^%s*([^@| ]+)@*([^@| ]*).*')
      if not sState or sState == '' then
        log("parse_data:NPC=[%s],st[%s],snd[%s]:f[%s]:<%s>", oNPC and oNPC:name(), sState, sSound, sField, "Info") --/#~#
      end
      if sState and sState == '' then sState = nil end
      if sSound and sSound == '' then sSound = nil end
      table.insert( tRet, {state = sState, sound = sSound} )
    end
  end
--  log("parse_syn_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~#
  --table.print(tRet,"parse_syn_data|"..(oNPC and oNPC:name()) or '') --/#~#
  return tRet --/>
end
function parse_data(oNPC,sStr)
  local tRet = {}
  if sStr and sStr ~= '' then
    local sField,sDist,sState,sSound,tDat
    for sField in sStr:gmatch("(%|*%d+%|[^%|]+)%p*") do
      sDist,sState,sSound = sField:match('^%s*([^| ]+)%|*([^|@ ]*)@*(%S*)')
      if not (tonumber(sDist) and sState) or sState == '' then
        log("parse_data:NPC=[%s],dist=[%s]=[%s][%s]:f[%s]:<%s>", oNPC and oNPC:name(), sDist, sState, sSound, sField, "Info") --/#~#
      end
      tDat = {dist = tonumber(sDist)}
      if sState then
        if sState ~= '' then
          tDat.state = xr_logic.parse_condlist(oNPC, sDist, sState, sState)
        else
          tDat.state = {}
        end
      end
      if sSound and sSound ~= '' then
        tDat.sound = xr_logic.parse_condlist(oNPC, sDist, sSound, sSound)
      end
      table.insert(tRet, tDat)
    end
  end
--  log("parse_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~#
  --table.print(tRet,"parse_data|"..(oNPC and oNPC:name()) or '') --/#~#
  return tRet --/>
end

function parse_zone_data(oNPC,sStr)
  local tRet = {}
  if sStr and sStr ~= '' then
    local sField,sZone,sState,sSound,tDat
    for sField in sStr:gmatch("(%|*[^%|]+%|[^%|]+)%p*") do
      sZone,sState,sSound = sField:match('^%s*([^| ]+)%|*([^|@ ]*)@*(%S*)')
      if not (sZone and sState) or sState == '' then
        log("parse_zone_data:NPC=[%s]<~zone=[%s]=[%s][%s]:f[%s]:<%s>", oNPC and oNPC:name(), sZone, sState, sSound, sField, "Info") --/#~#
      end
      tDat = {zone = sZone}
      if sState then
        if sState ~= '' then
          tDat.state = xr_logic.parse_condlist(oNPC, sDist, sState, sState)
        else
          tDat.state = {}
        end
      end
      if sSound and sSound ~= '' then
        tDat.sound = xr_logic.parse_condlist(oNPC, sZone, sSound, sSound)
      end
      table.insert(tRet, tDat)
    end
  end
--  log("parse_zone_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~#
  --table.print(tRet,"parse_zone_data|"..(oNPC and oNPC:name()) or '') --/#~#
  return tRet --/>
end

function parse_syn_data(oNPC,sStr)
  local tRet = {}
  if sStr and sStr ~= '' then
    local sField,sState,sSound
    for sField in sStr:gmatch("(%|*[^%|]+%|*)%p*") do
      sState,sSound = sField:match('^%s*([^@| ]+)@*([^@| ]*).*')
      if not sState or sState == '' then
        log("parse_data:NPC=[%s],st[%s],snd[%s]:f[%s]:<%s>", oNPC and oNPC:name(), sState, sSound, sField, "Info") --/#~#
      end
      if sState and sState == '' then sState = nil end
      if sSound and sSound == '' then sSound = nil end
      table.insert( tRet, {state = sState, sound = sSound} )
    end
  end
--  log("parse_syn_data:NPC=[%s],Str=[%s]%s", oNPC and oNPC:name(), sStr, '') --/#~#
  --table.print(tRet,"parse_syn_data|"..(oNPC and oNPC:name()) or '') --/#~#
  return tRet --/>
end
 

 

 

Изменено пользователем Artos
  • Нравится 1

"Но иногда найдется вдруг чудак, этот чудак все сделает не так ..."© Машина времени

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


Ссылка на сообщение
  • Недавно просматривали   0 пользователей

    • Ни один зарегистрированный пользователь не просматривает эту страницу.
×
×
  • Создать...