AutoExecConfig() или стена быдлокода от Refresh

Сообщения
401
Реакции
113
Помог
2 раз(а)
Здравствуйте!

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

Опуская все регалии, заслуги и опыт моего оппонента, оставляя только суть "вопроса", можно подытожить следующее:
  1. Функция AutoExecConfig() всегда корректно читает данные из конфигурационного файла.
  2. Поскольку делает она это асинхронным запросом результат ее работы доступен лишь в следующем кадре.
Код:
#include <amxmodx>
#include <amxmisc>

new pCvar1, pCvar2, Cvar1, Cvar2[32]

public plugin_init() {
    register_plugin("test cvars", "1.0", "mx?!")
}

public plugin_cfg() {
    //new szConfigsDir[64]
    log_to_file("acs_debug.txt", "fresh start? %s", get_cvar_pointer("_pointer") ? "no" : "yes")

    //get_configsdir(szConfigsDir, 63)
    //server_cmd("exec %s/testcvars.cfg", szConfigsDir)
    //server_exec()

    create_cvar("_pointer", "0")

    pCvar1 = create_cvar("test_cvar1", "0")
    pCvar2 = create_cvar("test_cvar2", "value")

    bind_pcvar_num(pCvar1, Cvar1)
    bind_pcvar_string(pCvar2, Cvar2, charsmax(Cvar2))

    hook_cvar_change(pCvar1, "hook_cvar1")
    hook_cvar_change(pCvar2, "hook_cvar2")

    log_to_file("acs_debug.txt", "time before AutoExecConfig(): %f", get_gametime())
    AutoExecConfig(.name = "testcvars")

    log_to_file("acs_debug.txt", "check(1): cvar1 = %d, cvar2 = %s", Cvar1, Cvar2)
    RequestFrame("check_cvar")
    //set_task(0.01, "check_cvar", 0);
    log_to_file("acs_debug.txt", "here we should initialize db connection %f", get_gametime())
}

public hook_cvar1(pCvar, const szOldVal[], const szNewVal[]) {
    log_to_file("acs_debug.txt", "cvar1 old val %s, new val %s, time %f", szOldVal, szNewVal, get_gametime())
}

public hook_cvar2(pCvar, const szOldVal[], const szNewVal[]) {
    log_to_file("acs_debug.txt", "cvar2 old val %s, new val %s, time %f", szOldVal, szNewVal, get_gametime())
}

public check_cvar() {
    log_to_file("acs_debug.txt", "check(2): cvar1 = %d, cvar2 = %s", Cvar1, Cvar2)
}
Результат работы:

Код:
L 01/28/2024 - 15:34:19: fresh start? yes
L 01/28/2024 - 15:34:19: time before AutoExecConfig(): 1.000000
L 01/28/2024 - 15:34:19: check(1): cvar1 = 0, cvar2 = value
L 01/28/2024 - 15:34:19: here we should initialize db connection 1.000000
L 01/28/2024 - 15:34:20: cvar1 old val 0, new val 333, time 1.000000
L 01/28/2024 - 15:34:20: cvar2 old val value, new val value_new3, time 1.000000
L 01/28/2024 - 15:34:20: check(2): cvar1 = 333, cvar2 = value_new3
L 01/28/2024 - 15:36:03: fresh start? no
L 01/28/2024 - 15:36:03: time before AutoExecConfig(): 1.000000
L 01/28/2024 - 15:36:03: check(1): cvar1 = 333, cvar2 = value_new3
L 01/28/2024 - 15:36:03: here we should initialize db connection 1.000000
L 01/28/2024 - 15:36:03: cvar1 old val 333, new val 444, time 1.000000
L 01/28/2024 - 15:36:03: cvar2 old val value_new3, new val value_new4, time 1.000000
L 01/28/2024 - 15:36:03: check(2): cvar1 = 444, cvar2 = value_new4

У меня возник вопрос, почему??? за 5 лет программирования, нельзя было добавить в эту функцию callback оформленный через RequestFrame() и не лепить костыли, которые все копируют и потом быдлокодерам, вроде меня, предъявляют как божественную истину: "так все делают", "не будь вторым Карауловым", "я 5 лет программирую, так надо", "нужно переделать автоконфиг на конфиг написаннный вручную, и вызывать через через server_cmd("exec", путь); server_exec(), эта комбинация сразу же запускает конфиг в текущем кадре"...

Разработчики AMXX, очевидным образом, пытались упростить и унифицировать процесс разработки плагинов, однако даже самые опытные программисты используют таймер от 3 до 7 секунд или форвард OnConfigsExecuted(), который вызывается далеко не сразу, а за время потраченное на инициализацию таким образом плагина, на сервер зайдут все пользователи, в обход возможно установленных ограничений.

Второй вопрос, вытекает из первого. Для того чтобы использовать актуальные значения кваров через AutoExecConfig() в форварде plugin_precache(), очевидно, необходимо просто поменять порядок вызова форвардов, поставив на первое место plugin_cfg(). Почему за 5 лет программирования нельзя было организовать это второе незначительное изменение, ведь с Оксихромом там трется и другой опытный программист, Сергей.
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Сообщения
401
Реакции
113
Помог
2 раз(а)
fl0wer, можешь показать пример плагина, который сломается?
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Сообщения
401
Реакции
113
Помог
2 раз(а)
fl0wer, это теория, есть ли конкретный плагин, который пострадает. Обычно люди которые инициализируют в init() не используют cfg().
 
Сообщения
3,582
Реакции
1,571
Помог
137 раз(а)
Refresh, это не теория а обратная совместимость называется.
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Поскольку делает она это асинхронным запросом
AutoExecConfig не делает это асинхроно, асинхороно это когда с коллбэком.
Тут же просто через натив добавляются все кфг со всех плагинов в хранилище, а после plugin_cfg вызывается создание всех добавленных конфигов.
С одной стороны прикольно, что собрали все конфиги и после plugin_cfg создали, но какой смысла тогда от таких конфигов, которые даже в прекеше не могу использовать, ведь cfg как раз таки и говорит о том, как программа должна работать, а не присобачиваться где-то потом.

 
Сообщения
1,293
Реакции
2,294
Помог
57 раз(а)
Под "асинхронно" понимается не мгновенный результат.
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Nordic Warrior, тогда создать еще 1 форвард, перед precache().
Такой форвард есть, называется plugin_natives, он вызывается раньше precache.

Только вот загвоздка в том, что это никак не поменяет ситуацию, так как конфиги сначала собираются, а потом создаются после plugin_cfg.
 
Сообщения
401
Реакции
113
Помог
2 раз(а)
fl0wer, в любом случае надо что-то двигать, либо precache переместить после cfg(), либо cfg() перед precache(). Это будет не сильно сложная задача исправить совместимость плагина с новой версией amxx.
 
Сообщения
1,698
Реакции
1,510
Помог
26 раз(а)
Refresh, исходники у amxmodx открыты, как говорится велком. Перемещать ничего не надо, нужно хранилище убрать и создавать по факту вызова натива, тогда никакая совместимость не сломается.
 

AUF

Сообщения
91
Реакции
8
тоже волнует этот вопрос) bot писал про актуальные значения кваров OnConfigsExecuted()
но допустим есть квар bind_pcvar_string(create_cvar("snd_path", "events/task_complete.wav"), SND_PATH, charsmax(SND_PATH))
и что бы этот квар нормально читался нужно грузить его первым в plugin_precache и далее вызывать кфг из plugin_precache
server_cmd("exec addons/amxmodx/configs/Конфиг.cfg")
server_exec()
и далее
precache_sound или precache_generic для загрузки игроку.
можно ли как то вызвать нормально конфиг и прочитать из него квар нормально в таком случаи?? просто если конфиг не вызвать в plugin_precache а позже то и в plugin_precache не попадет сам звук который надо загрузить игроку исходя из квара.
также и AutoExecConfig конфиг создает с кварами но прочитать то что в кваре в plugin_precache не получается. бред да и только)
спасает только это
server_cmd("exec addons/amxmodx/configs/Конфиг.cfg")
server_exec()
вызвал когда нужно и в любой момент да хоть 100 раз) а кто то это называет быдлокодом) тут я бы поспорил теже 100 раз!)
 
Сообщения
333
Реакции
290
Помог
9 раз(а)
но допустим есть квар bind_pcvar_string(create_cvar("snd_path", "events/task_complete.wav"), SND_PATH, charsmax(SND_PATH))
Ну, это же вы его сделали кваром. Он у вас меняется в течение карты? Есть необходимость его изменения через консоль в процессе игры?

и что бы этот квар нормально читался нужно грузить его первым в plugin_precache и далее вызывать кфг из plugin_precache
И чтобы ЭТО нормально читалось, нужно внести его в *.ini и оттуда читать. Для чтения настроек из файла давно придумали парсеры.
 
Сообщения
401
Реакции
113
Помог
2 раз(а)
Финт с RequestFrame() не работает, если в каком-то плагине написанном небыдлокодером внутри plugin_init() или plugin_cfg() используется :
Код:
server_cmd("exec %s")
server_exec()
Замкнутый круг :rofl:
 
Последнее редактирование:

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу