Я в курсе, что выложил не 1mpulse, но и воздержаться от критики этого, мягко говоря, быдлокода, не могу не удержаться.
ОффтопЭто должно было когда-нибудь случиться.
Обозревать буду только ядро. Модули - отдельная тема.
Ну, поехали.
switch(GetEngineVersion())
{
case Engine_CSGO: GameCSGO = true;
case Engine_CSS: GameCSGO = false;
}
Такого дерьма я давно не видел...
GameCSGO = (GetEngineVersion() == Engine_CSGO);
Base.sp
void LoadPlayer(int iClient)
{
if(IsValidPlayer(iClient))
{
if(cfg_bGameCMS)
{
char szQuery[256];
FormatEx(szQuery, sizeof(szQuery), "SELECT `shilings` FROM `users` WHERE `steam_id` = '%s'", g_SteamID[iClient]);
g_hDatabase.Query(SQL_Callback_LoadPlayer, szQuery, GetClientUserId(iClient), DBPrio_High);
}
else
{
char szQuery[256];
FormatEx(szQuery, sizeof(szQuery), "SELECT `cash`, `all_cash` FROM `lk` WHERE `auth` = '%s'", g_SteamID[iClient]);
g_hDatabase.Query(SQL_Callback_LoadPlayer, szQuery, GetClientUserId(iClient), DBPrio_High);
}
}
}
._.
void LoadPlayer(int iClient)
{
if (!IsValidPlayer(iClient))
return;
char szQuery[128];
if (cfg_bGameCMS)
FormatEx(szQuery, sizeof(szQuery), "SELECT `shilings` FROM `users` WHERE `steam_id` = '%s'", g_SteamID[iClient]);
else
FormatEx(szQuery, sizeof(szQuery), "SELECT `cash`, `all_cash` FROM `lk` WHERE `auth` = '%s'", g_SteamID[iClient]);
g_hDatabase.Query(SQL_Callback_LoadPlayer, szQuery, GetClientUserId(iClient), DBPrio_High);
}
// или можно вообще так, но тогда сами запросы лучше вынести в константы куда-нибудь
void LoadPlayer(int iClient)
{
if (!IsValidPlayer(iClient))
return;
char szQuery[128];
// без констант
FormatEx(szQuery, sizeof(szQuery), cfg_bGameCMS ? "SELECT `shilings` FROM `users` WHERE `steam_id` = '%s'" : "SELECT `cash`, `all_cash` FROM `lk` WHERE `auth` = '%s'", g_SteamID[iClient]);
// с константами
FormatEx(szQuery, sizeof(szQuery), cfg_bGameCMS ? gc_szGetClientMoney_WithCMS : gc_szGetClientMoney_WithoutCMS, g_SteamID[iClient]);
g_hDatabase.Query(SQL_Callback_LoadPlayer, szQuery, GetClientUserId(iClient), DBPrio_High);
}
if(cfg_bGameCMS)
{
if(hResults.FetchRow())
{
g_iClientInfo[iClient][Client_Cash] = hResults.FetchInt(0);
g_iClientInfo[iClient][Client_AllCash] = 0;
}
else
{
g_iClientInfo[iClient][Client_Cash] = -1;
g_iClientInfo[iClient][Client_AllCash] = 0;
}
}
._. [x2]
if(cfg_bGameCMS)
{
g_iClientInfo[iClient][Client_AllCash] = 0;
g_iClientInfo[iClient][Client_Cash] = hResults.FetchRow() ? hResults.FetchInt(0) : -1;
}
C
SavePlayer() та же ерунда, что и с
LoadPlayer(). Тупо всё сократить можно.
public void SQL_Callback_LoadPlayerMenu(Database hDatabase, DBResultSet hResults, const char[] sError, any iUserID)
{
if(sError[0])
{
LogError("Could not load the player, reason: %s", sError);
return;
}
int iClient = GetClientOfUserId(iUserID);
// ...
Надо экономить память:
public void SQL_Callback_LoadPlayerMenu(Database hDatabase, DBResultSet hResults, const char[] sError, any iClient)
{
if(sError[0])
{
LogError("Could not load the player, reason: %s", sError);
return;
}
iClient = GetClientOfUserId(iClient);
// ...
Cmds.sp
int key_cash;
key_cash = results.FetchInt(0);
Лишние вызовы к виртуалке.
int key_cash = results.FetchInt(0);
Ещё в
sm_lkrub нет проверки на переданного игрока. Там в качестве аргумента надо передавать UserID, но проверка на присутствие на сервере отсутствует. ¯\_(ツ)_/¯
Configs.sp
char ui[32][32], uo[512];
hKV.GetString("commands_open_menu", uo, sizeof(uo), "sm_lk");
int jl = ExplodeString(uo, ";", ui, 32, 32, false);
for(int i; i < jl; i++) RegConsoleCmd(ui[i], sm_lk);
Сказать, что я в шоке - ничего не сказать.
char uo[512];
hKv.GetString("commands_open_menu", uo, sizeof(uo); "sm_lk");
int iPos;
while (iPos != -1) {
iPos = FindCharInString(uo, ';', true);
RegConsoleCmd(uo[iPos+1], sm_lk);
if (iPos != -1)
uo[iPos] = 0;
}
Menus.sp
Panel hPanel = new Panel();
hPanel.SetTitle("Информация:");
hPanel.DrawText(" ");
hPanel.DrawText("Вам необходимно привязать ваш SteamID");
hPanel.DrawText("к аккаунту на нашем сайте.");
hPanel.Send(iClient, MenuHandler_MyPanel, 30);
Хендл не закрывается. Вообще. Даже в каллбеке. Натуральный мемори лик.
public int ShowMainMenu_CallBack(Handle menu, MenuAction action, iClient, Item)
Код на старом и новом синтаксисе одновременно.
Natives.sp
public APLRes AskPluginLoad2(Handle hMyself, bool bLate, char[] sError, int iErr_max)
{
RegPluginLibrary("lk");
CreateNative("LK_GetDatabase", LK_GetDatabase_);
// ...
Ну, либу ващет регают после всех нативов, а не ДО.
public int LK_GetClientCash_(Handle hPlugin, int iNumParams)
{
int iClient = GetNativeCell(1);
return g_iClientInfo[iClient][Client_Cash];
}
А если я криворукий говнокодер и передам не клиента? Выйду за пределы массива, и SM откоммуниздит именно ядро за невнимательность.
Stocks.sp
stock bool IsValidPlayer(int iClient)
{
if(iClient && IsClientInGame(iClient) && !IsFakeClient(iClient)) return true;
return false;
}
:/
stock bool IsValidPlayer(int iClient)
{
return (iClient && IsClientInGame(iClient) && !IsFakeClient(iClient));
}
for(int i = 1; i < iSize; i+=2)
{
delete view_as<Handle>(g_hFuncArray.Get(i));
}
Те, кто разбирали, что именно делает
delete, скорее всего, уже знают, почему здесь я недоволен.
Поскольку
delete, помимо удаления указателя, выполняет так же зануливание переменной, то он создаст целую грёбаную переменную, удалит указатель в ней, и зануллит.
Лишние вызовы к виртуалке.
Делаем так:
for(int i = 1; i < iSize; i+=2)
{
CloseHandle(view_as<Handle>(g_hFuncArray.Get(i)));
}
GetRandomKey() - ужас. Я даже это комментировать не хочу.