UCC Не комирируется !

Статус
В этой теме нельзя размещать новые ответы.
Сообщения
8
Реакции
-1
Ошибка
AMX Mod X Compiler 1.8.3-dev+5147
Copyright (c) 1997-2006 ITB CompuPhase
Copyright (c) 2004-2013 AMX Mod X Team

ucc.sma(49) : error 017: undefined symbol "MAX_AUTHID_LENGTH"
ucc.sma(79) : error 017: undefined symbol "MAX_PLAYERS"
ucc.sma(83) : error 009: invalid array size (negative or zero)
ucc.sma(137) : error 017: undefined symbol "create_cvar"
ucc.sma(137) : warning 215: expression has no effect
ucc.sma(137) : error 029: invalid expression, assumed zero
ucc.sma(137) : error 017: undefined symbol "description"
ucc.sma(137) : fatal error 107: too many error messages on one line
Компилятор
WEB-компилятор
Amx Mod X
1.9.0
Исходный код
#include <amxmodx>
#include <amxmisc>
#include <sqlx>
#include <reapi>

//#define CSX_EASY_STATS // use only with CSX Easy Stats plugin!!!

const MYSQL_TIMEOUT = 2;
const REASON_LENGTH = 64;
const GAG_MENU_ITEMS = 5;
const MUTE_MENU_ITEMS = 6;

enum natives_return {
RETURN_ERR = 0,
RETURN_OK
};

enum chats_by_stats {
DISABLE = -1,
CSX,
CSSTATS_MYSQL,
CSSTATSX_SQL,
AES
#if defined CSX_EASY_STATS
, CSXES_GAMETIME
#endif
};

enum block_types {
NONE = -2,
STATS,
TEXT_CHAT,
VOICE_CHAT,
ALL_CHATS
};

enum _:menu_settings {
SELECTED_TIME,
SELECTED_REASON,
SELECTED_TYPE,
CURRENT_POS
};

enum _:block_data {
EXPIRED,
REASON[REASON_LENGTH],
ADMIN_STEAMID[MAX_AUTHID_LENGTH],
block_types:GAG_BLOCK_TYPE
};

enum _:cvars {
MYSQL_HOST,
MYSQL_USER,
MYSQL_PASS,
MYSQL_DBNAME,
MYSQL_CLEAR_EXPIRED,

SAY_SORRY,
SAY_MUTE,
chats_by_stats:CHATS_BY_STATS,
BLOCK_INFO,
block_types:DEFAULT_BLOCK,
MIN_ALLOW_VAL,
GAG_ACCESS,
SUPER_ACCESS,
C_BY_S_IMMUNITY
};

new Trie:g_tAllowCmds;
new Array:g_arrGagTimes,
Array:g_arrBlockTypes,
Array:g_arrReasons

new Handle:g_hTuple,
g_thData[3];

new g_PlayerData[MAX_PLAYERS + 1][block_data],
g_PlayerMute[MAX_PLAYERS + 1][MAX_PLAYERS + 1],
g_arrPlayers[MAX_PLAYERS + 1][MAX_PLAYERS],
g_MenuData[MAX_PLAYERS + 1][menu_settings],
g_iFragStats[MAX_PLAYERS + 1];

new g_szAesLevelName[64];

new g_Cvar[cvars];
new pCvar1, // mysql host
pCvar2, // mysql user
pCvar3, // mysql pass
pCvar4, // mysql db
pCvar5, // mysql expired period
pCvar6, // gag access
pCvar7, // super access
pCvar8; // immunity

#define is_blocked_text_chat(%0) (g_PlayerData[%0][GAG_BLOCK_TYPE] == STATS || g_PlayerData[%0][GAG_BLOCK_TYPE] == TEXT_CHAT || g_PlayerData[%0][GAG_BLOCK_TYPE] == ALL_CHATS)
#define is_blocked_voice_chat(%0) (g_PlayerData[%0][GAG_BLOCK_TYPE] == STATS || g_PlayerData[%0][GAG_BLOCK_TYPE] == VOICE_CHAT || g_PlayerData[%0][GAG_BLOCK_TYPE] == ALL_CHATS)

native get_user_stats(index, st[8], bh[8]);
native csstats_get_user_stats(index, st[22]);
native get_user_stats_sql(index, st[8], bh[8]);
native aes_get_player_level(index);
native aes_get_level_name(index, name[], len, lang);

public plugin_natives()
{
register_library("Ultimate Chats Controller");
register_native("ucc_is_client_gaged", "native_ucc_is_client_gaged");
register_native("ucc_set_client_gag", "native_ucc_set_client_gag");
register_native("ucc_is_client_muted", "native_ucc_is_client_muted");
register_native("ucc_set_client_muted", "native_ucc_set_client_muted");

set_native_filter("native_filter");
}

public native_filter(const name[], index, trap)
return trap ? PLUGIN_CONTINUE : PLUGIN_HANDLED;

public plugin_init()
{
#define PNAME "Ultimate Chats Controller"
#define VERSION "5.2(c)"
#define AUTHOR "neygomon"
register_plugin(PNAME, VERSION, AUTHOR);
register_dictionary("ucc.txt");
create_cvar("ucc_version", VERSION, .flags = FCVAR_SERVER, .description = "Plugin version. Don't edit, please :)");

pCvar1 = create_cvar(
"ucc_mysql_host",
"127.0.0.1",
.flags = FCVAR_PROTECTED,
.description = fmt("%l", "DESC_MYSQL_HOST")
);
pCvar2 = create_cvar(
"ucc_mysql_user",
"root",
.flags = FCVAR_PROTECTED,
.description = fmt("%l", "DESC_MYSQL_USER")
);
pCvar3 = create_cvar(
"ucc_mysql_pass",
"",
.flags = FCVAR_PROTECTED,
.description = fmt("%l", "DESC_MYSQL_PASS")
);
pCvar4 = create_cvar(
"ucc_mysql_dbname",
"dbname",
.flags = FCVAR_PROTECTED,
.description = fmt("%l", "DESC_MYSQL_DBNAME")
);
pCvar5 = create_cvar(
"ucc_mysql_clear_expired",
"30",
.description = fmt("%l", "DESC_MYSQL_CLEAR_EXPIRED"),
.has_min = true,
.min_val = 0.0
);

pCvar6 = create_cvar(
"ucc_gag_access",
"d",
.description = fmt("%l", "DESC_GAG_ACCESS")
);
pCvar7 = create_cvar(
"ucc_superadmin_access",
"l",
.description = fmt("%l", "DESC_SUPER_ACCESS")
);
pCvar8 = create_cvar(
"ucc_chats_by_stats_immunity",
"u",
.description = fmt("%l", "DESC_C_BY_S_IMMUNITY")
);

bind_pcvar_num(
create_cvar(
"ucc_say_sorry",
"15",
.description = fmt("%l", "DESC_SAY_SORRY"),
.has_min = true,
.min_val = 0.0
),
g_Cvar[SAY_SORRY]
);
bind_pcvar_num(
create_cvar(
"ucc_say_mute",
"1",
.description = fmt("%l", "DESC_SAY_MUTE"),
.has_min = true,
.has_max = true,
.min_val = 0.0,
.max_val = 1.0
),
g_Cvar[SAY_MUTE]
);
bind_pcvar_num(
create_cvar(
"ucc_chats_by_stats",
"0",
.description = fmt("%l", "DESC_CHATS_BY_STATS"),
.has_min = true,
.has_max = true,
.min_val = -1.0,
.max_val = 4.0
),
g_Cvar[CHATS_BY_STATS]
);
bind_pcvar_num(
create_cvar(
"ucc_block_info",
"1",
.description = fmt("%l", "DESC_BLOCK_INFO"),
.has_min = true,
.has_max = true,
.min_val = 0.0,
.max_val = 1.0
),
g_Cvar[BLOCK_INFO]
);
bind_pcvar_num(
create_cvar(
"ucc_default_block",
"1",
.description = fmt("%l", "DESC_DEFAULT_BLOCK"),
.has_min = true,
.has_max = true,
.min_val = 0.0,
.max_val = 2.0
),
g_Cvar[DEFAULT_BLOCK]
);
bind_pcvar_num(
create_cvar(
"ucc_min_allow_value",
"1",
.description = fmt("%l", "DESC_MIN_ALLOW_VAL"),
.has_min = true,
.min_val = 0.0
),
g_Cvar[MIN_ALLOW_VAL]
);

AutoExecConfig(.autoCreate = true, .name = "ucc");

if(SQL__Connect())
{
Get_Flags();
Get_ArrayCvars();
Reg_Commands();

if(g_Cvar[CHATS_BY_STATS] == AES && g_Cvar[BLOCK_INFO])
set_task_ex(1.0, "get_allow_level");

register_menucmd(register_menuid("UCC GagMenu"), 1023, "GagMenuHandler");
register_menucmd(register_menuid("UCC MuteMenu"), 1023, "MuteMenuHandler");
set_task_ex(60.0, "CheckBlockedUsers", .flags = SetTask_Repeat);
}
}

public plugin_end()
{
SQL_FreeHandle(g_hTuple);
TrieDestroy(g_tAllowCmds);
ArrayDestroy(g_arrGagTimes);
ArrayDestroy(g_arrBlockTypes);
ArrayDestroy(g_arrReasons);
}

public client_putinserver(id)
{
if(is_user_bot(id) || is_user_hltv(id))
return;

arrayset(g_PlayerMute[id], 0, sizeof g_PlayerMute[]);
g_PlayerData[id][EXPIRED] = -1;
g_PlayerData[id][REASON][0] = EOS;
g_PlayerData[id][ADMIN_STEAMID][0] = EOS;
g_PlayerData[id][GAG_BLOCK_TYPE] = NONE;

if(g_Cvar[CHATS_BY_STATS] > DISABLE)
{
if(!get_chats_access(id))
set_user_block(id, STATS);
}

new szIP[MAX_IP_LENGTH], szAuth[MAX_AUTHID_LENGTH];
get_user_ip(id, szIP, charsmax(szIP), true);
get_user_authid(id, szAuth, charsmax(szAuth));

g_thData[0] = id;
SQL_ThreadQuery(
g_hTuple,
"SQL_ThreadHandler_LoadPlayer",
fmt("SELECT `expired_time`, `reason`, `admin_steamid`, `block_type` FROM `ucc_gag` WHERE (`ip` = '%s' OR `steamid` = '%s') AND (`expired_time` = '0' OR `expired_time` > '%d')", szIP, szAuth, get_systime()),
g_thData,
sizeof(g_thData)
);
}
/* HookChain Handlers */
public CBasePlayer_Spawn_Post(const id)
{
if(!is_user_connected(id))
return;
if(g_PlayerData[id][GAG_BLOCK_TYPE] != STATS)
return;
if(get_chats_access(id))
{
VTC_UnmuteClient(id);
g_PlayerData[id][GAG_BLOCK_TYPE] = NONE;
}
else if(g_Cvar[BLOCK_INFO])
{
custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_BLOCK_CHATS0");

switch(g_Cvar[CHATS_BY_STATS])
{
case AES: custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_BLOCK_CHATS2", g_szAesLevelName);
#if defined CSX_EASY_STATS
case CSXES_GAMETIME:
custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_BLOCK_CHATS4", g_Cvar[MIN_ALLOW_VAL]);
#endif
default: custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_BLOCK_CHATS3", g_iFragStats[id], g_Cvar[MIN_ALLOW_VAL]);
}
}
}

public CanPlayerHearPlayer_Pre(const iReciever, const iSender)
{
if(iSender != iReciever)
{
if(g_PlayerMute[iReciever][iSender])
{
SetHookChainReturn(ATYPE_INTEGER, false);
return HC_SUPERCEDE;
}
}
return HC_CONTINUE;
}
/* srvcmd_Flush */
public srvcmd_Flush()
{
SQL_ThreadQuery(g_hTuple, "SQL_ThreadHandler_Truncate", "TRUNCATE `ucc_gag`");

for(new id; id < sizeof g_PlayerData; ++id)
{
if(g_PlayerData[id][EXPIRED] >= 0 && is_user_connected(id))
VTC_UnmuteClient(id);

g_PlayerData[id][EXPIRED] = -1;
g_PlayerData[id][REASON][0] = EOS;
g_PlayerData[id][ADMIN_STEAMID][0]= EOS;
g_PlayerData[id][GAG_BLOCK_TYPE] = NONE;
}

log_amx("%s [v: %s][a: %s] flushed all gags", PNAME, VERSION, AUTHOR);
}
/* clcmd_SaySorry */
public clcmd_SaySorry(id)
{
if(is_blocked_text_chat(id))
{
static iFloodTime[MAX_PLAYERS + 1], systime;
if(iFloodTime[id] > (systime = get_systime()))
custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_SORRY_FLOOD", iFloodTime[id] - systime);
else
{
new szName[MAX_NAME_LENGTH];
get_user_name(id, szName, charsmax(szName));

new players[MAX_PLAYERS], pnum;
get_players_ex(players, pnum, GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);

for(new i, admin, flags, auth[MAX_AUTHID_LENGTH]; i < pnum; ++i)
{
admin = players[i];
flags = get_user_flags(admin);

if(flags & g_Cvar[SUPER_ACCESS])
custom_color_chat(admin, 0, "%l %l", "MSG_PREFIX", "MSG_SORRY_ADMIN", szName, g_PlayerData[id][REASON]);
else if(flags & g_Cvar[GAG_ACCESS])
{
if(strcmp(g_PlayerData[id][ADMIN_STEAMID], auth) == 0)
custom_color_chat(admin, 0, "%l %l", "MSG_PREFIX", "MSG_SORRY_ADMIN", szName, g_PlayerData[id][REASON]);
}
}

iFloodTime[id] = systime + g_Cvar[SAY_SORRY];
}
}

return PLUGIN_HANDLED;
}
/* clcmd_SayChat */
public clcmd_SayChat(id)
{
if(!is_blocked_text_chat(id))
return PLUGIN_CONTINUE;

new szMessage[64];
read_args(szMessage, charsmax(szMessage));
remove_quotes(szMessage);

if(TrieKeyExists(g_tAllowCmds, szMessage))
return PLUGIN_CONTINUE;
else if(g_PlayerData[id][GAG_BLOCK_TYPE] == STATS)
{
if(g_Cvar[BLOCK_INFO])
{
custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_BLOCK_CHATS0");

switch(g_Cvar[CHATS_BY_STATS])
{
case AES: custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_BLOCK_CHATS2", g_szAesLevelName);
#if defined CSX_EASY_STATS
case CSXES_GAMETIME:
custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_BLOCK_CHATS4", g_Cvar[MIN_ALLOW_VAL]);
#endif
default: custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_BLOCK_CHATS3", g_iFragStats[id], g_Cvar[MIN_ALLOW_VAL]);
}
}
}
else
{
new szName[MAX_NAME_LENGTH], ost;
get_user_name(id, szName, charsmax(szName));
custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_CHAT_IS_BLOCKED", szName, g_PlayerData[id][REASON]);

if(g_PlayerData[id][EXPIRED] > 0)
{
if((ost = g_PlayerData[id][EXPIRED] - get_systime()) / 60 > 0)
custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_BLOCK_EXPIRED_TIME", ost / 60);
else custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_BLOCK_EXPIRED");
}
else custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_SAY_SORRY");
}

return PLUGIN_HANDLED;
}
/* clcmd_GagMenu */
public clcmd_GagMenu(id)
{
if(get_user_flags(id) & g_Cvar[GAG_ACCESS])
{
g_MenuData[id][SELECTED_TIME] = 0;
g_MenuData[id][SELECTED_TYPE] = any:g_Cvar[DEFAULT_BLOCK];
g_MenuData[id][CURRENT_POS] = 0;

Show_GagMenu(id, 0);
}

return PLUGIN_HANDLED;
}
/* clcmd_MuteMenu */
public clcmd_MuteMenu(id)
{
g_MenuData[id][CURRENT_POS] = 0;

Show_MuteMenu(id, 0);
return PLUGIN_HANDLED;
}
/* MySQL handlers */
public SQL_ThreadHandler_Init(failstate, Handle:query, err[], errcode)
{
if(failstate != TQUERY_SUCCESS)
log_amx("MySQL INIT is FAILED... [#%d] %s", errcode, err);

return PLUGIN_CONTINUE;
}

public SQL_ThreadHandler_LoadPlayer(failstate, Handle:query, err[], errcode, data[], datasize)
{
if(failstate == TQUERY_SUCCESS)
{
if(SQL_NumResults(query))
{
new id = data[0];

g_PlayerData[id][EXPIRED] = SQL_ReadResult(query, 0);
g_PlayerData[id][GAG_BLOCK_TYPE] = any:SQL_ReadResult(query, 3);
SQL_ReadResult(query, 1, g_PlayerData[id][REASON], charsmax(g_PlayerData[][REASON]));
SQL_ReadResult(query, 2, g_PlayerData[id][ADMIN_STEAMID], charsmax(g_PlayerData[][ADMIN_STEAMID]));

set_user_block(id, g_PlayerData[id][GAG_BLOCK_TYPE]);
}
}
else log_amx("MySQL LoadPlayer is FAILED... [#%d] %s", errcode, err);

return PLUGIN_CONTINUE;
}

public SQL_ThreadHandler_BlockPlayer(failstate, Handle:query, err[], errcode)
{
if(failstate != TQUERY_SUCCESS)
log_amx("MySQL BLOCK is FAILED... [#%d] %s", errcode, err);

return PLUGIN_CONTINUE;
}


public SQL_ThreadHandler_UnblockPlayer(failstate, Handle:query, err[], errcode)
{
if(failstate != TQUERY_SUCCESS)
log_amx("MySQL UNBLOCK is FAILED... [#%d] %s", errcode, err);

return PLUGIN_CONTINUE;
}

