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

Справочник по функциям и классам


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

malandrinus

ИМХО, посты-толковалки типа Desertir приносят больше вреда, чем пользы.

Кроме перечисления и 'типа, чего-то, но не проверял и наверное ...' по сути тавтология.

К примеру:

InitStatic(string, CUIWindow*); --одна из самых распространенных функций, название говорит само за себя
- ну очень "внятно" для тех, кто может даже и может перевести 'static', но ни к чему применить понять это понятие не знает. :-(

 

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

 

CScriptXmlInit() - класс-конструктор (как всегда доступен в виде глобальной функции). Предназначен для создания окон на базе xml-файлов. Ресультатом функции является объект-заготовка ('userdata').

 

ParseFile(string) --/ метод, распарсивающий (разбирающий) исходный xml-файл (string) в объект класса, что позволяет к полученным элементам объекта применять различные методы.

Элементы результирующего объекта получают названия/имена соответствующие тэгам разобранного xml-файла и все дальнейшие методы применяются к элементам с соответствующими 'тэговыми' именами.

Различные параметры (координаты, расцветка,тексты,шрифты,...), заданные тэгами xml-файла наследуются соответствующими элементами при их инициализации методами класса.

 

InitStatic(string, CUIWindow*) --/ метод, создающий обычную (статичную) область. Параметром является название (стринг) тэга из xml-файла. Применяется, например, для организации различных строк текста/заголовков, отображения текстур/картинок/иконок.

 

InitButton(string, CUIWindow*) --/ метод, создающий область обычной 'кнопки', имещую одно визуальное состояние, т.е. вид кнопки не изменяем.

 

Init3tButton(string, CUIWindow*) --/ метод, создающий область обычной кнопки, имеющую три визуальных состояния (не активна, в фокусе, нажата).

 

InitCheck(string, CUIWindow*) --/ метод, создающий область 'чек-бокс' (кнопка-галочка). Может принимать два фиксированных состояния: отмечена/не отмечена.

 

InitTab(string, CUIWindow*) --/ метод, создающий область (табулятор), которая объединяет несколько вложенных областей. Применяется для создания окна с закладками.

 

InitList(string, CUIWindow*) --/ метод, создающий область (листинг), в котором организуется список из строк, являющихся интерактивными элементами. При большом кол-ве элементов (превышающем размеры выделенной области листинга) используется совместно с методом InitScrollView, отображающем полосу прокрутки (скроллинг).

...

и т.д.

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

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

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


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

Desertir

Мой пост не преследует цель 'покритиковать', она совершенно иная.

Этот топик все же имеет название "Справочник ..." и предназначен и для для опытных (но забывчивых) и начинающих модмейкеров.

Твоя 'проба пера' вполне была бы уместна в топиках по ковыряниям в кодах ..., но никак не в справочном топике, по которому многие сверяют свои познания и набираются знаний/навыков.

В тему вспоминается басня Крылова, когда слепые изучали наощупь слона и у каждого он был то лопухом/колонной/змеей/..., в зависимости от того, что и как ощупывал слепец (ухо/ногу/хвост/...). Если на базе их описаний попытаться составить мнение о 'что-же такое слон', но картина выходит далекой от реалии.

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

Все же иногда лучше не 'начинать' подобным образом и будет 'Ничего', чем ложное/пустое ... (ИМХО). Самостоятелная попытка познать неизвестное в подобных случаях скорее принесет бОльшую пользу, чем трата времени на чтение и попытку понять пустое/искаженное толкование.

 

Бум надеяться, что у malandrinus'а появится время, возможность и желание свести подобные посты в нечто достойное 'Справочника'. :-)

Для меня, это основой топик, из-за которого заглядываю на портал.

 

 

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

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

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


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

malandrinus

Т.к. топик, по моему мнению, все же не подразумевает полемику, да и сам ты пишешь о 'смеси стола заказов и отделения ковырялки', вероятно не стОит затевать обмен мнениями. Но все же пару моментов прокомментирую.

 

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

Наиболее удобной (ИМХО) формой подобного топика было бы его разделение на два: собственно справочник с готовыми и статьями/разделами и топик с черновиками, вопросами, пояснениями-трактовками, полемикой, ...

 

2.

В сущности, это самый правильный способ создания окон. При желании можно всегда скриптов изменить нужные динамические характеристики окна. Полностью же скриптовое создание окон используется модостроителями почти всегда только лишь по причине незнания возможностей XML.
Не считаю себя знатоком всех возможностей XML, но все же чего-то знаю. Тем не менее, последнее время стал предпочитать именно вариант 'без XML'.

'Правильность' - понятие все же относительное, тем более в подобном вопросе (какой метод правильнее применять). Можно назвать немало ситуаций, когда применение скриптового метода будет 'не менее, и даже более правильным'. :-)

