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

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

@Zander_driver 

1. В OGSE есть обработчик [m_net_utils.script] – это те самые "модули Артоса"?

2. Я ни в коем случае не пытаюсь освоить современное программирование ковырянием игры 2007 года – я пытаюсь уменьшить количество "кочек" в игре, в которой приятно убивать время, для чего перебираю существующие моды и пытаюсь их повторить в той мере, в которой это подходит для моих целей. Готовые решения уровня "электросамокат с гироскопом, GPS и подсветкой дороги" не годятся, если мне нужна просто табуретка. Опять же, даже чужие функции надо изучить, чтобы понять причину ошибок и вылетов.

@dsh

1. Ссылка на [m_netpk.script] на GitHub у меня есть, но так как из этих черных ящиков под названием "нетпакеты" я пока докопался до начинки только одного, 3,5к строк кода я буду изучать долго.

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

 

Теперь практика: проверка состояния фонарика и ПНВ

Spoiler

function net_cse_alife_item_torch:__init(obj,mode)

self.st_props = {}
self.up_props = {
        { name = 'torch_flags',   type = 'u8',  default = -1 },


    _G.torch_flags = { --/ torch
        Active            = 1,
        NightVisionActive = 2,
        Attached          = 4

 

Вывод: переменная состояния фонарика имеет тип u8 и находится в начале раздела UPDATE.

 

Spoiler

    local item = db.actor:item_in_slot(9)
    if item then
        local sobj = alife():object(item:id())
        local pk = net_packet()
        sobj:UPDATE_Write(pk)
        pk:r_seek(0)
        local v = pk:r_u8()
        news_manager.send_tip(db.actor, v)
    end

 

Результат: 0 в любом состоянии.

 

Эксперимент: читаю аналогичное значение от конца раздела UPDATE через сдвиг pk:r_seek(pk:w_tell() -1). Результат: все выключено – 4, фонарик – 5, ПНВ – 6, все вместе – 7. Я не знаю, что именно я прочитал, но это точно переменная размером 1 байт, которая меняется при переключении режима фонарика и остается на указанном значении до следующего переключения. Ну и как сие понимать?

Мини-моды: ТЧ ЧН ЗП

Шпаргалка

Ссылка на комментарий
8 минут назад, Norman Eisenherz сказал:

Ну и как сие понимать?

Прекратить заниматься ерундой и использовать таки m_netpk.script :)

 

Вывод: переменная состояния фонарика имеет тип

u8 и находится в начале раздела UPDATE.

Вывод неверный. Перед блоком переменных фонарика идут блоки переменных классов родителей.

  • Согласен 1
  • Полезно 1

Подарки

  • Ссылка на комментарий
    2 часа назад, Norman Eisenherz сказал:

    3,5к строк кода я буду изучать долго.

    Ну, на здоровье.

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

    2 часа назад, Norman Eisenherz сказал:

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

    Похоже, для вас совет dsh подойдет. Читайте темы в этом разделе, от корки до корки. На этот вопрос, ответы найдете.

     

    Скрытый текст

    Да, зачастую так оно и делалось. Хотите все это повторить - удачи и упорства вам.

     

    • Согласен 1

    Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

    Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

    AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

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

    @Norman Eisenherz,

    Скрытый текст
    
    function get_torch_state()
    	local torch = db.actor:object("device_torch")
    	local s_obj = alife():object(torch:id())
    	local pk = get_netpk(s_obj, 2)
    	if pk:isOk() then
    		local data = pk:get()
    		return bit_and(data.upd.torch_flags, torch_flags.Active) ~= 0
    	end
    end

     

    Что я сделал? Взял готовый модуль из https://www.amk-team.ru/forum/topic/13216-sborochnyy-ceh/?do=findComment&comment=971137, пробежал глазами скрипт на предмет того, где именно в нет-пакете лежат флаги фонарика согласно его классу - up_props, значит в update части нет-пакета, вспомнил по приложенной инструкции, как именно читать только update часть, и как в результатах она будет называться, накидал базовый скрипт для чтения текущего флага и сравнения его с флагом включения.

    Естественно, ещё и модуль подключить надо, но на это есть исчерпывающие сведения в посте по вышеприведённой ссылке, как инструкция Артоса, так и дополнения к ней.

    На всё потребовалось не больше 10 минут. Куда меньше, чем глубокое изучение трёх с половиной килострок кода.

    Не изобретай велосипед - его уже вылизали со всех сторон за эти годы.

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

    Здрасьте.

     

    Задача: записать текущее состояние STATE/UPDATE-пакетов оружия в слоте, удалить оружие, через несколько секунд (по инфо-поршню) отспавнить его снова и прочитать состояние. STATE-пакет успешно читается, пока объект переходит в онлайн, UPDATE-пакет не читается, поэтому режим стрельбы и все, что связано с гранатометом, грузится в состоянии по умолчанию.

    Spoiler
    
    		if item then
    			local sect = item:section()
    			local sobj = alife():object(item:id())
    	-- запись данных в STATE- и UPDATE-пакеты
    			local pk = net_packet()
    			sobj:STATE_Write(pk)
    			local pku = net_packet()
    			sobj:UPDATE_Write(pku)
    	-- переспавн
    			alife():release(sobj)
    			local act = db.actor
    			local pos = act:position()
    			pos.x = pos.x + 1
    			local nobj = alife():create(sect, pos, act:level_vertex_id(), act:game_vertex_id())
    			local id = nobj.id
    	-- чтение данных из STATE-пакета
    			local size = pk:w_tell()
    			pk:r_seek(0)
    			nobj:STATE_Read(pk, size)
    				-- news_manager.send_tip(db.actor, "pk: " .. size)
    	-- чтение данных из UPDATE-пакета
    			local size = pku:w_tell()
    			pku:r_seek(0)
    			nobj:UPDATE_Read(pku)
    				-- news_manager.send_tip(db.actor, "pku: " .. size)
    
    	-- отслеживание ввода в онлайн и перенос
    			local function online()
    				return level.object_by_id(id)
    			end
    
    			local function pick()
    				local item = level.object_by_id(id)
    				db.actor:transfer_item(item, db.actor)
    			end
    
    			level.add_call(online, pick)
    		end

     

     

    Попадалось упоминание о том, что данные из обоих пакетов пишутся в объект при выходе последнего в онлайн, то есть и UPDATE-пакет надо писать в серверный объект, а клиентский объект получит данные из него. Ставил функцию UPDATE_Read и до, и после выхода объекта в онлайн – никакого эффекта. Проверял содержимое исходного UPDATE-пакета – данные записываются правильно: например, grenade_mode = 1 (r_u8 от позиции 0), если был выбран подствольник.

     

    Как правильно переносить данные UPDATE-пакета?

    Мини-моды: ТЧ ЧН ЗП

    Шпаргалка

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

    Для начала попробуй после строк:

                local nobj = alife():create(sect, pos, act:level_vertex_id(), act:game_vertex_id())
                local id = nobj.id

    вставить строку:

    nobj = alife():object(id)

    alife():create возвращает объект типа чуть ли не cse_abstract, и методы State_Read/Update_Read вызываются для этого типа.

    alife():object возвращает реальный тип, какой-нибудь cse_alife_weapon_magazined_wgl. Соответственно State_Read/Update_Read вызовутся от него и заполнят grenade_mode.

    Изменено пользователем abramcumner
    • Полезно 2

    Подарки

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

    @abramcumner Проверил clsid с указанными изменениями и без: определяется как "127", то есть "wpn_groza_s" – гранатомет уже должен быть. На чтении UPDATE-пакета изменения не сказались.

     

    Еще вопрос: если требуется изменить одну переменную в конце нетпакета, обязательно ли читать его весь или можно как-то сдвигать позицию записи не только от начала через w_begin(), но и от конца пакета?

    Мини-моды: ТЧ ЧН ЗП

    Шпаргалка

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

     

    11 часов назад, Norman Eisenherz сказал:

    можно как-то сдвигать позицию записи не только от начала через w_begin(), но и от конца пакета?

    Нет. Сдвигать только через r/w_seek() от текущей позиции чтения/записи. w_begin() - это поставить позицию записи в начало пакета и записать два байта.

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

    naxac.gif


    Подарки

    Ссылка на комментарий
    В 25.02.2020 в 18:19, Norman Eisenherz сказал:

    все, что связано с гранатометом, грузится в состоянии по умолчанию

    Всё, что связано с подствольным гранатометом существует только в клиентском объекте, поэтому его состояние по умолчанию.

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

    В приведенном примере section объекта одинаковая, может его не release/create, а transfer'ить в какой-нибудь секретный ящик и обратно?

    S.T.A.L.K.E.R. CoP Objects (upd 10.04.24)


    Подарки

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

    @WinCap

    1. Это как раз текущая реализация мода: на время торговли/обыска оружие как оно есть улетает во временный ящик. С правильно расставленными отсрочками предметы не теряются на полпути, даже если окно обыска было случайно закрыто через долю секунды, но переспавн, если верить форуму, занимает всего около 20 циклов, тогда как с ящиком и переносом требуется не меньше 100, иначе вылет с потерянным родителем в логе.

    2. Есть все-таки в игре рабочий метод переноса данных из UPDATE-пакета в объект или нет?

    Мини-моды: ТЧ ЧН ЗП

    Шпаргалка

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

    По прошлой теме: посмотрел OGSE 0.6.9.3. с патчами от февраля 2018 года – при замене прицела на оружии с гранатометом режим стрельбы сбрасывается на "авто", режим гранатомета отключается, гранаты и патроны в качестве "костыля" переспавниваются в инвентарь. Видимо, ответ на вопрос № 2 отрицательный…

     

    Другая задача: есть способ создания виртуального LTX-файла через create_ini_file(string). Сам файл создать получается, прочитать из него выбранные строки – тоже, но при попытке создать предмет на основе указанной в файле секции случается вылет с ошибкой "секция не найдена". Идея в том, чтобы временно получить броню со статусом quest_item = true, не прописывая новую секцию для каждого вида брони вручную. Как правильно сослаться на виртуальный LTX-файл и возможен ли такой спавн в принципе?

    Spoiler
    
    		local item = db.actor:item_in_slot(6)
    		if item then
    			local sect = item:section()
    
    			local strings = {
    				"#include \"misc\\outfit.ltx\"",
    				"[" .. sect .. "_q]:" .. sect,
    				"description = test",
    				"quest_item = true"
    					}
    
    			local text = table.concat(strings, "\n")
    			local ini = create_ini_file(text)
    
    			local act = db.actor
    			local pos = act:position()
    			pos.x = pos.x + 1
    			local spawn = alife():create(sect .. "_q", pos, act:level_vertex_id(), act:game_vertex_id())
    		end

     

     

    Изменено пользователем Norman Eisenherz
    • Смешно 1

    Мини-моды: ТЧ ЧН ЗП

    Шпаргалка

    Ссылка на комментарий
    только что, Norman Eisenherz сказал:

    от февраля 2018 года

    Даже стесняюсь спросить, а какой же год у нас на дворе...

    Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

    Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

    AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

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

    @Zander_driver, не всем можется и, главное, хочется ковыряться в движке.

     

    @Norman Eisenherz, функция create_ini_file создаёт объект в памяти, к которому можно применять все методы этого класса, такие как ini:line_count(), ini:r_bool() и др. Но это не значит, что этот объект автоматически подключён в качестве игрового ресурса аналогично инклюдам в system.ltx.

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

    @Kirgudu То, что файл хранится без привязки к system.ltx – ожидаемо, но вроде бы такой виртуальный файл можно сохранить на жестком диске. Как это сделать?

    Мини-моды: ТЧ ЧН ЗП

    Шпаргалка

    Ссылка на комментарий
    4 часа назад, Kirgudu сказал:

    не всем можется

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

    Не всем хочется - да... Даже не ковыряться а просто взять готовое. Те же Артосомодули примером.

    • Согласен 1

    Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

    Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

    AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

    Ссылка на комментарий
    6 часов назад, Norman Eisenherz сказал:

    но вроде бы такой виртуальный файл можно сохранить на жестком диске. Как это сделать?

    local file = io.open() / file:write() / file:close() - для ЧН/ЗП. Для ТЧ я такого способа не знаю. В любом случае сохранение на лету скорее всего не даст автоматического подключения к ресурсам, а сохранение с целью последующего чтения при запуске игры равносильно формированию нужного конфига заранее.

     

    Но соглашусь с @Zander_driver. Совершенно непонятны цели данных усилий. Если для самообразования - это похвально, вот только начинать (и продолжать) тогда нужно с того, что страницей раньше написал @dsh: чтения этой и соседних (справочник, общие вопросы) тем от начала и до конца. В противном случае лучше таки обратить своё внимание на доработанные движки или модули Артоса. Ведь они и вправду "из коробки" обеспечат то, что ты пытаешься сделать.

    • Согласен 1
    Ссылка на комментарий
    34 минуты назад, Kirgudu сказал:

    В любом случае сохранение на лету скорее всего не даст автоматического подключения к ресурсам

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

    • Согласен 1

    Мод, где не бывает одинаковых путей - Судьба Зоны. (Лучшее, что у меня получилось на X-Ray) На базе модифицированного движка OGSR Engine.

    Бывший мододел на X-Ray / Начинающий игродел на Unreal Engine. Программист.

    AMD Ryzen 9 7950X (16 ядер, 5.7ГГц); RTX 3080; 128 ГБ DDR5; Arctic Liquid Freezer II-420; 3 ТБ SSD PCIe 4.0; 4ТБ HDD.

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

    @Kirgudu Какая функция [lua_helper] или [m_netpk] должна помочь в изменении квестового статуса надетой брони?

     

    (Снова по старой теме) Подключил [m_netpk], скопировал данные автомата в руках, отспавнил новый, перенес данные, результат ровно тот же: все параметры UPDATE-пакета в состоянии по умолчанию (гранатомет выключен, в стволе один патрон согласно данным STATE-пакета). Где я ошибся?

    Spoiler
    
    local item = db.actor:item_in_slot(2)	-- автомат + пгм
    	if item then
    		local sect = item:section()
    		local sobj = alife():object(item:id())
    	
    		local pk = get_netpk(sobj)
    		local data = pk:get()
    	
    		alife():release(sobj)
    		local act = db.actor
    		local pos = act:position()
    		pos.x = pos.x + 1
    		local nobj = alife():create(sect, pos, act:level_vertex_id(), act:game_vertex_id())
    	
    		local npk = get_netpk(nobj)
    		npk:set(data)
    	end

     

     

    Мини-моды: ТЧ ЧН ЗП

    Шпаргалка

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

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

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

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

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

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

    Войти

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

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

    AMK-Team.ru

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