Случайная подборка модов
Смерти Вопреки. Послушник
3.4
R.M.A. Atmospheric Addon 3.0
4.0
Call of Misery
4.1
«Последний Сталкер»
4.1
Пропавшая экспедиция
2.4
Sins of the past. Пролог
3.3
Последние обновленные темы Прямой эфир Самые популярные темы Последние новости
  • Страница 1 из 1
  • 1
Архив - только для чтения
"Способы вывода информации в лог-файл"
Российская Федерация  Rolan
Вторник, 23.11.2010, 22:55 | Сообщение # 1
Статус:
Отмычка:
Сообщений: 169
Награды: 2
Регистрация: 31.05.2010

Сразу оговорюсь, что вся информация ниже предназначена для ТЧ. В ЧН экспортировано пространство имён io и проблемы как-бы и нет вовсе.

Имеются экспортированные в Lua функции log(string), error_log(string) и flush(). И эти функции не работают! По крайней мере никому до сих пор не удалось заставить их работать в релизной версии движка.
Так что общепринятым способом является использование консоли. Известно, что всё, что пишется в консоль, пишется одновременно и в лог-файл. Файл этот находится в месте, определяемом переменной $logs$, которая в свою очередь находится в файле fsgame.ltx.
Для управления консолью имеется класс CConsole. Экземпляр этого класса можно получить с помощью глобальной функции get_console().
В этом классе нет функций, которые позволили бы вывести на консоль (и соответственно в лог) произвольную строку. Однако имеется функция execute(string), которая предназначена для выполнения команд консоли. Разумеется, выполнить можно только те команды, которые поддерживает движок. Если команда не поддерживается, то в консоль выводится сообщение:
! Unknown command: <команда_которую_пытался_выполнить>
Вот так и можно вывести некий текст. Пишем его вместо команды и он попадёт в консоль и в лог в составе сообщения об ошибке. Т.е. можно выводить сообщения так:
get_console():execute(<моё_сообщение>)
У метода есть недостатки.
Первое, сообщение не должно быть командой. Обычно с этим не возникает проблем, но всё-таки следить надо.
Второе, если в сообщении есть пробельные символы, то движок воспринимает как команду только последовательность символов до первого такого символа. Остальное - это как бы аргументы команды. В лог выведется только "команда", а остальное пропадёт. Есть два способа для решения этой проблемы. Первый состоит в замене всех пробелов на другой символ, например знак подчеркивания. Тогда команда вывода в лог будет выглядеть так:
get_console():execute(string.gsub(<моё_сообщение>, " ", "_"))
Функция string.gsub(str, ptrn, rep) заменяет в строке str все вхождения строки ptrn на строку rep.
Второй способ решения проблемы заключается в использовании функции команды консоли load. Эта команда загружает сейв с определённым именем. Если такого нет, то в лог выводится ещё и имя не найденного сейва.
get_console():execute("load ~~~ "..<сообщение>)
Поскольку файла, начинающегося с "~~~" точно не существует, то это сработает всегда. Сообщение в логе в этом случае выглядит так:
! Cannot find saved game ~~~ моё сообщение
При таком способе в сообщении могут быть пробелы и они отобразятся нормально. Кроме того, нет риска, что сообщение окажется командой консоли.
Недостаток метода - лишнее обращение к жёсткому диску на предмет проверки существования сейва. Кроме того, этот метод аккуратно обходится только с пробелами. Прочие специальные символы конвертируются в пробелы.
Полезно также упомянуть про команду консоли "flush", которая позволяет принудительно записать на диск всё, что на данный момент было выведено в консоль. Это может быть весьма полезно, поскольку при краше игры лог потеряется, если только не был записан этой командой. Так что вот такую строчку рекомендуется ставить перед потенциально опасными местами:
get_console():execute("flush")
В любом случае описанные методы нагружают сообщение лишними частями. Кроме того, в тот же лог выводятся и другие сообщения от движка. Хотя указанные методы чрезвычайно полезны, их недостатки иногда сильно мешают.

Но есть и ещё один способ, который может компенсировать эти недостатки. Оказывается, можно перенаправить консольный вывод движка в текстовый файл. После этого в этот файл можно выводить что угодно функцией Lua print(). Описание этой функции можно посмотреть на сайте Lua. Скажу только, что в сочетании с функцией форматирования текста string.format() так можно вывести в файл совершенно произвольно оформленный текст.
Для реализации метода можно запускать игру через батник примерно такого содержания:
XR_3DA.exe -nointro >> log.txt

У метода замечен только один недостаток. Нет никакой возможности принудительно записать файл на диск. Функция Flush осталась в неэкспортированном пространстве имён io. Хотя в отличие от консольного лога этот файл записывается на диск сам, но из-за буферизации часть его может таки пропасть в случае краша игры. При нормальном выходе из игры всё естественно запишется как надо.

Автор: Malandrinus

  Злобная реклама
Вторник, 23.11.2010, 22:55
Статус:
Сообщений: 666
Регистрация: 31.05.2010
  • Страница 1 из 1
  • 1
Поиск: