Правила форума Гаранты форума
Размещение рекламы AMX-X компилятор

Здравствуйте, гость Вход | Регистрация

Наши новости:

14-дек
24-апр
10-апр
11-апр

Помощь по SQL

Статус пользователя filip
сообщение 6.10.2015, 9:38
Сообщение #1


Стаж: 13 лет

Сообщений: 418
Благодарностей: 332
Полезность: 779

Очень нужна помощь людей, работавших с sql.
Есть sql банк. Плагин работает следующим образом: сверяет ваш id на форуме и если он указан, то на сервере вам доступен банк (предварительно нужна рега на форуме и заполнение графы STEAM ID)
Сделал его на основе туториалов и аналогичных плагинов. Свои функции плагин выполняет, но с косяком. Допустим если вы в самом начале карты зашли в свой банк, то проблем нет, ввод/вывод средств доступен. Но если через некоторое время игры попытаться повторно зайти в банк, вам выдается окошко как неавторизованному пользователю: "авторизуйтесь бла бла бла".

Моя догадка: видимо число открытых соединений к БД ограничено и она просто не воспринимает новые запросы. Как обрубать соединение после того, как игрок завершил снятие или пополнение счета в банке?
Код:
/* Plugin generated by AMXX-Studio */

#include <amxmodx>
#include <engine>
#include <cstrike>
#include <sqlx>
#include <money_ul>

#define PLUGIN "CSDM_Bank"
#define VERSION "1.0"
#define AUTHOR "rukojop:-)"

#define HOST ""
#define USER ""
#define PASS ""
#define DBASE ""

new Handle:SQL_Tuple
new Handle:SQL_Connection
new account_money[33]
new bool:autorized[33]

public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)

register_clcmd("say /test", "MainMenu")
register_clcmd("say /ttt", "qqq")

register_dictionary("bank.txt")

set_task(1.0, "mysql_connection")
}
public client_putinserver(id)
{
set_task(0.1, "CheckUser", id);
}
public mysql_connection(id)
{
new err, error[256]

SQL_Tuple = SQL_MakeDbTuple (HOST, USER, PASS, DBASE)
SQL_Connection = SQL_Connect(SQL_Tuple, err, error, charsmax(error))

if(SQL_Connection != Empty_Handle)
{
log_amx("[BANK connect ok]")
}else{
log_amx("[SQLX sql error] %s ",error)
}
}
public client_disconnect(id)
{
account_money[id] = 0
autorized[id] = false
}
public CheckUser(id)
{
new SteamId[35], szTemp[512]
new Data[1]
Data[0] = id
get_user_authid(id, SteamId, charsmax(SteamId))
format(szTemp, charsmax(szTemp), "SELECT `eco_points` FROM `ipb_pfields_content` WHERE `field_11` = '%s'", SteamId)
SQL_ThreadQuery (SQL_Tuple, "CheckUserHandle", szTemp, Data, 1)
}

public CheckUserHandle(FailState,Handle:Query,Error[],Errcode,Data[],DataSize)
{
/*new Float:money, field
field = SQL_FieldNameToNum(Query, "eco_points")
SQL_ReadResult(Query, field, money)
account_money[Data[0]] = floatround(money)*/
if(SQL_NumResults(Query) > 0)
{
new field = SQL_FieldNameToNum(Query, "eco_points")
account_money[Data[0]] = SQL_ReadResult(Query, field)
autorized[Data[0]] = true
}
else
{
autorized[Data[0]] = false
}
}
public qqq(id)
{
client_print(id,print_center,"Деньги %d", account_money[id])
}
public database_update(id)
{
new SteamId[35], szTemp[512]

get_user_authid(id, SteamId, charsmax(SteamId))
format(szTemp, charsmax(szTemp), "UPDATE `ipb_pfields_content` SET `eco_points`= '%i' WHERE `ipb_pfields_content`.`field_11` = '%s'", account_money[id], SteamId)
SQL_ThreadQuery (SQL_Tuple, "IgnoreHandle", szTemp)
}
public IgnoreHandle(FailState,Handle:Query,Error[],Errcode,Data[],DataSize)
{
SQL_FreeHandle(Query)
return PLUGIN_HANDLED
}
public MainMenu(id)
{
if (autorized[id])
{
new menu = menu_create("\rДобро пожаловать в Банк", "MainMenu_handler")

menu_additem(menu, "\wПополнить счет", "1")
menu_additem(menu, "\wСнять со счета","2")
menu_additem(menu, "\wПередать деньги","3")
menu_additem(menu, "\rВыход", "0")
menu_setprop(menu, MPROP_PERPAGE, 0)

// Устанавливаем свойства меню
//menu_setprop(i_Menu, MPROP_EXIT, MEXIT_ALL)
menu_display(id, menu, 0)

return PLUGIN_HANDLED
}else{
//client_print(id,print_center,"Авторизуйтесь на форуме")
show_motd(id, "autorizacion.txt", "Что дает авторизация")
}
return PLUGIN_HANDLED
}
public MainMenu_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)

