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

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

, а можно несколько глупый вопрос?  У метода SetProgressPos есть ли максимальные значения? ну скажем как можно адекватно указать "шкале", что она должен расти скажем от нуля до 1000?

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

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

Ты же наверняка знаешь, что при апдейте скриптового окна есть нюанс.

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

 

Вампир35

Используй такую конструкцию :

function твой_класс:Update()
    CUIScriptWnd.Update(self) -- обязательно!
    -- твои действия
end

А занимался ли кто оптимизацией массового входа неписей в онлайн?

Подобной оптимизацией уже занимались.

 

Когда-то давно я написал подробный тутор по работе с coroutine.

На его основе Artos уже сделал рабочий код перебора 65535 объектов с "растяжкой" во времени.

Т.е. объекты перебирались не лавинно, а по некоторому количеству, или по достижении лимита времени на один апдейт.

В общем нужно поискать. Или, при возможности (памяти) , я восстановлю этот код

Вот. Нашел :)

Как пример.

 

 

 

Вот это на апдейте у актора:

на апдейте 
local iPrgScan =  25  --/ периодичность сканирования Зоны (25ms => ~15 минут)

 

function OnUpdate(uo,delta)

  --/ непрерывное циклическое сканирование локаций по всему диапазону ID объектов (1...65534)

  if coroutine.status(CoScan) == 'suspended' then --/ статус сопрограммы: приостановлена?

    local bFlg,Result = coroutine.resume(CoScan, iPrgScan) --/ (пере)запуск сопрограммы

    if not bFlg then --/ ошибка при выполнении сопрограммы

      printf("OnUpdate:Error_CoScan=[%s]:<%s>", Result, "Error!")

    end

  end

end

А это основа сопрограммы:

цикл coroutine 
local tOAMain,tTmpMain = {},{} --/ дин.массив основных объектов (используется в m_news.script)

local tOwners,tTmpOwn  = {},{} --/ дин.массив владельцев предметов

 

local CoScan = coroutine.create( --/ сопрограмма сканирования объектов игры

  function(iTimeLimit) --/ функция сканирования объектов игры с ограничением времени работы

--    log("%s:CoScan:TimeLimit=[%s]:[%s]", sModule, iTimeLimit, ">") --/#~#

    local oPTimer,iTimeStop,soObj = nil,nil,nil

    local iCurID = 65535 --/ начальный ID

    while true do

      if iCurID >= 65534 then --/ проверка: цикл закончен (или предустановка)?

        --coroutine.yield(iCurID) --/ приостановка (опционально)

        if iCurID == 65534 then

          tOAMain,tOwners = tTmpMain,tTmpOwn --/ обновляем основные массивы

          log("%s:CoScan:Owners=[%s]:Time=[%s]%s", sModule, GetSizeTable(tOwners), Get_StrTime(), "") --/#~#

          --Print_Tables_OffLineAlife() --/#~# for Debug

        end

        --/ предустановки для нового цикла:

        tTmpMain,tTmpOwn = {},{} --/ временные массивы

        iCurID = 0 --/ начальный ID (опускаем 0-actor)

        iTimeStop = iTimeLimit --/ начальная установка для таймера

        oPTimer = profile_timer() --/ (пере)создаем объект таймера

      end

      iCurID = iCurID +1 --/ переход к следующему ID

      soObj = sim:object(iCurID) --/ очередной серверный объект игры

      if soObj then --/ объект в игре? ('пустышки' пропускаются и таймером)

        oPTimer:start() --/ старт таймера (на продолжение)

        --/ -- обработка объекта ----------------

        this.Build_TableObj(soObj,iCurID)

        --/ -------------------------------------

        oPTimer:stop() --/ (при)остановка таймера

        if oPTimer:time() > iTimeStop then --/ проверка: не закончен ли лимит времени?

          coroutine.yield(iCurID) --/ приостановка цикла

          iTimeStop = oPTimer:time() + iTimeLimit --/ обновляем для текущего подцикла сканирования

        end

      end

    end

    printf("%s:DoScan:<Error!>")

    return 65535 --/>

  end

)

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

Будучи запущенным один раз - на протяжении всей игры периодически сканирует всю Зону по всем объектам создавая соответствующие 'тематические' таблицы. И все это практически в фоновом режиме. 

 

 

Вот инфа по coroutine :

http://www.amk-team.ru/forum/index.php?showtopic=7450&page=16#entry622983

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

Помню эту тему, много там полезной информации, и не только для новичков. Только какая связь между перебором серверных объектов и оптимизацией выхода НПС online? По моему, основные тормоза происходят при загрузке моделей, звуков, текстур, и тд. Могу конечно ошибаться, но вопрос интересный и похоже не решённый

Ссылка на комментарий
Кривая инфа из луа_хелпа - не показатель. Все методы есть и в ТЧ

Действительно работает ! Правда не все - SetRange таки дает вылет "...attempt to call method..."

Информацию брал не из луа_хелп, а из Справочника по ф-циям и классам... Интересно - остальное, описанное в нем как недоэкспортированное - то-же хотя-бы частично рабочее в ТЧ ?

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

"Могу конечно ошибаться, но вопрос интересный и похоже не решённый"

 

Ну так вот замеры:

xr_motivator (esc_factory_bandit4):net_spawn, alive

xr_motivator 1: 218.31875610352

xr_motivator 2: 10.894275665283

xr_motivator 3: 1025343.3125

xr_motivator 4: 4695.3569335938

xr_motivator total: 1030485.3125

ну и т.д. для каждого непися.

 

где 3 - xr_sound.load_sound() ну и далее по тексту: sound_theme.load_sound()

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

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

Методика стандартная - profile_timer().

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

Есть ли способ получить актуальный список имен clsid ?
Имеется в виду вот этот список из lua_help

 

C++ class clsid {
    const actor = 78;
    const ameba_zone = 173;
    const art_bast_artefact = 0;
    const art_black_drops = 1;
    const art_dummy = 3;
    const art_electric_ball = 4;
    const art_faded_ball = 5;
    const art_galantine = 6;
    const art_gravi = 7;
    const art_gravi_black = 2;
    const art_mercury_ball = 8;
    const art_needles = 9;
    const art_rusty_hair = 10;
    const art_thorn = 11;
    const art_zuda = 12;
    const artefact = 39;
    const artefact_s = 90;
    const bloodsucker = 13;
    const bloodsucker_s = 95;
    const boar = 14;
    const boar_s = 96;
    const burer = 15;
    const burer_s = 97;
    const car = 49;
    const car_s = 91;
    const cat = 16;
    const cat_s = 98;
    const chimera = 28;
    const chimera_s = 99;
    const controller = 17;
    const controller_s = 100;
    const crow = 18;
    const device_detector_simple = 51;
    const device_pda = 50;
    const device_torch = 52;
    const device_torch_s = 119;
    const dog_black = 19;
    const dog_red = 22;
    const dog_s = 103;
    const equ_exo = 53;
    const equ_military = 54;
    const equ_scientific = 55;
    const equ_stalker = 56;
    const equ_stalker_s = 57;
    const flesh = 23;
    const flesh_group = 24;
    const flesh_s = 104;
    const fracture = 25;
    const fracture_s = 106;
    const game = 61;
    const game_cl_LastStanding = 45;
    const game_cl_artefact_hunt = 43;
    const game_cl_deathmatch = 44;
    const game_cl_single = 46;
    const game_cl_team_deathmatch = 47;
    const game_sv_LastStanding = 116;
    const game_sv_artefact_hunt = 114;
    const game_sv_deathmatch = 115;
    const game_sv_single = 117;
    const game_sv_team_deathmatch = 118;
    const game_ui_artefact_hunt = 120;
    const game_ui_deathmatch = 121;
    const game_ui_single = 122;
    const game_ui_team_deathmatch = 123;
    const gigant_s = 105;
    const graph_point = 27;
    const hanging_lamp = 81;
    const helicopter = 48;
    const hud_manager = 64;
    const inventory_box = 82;
    const level = 60;
    const level_changer = 74;
    const main_menu = 75;
    const mp_players_bag = 76;
    const nogravity_zone = 179;
    const obj_antirad = 65;
    const obj_attachable = 66;
    const obj_bandage = 67;
    const obj_bolt = 68;
    const obj_bottle = 69;
    const obj_breakable = 79;
    const obj_climable = 80;
    const obj_document = 70;
    const obj_explosive = 71;
    const obj_food = 72;
    const obj_medkit = 73;
    const obj_phskeleton = 87;
    const obj_phys_destroyable = 86;
    const obj_physic = 83;
    const online_offline_group = 77;
    const phantom = 29;
    const poltergeist = 30;
    const poltergeist_s = 107;
    const projector = 84;
    const pseudo_gigant = 26;
    const pseudodog_s = 108;
    const psy_dog = 21;
    const psy_dog_phantom = 20;
    const psy_dog_phantom_s = 101;
    const psy_dog_s = 102;
    const respawn = 88;
    const script_object = 92;
    const script_stalker = 33;
    const script_trader = 35;
    const script_zone = 89;
    const smart_terrain = 93;
    const smart_zone = 94;
    const snork = 31;
    const snork_s = 109;
    const space_restrictor = 112;
    const spectator = 113;
    const stalker = 32;
    const switcher = 85;
    const team_base_zone = 182;
    const torrid_zone = 183;
    const trader = 34;
    const tushkano = 36;
    const tushkano_s = 110;
    const wpn_ak74 = 142;
    const wpn_ak74_s = 124;
    const wpn_ammo = 38;
    const wpn_ammo_m209 = 40;
    const wpn_ammo_og7b = 41;
    const wpn_ammo_vog25 = 42;
    const wpn_binocular = 143;
    const wpn_binocular_s = 125;
    const wpn_bm16 = 144;
    const wpn_bm16_s = 126;
    const wpn_fn2000 = 145;
    const wpn_fort = 146;
    const wpn_grenade_f1 = 58;
    const wpn_grenade_fake = 59;
    const wpn_grenade_launcher = 147;
    const wpn_grenade_rgd5 = 62;
    const wpn_grenade_rpg7 = 63;
    const wpn_groza = 148;
    const wpn_groza_s = 127;
    const wpn_hpsa = 149;
    const wpn_hpsa_s = 128;
    const wpn_knife = 150;
    const wpn_knife_s = 129;
    const wpn_lr300 = 151;
    const wpn_lr300_s = 130;
    const wpn_mounted = 152;
    const wpn_pm = 153;
    const wpn_pm_s = 131;
    const wpn_rg6 = 154;
    const wpn_rg6_s = 132;
    const wpn_rpg7 = 155;
    const wpn_rpg7_s = 133;
    const wpn_scope = 156;
    const wpn_scope_s = 134;
    const wpn_shotgun = 157;
    const wpn_shotgun_s = 135;
    const wpn_silencer = 158;
    const wpn_stat_mgun = 159;
    const wpn_svd = 160;
    const wpn_svd_s = 136;
    const wpn_svu = 161;
    const wpn_svu_s = 137;
    const wpn_usp45 = 162;
    const wpn_usp45_s = 138;
    const wpn_val = 163;
    const wpn_val_s = 139;
    const wpn_vintorez = 164;
    const wpn_vintorez_s = 140;
    const wpn_walther = 165;
    const wpn_walther_s = 141;
    const wpn_wmagaz = 166;
    const wpn_wmaggl = 167;
    const zombie = 37;
    const zombie_s = 111;
    const zone = 184;
    const zone_acid_fog = 172;
    const zone_bfuzz = 174;
    const zone_bfuzz_s = 168;
    const zone_dead = 175;
    const zone_galant_s = 169;
    const zone_galantine = 176;
    const zone_mbald_s = 170;
    const zone_mincer = 178;
    const zone_mincer_s = 171;
    const zone_mosquito_bald = 177;
    const zone_radioactive = 180;
    const zone_rusty_hair = 181;

};

 

 

который, похоже, не совсем соответствовал действительности даже для чистого ТЧ.
Нужен именно список существующих строковых имен. Попытка взять множество clsid целиком, возвращает userdat-у, с которой непонятно что дальше делать.

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

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

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

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

Стандартных способов не знаю, а альтернативный придумал: )

Нужно пространство имён IO, посредством которого читать xrGame.dll. Если подойдёт, то часика через полтора покажу. Сейчас нет возможности.

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

Не думаю что у тебя получиться читать байт код :) Ни каких строк в clsid нет, это всего лишь набор числовых констант.

 

@Dennis_Chikin

 

Все равно многовато, даже для солянки. Попробуй замерять с os.clocк вместо profile_timer

 

Не пробовал кешировать звуки и при spawn уже назначать готовые sound objects?

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

На предыдущей странице ссылка на полную историю вопроса.

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

 

Субъективно все эффекты вполне соответствуют замерам.

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

Не думаю что у тебя получиться читать байт код

IO для того и создана, чтобы читать файлы. Особенно если разрабы предусмотрели модификатор 'b' для функции io.open.

Собственно свой предыдущий пост я и писал, потому что уже получилось. Иначе сидел бы молча.

Изменено пользователем Nazgool
Ссылка на комментарий
Ни каких строк в clsid нет, это всего лишь набор числовых констант.
function IsStalker (object, class_id)
    local id = class_id or get_clsid (object)
    if id == clsid.actor or id == clsid.script_stalker then
       return true
    end
    return false
end

 

 

Я знаю что это числовые константы. Но вот в приведенном примере - actor это что? script_stalker это что? строковые ключи. Строковые! по которым мы эти самые числовые константы получаем. и сравниваем с значением полученным из obj:clsid().

Вот мне нужен полный список этих ключей.

Или как вариант - мне нужен способ узнать этот ключ для конкретного объекта, у которого я знаю числовое значение возвращаемое obj:clsid()

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

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

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

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

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

@Zander_driver, да, это строковые ключи, но они там не хранятся. По сути там ничего не храниться, есть метатаблица этой юзердаты, которая была "создана" в движке. У нее есть поле __index, который представляет из себя адрес функции, причем движковой, Сишной, и которая вызывается при попытке индексации (obj.some_field или obj.["some_field"], в общем случае, ключом может быть любое значение). Ей передается этот ключ (та самая строка) и уже по ней эта Сишная функция возвращает константу. Т.о. прочесть все доступные ключи, действительно, можно только из xrGame.dll Обратное преобразование так же невозможно.

А читать байтово длл, да еще из Луа, ну это как копаться в стоге сена в поисках иголки. IO так и называется input\output. Читать байты нужно для своего формата, аля all.spawn (чисто пример).

PS: hex редактором можно найти какйто список строковых значений, похожий на список clsid, но боюсь, я могу ошибаться, смещение для ТЧ 04 0046BF7C, прикола ради можно посмотреть.

ТЧ 1.0004. SAP и Trans mod

github

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

Desertir

Смещение отличается в разных версиях xrGame.

 

Zander_driver

Не знаю что дальше хочешь делать, но вот тебе массив t с ключами из clsid, а дальше уже просто. (сделано топором, зато быстро и главное работает. оптимизируешь сам)

local xrgame_path = getFS():update_path("$fs_root$", "bin\\xrGame.dll")
local f = io.open(xrgame_path, 'rb')
local s = f:read('*a')

local _,start = s:find('CCharacterInfo>::InitInternal')
local limit = s:find('CObjectItemClientServerSingleMp')
start = start + 10

local p = f:seek("set", start)
local t = {}
local key = ''

while p < limit do
    local w = f:read(1)
	if w:byte()~=0 then
	    key = key..w
	elseif #key>0 then
	    if clsid[key] then
	        t[#t+1] = key
		end
	    key = ''
	end
	p = p+1
end
Изменено пользователем Nazgool
  • Спасибо 1
Ссылка на комментарий

Смещение отличается в разных версиях xrGame.

Неужели? Наверное тогда я правильно сделал, что указал версию, или нет?

На кой читать статические данные из скриптов? Раз они не изменяются динамически, hex редактором читаем и хардкодим в скрипты. И еще, разве это будет работать с сидами, которые мы добавили сами в скриптах? Это вот как раз про динамику.

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

ТЧ 1.0004. SAP и Trans mod

github

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

Desertir

Наверное существует и x-ray extensions, в котором время от времени что-то меняется?

Или нет?

 

Речь шла о способе "вытаскивания" ключей clsid из userdata!

Свои, добавленные, можно "запомнить" и стандартными средствами lua.

А "на кой ..." меня не интересует. Надо человеку, значит надо. Более интересно само решение поставленной задачи. Просто академический интерес.

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

Ты же наверняка знаешь, что при апдейте скриптового окна есть нюанс.

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

Nazgool, Charsy, спасибо за помощь).


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


 

Наверное существует и x-ray extensions, в котором время от времени что-то меняется?

Или нет?

Сейчас удобнее работать с седьмой версией - больше возможностей)

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

Ну так использовать полноформатное game_time.

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

function time_check()

...

global_time_ms = time_global()

game_time_time = game.get_game_time() -- полное игровое время

game_time_sec = game_time_time:diffSec( game_time_base ) -- секунд от загрузки

local _, _, _, _, _, _, ms = game_time_time:get() -- y, m, d, hh, mm, ss, ms

game_time_ms = game_time_sec * 1000 + ms -- ms от загрузки

end

 

 

function init_time_check()

game_time_time = game.get_game_time()

game_time_base = game_time_time

-- local y, m, d, hh, mm, ss, ms = game_time_time:get()

-- game_time_sec = game_time_time:diffSec( game_time_start )

-- game_time_ms = game_time_sec * 1000 + ms -- время теперь считается от загрузки

game_time_sec = game_time_time:diffSec( game_time_base )

_, _, _, _, _, _, game_time_ms = game_time_time:get()

level.add_call( time_check, dummy_action )

end

 

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

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

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

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

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

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

Войти

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

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

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