Мало кто уделяет дизайну должное внимание но ... если принять во внимание, что метод XML расчитан в основном на разрешение 4:3, и еще позволяется 16:10 дублированием уже имеющегося, то для немало уже появившихся ноутбучных экранов с их 16:9, 15x9 или 5x4 применение XML метода становится похоже на "взять болванку и обработать топором и рашпилем".

 

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

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

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


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

abramcumner

Все же стОит снимать шоры и не считать свое мнение самым правильным ....

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

Ну а дизайнер - именно риcует, а LTX/XML и пр. подобное - удел кодеров. Или у нас уже дизайнеры освоили XML-форматы и русуют ими? ;-)

 

Проблема с разными разрешениями при работе с хмл надуманная. В работе с хмл нет завязки на разрешение 4:3

Действительно нет ... вот только все исходные XML'ки (все значения параметров) заточены под именно это разрешение и 'широкоформатникам' часто приходится играть на том, что дизайнер нарисовал, а у кодера руки дошли ... Адаптации модов под 'широкоформатники' (точнее их отсутствие) - пример тому, что модмейкеры в одну из последних очередей вспоминают о 'инако-форматниках'.

Не проще ли порой, не штамповать кучку XML'ек, а в самом скрипте динамически подстроить именно так, как нарисовал дизайнер? Иль ты считаешь, что на 1024x768 (это те же 4:3) задуманное будет тем же, что и на 1600x1200, хотя бы с выбором шрифтов?

 

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

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

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


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

Kirag

Хотел бы обратить внимание на критичный недостаток:

В кодах xml-фвйлов, как оригинала так и модмейкеров, нередко встречается использование табуляторов вместо пробелов.

Т.о. чистка (замена на пустой символ '') всех табуляторов в строке прочитанного файла будет приводить к ошибочному чтению наименований тэгов ...

Например, если в тэге встретится тэг <font font="letterica18" />, в котором между 'font' 'font' будет использован табулятор (иль несколько), то в игре парсер движка прочтет этот тэг правильно, а твой парсер получит 'fontfont' в качестве тэга, потеряв параметр(ы).

 

Оптимальнее этот код (строки 22,23,24 в parse_xml.script):

str_del = string.gsub(str_del,'\013',"")

str_del = string.gsub(str_del,'\010',"")

str_del = string.gsub(str_del,'\009',"")

 

заменить на:

str_del = string.gsub(str_del,'[\013|\010]','') --/ чистка/замена переносов по маске (оба за один проход)

str_del = string.gsub(str_del,'\009+',' ') --/ замена одиночных (или групп) табуляторов на одиночный пробел ('\032')

 

или даже так:

str_del = string.gsub(str_del,'[\013|\010|\009+]','\032') --/ замена переносов/табуляторов по маске (все за один проход) на одиночный пробел

str_del = string.gsub(str_del,'\032+','\032') --/ замена групп пробелов на одиночный пробел (далее меньше по-символьных итераций)

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

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

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


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

Kirag

Осмелюсь все же предложить использовать вариант:

 

str_del = string.gsub(str_del,'[\013|\010|\009+]','\032') --/ замена(!) переносов и табуляторов по шаблонам (за один проход) на одиночный пробел

str_del = string.gsub(str_del,'\032\032+','\032') --/ (опционально) замена групп пробелов на одиночный пробел (далее меньше по-символьных итераций)

 

т.к. исключает даже такие возможные извраты написания тэгов, как:

<hud_fps x="1005" y="05" width="5" height="20">

<text

x="0" y="0" font="graffiti19" r="255" g="255" b="50" a="255" align="l"/>

</hud_fps>

 

В таком случае нынешний вариант даст табличку для этого тэга:

hud_fps.textx="0".y = 0

hud_fps.textx="0".font = graffiti19

hud_fps.textx="0".a = 255

hud_fps.textx="0".r = 255

hud_fps.textx="0".g = 255

hud_fps.textx="0".b = 50

