Версия: 1.0
Настройки
1. Указать в кавычках данные от вашей базы данных.
- Код: Выделить всё
new const sql_host[] = "" // Хост
new const sql_user[] = "" // Пользователь
new const sql_password[] = "" // Пароль
new const sql_base[] = "" // Название базы
new const sql_table[] = "" // Название таблицы
2. Создать в базе данных таблицу, название которой вы указали в первом пункте, с 7 столбцами.
Название - Тип - Длина
- Код: Выделить всё
name - varchar - 32
steamid - varchar - 32
ip - varchar - 32
code - varchar - 32
referals - int
points - int
refered - int
3. Если у вас версия AMX НЕ 1.8.3, вам придется переделывать функции цветного чата (с client_print_color на другое), т.к. я писал под свой сервер, где стоит 1.8.3.
Описание.
Плагин совмещает в себе две связанные функции.
Первая - система рефералов. Для игрока, первый раз зашедшего на сервер, генерируется код из 10 случайных символов (5 заглавных латинских букв и 5 цифр). Игроку доступно меню, в котором он может узнать свой код, ввести чей-то код и сделать ставку (но об этом чуть позже). Итак, вы узнали свой код и даете его своему другу. Он его вводит через меню и получает 25 очков (по дефолту). Вы же получаете 10 игроков. Введя один раз чей-то код, он не сможет больше ввести код кого-либо. Ваш же код ваши разные друзья могут вводить. 25 очков является стимулом ввести чей-то код, а вы соответственно за каждого приглашенного получаете 10. Все эти числа легко меняются в исходнике.
Вторая - собственно рулетка. Идея взята с сайтов-рулеток CS:GO. Всё просто. Игроки ставят очки, которые получили из реферальной системы или выиграли у других. Чем больше поставил - тем выше шанс на победу. В конце система с учетом шансов рандомно выбирает победителя. Победитель получает весь банк. Один игрок поставил -> появился HUD со всей информацией. Два игрока поставили -> пошел отсчет до конца игры.
Лично я на своем сервере хотел за эти очки давать привилегии, а сами очки продавать за реал. Всё-таки заманчиво купить 100 очков, выиграть чужие и купить админку за несколько тысяч. Но азарт есть азарт и на деле всё проиграется.
Проблемы.
Главная проблема заключается в том, что при помощи скачивания новых CS клиентов или с помощью чита для смены SteamID игроки могут накручивать (вводить свой же код), так как сохранение ВСЕГО идет на стим айди. При этом также сохраняются ники, айпи, стимайди, сколько пригласил, количество очков и так далее.
Что делать с этим?
Вариант 1. Вручную мониторить айпи. Очень геморойно и тупо. Но для экстремалов сойдет. (не забывайте про динамические айпи).
Вариант 2. Если у вас на сервере есть система уровней / званий и т.д. вы можете сделать условие для ввода чужого кода. Например, чтобы ввести чей-то код, надо поиграть на сервере какое-то время и чего-то добиться. Тогда накрутчиков не будет или эффективность их накрутки будет стремиться к нулю.
Вариант 3. Сделать сохранение по никам, при этом установив регистрацию.
Все данные сохраняются в базу, данные от которой вы указали вначале.
Посмотреть как работает плагин можете у меня на сервере из подписи. Правда у меня стоит ограничение на ввод кода по рангу.
QIWI: 79653987404
WebMoney: R349359535254
WebMoney: R349359535254
- Код: Выделить всё
#include < amxmodx >
#include < sqlx >
#define PLUGIN "[JBX] Roulette"
#define VERSION "0.1"
#define AUTHOR "Erasus"
new const g_szAlphabet[][] = {
"A",
"B",
"C",
"D",
"E",
"F",
"G",
"H",
"I",
"J",
"K",
"L",
"M",
"N",
"O",
"P",
"Q",
"R",
"S",
"T",
"U",
"V",
"W",
"X",
"Y",
"Z"
}
new g_iPoints[33];
new g_iReferals[33];
new g_szCode[33][32];
new g_iEmptyUser[33];
new g_iRefered[33];
new g_szQuery[512];
new bool:g_bGame;
new g_iCounter = 1;
new g_iBet[33];
new g_iTime;
new g_iBank;
new g_iPlayers;
new bool:g_bUserInformerRoulette[33];
new g_iSyncHud;
new g_iUserMinTicker[33];
new g_iUserMaxTicket[33];
new const sql_host[] = "" // Хост
new const sql_user[] = "" // Пользователь
new const sql_password[] = "" // Пароль
new const sql_base[] = "" // Название базы
new const sql_table[] = "" // Название таблицы
new Handle:SQL_Tuple;
new Handle:SQL_Connection;
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR);
register_clcmd("refer_code", "cmd_ReferCode");
register_clcmd("deposit", "cmd_MakeBet");
register_clcmd("say /roulette", "show_RouletteMenu");
g_iSyncHud = CreateHudSyncObj();
set_task(1.0, "roulette_Informer", 7324823, _, _, "b");
}
public cmd_MakeBet(id)
{
if(g_iBet[id])
{
client_print_color(id, print_team_red, "^1[^4JBXRoulette^1] Вы уже делали ставку!");
return PLUGIN_HANDLED;
}
new sz_Args[64], i_Deposit;
read_args(sz_Args, charsmax(sz_Args));
if(!sz_Args[0])
return PLUGIN_HANDLED;
remove_quotes(sz_Args);
i_Deposit = str_to_num(sz_Args);
if(i_Deposit <= 0)
{
client_print_color(id, print_team_red, "^1[^4JBXRoulette^1] Ставка должна быть больше 0!");
return PLUGIN_HANDLED;
}
if(g_iPoints[id] < i_Deposit)
{
client_print_color(id, print_team_red, "^1[^4JBXRoulette^1] У вас недостаточно очков!");
}else{
new sz_Name[32];
g_bGame = true;
get_user_name(id, sz_Name, charsmax(sz_Name));
client_print_color(0, print_team_blue, "^1[^4JBXRoulette^1] ^3%s ^1поставил ^3%d очков^1!", sz_Name, i_Deposit);
g_iPoints[id] -= i_Deposit;
g_iUserMinTicker[id] = g_iBank + 1;
g_iUserMaxTicket[id] = g_iBank + i_Deposit;
g_iBank += i_Deposit;
client_print_color(0, print_team_blue, "^1[^4JBXRoulette^1] ^1Его билеты: от ^3%d ^1до ^3%d^1.", g_iUserMinTicker[id], g_iUserMaxTicket[id]);
if(!g_iBet[id])
g_iPlayers++;
g_iBet[id] += i_Deposit;
if(g_iPlayers == 2)
{
client_print_color(0, print_team_red, "^1[^4JBXRoulette^1] Нашлось 2 игрока! Начинаем отсчет до конца игры!");
g_iTime = 60;
set_task(1.0, "count_time");
}
}
return PLUGIN_HANDLED;
}
public count_time()
{
if(g_iTime == -1)
return;
if(!g_iTime)
{
new i_Players[32], i_Num, i_Player, i_Result, i_Winner;
get_players(i_Players, i_Num);
i_Result = random_num(1, g_iBank);
for(new i = 0; i < i_Num; i++)
{
i_Player = i_Players[i];
if(!g_iBet[i_Player])
continue;
if(i_Result >= g_iUserMinTicker[i_Player] && i_Result <= g_iUserMaxTicket[i_Player])
{
i_Winner = i_Player;
break;
}else
continue;
}
new sz_Name[32], Float:f_Chance;
new const perc[] = "%";
g_bGame = false;
get_user_name(i_Winner, sz_Name, charsmax(sz_Name));
f_Chance = float(g_iBet[i_Player]) / float(g_iBank);
client_print_color(0, print_team_blue, "^1[^4JBXRoulette^1] Победный билет: ^3%d^1.", i_Result);
client_print_color(0, print_team_red, "^1[^4JBXRoulette^1] ^3%s ^1выиграл в этой игре ^3%d очков ^1с шансом ^3%d%s!", sz_Name, g_iBank, floatround(f_Chance * 100.0), perc);
g_iPoints[i_Winner] += g_iBank;
g_iCounter++;
g_iBank = 0;
g_iPlayers = 0;
arrayset(g_iBet, 0, 33);
arrayset(g_iUserMinTicker, 0, 33);
arrayset(g_iUserMaxTicket, 0, 33);
}else{
--g_iTime;
set_task(1.0, "count_time");
}
}
public roulette_Informer()
{
if(!g_bGame)
return;
new i_Players[32], i_Num, i_Player, i_Len;
static sz_Informer[512];
get_players(i_Players, i_Num);
i_Len += format(sz_Informer[i_Len], charsmax(sz_Informer) - i_Len, "Игра #%d^nБанк: %d очков^nОсталось: %d сек.^nУчастников: %d^n^n", g_iCounter, g_iBank, g_iTime, g_iPlayers);
for(new i = 0; i < i_Num; i++)
{
i_Player = i_Players[i];
if(!g_iBet[i_Player])
continue;
new sz_Name[32], Float:f_Chance;
get_user_name(i_Player, sz_Name, charsmax(sz_Name));
f_Chance = float(g_iBet[i_Player]) / float(g_iBank);
i_Len += format(sz_Informer[i_Len], charsmax(sz_Informer) - i_Len, "%s [%d очков - %d%%%% шанс]^n", sz_Name, g_iBet[i_Player], floatround(f_Chance * 100.0));
}
get_players(i_Players, i_Num, "ch");
for(new i = 0; i < i_Num; i++)
{
i_Player = i_Players[i];
if(g_bUserInformerRoulette[i_Player])
continue;
set_hudmessage(150, 150, 0, -1.0, 0.02, 0, 6.0, 1.0);
ShowSyncHudMsg(i_Player, g_iSyncHud, sz_Informer);
}
}
public cmd_ReferCode(id)
{
if(g_iEmptyUser[id])
{
client_print_color(id, print_team_red, "^1[^4JBXRoulette^1] ^3Перезайдите на сервер ^1для доступа к системе!");
return PLUGIN_HANDLED;
}
if(g_iRefered[id])
{
client_print_color(id, print_team_red, "^1[^4JBXRoulette^1] Вы уже вводили код.");
return PLUGIN_HANDLED;
}
new sz_Args[64];
read_args(sz_Args, charsmax(sz_Args));
if(!sz_Args[0])
return PLUGIN_HANDLED;
new data[1];
data[0] = id;
remove_quotes(sz_Args);
format(g_szQuery, charsmax(g_szQuery), "SELECT * FROM `%s` WHERE `code` LIKE '%s'", sql_table, sz_Args);
SQL_ThreadQuery(SQL_Tuple, "CheckData", g_szQuery, data, 1);
return PLUGIN_HANDLED;
}
public CheckData(FailState,Handle:Query,Error[],Errcode,Data[],DataSize)
{
if(FailState == TQUERY_CONNECT_FAILED)
log_amx("Load - Could not connect to SQL database. [%d] %s", Errcode, Error);
else if(FailState == TQUERY_QUERY_FAILED)
log_amx("Load Query failed. [%d] %s", Errcode, Error);
new id = Data[0]
if(SQL_NumResults(Query) < 1)
client_print_color(id, print_team_red, "^1[^4JBXRoulette^1] Код ^3не был найден^1!");
else{
new sz_Name[32], sz_MyName[32], sz_Steam[32], i_Refers, i_Points, i_Players[32], i_Num, i_Player, bool:is_Online, p_Id, szTemp[1024];
get_players(i_Players, i_Num);
get_user_name(id, sz_MyName, charsmax(sz_MyName));
SQL_ReadResult(Query, 0, sz_Name, charsmax(sz_Name));
SQL_ReadResult(Query, 1, sz_Steam, charsmax(sz_Steam));
i_Refers = SQL_ReadResult(Query, 4);
i_Points = SQL_ReadResult(Query, 5);
for(new i = 0; i < i_Num; i++)
{
i_Player = i_Players[i];
new tempSteam[32];
get_user_authid(i_Player, tempSteam, charsmax(tempSteam));
if(equal(sz_Steam, tempSteam))
{
is_Online = true;
p_Id = i_Player;
break;
}
}
if(p_Id == id)
{
client_print_color(id, print_team_red, "^1[^4JBXRoulette^1] Вы не можете пригласить самого себя!");
show_RouletteMenu(id);
return PLUGIN_HANDLED;
}
g_iRefered[id] = 1;
g_iPoints[id] += 100;
if(is_Online)
{
g_iPoints[p_Id] += 50;
g_iReferals[p_Id]++;
}else{
formatex(szTemp, charsmax(szTemp), "UPDATE `%s` SET `points` = '%d',`referals` = '%d' WHERE `steamid` = '%s'", sql_table, i_Points + 50, i_Refers + 1, sz_Steam)
SQL_ThreadQuery(SQL_Tuple, "IgnoreHandle", szTemp)
}
client_print_color(0, print_team_blue, "^1[^4JBXRoulette^1] ^3%s ^1успешно пригласил ^3%s^1!", sz_Name, sz_MyName);
client_cmd(0, "spk fvox/bell");
}
return PLUGIN_HANDLED
}
public plugin_cfg()
{
SQL_Tuple = SQL_MakeDbTuple(sql_host, sql_user, sql_password, sql_base)
new i_Error, sz_Error[256]
SQL_Connection = SQL_Connect(SQL_Tuple, i_Error, sz_Error, charsmax(sz_Error))
if(SQL_Connection != Empty_Handle)
log_amx("[SQL] Sucessfully connected.")
else{
log_amx("[SQL Error] %s ", sz_Error)
pause("a")
}
}
public client_putinserver(id)
{
new sz_Steam[32], data[1]
data[0] = id
get_user_authid(id, sz_Steam, charsmax(sz_Steam))
format(g_szQuery, charsmax(g_szQuery), "SELECT * FROM `%s` WHERE `steamid` LIKE '%s'", sql_table, sz_Steam)
SQL_ThreadQuery(SQL_Tuple, "CheckInfo", g_szQuery, data, 1)
}
public CheckInfo(FailState,Handle:Query,Error[],Errcode,Data[],DataSize)
{
if(FailState == TQUERY_CONNECT_FAILED)
log_amx("Load - Could not connect to SQL database. [%d] %s", Errcode, Error)
else if(FailState == TQUERY_QUERY_FAILED)
log_amx("Load Query failed. [%d] %s", Errcode, Error)
new id = Data[0]
if(SQL_NumResults(Query) < 1)
g_iEmptyUser[id] = 1
else{
g_iEmptyUser[id] = 0
SQL_ReadResult(Query, 3, g_szCode[id], 31);
g_iReferals[id] = SQL_ReadResult(Query, 4);
g_iPoints[id] = SQL_ReadResult(Query, 5);
g_iRefered[id] = SQL_ReadResult(Query, 6);
}
return PLUGIN_HANDLED
}
public client_disconnect(id)
{
new sz_Name[33], sz_Steam[32], sz_Ip[32], szTemp[1024];
get_user_authid(id, sz_Steam, charsmax(sz_Steam));
get_user_name(id, sz_Name, charsmax(sz_Name));
get_user_ip(id, sz_Ip, charsmax(sz_Ip), 1);
if(g_iEmptyUser[id])
{
formatex(g_szCode[id], 31, "%d%s%d%s%d%s%d%s%d%s", random_num(0, 9), g_szAlphabet[random_num(0, 25)], random_num(0, 9), g_szAlphabet[random_num(0, 25)], random_num(0, 9), g_szAlphabet[random_num(0, 25)], random_num(0, 9), g_szAlphabet[random_num(0, 25)], random_num(0, 9), g_szAlphabet[random_num(0, 25)]);
formatex(szTemp, charsmax(szTemp), "INSERT INTO `%s` (`name`, `steamid`, `ip`, `code`, `referals`, `points`, `refered`) VALUES ('%s', '%s', '%s', '%s', '0', '0', '0')", sql_table, sz_Name, sz_Steam, sz_Ip, g_szCode[id]);
}else
formatex(szTemp, charsmax(szTemp), "UPDATE `%s` SET `referals` = '%d',`points` = '%d',`refered` = '%d' WHERE `steamid` = '%s'", sql_table, g_iReferals[id], g_iPoints[id], g_iRefered[id], sz_Steam)
SQL_ThreadQuery(SQL_Tuple, "IgnoreHandle", szTemp)
g_iPoints[id] = 0;
g_iReferals[id] = 0;
g_iRefered[id] = 0;
formatex(g_szCode[id], 31, "");
}
public show_RouletteMenu(id)
{
if(g_iEmptyUser[id])
{
client_print_color(id, print_team_red, "^1[^4JBXRoulette^1] ^3Перезайдите на сервер ^1для доступа к меню!");
return;
}
new sz_Title[256], i_Menu;
formatex(sz_Title, charsmax(sz_Title), "\yВаш код: \r%s^n\yРефералов: \r%d^n\yОчков: \r%d", g_szCode[id], g_iReferals[id], g_iPoints[id]);
i_Menu = menu_create(sz_Title, "roulette_Handler");
if(!g_iBet[id])
menu_additem(i_Menu, "Сделать ставку", "1");
else
menu_additem(i_Menu, "Сделать ставку", "1", ADMIN_ADMIN);
if(!g_iRefered[id])
menu_additem(i_Menu, "Ввести код", "2");
else
menu_additem(i_Menu, "Ввести код", "2", ADMIN_ADMIN);
menu_additem(i_Menu, "Отправить код в чат и консоль", "3");
menu_additem(i_Menu, "\yМагазин \d[скоро]", "4", ADMIN_ADMIN);
menu_setprop(i_Menu, MPROP_EXITNAME, "Выход");
menu_setprop(i_Menu, MPROP_EXIT, MEXIT_ALL);
menu_display(id, i_Menu, 0);
}
public roulette_Handler(id, menu, item)
{
if (item == MENU_EXIT)
{
menu_destroy(menu);
return PLUGIN_HANDLED;
}
new s_Data[6], s_Name[64], i_Access, i_Callback;
menu_item_getinfo(menu, item, i_Access, s_Data, charsmax(s_Data), s_Name, charsmax(s_Name), i_Callback);
new i_Key = str_to_num(s_Data);
switch(i_Key)
{
case 1:
{
client_print_color(id, print_team_red, "^1[^4JBXRoulette^1] Введите сумму ставки.");
client_cmd(id, "messagemode deposit");
}
case 2:
{
if(!g_iRefered[id])
client_cmd(id, "messagemode refer_code");
else{
client_print_color(id, print_team_red, "^1[^4JBXRoulette^1] Вы уже вводили код.");
show_RouletteMenu(id);
}
}
case 3:
{
client_cmd(id, "say %s", g_szCode[id]);
client_print(id, print_console, "%s", g_szCode[id]);
}
}
menu_destroy(menu);
return PLUGIN_HANDLED;
}
public IgnoreHandle(FailState,Handle:Query,Error[],Errcode,Data[],DataSize)
{
SQL_FreeHandle(Query)
return PLUGIN_HANDLED
}
public plugin_end()
{
SQL_FreeHandle(SQL_Connection);
SQL_FreeHandle(SQL_Tuple);
}
Утверждено. //Leonidddd