PDA

Просмотр полной версии : [Вопрос] Как сделать систему страниц для диалога с информацией из базы данных



Сергей
28.08.2019, 16:44
День добрый
Вопрос такой, значит делаю кнопки в диалоге: Далее и Назад
Дело дошло до того, что нужно подгрузить из БД по конкретному mysql_id информацию
Так вот, нажимаю я допустим в диалоге не на кнопки Далее или Назад, а на информацию

и в принте следующая информация


M-ID: - [ 1394 ] | Авторизован
Так вот для того чтобы подгрузить информацию, хочу использовать strdel для того, чтобы удалить всё, кроме чисел: 1394

И вот логический вопрос, как это сделать?)

m1n1vv
28.08.2019, 16:51
В чем смысл?

Сергей
28.08.2019, 17:46
В чем смысл?

Дальше мне нужно загрузить данные, и показать их игроку, а чтобы их загрузить нужен mysql_id в моем случае это
1394
Или вот ещё вопрос, как можно скрыть mysql_id при отображении диалогового окна
Т.е в данный момент так:


load_mysql_dd = cache_get_field_content_int(i, "mysql_id",m_connect);
cache_get_field_content(i, "p_act", load_p_act,Mysql_Log,30);
format(dialog_string, sizeof(dialog_string), "%s[%d] | %s\n", dialog_string,load_mysql_dd, load_p_act);

Вот убрать из диалога, это легко, но, дальше мне нужно будет работать с mysql_id
Я могу сейчас с ним в принципе работать, но, при условии того, что он остается в диалоге.
НО, я же не ищу легких путей, и хочу избавиться от него именно в диалоговом окне, может записывать все mysql_id'ы в переменную?

DeimoS
28.08.2019, 18:19
А не проще сохранить кэш и при выборе конкретного пункта просто работать с кэшем? Параметр listitem будет идентичен индексу строки в кэше. Если у тебя диалог может содержать несколько страниц, то тот же самый индекс можно получить по формуле "номер_страницы*максимальное_число_строк_на_странице+listitem"

Сергей
29.08.2019, 09:19
Хорошо, вот к примеру вся система целиком:


После запроса, ответ.


CacheID_List[playerid] = cache_save(Mysql_Log);
PageID_List[playerid] = 0;
PageCount_List[playerid] = rows;

#define MAX_ROWS_LIST 20

forward Show_PlayerListID(playerid);
public Show_PlayerListID(playerid)
{
if(CacheID_List[playerid] == Cache:-1) return SCMError(playerid, "[Server]: {FFFFFF}Нет активного кэша с информацией");
cache_set_active(CacheID_List[playerid],Mysql_Log);

static dialog_string[750];
dialog_string[0] = EOS;
new load_p_act[30],rows,i,load_name[MAX_PLAYER_NAME],load_mysql_dd;
i = PageID_List[playerid]*20;
rows = i+20;
if(rows > PageCount_List[playerid]) rows = PageCount_List[playerid];
for(; i < rows; i++)
{
load_mysql_dd = cache_get_field_content_int(i, "mysql_id",Mysql_Log);
cache_get_field_content(i, "nickname", load_name,Mysql_Log,MAX_PLAYER_NAME);
cache_get_field_content(i, "p_act", load_p_act,Mysql_Log,30);
format(dialog_string, sizeof(dialog_string), "%s[%d] | %s\n", dialog_string,load_mysql_dd, load_p_act);
}
if(PageCount_List[playerid] > MAX_ROWS_LIST && rows != PageCount_List[playerid]) strcat(dialog_string, "Далее\n");
if(PageID_List[playerid] != 0) strcat(dialog_string, "Назад");


new str[26];
format(str,sizeof(str),"%s",load_name);
SPD(playerid, dID_Dialog_pyatb, DIALOG_STYLE_LIST, str, dialog_string, "Выбор", "Отмена");
return 1;
}

В диалоге:


if(!strcmp_with_isnull(inputtext, "Далее >>>"))
{
PageID_List[playerid] += 1;
Show_PlayerListID(playerid);
return 1;
}
else if(!strcmp_with_isnull(inputtext, "<<< Назад"))
{
PageID_List[playerid] -= 1;
Show_PlayerListID(playerid);
return 1;
}
else
{
printf("Kol_Vo: %d",PageID_List[playerid]*PageCount_List[playerid]+listitem);

}

Складываем формулу, и получаем результат, в итоге ко мне не приходит то, что сейчас делать дальше с ней

DeimoS
29.08.2019, 09:41
if(!strcmp_with_isnull(inputtext, "Далее >>>"))
{
PageID_List[playerid] += 1;
Show_PlayerListID(playerid);
return 1;
}
else if(!strcmp_with_isnull(inputtext, "<<< Назад"))
{
PageID_List[playerid] -= 1;
Show_PlayerListID(playerid);
return 1;
}
else
{
new idx = PageID_List[playerid]*PageCount_List[playerid]+listitem;

new load_p_act[30],
load_name[MAX_PLAYER_NAME],
load_mysql_dd;
load_mysql_dd = cache_get_field_content_int(idx, "mysql_id",Mysql_Log);
cache_get_field_content(idx, "nickname", load_name,Mysql_Log,MAX_PLAYER_NAME);
cache_get_field_content(idx, "p_act", load_p_act,Mysql_Log,30);

printf("RowID: %d\nNicnName: %s\np_act: %s", load_mysql_dd, load_name, load_p_act);
}

Главное не забывай вовремя удалять кэш (при любом закрытии диалога + при выходе игрока перепроверяй, удалён ли он).
И тут, кстати, очень хорошо подходят pVar для хранения ID кэша и номера страницы. Количество строк можно узнавать их того же сохранённого кэша.
Как-то так:
const MAX_ROW_IN_PAGE = 30;
new pVarName__CacheID[] = "pVarName__CacheID";
new pVarName__Page[] = "pVarName__Page";

CMD:test(playerid)
{
new query_string[...];
format(query_string, sizeof(query_string), "SELECT ... FROM ... WHERE ...", ...);
mysql_tquery(mysql_connection_ID, query_string, "@MySQL__SomeFunc", "i", playerid);
return 1;
}


@MySQL__SomeFunc(playerid);
@MySQL__SomeFunc(playerid)
{
new row_count;
if(!GetPVarType(playerid, pVarName__CacheID))
{
cache_get_row_count(row_count);
if(!row_count)
{
SendClientMessage(playerid, 0xFF0000FF, "Ошибка: {FFFFFF}Таблица пуста.");
return 1;
}
SetPVarInt(playerid, pVarName__CacheID, _:cache_save());
}
else
{
cache_unset_active();// Это для того, чтоб в лог не писало предупреждение о том, что кэш уже активен, если он действительно был активен
cache_set_active(Cache:GetPVarInt(playerid, pVarName__CacheID));
cache_get_row_count(row_count);
}

new page = GetPVarInt(playerid, pVarName__Page);
new i = page*MAX_ROW_IN_PAGE;

// Форматируем диалог
return 1;
}
И если нужно повторно показать диалог, вызываем
@MySQL__SomeFunc(playerid);
напрямую.

Ну и удаление кэша можно сделать так:
stock SomeFunc(playerid)
{
if(GetPVarType(playerid, pVarName__CacheID))
{
cache_delete(Cache:GetPVarInt(playerid, pVarName__CacheID));
DeletePVar(playerid, pVarName__CacheID);
DeletePVar(playerid, pVarName__Page);
}
return 1;
}

Сергей
29.08.2019, 17:22
if(!strcmp_with_isnull(inputtext, "Далее >>>"))
{
PageID_List[playerid] += 1;
Show_PlayerListID(playerid);
return 1;
}
else if(!strcmp_with_isnull(inputtext, "<<< Назад"))
{
PageID_List[playerid] -= 1;
Show_PlayerListID(playerid);
return 1;
}
else
{
new idx = PageID_List[playerid]*PageCount_List[playerid]+listitem;

new load_p_act[30],
load_name[MAX_PLAYER_NAME],
load_mysql_dd;
load_mysql_dd = cache_get_field_content_int(idx, "mysql_id",Mysql_Log);
cache_get_field_content(idx, "nickname", load_name,Mysql_Log,MAX_PLAYER_NAME);
cache_get_field_content(idx, "p_act", load_p_act,Mysql_Log,30);

printf("RowID: %d\nNicnName: %s\np_act: %s", load_mysql_dd, load_name, load_p_act);
}

Главное не забывай вовремя удалять кэш (при любом закрытии диалога + при выходе игрока перепроверяй, удалён ли он).
И тут, кстати, очень хорошо подходят pVar для хранения ID кэша и номера страницы. Количество строк можно узнавать их того же сохранённого кэша.
Как-то так:
const MAX_ROW_IN_PAGE = 30;
new pVarName__CacheID[] = "pVarName__CacheID";
new pVarName__Page[] = "pVarName__Page";

CMD:test(playerid)
{
new query_string[...];
format(query_string, sizeof(query_string), "SELECT ... FROM ... WHERE ...", ...);
mysql_tquery(mysql_connection_ID, query_string, "@MySQL__SomeFunc", "i", playerid);
return 1;
}


@MySQL__SomeFunc(playerid);
@MySQL__SomeFunc(playerid)
{
new row_count;
if(!GetPVarType(playerid, pVarName__CacheID))
{
cache_get_row_count(row_count);
if(!row_count)
{
SendClientMessage(playerid, 0xFF0000FF, "Ошибка: {FFFFFF}Таблица пуста.");
return 1;
}
SetPVarInt(playerid, pVarName__CacheID, _:cache_save());
}
else
{
cache_unset_active();// Это для того, чтоб в лог не писало предупреждение о том, что кэш уже активен, если он действительно был активен
cache_set_active(Cache:GetPVarInt(playerid, pVarName__CacheID));
cache_get_row_count(row_count);
}

new page = GetPVarInt(playerid, pVarName__Page);
new i = page*MAX_ROW_IN_PAGE;

// Форматируем диалог
return 1;
}
И если нужно повторно показать диалог, вызываем
@MySQL__SomeFunc(playerid);
напрямую.

Ну и удаление кэша можно сделать так:
stock SomeFunc(playerid)
{
if(GetPVarType(playerid, pVarName__CacheID))
{
cache_delete(Cache:GetPVarInt(playerid, pVarName__CacheID));
DeletePVar(playerid, pVarName__CacheID);
DeletePVar(playerid, pVarName__Page);
}
return 1;
}

Хорошо, а без использования кэша, и всей этой кучи мороки, проще же будет прыгать по лимитам?

DeimoS
29.08.2019, 17:54
Хорошо, а без использования кэша, и всей этой кучи мороки, проще же будет прыгать по лимитам?

По каким лимитам?

Это наоборот самый универсальный и простой способ сделать диалог-список, который может содержать в себе сколько угодно строк одновременно.

Сергей
29.08.2019, 19:37
По каким лимитам?

Это наоборот самый универсальный и простой способ сделать диалог-список, который может содержать в себе сколько угодно строк одновременно.

Каждый раз чистить просто... Я по пробую второй вариант с Пварами и отпишу

DeimoS
29.08.2019, 20:58
Каждый раз чистить просто... Я по пробую второй вариант с Пварами и отпишу

В смысле? Тяжело вставить удаление кэша при выходе из сервера, отмене/закрытии диалога и выполнении действия? Ничего сложного же

Сергей
30.08.2019, 05:05
В смысле? Тяжело вставить удаление кэша при выходе из сервера, отмене/закрытии диалога и выполнении действия? Ничего сложного же

Дак яж не спорю, просто кто-то называет это геморный вариант, и предложил прыганье по страницам с использованием лимита именно в запросе

DeimoS
30.08.2019, 08:30
Дак яж не спорю, просто кто-то называет это геморный вариант, и предложил прыганье по страницам с использованием лимита именно в запросе

А, то есть, один раз отправить запрос и после работать с выгруженными данными гемморнее, чем постоянно форматировать и отсылать в базу новый запрос, всё так же выгружая данные и так же работая с кэшем, что и в первом варианте? Тот, кто тебе это посоветовал, явно знает как жить (нет).

Иными словами, в варианте с LIMIT ты лишь добавишь дополнительную отправку запроса в базу, тратя на это процессорное время и усложнив код в несколько раз. Весь остальной код у тебя будет практически таким же, за исключением отсутствия удаления кэша (но отчищать переменные при закрытии диалога всё так же придётся, а так же придётся как-то определять какую именно строку выбрал игрок, соотнося её с данными в таблице).
В общем, твой советчик - Григорий Остер от мира программирования :)

Сергей
30.08.2019, 08:56
А, то есть, один раз отправить запрос и после работать с выгруженными данными гемморнее, чем постоянно форматировать и отсылать в базу новый запрос, всё так же выгружая данные и так же работая с кэшем, что и в первом варианте? Тот, кто тебе это посоветовал, явно знает как жить (нет).

Иными словами, в варианте с LIMIT ты лишь добавишь дополнительную отправку запроса в базу, тратя на это процессорное время и усложнив код в несколько раз. Весь остальной код у тебя будет практически таким же, за исключением отсутствия удаления кэша (но отчищать переменные при закрытии диалога всё так же придётся, а так же придётся как-то определять какую именно строку выбрал игрок, соотнося её с данными в таблице).
В общем, твой советчик - Григорий Остер от мира программирования :)

Спасибо за пояснение)
UPD, по теме.
Вообщем, я по пробовал работать с индексом.
По страницам бегаю отлично, но, беда в том, что после первого ввода команды, выходит ошибка с нет активного кэша.



new string[78 + MAX_PLAYER_NAME + 50];
format(string, sizeof(string), "SELECT * FROM `"TABLES"` WHERE BINARY `nickname`='%s' AND `dates`='%s' ORDER BY `mysql_id` DESC;",names_player,dates3);
mysql_function_query(m_connect, string, true, "OnLoadCallBack", "d",playerid);


forward OnLoadCallBack(playerid);
public OnLoadCallBack(playerid)// Пришёл ответ из самого стока
{
new rows = cache_get_row_count(m_connect);
if(rows == 0) return SCMError(playerid,"[Log Info]: {FFFFFF}Логов не найдено.");
if(GetPVarInt(playerid,"ID_Test") == 1)
{
DeletePVar(playerid,"_NickName");
DeletePVar(playerid,"ID_Test");
cache_delete(Cache:CacheID_List[playerid],m_connect);
PageCount_List[playerid] = _:CacheID_List[playerid] = -1;
}
CacheID_List[playerid] = cache_save(m_connect);
PageID_List[playerid] = 0;
PageCount_List[playerid] = rows;
SetPVarInt(playerid,"ID_Test",1);
Show_PlayerListID(playerid);
return 1;
}
stock Show_PlayerListID(playerid)
{
if(CacheID_List[playerid] == Cache:-1) return SCMError(playerid, "[Server]: {FFFFFF}Нет активного кэша с информацией");
cache_set_active(CacheID_List[playerid],m_connect);

static dialog_string[750];
dialog_string[0] = EOS;
new load_p_act[30],rows,i,load_name[MAX_PLAYER_NAME],load_mysql_dd;
i = PageID_List[playerid]*20;
rows = i+20;
if(rows > PageCount_List[playerid]) rows = PageCount_List[playerid];
for(; i < rows; i++)
{
load_mysql_dd = cache_get_field_content_int(i, "mysql_id",m_connect);
cache_get_field_content(i, "nickname", load_name,m_connect,MAX_PLAYER_NAME);
cache_get_field_content(i, "p_act", load_p_act,m_connect,30);
format(dialog_string, sizeof(dialog_string), "%s[%d] | %s\n", dialog_string,load_mysql_dd, load_p_act);
}
if(PageCount_List[playerid] > MAX_ROWS_LIST && rows != PageCount_List[playerid]) strcat(dialog_string, "Далее\n");
if(PageID_List[playerid] != 0) strcat(dialog_string, "Назад");


new str[27];
format(str,sizeof(str),""COLOR_SERVER"%s",load_name);
SPD(playerid, dID_A_Panel_Logs, DIALOG_STYLE_LIST, str, dialog_string, "Выбор", "Отмена");
SetPVarString(playerid,"log_NickName",load_name);
return 1;
}
И сам диалог:



stock Show_InPlayer(playerid,listitem)
{
new idx = PageID_List[playerid]*PageCount_List[playerid]+listitem;
printf("idx: %d",idx);
new test_0[30],test_1[30],test_2[30],test_3[30];
new load_name[MAX_PLAYER_NAME];
cache_get_field_content(idx,"test_1",test_0,Mysql_Log,30);
cache_get_field_content(idx,"test_2",test_1,Mysql_Log,30);
cache_get_field_content(idx,"test_3",test_2,Mysql_Log,30);
cache_get_field_content(idx,"test_4",test_3,Mysql_Log,30);
//=========//
GetPVarString(playerid,"_NickName",load_name,MAX_PLAYER_NAME);
new str_r[400];
format(str_r,sizeof(str_r),"%s\n%s\n%s\%s",load_name,test_0,test_1,test_2,test_3);
SPD(playerid, dID_Dialog, DIALOG_STYLE_MSGBOX, "Info", str_r, "Ок","Назад");
return 1;
}
Ошибка:

[07:31:28 08/30/19] [WARNING] cache_get_field_content - no active cache
[07:31:28 08/30/19] [WARNING] cache_get_field_content - no active cache
[07:31:28 08/30/19] [WARNING] cache_get_field_content - no active cache
[07:31:28 08/30/19] [WARNING] cache_get_field_content - no active cache
Я так понимаю, что жалуется на загрузку данных из стока, НО, вот вопрос, если idx совпадает, и всё как бы нормально должно быть, почему же ошибка?
Она появляется именно тогда, когда кэша в принципе и не может быть, жмем в диалоге кнопку назад, и снова нажимаем на 1 наименование из списка, и вуаля, всё нормально работает, закрываем диалог, открываем снова, и снова ошибка с загрузкой данных....

DeimoS
30.08.2019, 09:48
cache_set_active используй при всяком обращении к сохранённому кэшу. Стоит отправить какой-то другой запрос в БД и плагин сразу переключается с твоего сохранённого кэша, из-за чего ошибка и появляется.

Сергей
30.08.2019, 17:45
cache_set_active используй при всяком обращении к сохранённому кэшу. Стоит отправить какой-то другой запрос в БД и плагин сразу переключается с твоего сохранённого кэша, из-за чего ошибка и появляется.

Хорошо, добавляем cache_set_active в сток с показом инфы, вводим команду, нажимаем на 1 из пунктов в диалоге, инфа появляется, пробуем повторить комбинацию ещё несколько раз, работает, НО, на 4-тый раз уже всё не так, на 5-тый раз уже всё ломается, непонятно почему...
Ошибка:



[15:47:55 08/30/19] [ERROR] CMySQLResult::GetRowDataByName() - invalid row index ('42') (Query: "SELECT * FROM `accounts` WHERE BINARY `nickname`='Names' AND `dates`='28/08/2019' ORDER BY `mysql_id` DESC;")
[15:47:55 08/30/19] [ERROR] CMySQLResult::GetRowDataByName() - invalid row index ('42') (Query: "SELECT * FROM `accounts` WHERE BINARY `nickname`='Names' AND `dates`='28/08/2019' ORDER BY `mysql_id` DESC;")
[15:47:55 08/30/19] [ERROR] CMySQLResult::GetRowDataByName() - invalid row index ('42') (Query: "SELECT * FROM `accounts` WHERE BINARY `nickname`='Names' AND `dates`='28/08/2019' ORDER BY `mysql_id` DESC;")
[15:47:55 08/30/19] [ERROR] CMySQLResult::GetRowDataByName() - invalid row index ('42') (Query: "SELECT * FROM `accounts` WHERE BINARY `nickname`='Names' AND `dates`='28/08/2019' ORDER BY `mysql_id` DESC;")

DeimoS
30.08.2019, 20:14
Эмм, а это тот запрос, с которым ты работаешь изначально? Если нет, то не везде проставил cache_set_active

Сергей
30.08.2019, 22:57
Эмм, а это тот запрос, с которым ты работаешь изначально? Если нет, то не везде проставил cache_set_active

Да, это именно первый запрос
Где ещё я его мог упустить? Если есть сток с информацией, и есть диалог, в котором я хожу по страницам, и сам собственно сток с инфой в котором уже есть cache_set_active

DeimoS
30.08.2019, 23:32
Да, это именно первый запрос
Где ещё я его мог упустить? Если есть сток с информацией, и есть диалог, в котором я хожу по страницам, и сам собственно сток с инфой в котором уже есть cache_set_active

Если это изначальный запрос, значит проблема в формуле, по которой определяешь индекс строки. Ну той, которая

"номер_страницы*максимальное_число_строк_на_странице+listitem"
Логируй все переменные.

Система, на самом деле, крайне простая. Главное раз вникнуть и понять принципы её работы. Там всё работает на нескольких переменных и, при этом, нет никаких лимитов на количество данных, которые возвращаются из базы.

Сергей
30.08.2019, 23:42
Если это изначальный запрос, значит проблема в формуле, по которой определяешь индекс строки. Ну той, которая

Логируй все переменные.

Система, на самом деле, крайне простая. Главное раз вникнуть и понять принципы её работы. Там всё работает на нескольких переменных и, при этом, нет никаких лимитов на количество данных, которые возвращаются из базы.

Так непонятно почему после 4-5 открываний диалога с информацией всё идёт по пи, к чёрту вообщем, вот что именно не понятно

DeimoS
30.08.2019, 23:50
Так непонятно почему после 4-5 открываний диалога с информацией всё идёт по пи, к чёрту вообщем, вот что именно не понятно

Ошибка в коде? :)
Говорю же, логируй значения переменных и смотри в какой момент времени и какие переменные начинают хранить неправильные значения. И от этого уже пляши

Сергей
31.08.2019, 10:08
Ошибка в коде? :)
Говорю же, логируй значения переменных и смотри в какой момент времени и какие переменные начинают хранить неправильные значения. И от этого уже пляши

Странная ерунда, перелистываем на вторую страницу, открываем информацию, и получаем ошибку... Возвращаемся на первую страницу, открываем информацию, всё нормально...

DeimoS
31.08.2019, 10:26
Странная ерунда, перелистываем на вторую страницу, открываем информацию, и получаем ошибку... Возвращаемся на первую страницу, открываем информацию, всё нормально...

Так а что странного? Ты либо показываешь вторую страницу, хотя данных у тебя есть только на первую/выбираешь пункт, которого не существует, либо у тебя ошибки в формулах/в присвоении значений переменным.

Повторяю уже, наверное, в третий раз: вместо этих рассуждений о странностях просто залогируй свой код и изучи логи на предмет странностей. Делов на 10 минут, если заняться.

Сергей
31.08.2019, 10:29
Так а что странного? Ты либо показываешь вторую страницу, хотя данных у тебя есть только на первую/выбираешь пункт, которого не существует, либо у тебя ошибки в формулах/в присвоении значений переменным.

Повторяю уже, наверное, в третий раз: вместо этих рассуждений о странностях просто залогируй свой код и изучи логи на предмет странностей. Делов на 10 минут, если заняться.

Так и получается, что информация есть только на первую страницу, а на вторую получается нет
И вот теперь снова логический вопрос, тут я так понимаю нужен костыль, снова запрос, и снова запись в кэш, правильно?

DeimoS
31.08.2019, 10:37
Так и получается, что информация есть только на первую страницу, а на вторую получается нет
И вот теперь снова логический вопрос, тут я так понимаю нужен костыль, снова запрос, и снова запись в кэш, правильно?

Эмм, что? Если у тебя в бд есть данные и на вторую страницу, то ты выгружаешь их СРАЗУ в кэш и уже дальше работаешь с кэшем. Никаких повторных запросов не потребуется. В этом и смысл такого метода.

Я же тебе выше давал практически готовый код на pVar. Там остаётся только внутренности диалога дописать и всё.

Сергей
31.08.2019, 19:22
Эмм, что? Если у тебя в бд есть данные и на вторую страницу, то ты выгружаешь их СРАЗУ в кэш и уже дальше работаешь с кэшем. Никаких повторных запросов не потребуется. В этом и смысл такого метода.