public SQL_ThreadHandler_Truncate(failstate, Handle:query, err[], errcode)
{
if(failstate != TQUERY_SUCCESS)
log_amx("MySQL FLUSH is FAILED... [#%d] %s", errcode, err);

return PLUGIN_CONTINUE;
}
/* Tasks handlers */
public get_allow_level()
aes_get_level_name(g_Cvar[MIN_ALLOW_VAL], g_szAesLevelName, charsmax(g_szAesLevelName), LANG_SERVER);

public CheckBlockedUsers()
{
new players[MAX_PLAYERS], pnum;
get_players_ex(players, pnum);

for(new i, id, sys = get_systime(); i < pnum; ++i)
{
id = players[i];

if(g_PlayerData[id][EXPIRED] > 0)
{
if(sys > g_PlayerData[id][EXPIRED])
user_unblock(id);
}
}
}
/* Menu Handlers */
public GagMenuHandler(id, iKey)
{
switch(iKey)
{
case 5:
{
if(++g_MenuData[id][SELECTED_TIME] > ArraySize(g_arrGagTimes)-1)
g_MenuData[id][SELECTED_TIME] = 0;

Show_GagMenu(id, g_MenuData[id][CURRENT_POS]);
}
case 6:
{
if(++g_MenuData[id][SELECTED_TYPE] > ArraySize(g_arrBlockTypes)-1)
g_MenuData[id][SELECTED_TYPE] = 0;

Show_GagMenu(id, g_MenuData[id][CURRENT_POS]);
}
case 7:
{
if(++g_MenuData[id][SELECTED_REASON] > ArraySize(g_arrReasons)-1)
g_MenuData[id][SELECTED_REASON] = 0;

Show_GagMenu(id, g_MenuData[id][CURRENT_POS]);
}
case 8: Show_GagMenu(id, ++g_MenuData[id][CURRENT_POS]);
case 9:
{
if(g_MenuData[id][CURRENT_POS])
Show_GagMenu(id, --g_MenuData[id][CURRENT_POS]);
}
default:
{
new player = g_arrPlayers[id][g_MenuData[id][CURRENT_POS] * GAG_MENU_ITEMS + iKey];

if(!is_user_connected(player))
{
Show_GagMenu(id, g_MenuData[id][CURRENT_POS]);
return PLUGIN_HANDLED;
}

new szAdminName[MAX_NAME_LENGTH], szPlayerName[MAX_NAME_LENGTH];
get_user_name(id, szAdminName, charsmax(szAdminName));
get_user_name(player, szPlayerName, charsmax(szPlayerName));

if(g_PlayerData[player][GAG_BLOCK_TYPE] > STATS)
{
user_unblock(player);

custom_color_chat(0, player, "%l %l", "MSG_PREFIX", "MSG_CHAT_UNBLOCK_ALL", szPlayerName, szAdminName);
custom_color_chat(player, 0, "%l %l", "MSG_PREFIX", "MSG_CHAT_UNBLOCK_PL", szPlayerName, szAdminName);
}
else
{
new blocktime = ArrayGetCell(g_arrGagTimes, g_MenuData[id][SELECTED_TIME]),
block_types:block_type = any:g_MenuData[id][SELECTED_TYPE],
blockreason[REASON_LENGTH];

ArrayGetString(g_arrReasons, g_MenuData[id][SELECTED_REASON], blockreason, charsmax(blockreason));

user_block(player, id, blocktime, blockreason, block_type);

new blocktimeinfo[32];

if(!blocktime)
formatex(blocktimeinfo, charsmax(blocktimeinfo), "навсегда");
else formatex(blocktimeinfo, charsmax(blocktimeinfo), "на %d минут", blocktime);

switch(block_type)
{
case TEXT_CHAT:
{
custom_color_chat(0, player, "%l %l", "MSG_PREFIX", "MSG_TEXTCHAT_BLOCK_ALL", szAdminName, szPlayerName, blocktimeinfo, blockreason);
custom_color_chat(player, 0, "%l %l", "MSG_PREFIX", "MSG_TEXTCHAT_BLOCK_PL", szPlayerName, szAdminName, blocktimeinfo, blockreason);
}
case VOICE_CHAT:
{
custom_color_chat(0, player, "%l %l", "MSG_PREFIX", "MSG_VOICECHAT_BLOCK_ALL", szAdminName, szPlayerName, blocktimeinfo, blockreason);
custom_color_chat(player, 0, "%l %l", "MSG_PREFIX", "MSG_VOICECHAT_BLOCK_PL", szPlayerName, szAdminName, blocktimeinfo, blockreason);
}
case ALL_CHATS:
{
custom_color_chat(0, player, "%l %l", "MSG_PREFIX", "MSG_ALLCHATS_BLOCK_ALL", szAdminName, szPlayerName, blocktimeinfo, blockreason);
custom_color_chat(player, 0, "%l %l", "MSG_PREFIX", "MSG_ALLCHATS_BLOCK_PL", szPlayerName, szAdminName, blocktimeinfo, blockreason);
}
}
}
Show_GagMenu(id, g_MenuData[id][CURRENT_POS]);
}
}
return PLUGIN_HANDLED;
}