// Если посмотреть раньше на использовании menu_additem, то можно увидеть, что мы посылали некоторую информацию
// В данном случае вся информация - целочисленная
new i_Key = str_to_num(s_Data)

// Теперь найдем, какая именно опция была использована
switch(i_Key)
{
case 1:
{
if( get_user_flags(id) & ADMIN_ADMIN )
{
client_print(id,print_center,"Банк работает только на вывод средств")
return PLUGIN_HANDLED
}
else Borrow(id)
// client_print(id,print_center,"Пополнить счет")
}
case 2:
{
Deduce(id)
// client_print(id,print_center,"Снять со счета")
}
case 3:
{
client_cmd(id,"say /donate")
//client_print(id,print_center,"Передать деньги")
}
}

// Уничтожение меню
menu_destroy(menu)
return PLUGIN_HANDLED
}
public Deduce(id)
{
new szText[ 555 char ]
formatex( szText, charsmax( szText ), "%L", id, "GIVE_MONEY", account_money[id]);
new Deduce_menu = menu_create( szText, "Deduce_handler" );

//new Deduce_menu = menu_create("\rВывод средств, \wв банке %i $", "Deduce_handler", account_money[id])

if(account_money[id] > 3000)
menu_additem(Deduce_menu, "Вывести 3000$", "1")
else
menu_additem(Deduce_menu, "Вывести 3000$", "1", ADMIN_ADMIN)
if (account_money[id] > 5000)
menu_additem(Deduce_menu, "Вывести 5000$", "2")
else
menu_additem(Deduce_menu, "Вывести 5000$", "2", ADMIN_ADMIN)
if (account_money[id] > 10000)
menu_additem(Deduce_menu, "Вывести 10 000$", "3")
else
menu_additem(Deduce_menu, "Вывести 10 000$", "3", ADMIN_ADMIN)
if (account_money[id] > 15000)
menu_additem(Deduce_menu, "Вывести 15 000$", "4")
else
menu_additem(Deduce_menu, "Вывести 15 000$", "4", ADMIN_ADMIN)
if (account_money[id] > 20000)
menu_additem(Deduce_menu, "Вывести 20 000$", "5")
else
menu_additem(Deduce_menu, "Вывести 20 000$", "5", ADMIN_ADMIN)
if (account_money[id] > 50000)
menu_additem(Deduce_menu, "Вывести 50 000$", "6")
else
menu_additem(Deduce_menu, "Вывести 50 000$", "6", ADMIN_ADMIN)

menu_additem(Deduce_menu, "\rВыход", "0")
menu_setprop(Deduce_menu, MPROP_PERPAGE, 0)
// Устанавливаем свойства меню
//menu_setprop(i_Menu, MPROP_EXIT, MEXIT_ALL)
menu_display(id, Deduce_menu, 0)
return PLUGIN_HANDLED
}
public Deduce_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)

// Если посмотреть раньше на использовании menu_additem, то можно увидеть, что мы посылали некоторую информацию
// В данном случае вся информация - целочисленная
new i_Key = str_to_num(s_Data)

// Теперь найдем, какая именно опция была использована
switch(i_Key)
{
case 1:
{
if( get_user_flags(id) & ADMIN_ADMIN )
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+3000)
}else{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+3000)
account_money[id] = account_money[id]-3000
client_print(id,print_center,"Избанка выведено 3 000")
database_update(id)
}
}
case 2:
{
if( get_user_flags(id) & ADMIN_ADMIN )
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+5000)
}else{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+5000)
account_money[id] = account_money[id]-5000
client_print(id,print_center,"Избанка выведено 5 000")
database_update(id)
}
}
case 3:
{
if( get_user_flags(id) & ADMIN_ADMIN )
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+10000)
}else{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+10000)
account_money[id] = account_money[id]-10000
client_print(id,print_center,"Избанка выведено 10 000")
database_update(id)
}
}
case 4:
{
if( get_user_flags(id) & ADMIN_ADMIN )
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+15000)
}else{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+15000)
account_money[id] = account_money[id]-15000
client_print(id,print_center,"Избанка выведено 15 000")
database_update(id)
}
}
case 5:
{
if( get_user_flags(id) & ADMIN_ADMIN )
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+20000)
}else{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+20000)
account_money[id] = account_money[id]-20000
client_print(id,print_center,"Избанка выведено 20 000")
database_update(id)
}
}
case 6:
{
if( get_user_flags(id) & ADMIN_ADMIN )
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+50000)
}else{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)+50000)
account_money[id] = account_money[id]-50000
client_print(id,print_center,"Избанка выведено 50 000")
database_update(id)
}
}
}

// Уничтожение меню
menu_destroy(menu)
return PLUGIN_HANDLED
}
public Borrow(id)
{
new szText[ 555 char ], szMoney
szMoney = cs_get_user_money_ul(id)
formatex( szText, charsmax( szText ), "%L", id, "POPOLNENIE", szMoney)
new Borrow_menu = menu_create( szText, "Borrow_handler" )

//new Borrow_menu = menu_create("\rПополнение банка, \wу Вас %d $", "Borrow_handler", szMoney)

if (cs_get_user_money(id) > 3000)
menu_additem(Borrow_menu, "\rПоложить \w3000\r$", "1")
if (cs_get_user_money(id) > 5000)
menu_additem(Borrow_menu, "\rПоложить \w5000\r$", "2")
if(cs_get_user_money(id) > 10000)
menu_additem(Borrow_menu, "\rПоложить \w10 000\r$", "3")
if (cs_get_user_money(id) > 15000)
menu_additem(Borrow_menu, "\rПоложить \w15 000\r$", "4")
if (cs_get_user_money(id) > 20000)
menu_additem(Borrow_menu, "\rПоложить \w20 000\r$", "5")
menu_additem(Borrow_menu, "\rПоложить \wВСЕ СРЕДСТВА\r$", "6")
menu_additem(Borrow_menu, "\rВыход", "0")
menu_setprop(Borrow_menu, MPROP_PERPAGE, 0)
// Устанавливаем свойства меню
//menu_setprop(i_Menu, MPROP_EXIT, MEXIT_ALL)
menu_display(id, Borrow_menu, 0)
return PLUGIN_HANDLED
}
public Borrow_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)

// Если посмотреть раньше на использовании menu_additem, то можно увидеть, что мы посылали некоторую информацию
// В данном случае вся информация - целочисленная
new i_Key = str_to_num(s_Data)

// Теперь найдем, какая именно опция была использована
switch(i_Key)
{
case 1:
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)-3000)
account_money[id] = account_money[id]+3000
client_print(id,print_center,"Вы сохранили в банк 3 000")
database_update(id)
}
case 2:
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)-5000)
account_money[id] = account_money[id]+5000
client_print(id,print_center,"Вы сохранили в банк 5 000")
database_update(id)
}
case 3:
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)-10000)
account_money[id] = account_money[id]+10000
client_print(id,print_center,"Вы сохранили в банк 10 000")
database_update(id)
}
case 4:
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)-15000)
account_money[id] = account_money[id]+15000
client_print(id,print_center,"Вы сохранили в банк 15 000")
database_update(id)
}
case 5:
{
cs_set_user_money_ul(id, cs_get_user_money_ul(id)-20000)
account_money[id] = account_money[id]+20000
client_print(id,print_center,"Вы сохранили в банк 20 000")
database_update(id)
}
case 6:
{
account_money[id] = account_money[id]+cs_get_user_money_ul(id)
client_print(id,print_center,"Вы сохранили в банк ВСЕ СВОИ ДЕНЬГИ")
cs_set_user_money_ul(id, 0)
database_update(id)
}
}

// Уничтожение меню
menu_destroy(menu)
return PLUGIN_HANDLED
}
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   Цитировать сообщение
Статус пользователя ThisIsSparta
сообщение 6.10.2015, 9:59
Сообщение #2
Стаж: 11 лет

Сообщений: 566
Благодарностей: 307
Полезность: 600

filip,
SQL_FreeHandle


попробуй после того как чекнул юзера на наличие в бд и загрузки данных освобождать дескриптор
Код:

public CheckUserHandle(FailState,Handle:Query,Error[],Errcode,Data[],DataSize)
{
if(SQL_NumResults(Query) > 0)
{
new field = SQL_FieldNameToNum(Query, "eco_points")
account_money[Data[0]] = SQL_ReadResult(Query, field)
autorized[Data[0]] = true
}
else
{
autorized[Data[0]] = false
}
SQL_FreeHandle(Query);
SQL_FreeHandle(SqlConnection);
}

Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя ykpon
сообщение 6.10.2015, 10:10
Сообщение #3


Стаж: 12 лет

Сообщений: 328
Благодарностей: 200
Полезность: < 0

Не может быть проблема в открытом соединении. И соединение открывается не от игрока, а от сервера, соответственно, если ты будешь закрывать соединение, то у кого то оно оборвется.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя filip
сообщение 6.10.2015, 12:55
Сообщение #4


Стаж: 13 лет

Сообщений: 418
Благодарностей: 332
Полезность: 779

ykpon, Можешь на пальцах объяснить взаимодействие сервера и БД? Соединение одно? Оно открыто всегда? Как это устроено?
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя ykpon
сообщение 6.10.2015, 13:11
Сообщение #5


Стаж: 12 лет

Сообщений: 328
Благодарностей: 200
Полезность: < 0

Цитата(filip @ 6.10.2015, 15:50) *
ykpon, Можешь на пальцах объяснить взаимодействие сервера и БД? Соединение одно? Оно открыто всегда? Как это устроено?

Вариант 1: Плагин включается, создается подключение к базе данных и висит, пока плагин не будет выключен либо оно не оборвется со стороны сервера базы данных.
Вариант 2: Плагин включается, выполняется какая нибудь функция с запросом в БД, соединение открывается, запрос выполняется, соединение закрывается.
Все зависит от того, как ты осуществляешь подключение.
У тебя есть функция, в которой создается подключение (38-51). Не вижу, правда, чтобы где то ты ее вызывал. Я в pawn не силен, конечно. Тут, наверное, каждое подключение открытым висит, пока плагин не отключится. Здесь же есть пример, как это реализовать. И в нем оно открыто, пока плагин не будет отключен. Ну и перед каждым запросом проверяется, открыто ли соединение. А запросы все выполняются как раз через уже открытое соединение.
Ну и, поди-ка, можно открывать соединение перед каждым запросом, а после запроса закрывать, но так не стоит делать, я думаю. Лучше проверять регулярно, открыто соединение или нет и, если закрыто, пробовать открыть, а если не открывается, выключать плагин и ждать, пока сможет открыть соединение.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
  Ответить в данную темуНачать новую тему
 
0 пользователей и 1 гостей читают эту тему: