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

Язык Lua. Общие вопросы программирования

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

С чего начинать и где взять.

 

Установка Lua:
http://www.amk-team.ru/forum/index.php?showtopic=11584&p=629106

 

Руководство «Программирование на языке Lua», третье издание:
http://www.amk-team.ru/forum/index.php?showtopic=11584&p=905308

Изменено пользователем Kirgudu
Ссылка на комментарий

@Graff46,

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

 

Короче, тебе нужно читать файл средствами самого сталкира. класс reader тебе в помощь.

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

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

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

Изменено пользователем Graff46
Ссылка на комментарий

 

 

Файл в котором я работаю это сейв ТЧ

Пожалуй ты его успешно теми своими экспериментами навернул

Ссылка на комментарий

 

 

класс reader тебе в помощь
Им можно воспользоваться до загрузки игры?

 

 

Пожалуй ты его успешно теми своими экспериментами навернул
Нет, он загружается нормально, я же файл не изменял, только читал его.

reader Это который при загрузке в биндере? Я им не смогу воспользоваться до загрузки игры из гл. меню...

Ссылка на комментарий

@Graff46,

local file = getFS():r_open("$game_config$", "savename.sav")
local str = file:r_stringZ()
Пользоваться можно и до загрузки уровня/алайфа. Изменено пользователем naxac

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

Ссылка на комментарий

@User_X.A.R26@Malandrinus, Ура! получилось! Не понадобились

 

бинарное же посимвольное чтение и собственная реализация функций поиска текста

я то хотел уже из хекс редактора шаблоны текста брать, но даже открыв файл как бинарный он сохранил свою "текстовую" структуру. Вот мой код 

 


function load_dialog:load_game_internal()	
	local console = get_console()
	local list = self:GetListWnd("list_window")	

	if list:GetSize()==0 then return end

	local index = list:GetSelectedItem()
	
	if index == -1 then return end
		
	local item  = list:GetItem(index)
	local fname = item.fn:GetText()
	
	if (alife() == nil) then
		local file = io.open(getFS():update_path("$app_data_root$", "savedgames\\") .. fname .. ".sav", "rb")
		get_console():execute(file:read("*a"):match("osen%d"))
		file:close()
		console:execute	("disconnect")	
		console:execute	("start server(" .. fname .. "/single/alife/load) client(localhost)")	
	else
		console:execute	("load " .. fname)	
	end
end 

 

Сохранение загрузилось, после выхода я вижу в логе 

! Unknown command:  osen2 

Теперь можно делать самому враппер сейвов...


 

 

local str = file:r_stringZ()
Такое не сделать наверно без загрузки уровня? Изменено пользователем Graff46
  • Нравится 1
Ссылка на комментарий

 

 

Пользоваться можно и до загрузки.
я попробовал 
[error]Arguments     : LUA error: ... of fukushima\gamedata\scripts\ui_load_dialog.script:275: attempt to call method 'r_stringZ' (a nil value)
 

stack trace:
Ссылка на комментарий

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

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

 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий
file:r_stringZ()

Это методы reader'а? Я не могу найти описание этого класса на нашем форуме и на близлежащих, из луа _хелп ни чего не понял, там только перечислены методы. Если можно, тыкните носом на описание класса reader.

Изменено пользователем Graff46
Ссылка на комментарий
@Graff46, да. Их описания , вернее всего, нигде и нет. Они похожи на методы класса net_packet.

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

Ссылка на комментарий

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

 

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

local low_boundary = 3
local upper_boundary = 7
local current_position = 5
for i=1,20 do
    print(current_position)
    current_position = current_position + 1
    current_position = low_boundary + math.fmod(current_position - low_boundary, upper_boundary - low_boundary + 1)
end
 

Плагины Total Commander для работы с игровыми архивами:

Архиваторный плагин (для работы с одиночным архивом): link1 link2

Системный плагин (для распаковки установленной игры): link1 link2

 

Ссылка на комментарий

Уважаемое сообщество, хотел бы поинтересоваться Вашим мнением по такому вопросу:

Все видели, наверное, мод автопаузы, который использует инжектор кода через подмену, например, апдейта актора. Но xray считает по другому, и на такие попытки разместить именно в коде класса функцию он уверенно сообщает, что "RUNTIME ERROR - no static '_update' in class 'actor_binder'". Вот меня и интересует - 

1) Отходит ли от стандарта языка такая технология инжектора кода? 

2) если язык это поддерживает - в данном случае luabind "не прав" (ибо сообщение о ошибке - выдает именно он)?

3) игнорировать ли мне такое сообщение или переписать код в соответствие со стандартами языка?

Благодарю за Ваше мнение!


не столь секретен, чтобы ограничиваться лишь туманными намеками

 

- эээ... да никаких секретов... у меня в тексте сообщение так и написано - "мод автопаузы", впервые мне встретился, наверное в НС в каком то репаке. в ооп еще был. мод, который после загрузки добавляет паузу на нажатие любой клавиши (ТЧ). inj.script  - там есть такой код, который не нравиться xray 1.0007

 