public MuteMenuHandler(id, iKey)
{
switch(iKey)
{
case 6:
{
arrayset(g_PlayerMute[id], 1, sizeof g_PlayerMute[]);
custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_MUTE_ALL_PLAYERS");
}
case 7:
{
arrayset(g_PlayerMute[id], 0, sizeof g_PlayerMute[]);
custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", "MSG_UNMUTE_ALL_PLAYERS");
}
case 8: Show_MuteMenu(id, ++g_MenuData[id][CURRENT_POS]);
case 9:
{
if(g_MenuData[id][CURRENT_POS])
Show_MuteMenu(id, --g_MenuData[id][CURRENT_POS]);
}
default:
{
new player = g_arrPlayers[id][g_MenuData[id][CURRENT_POS] * MUTE_MENU_ITEMS + iKey];

if(!is_user_connected(player))
{
Show_MuteMenu(id, g_MenuData[id][CURRENT_POS]);
return PLUGIN_HANDLED;
}

new szName[MAX_NAME_LENGTH];
get_user_name(player, szName, charsmax(szName));

g_PlayerMute[id][player] = !g_PlayerMute[id][player];
custom_color_chat(id, 0, "%l %l", "MSG_PREFIX", g_PlayerMute[id][player] ? "MSG_MUTE_PLAYER" : "MSG_UNMUTE_PLAYER", szName);

Show_MuteMenu(id, g_MenuData[id][CURRENT_POS]);
}
}

return PLUGIN_HANDLED;
}
/* Plugin API */
public native_ucc_is_client_gaged(plugin, params)
{
enum { index = 1, exp_time, gag_reason, gag_type };

new id = get_param(index);

if(is_user_connected(id))
{
set_param_byref(exp_time, g_PlayerData[id][EXPIRED]);
set_string(gag_reason, g_PlayerData[id][REASON], charsmax(g_PlayerData[][REASON]));

if(params > 3)
set_param_byref(gag_type, any:g_PlayerData[id][GAG_BLOCK_TYPE]);

return (g_PlayerData[id][GAG_BLOCK_TYPE] > NONE);
}

log_error(AMX_ERR_NATIVE, "Client %d not connected or index out of range!", id);
return RETURN_ERR;
}

public native_ucc_set_client_gag(plugin, params)
{
enum { index = 1, admin_id, block_time, gag_reason, gag_type };

new id = get_param(index);
new admin = get_param(admin_id);
new type = (params > 4) ? get_param(gag_type) : any:ALL_CHATS;

if(!is_user_connected(id))
{
log_error(AMX_ERR_NATIVE, "Client %d not connected or index out of range!", id);
return RETURN_ERR;
}
if(!is_user_connected(admin))
admin = 0;

new szReason[REASON_LENGTH];
get_string(gag_reason, szReason, charsmax(szReason));

user_block(id, admin, get_param(block_time), szReason, any:type);
return RETURN_OK;
}
public native_ucc_is_client_muted(plugin, params)
{
enum { index = 1, player };

new id = get_param(index);
new victim = get_param(player);

if(!is_user_connected(id))
{
log_error(AMX_ERR_NATIVE, "Client %d not connected or index out of range!", id);
return RETURN_ERR;
}
if(!is_user_connected(victim))
{
log_error(AMX_ERR_NATIVE, "Client %d not connected or index out of range!", victim);
return RETURN_ERR;
}

return g_PlayerMute[id][victim];
}

public native_ucc_set_client_muted(plugin, params)
{
enum { index = 1, player, muted };

new id = get_param(index);
new victim = get_param(player);
new set_mute = get_param(muted);

if(!is_user_connected(id))
{
log_error(AMX_ERR_NATIVE, "Client %d not connected or index out of range!", id);
return RETURN_ERR;
}
if(!is_user_connected(victim))
{
log_error(AMX_ERR_NATIVE, "Client %d not connected or index out of range!", victim);
return RETURN_ERR;
}

g_PlayerMute[id][victim] = (set_mute > 0) ? 1 : 0;
return RETURN_OK;
}
/* hook__cvar_change callbacks */
public hook__cvar_change_ga(pCvar, szOldValue[], szNewValue[])
read__flags(szNewValue, cvars:GAG_ACCESS);
public hook__cvar_change_sa(pCvar, szOldValue[], szNewValue[])
read__flags(szNewValue, cvars:SUPER_ACCESS);
public hook__cvar_change_cbs_imm(pCvar, szOldValue[], szNewValue[])
read__flags(szNewValue, cvars:C_BY_S_IMMUNITY);
/* Private functions */
Get_Flags()
{
hook_cvar_change(pCvar6, "hook__cvar_change_ga");
hook_cvar_change(pCvar7, "hook__cvar_change_sa");
hook_cvar_change(pCvar8, "hook__cvar_change_cbs_imm");

new szFlags[32];
get_pcvar_string(pCvar6, szFlags, charsmax(szFlags));
read__flags(szFlags, cvars:GAG_ACCESS);
get_pcvar_string(pCvar7, szFlags, charsmax(szFlags));
read__flags(szFlags, cvars:SUPER_ACCESS);
get_pcvar_string(pCvar8, szFlags, charsmax(szFlags));
read__flags(szFlags, cvars:C_BY_S_IMMUNITY);
}

Get_ArrayCvars()
{
g_tAllowCmds = TrieCreate();
g_arrGagTimes = ArrayCreate();
g_arrBlockTypes = ArrayCreate(REASON_LENGTH); // вдруг кто-то под спайсом...
g_arrReasons = ArrayCreate(REASON_LENGTH);

enum { times = 0, block_names, reasons, allowed_commands };
get_lang_settings(times);
get_lang_settings(block_names);
get_lang_settings(reasons);
get_lang_settings(allowed_commands);
}

SQL__Connect()
{
/*
fucking amxx...
@ force load config configs/plugins/ucc.cfg
@ plugin stopped, if config not found
*/
new szPath[64];
get_localinfo("amxx_configsdir", szPath, charsmax(szPath));
add(szPath, charsmax(szPath), "/plugins/ucc.cfg");
if(file_exists(szPath))
{
server_cmd("exec %s", szPath);
server_exec();
}
else
{
log_amx("%l", "INSTALL_INFO");
pause("d");
return false;
}

new szHost[64], szUser[64], szPass[64], szDB[32];
get_pcvar_string(pCvar1, szHost, charsmax(szHost));
get_pcvar_string(pCvar2, szUser, charsmax(szUser));
get_pcvar_string(pCvar3, szPass, charsmax(szPass));
get_pcvar_string(pCvar4, szDB, charsmax(szDB));

SQL_SetAffinity("mysql");
g_hTuple = SQL_MakeDbTuple(szHost, szUser, szPass, szDB, MYSQL_TIMEOUT);

new errcode, errstr[128], Handle:hTest = SQL_Connect(g_hTuple, errcode, errstr, charsmax(errstr));
if(hTest == Empty_Handle)
set_fail_state("[SQL ERROR #%d] %s", errcode, errstr);
else
{
SQL_FreeHandle(hTest);
SQL_SetCharset(g_hTuple, "utf8");

new iClearPeriod = get_systime() - 86400 * get_pcvar_num(pCvar5);

new szQuery[1024];
formatex(szQuery, charsmax(szQuery),
"CREATE TABLE IF NOT EXISTS `ucc_gag` ( \
`id` smallint(6) NOT NULL AUTO_INCREMENT, \
`name` varchar(32) NOT NULL, \
`steamid` varchar(32) NOT NULL, \
`ip` varchar(16) NOT NULL, \
`admin_name` varchar(32) NOT NULL, \
`admin_steamid` varchar(32) NOT NULL, \
`admin_ip` varchar(32) NOT NULL, \
`create_time` int(11) NOT NULL, \
`expired_time` int(11) NOT NULL, \
`reason` varchar(%d) NOT NULL, \
`block_type` int(11) NOT NULL, \
PRIMARY KEY (`id`), \
UNIQUE KEY `steamid` (`steamid`) \
)ENGINE=InnoDB DEFAULT CHARSET=utf8; \
DELETE FROM `ucc_gag` WHERE (`expired_time` < '%d' AND `expired_time` > '0') OR (`expired_time` = '-1' AND `create_time` < '%d');",
REASON_LENGTH, iClearPeriod, iClearPeriod
);

SQL_ThreadQuery(g_hTuple, "SQL_ThreadHandler_Init", szQuery);
return true;
}

return false;
}

Reg_Commands()
{
if(has_vtc())
{
register_clcmd("amx_gagmenu", "clcmd_GagMenu");

if(g_Cvar[CHATS_BY_STATS] > DISABLE)
RegisterHookChain(RG_CBasePlayer_Spawn, "CBasePlayer_Spawn_Post", true);
}
else log_amx("For amx_gagmenu needed meta plugin VTC");

if(g_Cvar[SAY_MUTE])
{
register_clcmd("say /mute", "clcmd_MuteMenu");
register_clcmd("say_team /mute", "clcmd_MuteMenu");

RegisterHookChain(RG_CSGameRules_CanPlayerHearPlayer, "CanPlayerHearPlayer_Pre", false);
}

if(g_Cvar[SAY_SORRY])
{
register_clcmd("say /sorry", "clcmd_SaySorry");
register_clcmd("say_team /sorry", "clcmd_SaySorry");
}

register_clcmd("say", "clcmd_SayChat");
register_clcmd("say_team", "clcmd_SayChat");

register_srvcmd("uсc_flush", "srvcmd_Flush");
}
/* Main Menu for gags/mute */
Show_GagMenu(id, iPos)
{
new szAuth[MAX_AUTHID_LENGTH];
new start, end, pnum;
new iLen, szMenu[512];
new iKeys = MENU_KEY_0|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8;

get_players_ex(g_arrPlayers[id], pnum, GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);
get_user_authid(id, szAuth, charsmax(szAuth));

start = iPos * GAG_MENU_ITEMS;
end = start + GAG_MENU_ITEMS;

iLen = formatex(szMenu, charsmax(szMenu), "%l\w\R%d/%d^n^n", "MENU_GAG_HEADER", iPos + 1, (pnum / GAG_MENU_ITEMS + ((pnum % GAG_MENU_ITEMS) ? 1 : 0)));

if(start >= pnum)
start = iPos = g_MenuData[id][CURRENT_POS] = 0;
if(end > pnum)
end = pnum;

for(new i = start, bool:bSuper = bool:(get_user_flags(id) & g_Cvar[SUPER_ACCESS]), szName[MAX_NAME_LENGTH], player, a; i < end; ++i)
{
player = g_arrPlayers[id][i];
get_user_name(player, szName, charsmax(szName));

if(id == player)
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r%d. \d%s %l^n", ++a, szName, "MENU_GAG_ITEM_YOU");
else if(!bSuper && get_user_flags(player) & ADMIN_IMMUNITY)
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r%d. \d%s %l^n", ++a, szName, "MENU_GAG_ITEM_IMMUNITY");
else if(g_PlayerData[player][GAG_BLOCK_TYPE] > NONE)
{
if(g_PlayerData[player][GAG_BLOCK_TYPE] == STATS)
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r%d. \d%s %l^n", ++a, szName, "MENU_GAG_ITEM_LOWSTATS");
else if(bSuper || strcmp(g_PlayerData[player][ADMIN_STEAMID], szAuth) == 0)
{
iKeys |= (1 << a++);
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r%d. \w%s %l^n", a, szName, "MENU_GAG_ITEM_UNGAG");
}
}
else
{
iKeys |= (1 << a++);

if(VTC_IsClientSpeaking(player))
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r%d. \w%s %l^n", a, szName, "MENU_GAG_ITEM_SPEAKING");
else iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r%d. \w%s^n", a, szName);
}
}

static selected_string[REASON_LENGTH],
selected_time;

selected_time = ArrayGetCell(g_arrGagTimes, g_MenuData[id][SELECTED_TIME]);

if(!selected_time)
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "^n\r6. %l^n", "MENU_GAG_PERMANENT");
else iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "^n\r6. %l^n", "MENU_GAG_MINUTES", selected_time);

ArrayGetString(g_arrBlockTypes, g_MenuData[id][SELECTED_TYPE], selected_string, charsmax(selected_string));
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r7. %l^n", "MENU_GAG_BLOCK_TYPE", selected_string);
ArrayGetString(g_arrReasons, g_MenuData[id][SELECTED_REASON], selected_string, charsmax(selected_string));
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r8. %l^n^n", "MENU_GAG_REASON", selected_string);

if(end != pnum)
{
formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r9. %l^n\r0. %l", "MENU_ITEM_NEXT", iPos ? "MENU_ITEM_BACK" : "MENU_ITEM_EXIT");
iKeys |= MENU_KEY_9;
}
else formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r0. %l", iPos ? "MENU_ITEM_BACK" : "MENU_ITEM_EXIT");

show_menu(id, iKeys, szMenu, -1, "UCC GagMenu");
return PLUGIN_HANDLED;
}

Show_MuteMenu(id, iPos)
{
new start, end, pnum;
new iLen, szMenu[512];
new iKeys = MENU_KEY_0|MENU_KEY_7|MENU_KEY_8;

get_players_ex(g_arrPlayers[id], pnum, GetPlayers_ExcludeBots|GetPlayers_ExcludeHLTV);

start = iPos * MUTE_MENU_ITEMS;
end = start + MUTE_MENU_ITEMS;

iLen = formatex(szMenu, charsmax(szMenu), "%l\w\R%d/%d^n^n", "MENU_MUTE_HEADER", iPos + 1, (pnum / MUTE_MENU_ITEMS + ((pnum % MUTE_MENU_ITEMS) ? 1 : 0)));

if(start >= pnum)
start = iPos = g_MenuData[id][CURRENT_POS] = 0;
if(end > pnum)
end = pnum;

for(new i = start, szName[MAX_NAME_LENGTH], player, a; i < end; ++i)
{
player = g_arrPlayers[id][i];
get_user_name(player, szName, charsmax(szName));

if(id == player)
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r%d. \d%s %l^n", ++a, szName, "MENU_MUTE_ITEM_YOU");
else
{
iKeys |= (1 << a++);

if(g_PlayerMute[id][player])
iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r%d. \w%s %l^n", a, szName, "MENU_MUTE_ITEM_MUTED");
else iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r%d. \w%s^n", a, szName);
}
}

iLen += formatex(szMenu[iLen], charsmax(szMenu) - iLen, "^n\r7. %l^n\r8. %l^n^n", "MENU_MUTE_ALL_GAG", "MENU_MUTE_ALL_UNGAG");

if(end != pnum)
{
formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r9. %l^n\r0. %l", "MENU_ITEM_NEXT", iPos ? "MENU_ITEM_BACK" : "MENU_ITEM_EXIT");
iKeys |= MENU_KEY_9;
}
else formatex(szMenu[iLen], charsmax(szMenu) - iLen, "\r0. %l", iPos ? "MENU_ITEM_BACK" : "MENU_ITEM_EXIT");

show_menu(id, iKeys, szMenu, -1, "UCC MuteMenu");
return PLUGIN_HANDLED;
}

user_block(id, admin, blocktime, blockreason[REASON_LENGTH], block_types:block_type)
{
set_user_block(id, block_type);

new szName[MAX_NAME_LENGTH * 2], szIP[MAX_IP_LENGTH], szAuth[MAX_AUTHID_LENGTH];
get_user_name(id, szName, charsmax(szName));
get_user_ip(id, szIP, charsmax(szIP), true);
get_user_authid(id, szAuth, charsmax(szAuth));

new szAdminName[MAX_NAME_LENGTH * 2], szAdminIP[MAX_IP_LENGTH], szAdminAuth[MAX_AUTHID_LENGTH];
get_user_name(admin, szAdminName, charsmax(szAdminName));
get_user_ip(admin, szAdminIP, charsmax(szAdminIP), true);
get_user_authid(admin, szAdminAuth, charsmax(szAdminAuth));

new iSystime = get_systime();

g_PlayerData[id][EXPIRED] = !blocktime ? 0 : iSystime + blocktime * 60;
g_PlayerData[id][REASON] = blockreason;
g_PlayerData[id][ADMIN_STEAMID] = szAdminAuth;

mysql_escape_string(szName, charsmax(szName));
mysql_escape_string(szAdminName, charsmax(szAdminName));
mysql_escape_string(g_PlayerData[id][REASON], charsmax(g_PlayerData[][REASON]));

new szQuery[1024];
formatex(szQuery, charsmax(szQuery),
"INSERT INTO `ucc_gag` (`name`, `steamid`, `ip`, `admin_name`, `admin_steamid`, `admin_ip`, `create_time`, `expired_time`, `reason`, `block_type`) \
VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d', '%s', '%d') \
ON DUPLICATE KEY UPDATE `name` = '%s', `ip` = '%s', `admin_name` = '%s', `admin_steamid` = '%s', `admin_ip` = '%s', `create_time` = '%d', `expired_time` = '%d', `reason` = '%s', `block_type` = '%d'",
szName, szAuth, szIP, szAdminName, szAdminAuth, szAdminIP, iSystime, g_PlayerData[id][EXPIRED], g_PlayerData[id][REASON], any:block_type,
szName, szIP, szAdminName, szAdminAuth, szAdminIP, iSystime, g_PlayerData[id][EXPIRED], g_PlayerData[id][REASON], any:block_type
);

SQL_ThreadQuery(g_hTuple, "SQL_ThreadHandler_BlockPlayer", szQuery);
}

user_unblock(id)
{
if(is_blocked_voice_chat(id))
VTC_UnmuteClient(id);

g_PlayerData[id][EXPIRED] = -1;
g_PlayerData[id][REASON][0] = EOS;
g_PlayerData[id][ADMIN_STEAMID][0] = EOS;
g_PlayerData[id][GAG_BLOCK_TYPE] = NONE;

new szIP[MAX_IP_LENGTH], szAuth[MAX_AUTHID_LENGTH];
get_user_ip(id, szIP, charsmax(szIP), true);
get_user_authid(id, szAuth, charsmax(szAuth));

SQL_ThreadQuery(
g_hTuple,
"SQL_ThreadHandler_UnblockPlayer",
fmt("UPDATE `ucc_gag` SET `expired_time` = '-1' WHERE `ip` = '%s' OR `steamid` = '%s'", szIP, szAuth)
);
}

set_user_block(id, block_types:block_type)
{
g_PlayerData[id][GAG_BLOCK_TYPE] = block_type;

switch(block_type)
{
case STATS, VOICE_CHAT, ALL_CHATS:
{
VTC_MuteClient(id);
client_cmd(id, "-voicerecord");
}
}
}

bool:get_chats_access(id)
{
if(get_user_flags(id) & g_Cvar[C_BY_S_IMMUNITY])
return true;

new value;

switch(g_Cvar[CHATS_BY_STATS])
{
case DISABLE: return true;
case CSX:
{
#if defined CSX_EASY_STATS
new st[8], bh[12];
#else
new st[8], bh[HIT_RIGHTLEG + 1];
#endif
if(!get_user_stats(id, st, bh))
return false;

value = st[0];
}
case CSSTATS_MYSQL:
{
new st[22];
if(csstats_get_user_stats(id, st) <= 0)
return false;

value = st[0];
}
case CSSTATSX_SQL:
{
new st[8], bh[HIT_RIGHTLEG + 1];
if(!get_user_stats_sql(id, st, bh))
return false;

value = st[0];
}
case AES:
{
new st[1];
if((st[0] = aes_get_player_level(id)) == -1)
return false;

value = st[0];
}
#if defined CSX_EASY_STATS
case CSXES_GAMETIME:
{
new st[8], bh[12];
if(!get_user_stats(id, st, bh))
return false;

value = bh[10] * 60;
}
#endif
}

g_iFragStats[id] = value;
return (value < g_Cvar[MIN_ALLOW_VAL]) ? false : true;
}
/* Stocks */
stock read__flags(str[], cvars:cvar)
g_Cvar[cvar] = read_flags(str);

stock custom_color_chat(id, id2, const szMessage[], any:...)
{
new szMsg[190];
vformat(szMsg, charsmax(szMsg), szMessage, 4);

if(id) client_print_color(id, print_team_default, szMsg);
else
{
new players[MAX_PLAYERS], pnum;
get_players_ex(players, pnum, GetPlayers_ExcludeBots);
for(new i; i < pnum; ++i)
{
if(players[i] != id2)
{
client_print_color(players[i], print_team_default, szMsg);
}
}
}
}

stock get_lang_settings(cvar_type)
{
enum { times = 0, block_names, reasons, allowed_commands };

new Key,
dummy,
szLangKey[32],
szLangValue[256];

switch(cvar_type)
{
case times:
{
do {
formatex(szLangKey, charsmax(szLangKey), "CFG_GAG_TIMES_%d", Key++);

dummy = LookupLangKey(szLangValue, charsmax(szLangValue), szLangKey, dummy);
if(dummy) ArrayPushCell(g_arrGagTimes, str_to_num(szLangValue));
}
while(dummy)
}
case block_names:
{
for(new i; i < any:ALL_CHATS+1; ++i)
{
formatex(szLangKey, charsmax(szLangKey), "CFG_BLOCK_NAMES_%d", i);
if(LookupLangKey(szLangValue, charsmax(szLangValue), szLangKey, dummy))
ArrayPushString(g_arrBlockTypes, szLangValue);
}
}
case reasons:
{
do {
formatex(szLangKey, charsmax(szLangKey), "CFG_REASONS_%d", Key++);

dummy = LookupLangKey(szLangValue, charsmax(szLangValue), szLangKey, dummy);
if(dummy) ArrayPushString(g_arrReasons, szLangValue);
}
while(dummy)
}
case allowed_commands:
{
do {
formatex(szLangKey, charsmax(szLangKey), "CFG_ALLOW_COMMANDS_%d", Key++);

dummy = LookupLangKey(szLangValue, charsmax(szLangValue), szLangKey, dummy);
if(dummy) TrieSetCell(g_tAllowCmds, szLangValue, 1);
}
while(dummy)
}
}
}

stock mysql_escape_string(output[], len)
{
static const szReplaceIn[][] = { "\\", "\0", "\n", "\r", "\x1a", "'", "^"" };
static const szReplaceOut[][] = { "\\\\", "\\0", "\\n", "\\r", "\Z", "\'", "\^"" };
for(new i; i < sizeof szReplaceIn; i++)
replace_string(output, len, szReplaceIn[i], szReplaceOut[i]);
}
Плагин Ultimate Chats Control.
Не компилируется!
В файле 3 sma из которых только два компилируется а самый главный ucc.sma не компилируется.
По началу не хватала инклюидов в локальном компиляторе. Я их добавил и в итоге ошибка при компиляции стала такой как внизу.
Ошибки: 1.8.3 и 1.8.2
Компилятор использовал и WEB и Локальный!
AMX Mod X Compiler 1.8.3-dev+5147
Copyright (c) 1997-2006 ITB CompuPhase
Copyright (c) 2004-2013 AMX Mod X Team

ucc.sma(49) : error 017: undefined symbol "MAX_AUTHID_LENGTH"
ucc.sma(79) : error 017: undefined symbol "MAX_PLAYERS"
ucc.sma(83) : error 009: invalid array size (negative or zero)
ucc.sma(137) : error 017: undefined symbol "create_cvar"
ucc.sma(137) : warning 215: expression has no effect
ucc.sma(137) : error 029: invalid expression, assumed zero
ucc.sma(137) : error 017: undefined symbol "description"
ucc.sma(137) : fatal error 107: too many error messages on one line
 
Сообщения
55
Реакции
5
Помог
1 раз(а)
Mr_DETAL6KA, только что скомпилировал всё норм
 

Вложения

  • 14.9 KB Просмотры: 517
Сообщения
2,491
Реакции
2,791
Помог
61 раз(а)
может можете скинуть компилированный файл...
Не могут ибо на форуме запрещено скомпилированые файлы (не включая несколько исключений).
Вы далее компилируете веб компилятором или локально?
 
Сообщения
7
Реакции
7
Помог
1 раз(а)
тоже нормально компилирует, вот попробуй.
 

Вложения

Сообщения
1,419
Реакции
2,509
Помог
59 раз(а)
Как уже сказали выше, проблема в том что компилятор не обновлён, о чём говорит первая строчка компилятора: AMX Mod X Compiler 1.8.3-dev+5147
Можете скачать AMX Mod X вашей версии что установлена на сервера и скомпилировать, если конечно версия установленная на сервере не ниже 1.9.0.
 
Статус
В этой теме нельзя размещать новые ответы.

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

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