hud_fps.textx="0".align = l

 

- т.е. исказив наименование тега (text -> textx="0"), потеряв параметр 'x' из-за удаленного переноса строки (а в игре это не приводит к ошибкам).

 

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

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

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


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

Gun12

Предложенный тобою вариант имеет значительные недостатки:

1. Цель кода, который ты предлагаешь оптимизировать, не только в получении имени тэга (открывающей части), а и в получении индекса строки со значением окончания найденого имени тэга (name_end). Это значение используется и для поиска следующей части этого тэга (закрывающей, если конечно она должна присутствовать) и для 'начала отсчета' для параметров тэга, которые идут следом за названием.

2. Не обрабатываются ситуации, когда тэг состоит только из названия, например: <window> или <text/>, т.к. шаблон не обрабатывает символы '>' и '/', и которые ошибочно включаются в имя тэга.

 

---

KOKC, чисто скриптового варианта для организации 'переноса' длинных строк, превышающих ширину выделенную для строки, к сожалению не существует.

 

Вот вариант резки по 10 чимволов:

local lerf_str = str or "" --/ присваиваем 'остатку' всю длину строки (или пустышку)
local max_size = 10 --/ режем по 10

while lerf_str:len() > 0 do --/ есть еще что резеть/печатать?
  get_console():execute("load ~~~ " .. lerf_str:sub(1,max_size) ) --/ печать первых 10-ти
  get_console():execute("flush")
  lerf_str = lerf_str:sub(max_size+1) --/ отсекаем напечатанное
end

 

Примечание: Вместо 'lerf_str:len()' можно использовать '#lerf_str', и при выводе на печать не обязательно применять 'tostring', т.к. строка не может быть ничем другим при подобных операциях (пустой символ - тоже строка).

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

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

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


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

Kirag

Не очень понятна конечная цель твоего поста.

Понять 'имеется ли некое ограничение' и есть ли более правильный вариант для 'твоего' способа чтения содержимого файла, чем ты пытаешься применить?

Или найти вариант чтения файлов, который даст приемлемые с точки зрения 'стабильности' применительно к классу FS?

 

На первое, могу только предполагать, что вероятно не зря сами разработчики игры, в версиях ЧН и ЗП ввели уже нормальное пространство 'io' для работы с файлами.

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

Ведь ни что не мешает скопировать любой файл (из пак-файла иль с виртуального диска) в удобное место и уже работать с ним. Т.о. работа с заведомо присутствующим файлом уже не имеет указанных тобою 'странностей и нестабильностей'.

По окончании - времянку можно и удалить, дабы не оставлять мусора. Используя этот вариант с промежуточным копированием, пока ни разу не замечал сбоев.

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

 

abramcumner

А откуда такая информация о чтении только до символа '/0' ? Может быть до '\000'?

Но ведь очевидно, что и суть вопроса и данный метод предназначен для конфиг-файлов (*.ltx, *.xml, и иже), а не для чтения иконок,текстур и пр. 'бинарников'. Читать в числовой массив дабы распарсивать по-битно далее - более ресурсоемко (ИМХО).

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

 

Примечание: Прошу куратора топика не рассматривать данный пост как оффтопик и продолжение темы о парсере. По сути это уточнение особенностей использования класса FS.

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

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

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


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

malandrinus

Исходные данные вопроса: Автор вопроса Kirag привел достаточно однозначный пример применяемой им функции:

- само название говорит о работе именно с текстовыми файлами типа LTX;

- конкретно указана папка ($game_config$), что говорит о работе с текстовыми конфиг-файлами;

- им применен именно метод r_stringZ.

 

Вопрос касается нестабильности работы с файлами остающимися в запакованном виде в пак-файлах *.db*, при попытке чтения которых фозникают фатальные ошибки.

Автор вопроса указал, что каких-либо затруднений чтения файлов указанным методом при условии их распаковки на физический диск не испытывает.

Мною также замечена данная особенность/ограничение, хотя далеко не всегда. При всевозможных вариациях применения данного метода (r_stringZ) с ограничением размера считываемых файлов никаких проблем. Для обхода 'ограничения' при работе с 'запакованными' файлами мною предложен вариант копирования копии файла (по сути распаковка), что дает возможность применять авторскую функцию с незначительной доработкой и требуемой стабильностью.

Причем замечу(!), я НЕ советую использовать, а только защищаю возможность применения метода 'r_stringZ', которую использовал Kirag, проверенную на практике в достаточно различных ситуациях игры и достаточным временем.

 

Ваше замечание о предназначении класса FS принципиально для бинарников - достаточно голословно. Можно получить/почитать аргументы/обоснования?

Но в любом случае - иного штатного метода работы с любыми файлами в игре (ТЧ) нет.

То, что строки в текстовых файлах разделяются спец.знаками ('\013','\010') - не относится к сути. В вопросе говорится о чтении всего содержимого файла в стринг, с последующим его построчным иль иным разбором и пр. - автор указал: 'дальше чищу от хлама, не суть'.

Ваши с abramcumner'ом высказывания по сути именно советуют отказаться от использования 'r_stringZ' и применять иной метод, который требует гораздо большей доработки и более ресурсоемок. Не оспариваю, читать по-байтно файл - это классика.

Но(!) Вы уверены в корректности своих советов относительно именно запакованных файлов? Не останется ли 'ограничение'?

 

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

 

 

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

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

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


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

 

malandrinus

А как объяснить(?) такой факт с позиции применяемых методов:

- пробуем читать из корня конфиг-папки (gamedata\config\...) запакованные файлы - ошибок нет.

- пробуем прочитать методом 'r_stringZ' например файл из пак-файла по пути: gamedata\config\misc\zone_kampfire.ltx - ошибка.

- разархивируем этот файл и кладем в соотв. папку на диске - файл читается и распарсивается без проблем.

- читаем запакованный исходный файл вариантом:

  local sStr = ''
  for i=1,iSize do --/ iSize - длина файла (size_real)
    sStr = sStr .. string.char( r:r_u8() )
  end

- ошибка отсутствует и файл корректно парсится далее.

В принципе, последний вариант вполне применим и для Kirag'a, если не критична по-байтная итерация для получаемого стринга ...

Ну а предпоследний - читаем мой первый пост по вопросу (о временной копии на диск).

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

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

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


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

malandrinus

К сожалению все же не получил ответа на поставленные вопросы (например: о применимости именно к запакованным файлам любых методов 'r_'). :-(

 

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

1. 'Об обязательности наличия нуль-терминатора'

malandrinus: Метод r_stringZ своим названием говорит, что читается с-строка или иначе строка с нулевым терминатором.

Предлагаю иную трактовку:

Метод 'r_stringZ' предначен для чтения байт-последовательности до первого обнаруженного нуль-терминатора (zero). Результатом является последовательность символов кодировка которых соответствует прочитанным байтам.

- Название метода 'r_stringZ' говорит о чтении некоего байт-массива в строку (не путать с текст-строкою!), т.е. возвращает значение прочитанных байтов в формате type == "string";

- вероятно(!), окончание 'Z' можно трактовать как сокращение от 'Zero', намекающее на чтение последовательности байт до символа NULL (нуль-терминатора) ИЛИ до 'отсутствия' байта (zero);

- однозначно, что последовательность байт считывается до нуль-терминатора и результат возвращается в 'строковом' формате.

- никакого намека на какие-либо ограничения чтения байт-массива и/или неконвертации считаных байт не имеется.

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

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

 

Итак в фразе:

malandrinus: Это однозначно и безо всяких исключений означает, что в конце этой строки стоит нулевой байт

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

 

2. 'О недопустимости применения метода 'r_stringZ' к текстовым файлам'

Нигде в исходном вопросе и моих пояснениях не упоминается о чтении текстовых файлов в текстовую строку.

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

Однако(!), речь идет о получении данным методом стринга прочитанного файла, т.е. сырой(!) последовательности символов, включая и переносы и пр. 'мусор'.

По сути, как я понял, и для Kirag'a и для меня требуется при прочтении файла это (упрощенно):

  local ltx = fs:exist("$game_config$", filename) --/< имя файла
  local size = ltx.size_real --/ размер файла
  local r = fs:r_open(ltx.name) --/ 'читалка' (объект/линк на файл)
  local str = '' --/ заготовка для 'сырого' стринга
  for i=1,size do --/ 'читаем' от начала и до конца файла
    local sym = r:r_u8() --/ прочитанный байт
    if sym > 0 then --/ нуль-терминатор?
      sStr = sStr .. string.char( sym ) --/ добавляем к стрингу
    else
      break --/ прерываем чтение по NULL
    end
  end
  return str --/> на выходе сырая последовательность прочитанных символов

- т.е. то, что и дает применение штатного метода 'r_stringZ'.

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

 

3. И последнее, о чем уже не раз повторяю, суть вопроса НЕ в применимости метода, а в том, что ТОЛЬКО с нерасспакованными файлами происходит сбой.

Т.к. природа сбоя непонятна, то (ИМХО) ни что не гарантирует наличия аналогичных сбоев и для других методов (того же r_u8()).

 

Пока же могу только предположить, что упомянутый тут в суе 'CreateFileMapping' и работа с созданной виртуальной областью запакованных файлов имеет некие особенности. Для гарантированной работы - стОит заморачиваться с распакованными копиями, если это не накладно для игры ...

 

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

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

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


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

malandrinus

Спасибо за 'дебаты' и Ваши 'трактовки'. :-)

К сожалению, не имея исходников методов мы можем говорить только о 'трактовках', проводя аналогии с известными и доступными исходниками из языковой классики.

За себя (что-то автор вопроса не проявляет активности) могу только констатировать: тема на сегодня для меня исчерпана. Будем подстраиваться под то, что имеем и в том виде как понимаем.

:-)

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

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


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

malandrinus

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

И к сожалению, тот же 'утиный' тест нами также трактуется по-разному и то, что 'вижу' я, тобою (не)видится иначе.

 

Т.к. все же люблю поковыряться в поисках ответа, проведу еще несколько тестов.

Пока в свете упомянутого тобою 'утиного' теста предлагаю все же не то что НЕ видно пояснить, а то что видно (плавает и крякает):

Выше уже приводил практические результаты чтения для взятого 'на бум' файла 'gamedata\config\misc\zone_kampfire.ltx'.

Итак, что же видим при применении метода 'r_stringZ':

- будучи на диске - файл читаем в стринг. Никаких намеков на ошибки нет даже в тредах (внешний перехватчик);

- будучи в пак-файле исходном(!) - чтение оканчивается ошибкой.

- будучи упакованным в дополнительный пак-файл - чтение заканчивается успехом.

 

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

Даже перепаковка в другой пак-файл - не прерывает кряканья утки.

 

Остается последний тест, который позволит достаточно приблизиться к искомому ответу или отсечь 'вину' метода:

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

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

Если же подправленный файл НЕ будет прочитан - Ваши заключения ошибочны. и 'крякание' утки оозначает именно крякание, а не то, что аналогично крякает и где-то называется манком. :-)

 

Добавлено через 10 мин.:

Kirag

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

Для меня пока остался единственный вопрос, касающийся 'конца файла'.

Если все же в метод 'r_stringZ' заложена проверка окончания файла - то какова природа сбоя именно на запакованных файлах. Причем сбой зависит от 'в какой запакован' и вероятно от пути (в корне или в подпапке).

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

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

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

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


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

malandrinus,

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

 

Возможно это и стенка, но предпочитаю все же проверить, хотя бы и собственным лбом/носом, а не 'холст' ли это в каморке папы Карло?

:crazy:

 

Добавлено через 5 мин.:

Kirag

У меня и комп позволяет и познания/навыки имеются для копаний в любых файлах/архивах иль на дисках/блинах. В пак-файлах сами файлы ничем(!) не отделены. Используется (условно) таблица с указанием начального адреса для чтени и размер. Никаких добавочных нуль-терминаторов нет.

Все (ИМХО) сводится к реализации виртуального пространства, куда игра "распаковывает" и дает доступ. К сожалению это движок и тут только предполагалки доступны.

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

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

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


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

malandrinus

Последний тест подтвердил корректность работы метода 'r_stringZ' при наличии в запакованных текстовых файлах нуль-терминатора.

Суть теста: в исходном пак-файле хекс-редактором в соответствующем месте текстового файла вместо, например символов комментария, устанавливался нуль-терминатор, что не изменяло ни формата пак-файла ни других иных параметров.

Т.о. Ваше утверждение о недопустимости применения данного метода для запакованных файлов - верно.

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

Примечание: При распаковке и обратной запаковке (утилитой 'converter.exe') ошибка чтения исходного файла все же отсутствовала, что говорит о зависимости от формата упаковки пак-файла.

 

Добавлено через 102 мин.:

P.S. В качестве бонуса для не имеющих достаточных навыков в скриптах:

--/ на входе: имя файла для прочтения в стринг (и опционально: кол-во считываемых байт)

function Read_FileToString( filename, max_size ) --/ чтение файла в стринг ('сырую' строку)
  local fs = getFS()
  local file = fs:exist("$game_config$", filename) --/ файл-объект в папке конфиг-файлов
  if file then --/ имеется ли заданный файл?
    local str = '' --/ заготовка для 'сырого' стринга
    if not max_size then max_size = 32768 end --/ если не задан ограничитель объема чтения
    if file.size_real < max_size then --/ размер файла не превышает допустимого?
      local reader = fs:r_open(file.name) --/ 'читалка' (объект/линк на файл)
      if reader then --/ условие возможности чтения
        reader:r_seek(0) --/ устанавливаем на 'начало' файла
        --/ последовательное по-байтовое считывание содержимого файла
        local byte = reader:r_u8() --/считываем 1-й байт
        while byte > 0 do --/ если не нуль-терминатор (NULL == 0x00)
          str = str .. string.char(byte) --/ конвертируем и добавляем к стрингу
          if reader:r_eof() then --/ если конец файла
            byte = 0 --/ приравниваем к нуль-терминатору
          else --/ считываем след.байт
            byte = reader:r_u8()
          end
        end
      end
    end
    --/ на выходе функции: 'сырая' последовательность прочитанных символов
    return str
  end
  return nil
end

Вариант с применением чтения в массив (плавающими r_u64 ... r_u8) с последующими 'unpack' и char(...) проигрывает по быстродействию и ресурсам.

 

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

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

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


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

P.S. В выше указаном варианте функции чтения, для модмейкеров, которые допускают наличие 'пустых' файлов в игре, можно внести доп.проверку на нулевую длину файла:

if file.size_real > 0  and file.size_real < max_size then --/ размер файла не 0 и не превышает допустимого?

В этом случае исключается возврат случайного символа для пустого файла.

 

(считаю тему затронутую Kirag'ом исчерпаной, 'бонус' дан для примера возможной реализации)

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

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

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


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

_Призрак_

Если уточняешь/дополняешь - стОит более тщательно применять слова:

а) Вызов функции коллбэка происходит НЕ при переходе в оффлайн, а при переходе объекта в онлайн.

б) Не только кол-во аргументов (3 иль 4) критично, а значение 4-го аргумента не 'nil'.

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

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

local function spawn_callback(user_data, id, obj)
  ...
end

если же 'user_data' не используется, то вид отрабатываемой функции должен иметь вид:

local function spawn_callback( id, obj)
  ...
end

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

 

Иными словами: Если при установке коллбэка применяется 4-ый аргумент ('user_data') - его значение должно быть проверено и выбрана функция коллбэка с соответствуюшим кол-вом и порядком входных аргументов.

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

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


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

singapur22, Gun12

А я бы осмелился посоветовать подобные разборки/ковырялки в скриптах/классах/методах/функциях проводить в рабочих топиках типа "Скриптование, ...", откуда позже уже проверенные и важные материалы вносить в "Справочник ...".

А излишки/издержки - можно будет подчищать и в рабочем топике.

ИМХО. ;)

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

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

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


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

*Shoker*

ИМХО, скрипт 'отлова' ... сыроват.

Уже говорил, что при смене режима стрельбы на подствольник - будет врать.

При смене типа патронов (<Y>) - так же будет врать, если кол-во нового типа будет меньше.

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

... и т.п.

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

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


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

*Shoker*, зря ты вместо топиков по ковыряниям в скриптах стал "увековечивать" в топике-справочнике ...

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

Модуль нет-пакетов, использованный тобою, полностью рабочий для ТЧ/ЧН/ЗП.

Параметр 'updgrenade_mode', о котором ты срашиваешь, никуда не делся с 2008 года. Он относится к оружию, которое имеет подствольник или возможность его установки. Как раз этот параметр мог бы помочь еще более оптимизировать скорость, т.к. и оружие не класса 'cse_alife_item_weapon_magazined_w_gl' или с параметром не равным 1 (подствольник штатно не установлен) и т.п. - можно не проверять на подствольные заряды.

Чтобы получать параметры типа 'upd' (UPDATE_Read|UPDATE_Write) - требуется вызывать с флагом 'true':

local p = sm_net_utils.Get_Data_Weapon(sobj,true) --/ полный пакет

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

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

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


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

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

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