Падения сервера

Статус
В этой теме нельзя размещать новые ответы.
Сообщения
106
Реакции
8
Помог
2 раз(а)
О, понимяу, у меня эта ошибка уже 3 года, падает раз в неделю стабильно)
 
Сообщения
3,256
Реакции
1,436
Помог
121 раз(а)
Похоже, что падения с последним логом были решены. Ещё некоторое время понаблюдаю, дабы удостовериться, и тогда поделюсь решением.
 
Сообщения
3,256
Реакции
1,436
Помог
121 раз(а)
Итак, проблема с последним логом падений действительно была решена.

Сервер клал код, который писался мной пару лет назад, когда я ещё не очень в нём разбирался.
Код:
public OnPlayerSpawn_post(const pPlayer)
{
    if(!is_user_connected(pPlayer))
        return;

    if(is_user_duelist(pPlayer) && get_user_flags(pPlayer) & VIP_FLAG)
    {
        g_bPlayerDoingDoubleJump[pPlayer] = false;

        for(new i = GRAVITY; i < TEAM; i++)
        {
            g_bPlayerData[pPlayer][i] = false;
        }

        new iOldMenu, iNewMenu;
        new bool:bIsViewingMenu = bool:player_menu_info(pPlayer, iOldMenu, iNewMenu);

        if(bIsViewingMenu && iNewMenu == g_iMenuIndentifier[pPlayer])
        {
            menu_cancel(pPlayer);
            reset_menu(pPlayer);
        }
    }
    else if(!is_user_duelist(pPlayer) && get_user_flags(pPlayer) & VIP_FLAG)
    {
        RequestFrame("OnNextFrame", pPlayer);
    }
}

public OnNextFrame(const pPlayer)
{
==> if(get_entvar(pPlayer, var_flags) & FL_ONGROUND) <==
    {
        if(g_bPlayerData[pPlayer][GRAVITY])
        {
            set_entvar(pPlayer, var_gravity, 0.5);
        }

        if(g_bPlayerData[pPlayer][SPEED])
        {
            set_entvar(pPlayer, var_maxspeed, 400.0);
        }

        if(g_bPlayerData[pPlayer][GODMODE])
        {
            set_entvar(pPlayer, var_takedamage, DAMAGE_NO);
        }

        if(g_bPlayerData[pPlayer][INVISIBILITY])
        {
            set_entvar(pPlayer, var_effects, get_entvar(pPlayer, var_effects) | EF_NODRAW);
            rg_set_user_footsteps(pPlayer, true);
        }

        if(g_bPlayerData[pPlayer][NOCLIP])
        {
            set_entvar(pPlayer, var_movetype, MOVETYPE_NOCLIP);
        }
    }
    else
    {
        RequestFrame("OnNextFrame", pPlayer);
    }
}

Началась проблема после замены Admin Load by fantom на Access Manager by BlackSignature.
Я заметил, что сервер падает после 2-3 смен карты, если на сервере присутствует игрок с флагами (подходящими по условию в код выше). Сначала грешил на сам Access Manager, но в какой-то из перезагрузок сервера в попытке выяснить подробности, у меня проскочила ошибка от моего плагина, ссылавшаяся на строку, которую я отметил в коде стрелочками.
Сама ошибка возникла у меня почему-то всего лишь два раза из примерно тридцати перезагрузок.
Код:
1) [ReAPI] get_entvar: invalid entity index 24857 [arg_index]
2) [ReAPI] get_entvar: invalid entity index 665522 [arg_index]
Я полез в код плагина, и мне стало ясно, что, по всей видимости, Access Manager подгружает флаги несколько быстрее, чем Admin Load, в следствии чего игрок получает флаги и подпадает под условия в плагине в момент "спавна" на самом сервере. Про нюанс о том что при заходе игрок спавнится на сервере в момент подключения я либо не знал, либо не учёл при написании плагина ещё тогда.

Для фикса мне оставалось только заменить is_user_connected на is_user_alive.

Однако, у меня есть несколько вопросов к более опытным пользователям:

1. Почему вышеуказанная ошибка в логах проявлялась настолько редко? Я чисто случайно её заметил.
2. Почему вообще такая ошибка кладёт сервер? get_entvar: invalid entity index 24857
3. Главный вопрос: откуда там вообще взялся такой индекс? RequestFrame каким-то образом искажает передаваемые данные?

Призываю в тред SergeyShorokhov fl0wer bionext Garey the_hunter Vaqtincha hajimura fantom s1lent
 
Сообщения
288
Реакции
226
Помог
6 раз(а)
Nordic Warrior,
1. Вероятно, ошибки всплывали в момент отключения игрока в момент спавна. Проскакивает редко, но бывает
2. Вряд ли такое положит сервер. Я полагаю, сервер упал вследствие дальнейшей работы плагина с неправильным индексом игрока
3. Такой индекс может быть при еще не подключившемся или только отключившемся игроке. Иного объяснения, почему pPlayer несет в себе такой мусор из цифр, я не нахожу. RequestFrame не может изменить никак индекс. Во-первых, RequestFrame всего лишь передает индекс игрока дальше, как один из аргументов функции. А во-вторых, pPlayer там const

И да, is_user_connected или is_user_alive в функции спавна от ошибки не избавят. Ведь RequestFrame задуман, как создание и работа с функцией в следующем фрейме, а значит, проверки на коннект также должны быть и в функции, которая лажает в логах. Короче говоря, у тебя ни одной безопасной проверки в следующем фрейме
 
Последнее редактирование:
Сообщения
3,256
Реакции
1,436
Помог
121 раз(а)
hajimura, спасибо за ответ.

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

Короче говоря, у тебя ни одной безопасной проверки в следующем фрейме
Да, уже подумал об этом. Спасибо.

К модераторам просьба закрыть тему.
 
Сообщения
2,713
Реакции
2,993
Помог
59 раз(а)
Где-то сидит UB и всё.
 
Статус
В этой теме нельзя размещать новые ответы.

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

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