Приветствую. Из-за моего плагина ломается физика на сервере. Симптомы - начинают проваливаться гранаты под пол, затем, через пару часов, под пол уходят предметы (уходят постепенно, понемногу, в пол, затем совсем исчезают). Это случается спустя случайное время после запуска сервера, иногда это несколько часов, иногда - сутки, но обычно не более. Это суть проблемы. Теперь о плагине.
Плагин защищает афк игроков, стоящих N секунд без движения, делая их неуязвимыми и накладывая эффект голограммы на модель игрока. Ключевой код плагина (код сокращён):
Код, проверяющий игрока:
Рендеринг модели:
Проверка, защищён ли игрок:
Снятие защиты:
Ранее проблема наблюдалась чаще, пока я не добавил пару лишних проверок в IsValidClient, поэтому я полагаю, что это моя ошибка. Вероятно, я каким-то образом затрагиваю не только игроков, но что-то ещё. В чём может быть моя ошибка и что я могу сделать, чтобы найти и исправить её?
Плагин защищает афк игроков, стоящих N секунд без движения, делая их неуязвимыми и накладывая эффект голограммы на модель игрока. Ключевой код плагина (код сокращён):
C-подобный:
SetProtection(client)
{
if (!IsValidClient(client))
return;
if (UnderProtection[client]) // Игрок не должен быть уже под защитой
return;
if (GetClientTeam(client) == TeamSpec) // Не должен быть наблюдателем
return;
if (GetEngineTime() < NextProtection[client]) // Выдерживаем время с момента предыдущей защиты
return;
SetEntProp(client, Prop_Data, "m_takedamage", 0, 1);
set_rendering(client, FX:FxHologram, 255, 255, 255, Render:RENDER_TRANSADD, TRANSPARENSY);
SetEntData(client, g_offsCollisionGroup, 1, 4, true);
UnderProtection[client] = true;
}
Код, проверяющий игрока:
C-подобный:
public IsValidClient(client)
{
if (!(1 <= client <= MaxClients) ||
!IsClientConnected(client) ||
!IsClientInGame(client) ||
!IsPlayerAlive(client) ||
IsFakeClient(client)
)
return false;
return true;
}
Рендеринг модели:
C-подобный:
set_rendering(index, FX:fx=FxNone, r=255, g=255, b=255, Render:render=Normal, amount=255)
{
SetEntProp(index, Prop_Send, "m_nRenderFX", _:fx, 1);
SetEntProp(index, Prop_Send, "m_nRenderMode", _:render, 1);
SetEntData(index, RenderOffs, r, 1, true);
SetEntData(index, RenderOffs + 1, g, 1, true);
SetEntData(index, RenderOffs + 2, b, 1, true);
SetEntData(index, RenderOffs + 3, amount, 1, true);
}
Проверка, защищён ли игрок:
C-подобный:
bool:IsProtected(client)
{
return GetEntProp(client, Prop_Data, "m_takedamage", 1) == 0;
}
Снятие защиты:
C-подобный:
RemoveProtection(client)
{
if(IsValidClient(client) && IsProtected(client))
{
SetEntProp(client, Prop_Data, "m_takedamage", 2, 1);
set_rendering(client);
SetEntData(client, g_offsCollisionGroup, 5, 4, true);
UnderProtection[client] = false;
}
NextProtection[client] = GetEngineTime() + FREEZE_TIME;
}
Ранее проблема наблюдалась чаще, пока я не добавил пару лишних проверок в IsValidClient, поэтому я полагаю, что это моя ошибка. Вероятно, я каким-то образом затрагиваю не только игроков, но что-то ещё. В чём может быть моя ошибка и что я могу сделать, чтобы найти и исправить её?