Я же тебе выше давал практически готовый код на pVar. Там остаётся только внутренности диалога дописать и всё.

Яя кароче понял, проблема в самой формуле, т.е, если у нас открыта первая страница всё нормально, перелиснул страницу на другую, сделал формулу в обратном направлении, как-бы и открывает информацию, но, неправильную)

UPD: не могу я вообщем придумать универсальную формулу, ничего не получается

DeimoS
01.09.2019, 04:51
Покажи весь код, что у тебя получился сейчас.

Сергей
01.09.2019, 15:50
Покажи весь код, что у тебя получился сейчас.

Ничего не изменилось, ибо работал по разным направлениям, искал баг возможно с переменными, и в итоге пришёл был к тому, что формула работает только в 1-дно стороннем порядке, новую я сделать увы не могу...



new names_player[MAX_PLAYER_NAME];
strmid(names_player,"Test_Names",0,strlen("Test_Names"),MAX_PLAYER_NAME);
new dates3[12];
format(dates3,sizeof(dates3),"28/08/2019");

new string[78 + MAX_PLAYER_NAME + 50];
format(string, sizeof(string), "SELECT * FROM `prizz` WHERE BINARY `nickname`='%s' AND `dates`='%s' ORDER BY `mysql_id` DESC;",names_player,dates3);
mysql_function_query(m_connect, string, true, "OnLoadIRSCallBack", "d",playerid);

forward OnLoadIRSCallBack(playerid);
public OnLoadIRSCallBack(playerid)// Пришёл ответ от запроса
{
new rows = cache_get_row_count(m_connect);
if(rows == 0) return SCM(playerid,-1,"ничего нет");
if(GetPVarInt(playerid,"tr_ID_Player") == 1)
{
DeletePVar(playerid,"_NickName");
DeletePVar(playerid,"tr_ID_Player");
DeletePVar(playerid,"UpdateIDPlayer");
cache_delete(Cache:CacheID_List[playerid],m_connect);
PageCount_List[playerid] = _:CacheID_List[playerid] = -1;
}
CacheID_List[playerid] = cache_save(m_connect);
PageID_List[playerid] = 0;
PageCount_List[playerid] = rows;
SetPVarInt(playerid,"tr_ID_Player",1);
Show_PlayerListID(playerid);
return 1;
}
stock Show_PlayerListID(playerid)
{
if(CacheID_List[playerid] == Cache:-1) return SCM(playerid,-1,"Нет активного кэша с информацией");
cache_set_active(CacheID_List[playerid],m_connect);
static dialog_string[750];
dialog_string[0] = EOS;

new load_p_act[30],rows,i,load_name[MAX_PLAYER_NAME],load_mysql_dd;
i = PageID_List[playerid]*20;
rows = i+20;

if(rows > PageCount_List[playerid]) rows = PageCount_List[playerid];
for(; i < rows; i++)
{
load_mysql_dd = cache_get_field_content_int(i, "mysql_id",Mysql_Log);
cache_get_field_content(i, "nickname", load_name,Mysql_Log,MAX_PLAYER_NAME);
cache_get_field_content(i, "p_act", load_p_act,Mysql_Log,30);
format(dialog_string, sizeof(dialog_string), "%s[%d] | %s\n", dialog_string,load_mysql_dd, load_p_act);
}
if(PageCount_List[playerid] > MAX_ROWS_LIST && rows != PageCount_List[playerid]) strcat(dialog_string, "Далее \n");
if(PageID_List[playerid] != 0) strcat(dialog_string, "Назад");


new str[30];
format(str,sizeof(str),"{FFFFFF}%s",load_name);
SPD(playerid, 100500, DIALOG_STYLE_LIST, str, dialog_string, "Выбор", "Отмена");
SetPVarString(playerid,"_NickName",load_name);
return 1;
}
case 100500:
{
if(response)
{
if(!strcmp_with_isnull(inputtext, "Далее >>>"))
{
SetPVarInt(playerid,"UpdateIDPlayer",2);
PageID_List[playerid] ++;
Show_PlayerListID(playerid);
return 1;
}
else if(!strcmp_with_isnull(inputtext, "<<< Назад"))
{
SetPVarInt(playerid,"UpdateIDPlayer",1);
if(PageID_List[playerid] != 0)PageID_List[playerid] --;
else if(PageID_List[playerid] == 0) PageID_List[playerid] = 0;
Show_PlayerListID(playerid);
return 1;
}
else Show_InPlayers(playerid,listitem);
}
}


stock Show_InPlayers(playerid,listitem)
{
new count[3] = 0;
count[0] = PageID_List[playerid];
count[1] = PageCount_List[playerid];

new idx;
if(GetPVarInt(playerid,"UpdateIDPlayer") == 2) idx = count[0]*count[1]+listitem;
else if(GetPVarInt(playerid,"UpdateIDPlayer") == 1) idx = idx = count[0]*count[1]-listitem;

printf("idx: %d",idx);
new load_act[30],load_result_1[30],load_result_2[30],load_Dates[30];
new load_name[MAX_PLAYER_NAME];

cache_set_active(CacheID_List[playerid],m_connect);
cache_get_field_content(idx,"p_act",load_act,m_connect,30);
cache_get_field_content(idx,"result_1",load_result_1,m_connect,30);
cache_get_field_content(idx,"result_2",load_result_2,m_connect,30);
cache_get_field_content(idx,"p_date",load_Dates,m_connect,30);

//=========//
GetPVarString(playerid,"_NickName",load_name,MAX_PLAYER_NAME);
new str_r[400];
format(str_r,sizeof(str_r),"%s\n%s\n%s\n%s",load_name,load_act,load_result_1,load_result_2,load_Dates);
SPD(playerid, 100501, DIALOG_STYLE_MSGBOX, "Информация", str_r, "Ок","Назад");
return 1;
}

UPD: Обновил подсчёты



new idx[2];
if(GetPVarInt(playerid,"UpdateLogPlayer") == 1) idx[1] = count[0]*count[1]+listitem;
else if(GetPVarInt(playerid,"UpdateLogPlayer") == 2) idx[0] = count[1]+count[0],idx[1] = idx[0]/(count[0]+count[0])+listitem-count[0];
else if(GetPVarInt(playerid,"UpdateLogPlayer") == 3) idx[1] = count[1]+listitem-count[0];
Для первой и второй страницы работает отлично, перехожу на 3-тью, и снова подсчёты нужно менять)
Как-то не очень хочется для каждой страницы делать нужные именно этой странице подсчёты.

DeimoS
02.09.2019, 21:53
Эмм, что у тебя тут за каша?
new idx;
if(GetPVarInt(playerid,"UpdateIDPlayer") == 2) idx = count[0]*count[1]+listitem;
else if(GetPVarInt(playerid,"UpdateIDPlayer") == 1) idx = idx = count[0]*count[1]-listitem;
Зачем тут разные формулы? Формула всегда будет одна: сначала количество страниц умножаешь на максимальное число строк на странице, тем самым узнавая какой первый ID строки будет показываться на этой странице, а потом к этому значению прибавляешь значение listitem, получая уже конкретную строку, которую выбрал игрок.

Вообще код крайне запутанным у тебя вышел. Я выше показывал как всё гораздо проще написать.

Сергей
02.09.2019, 22:30
Эмм, что у тебя тут за каша?
new idx;
if(GetPVarInt(playerid,"UpdateIDPlayer") == 2) idx = count[0]*count[1]+listitem;
else if(GetPVarInt(playerid,"UpdateIDPlayer") == 1) idx = idx = count[0]*count[1]-listitem;
Зачем тут разные формулы? Формула всегда будет одна: сначала количество страниц умножаешь на максимальное число строк на странице, тем самым узнавая какой первый ID строки будет показываться на этой странице, а потом к этому значению прибавляешь значение listitem, получая уже конкретную строку, которую выбрал игрок.

Вообще код крайне запутанным у тебя вышел. Я выше показывал как всё гораздо проще написать.

Дак не получается ни формулой овладеть в правильном состоянии чтобы она находилась, ни вашим примером
Как из рук всё выпало....

DeimoS
03.09.2019, 12:57
const PRIZE_MAX_ROW_IN_PAGE = 20;
new pVarName__Prize_CacheID[] = "pVarName__Prize_CacheID";
new pVarName__Prize_Page[] = "pVarName__Prize_Page";
new pVarName__Prize_RowIDX[] = "pVarName__Prize_RowIDX";

CMD:test(playerid)
{
ClearPrizeMySQLInfo(playerid);// Удаляем кэш на случай, если игрок уже работал с кэшем, но открытый диалог закрылся другим диалогом и старый кэш не удалился.

new names_player[MAX_PLAYER_NAME];
strmid(names_player,"Test_Names",0,MAX_PLAYER_NAME,MAX_PLAYER_NAME);
new dates3[12];
format(dates3,sizeof(dates3),"28/08/2019");

new query_string[80 + MAX_PLAYER_NAME + sizeof(dates3) + 1];
format(query_string, sizeof(query_string), "SELECT * FROM prizz WHERE BINARY nickname='%s' AND dates='%s' ORDER BY mysql_id DESC",
names_player,dates3);
mysql_tquery(Mysql_Log, query_string, "@MySQL__ShowPrizeList", "i", playerid);
return 1;
}


@MySQL__ShowPrizeList(playerid);
@MySQL__ShowPrizeList(playerid)
{
new row_count;
if(!GetPVarType(playerid, pVarName__Prize_CacheID))
{
row_count = cache_get_row_count();
if(!row_count)
{
SenPrizelientMessage(playerid, 0xFF0000FF, "Ошибка: {FFFFFF}Таблица пуста.");
return 1;
}
SetPVarInt(playerid, pVarName__Prize_CacheID, _:cache_save());
}
else
{
cache_set_active(Cache:0);
cache_set_active(Cache:GetPVarInt(playerid, pVarName__Prize_CacheID));
row_count = cache_get_row_count();
}

new page = GetPVarInt(playerid, pVarName__Prize_Page);
new i = page*PRIZE_MAX_ROW_IN_PAGE;

static dialog_string[750];
dialog_string[0] = EOS;

new load_p_act[30],
load_name[MAX_PLAYER_NAME],
load_mysql_dd;

for(new j; i < row_count; i++, j++)
{
if(j == PRIZE_MAX_ROW_IN_PAGE)
break;

load_mysql_dd = cache_get_field_content_int(i, "mysql_id", Mysql_Log);
cache_get_field_content(i, "nickname", load_name, Mysql_Log, MAX_PLAYER_NAME);
cache_get_field_content(i, "p_act", load_p_act, Mysql_Log);
format(dialog_string, sizeof(dialog_string), "%s[%d] | %s\n", dialog_string, load_mysql_dd, load_p_act);
}

if(row_count > (page*PRIZE_MAX_ROW_IN_PAGE)+PRIZE_MAX_ROW_IN_PAGE)
{
strcat(dialog_string, "Далее\n");
if(page > 0)
{
strcat(dialog_string, "Назад\n");
}
}
else if(page > 0)
{
strcat(dialog_string, "Назад\n");
}


new dialog_header[8+MAX_PLAYER_NAME+1];
format(dialog_header, sizeof(dialog_header), "{FFFFFF}%s", load_name);
SPD(playerid, 100500, DIALOG_STYLE_LIST, dialog_header, dialog_string, "Выбор", "Отмена");
return 1;
}


public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[])
{
if(dialogid == 100500)
{
if(!response)
{
ClearPrizeMySQLInfo(playerid);
return 1;
}

if(!strcmp(inputtext, "Далее"))
{
SetPVarInt(playerid, pVarName__Prize_Page, GetPVarInt(playerid, pVarName__Prize_Page)+1);
@MySQL__ShowPrizeList(playerid);
}
else if(!strcmp(inputtext, "Назад"))
{
SetPVarInt(playerid, pVarName__Prize_Page, GetPVarInt(playerid, pVarName__Prize_Page)-1);
@MySQL__ShowPrizeList(playerid);
}
else
{
cache_set_active(Cache:0);
cache_set_active(Cache:GetPVarInt(playerid, pVarName__Prize_CacheID));
new row_count = cache_get_row_count();

new page = GetPVarInt(playerid, pVarName__Prize_Page);
new idx = PRIZE_MAX_ROW_IN_PAGE*page+listitem;
SetPVarInt(playerid, pVarName__Prize_RowIDX, idx);

new load_act[30],
load_result_1[30],
load_result_2[30],
load_Dates[30],
load_name[MAX_PLAYER_NAME];

cache_get_field_content(idx, "nickname", load_name, m_connect);
cache_get_field_content(idx, "p_act", load_act, m_connect);
cache_get_field_content(idx, "result_1", load_result_1, m_connect);
cache_get_field_content(idx, "result_2", load_result_2, m_connect);
cache_get_field_content(idx, "p_date", load_Dates, m_connect);

//=========//
new str_r[400];
format(str_r, sizeof(str_r),"%s\n%s\n%s\n%s", load_name, load_act, load_result_1, load_result_2, load_Dates);
SPD(playerid, 100501, DIALOG_STYLE_MSGBOX, "Информация", str_r, "Ок","Назад");
}
return 1;
}
else if(dialogid == 100501)
{
if(!response)
{
@MySQL__ShowPrizeList(playerid);
DeletePVar(playerid, pVarName__Prize_RowIDX);
return 1;
}
cache_set_active(Cache:0);
cache_set_active(Cache:GetPVarInt(playerid, pVarName__Prize_CacheID));
new idx = GetPVarInt(playerid, pVarName__Prize_RowIDX);

new string[144+1];
cache_get_field_content(idx, "nickname", string, m_connect, MAX_PLAYER_NAME);
format(string, sizeof(string), "Была показана информация игрока %s. Кэш удалён!", string);
SendClientMessage(playerid, -1, string);

ClearPrizeMySQLInfo(playerid);
return 1;
}
return 1;
}

public OnPlayerDisconnect(playerid, reason)
{
ClearPrizeMySQLInfo(playerid);
return 1;
}

stock ClearPrizeMySQLInfo(playerid)
{
if(GetPVarType(playerid, pVarName__Prize_CacheID))
{
cache_delete(Cache:GetPVarInt(playerid, pVarName__Prize_CacheID));
DeletePVar(playerid, pVarName__Prize_CacheID);
DeletePVar(playerid, pVarName__Prize_Page);
DeletePVar(playerid, pVarName__Prize_RowIDX);
}
return 1;
}

На ошибки не проверял, но общий принцип работы с кэшем должен быть таким. Никаких формул для каждой отдельной страницы не нужно.