local function inj_main(func_name,flag,fn,narg)
 if not _G.bind_stalker.actor_binder["_"..fn] then
 _G.bind_stalker.actor_binder["_"..fn] = {}
  if narg==1 then
   _G.bind_stalker.actor_binder["_"..fn][1] = _G.bind_stalker.actor_binder[fn]
   _G.bind_stalker.actor_binder[fn] = function(...)
    for _,f in pairs (_G.bind_stalker.actor_binder["_"..fn]) do f(...) end end
  else
   _G.bind_stalker.actor_binder[fn.."_"] = _G.bind_stalker.actor_binder[fn] or function()end
   _G.bind_stalker.actor_binder[fn] = function(...) local arg={...}
    _G.bind_stalker.actor_binder[fn.."_"](...)
    for _,f in pairs (_G.bind_stalker.actor_binder["_"..fn]) do
     f(arg[narg])
    end
   end
  end
 end
 _G.bind_stalker.actor_binder["_"..fn][func_name] = loadstring('return _G["'..string.gsub(flag and func_name or "_","%.",'"]["')..'"]')()
end
function inj_update(func_name,flag)
	inj_main(func_name,flag,"update",1)
end

 

 

в данном случае вызов в классе актора update подменяется на 2-а вызова , один - сохраненная функция (оригинальный actor_binder.update), второй  - функция, переданная как параметр.

Вот собственно. если такой подход применяется к функции в модуле - движок не возражает, если к классу - вызывает runtime error, описанная выше.

Изменено пользователем Winsor
Ссылка на комментарий

@Winsor, попробуй так:

function inj_update(f)
  _G.actor_update = _G.bind_stalker.actor_binder.update
  _G.bind_stalker.actor_binder.update = function ( ... )
    _G.actor_update(...)
   f(...)
  end
end
Где f - подключаемая функция. Да, и подключать можно только после инициализации класса, иначе изменений не будет.

 

А вообще, ИМХО, метод так себе. Проще - написать нечто на подобии скрипта xr_s из ЗП, и через него подключать-отключать что угодно.

Изменено пользователем naxac
  • Спасибо 1

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

Ссылка на комментарий

 

 

можно только после инициализации класса

Перенеся сохранение функции в модуль - избавился от ошибки.

данную подмену необходимо делать после загрузки модуля но до инициализации класса , методы которого пытаемся подменить. Движок создает, например, биндер актора один раз, и любые подмены после вызова __init ни к чему не приводят. Но это частности. Интересовала вообще корректность такого подхода, насколько он оправдан.

Ссылка на комментарий

Движок создает, например, биндер актора один раз, и любые подмены после вызова __init ни к чему не приводят.

Странно. У меня, в частности,с биндером актера, это работало (в ОП-2 такое использовал).

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

Ссылка на комментарий

Код странен. Я вообще не понял, что он должен делать.

 

"RUNTIME ERROR - no static '_update' in class 'actor_binder'" - именно так, да.

 

 

local s = "_" .. fn
local binder = _G.bind_stalker.actor_binder
local t = binder[s]
if not t then
	t = {}
	binder[s] = t
	if narg==1 then
		t[1] = binder[fn]
		binder[fn] = function(...)
		for _,f in pairs ( t ) do
			f(...) end
		end
binder[fn] = function(...) - вот это вот что и зачем ?

И зачем в цикле пытаться вызвать как функцию единственный элемент какой-то таблицы, который вообще то-ли есть, то-ли нет ?

Изменено пользователем Dennis_Chikin
Ссылка на комментарий

 что он должен делать

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

 

вот это вот что и зачем

- это и есть непосредственно сама замена (fn=="update" ), внутри которой и вызывается свой код + сохраненная версия. по поводу цикла - ничего не скажу. Возможно автор предполагал через дополнительные параметры при первоначальном инжекте добавлять в таблицу t несколько функций, и таким образом их вызывать.

 

в том же скрипте автопаузы есть

local function inj_mm_on_kbd(func_name)
	local name = "ap_mm_on_kbd"
	_G[name] = _G.ui_main_menu.main_menu.OnKeyboard
	_G.ui_main_menu.main_menu.OnKeyboard =
		function(...)
			local arg={...}
			if not loadstring('return _G["'..string.gsub(func_name,"%.",'"]["')..'"]')()(arg[1],arg[2],arg[3]) then
				return _G[name](...)
			end
			return true
		end
end

 

тут подмена вызова нажатий клавиш в главном меню.

Изменено пользователем Winsor
Ссылка на комментарий

Привет всем.

Подскажите, можно ли через loadstring выполнить функцию, в параметр которой нужно передать строку? У меня получается только с числом. Или, может, как-то иначе можно это сделать: есть функция строкой и параметры разных типов (тоже строками), надо выполнить эту функцию?

 

upd: решил так:

function run(func, ...)
  ...
  local t = {...}
  for i,v in ipairs(t) do
    if tonumber(v) then t[i] = tonumber(v)
    elseif v == 'true' then t[i] = true
    elseif v == 'false' then t[i] = false
    end
  end
  return loadstring("return "..func)()(unpack(t))
end
Изменено пользователем naxac

Аддон для ОП-2.09.2: Яндекс/Google/GitHub

naxac.gif

Ссылка на комментарий

Народ, кто нибудь в курсе, можно ли ограничить исполнение цикла "repeat" определенной продолжительностью времени.

Ссылка на комментарий

Создайте аккаунт или авторизуйтесь, чтобы оставить комментарий

Комментарии могут оставлять только зарегистрированные пользователи

Создать аккаунт

Зарегистрировать новый аккаунт в нашем сообществе. Это несложно!

Зарегистрировать новый аккаунт

Войти

Есть аккаунт? Войти.

Войти
  • Недавно просматривали   0 пользователей

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

AMK-Team.ru

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