Русское сообщество по скриптингу

Создание статистик на основе nvault

Статьи или фрагменты кода для новичков и уже опытных скриптеров по AMXX.

Модератор: Chuvi

Правила форума
1. Запрещено материться и оскорблять других участников форума.
2. Запрещен флуд, оффтоп, дабл постинг во всех разделах форума, кроме раздела "Болтовня".
3. Запрещено взламывать сайт/форум или наносить любой вред проекту.
4. Запрещено рекламировать другие ресурсы.
5. Запрещено создавать темы без информативного названия. Название темы должно отображать ее смысл.

В данном разделе форума разрешено создавать темы, касающие только обучающему материалу по AMX Mod X.

Создание статистик на основе nvault

Сообщение BaJIeHoK » 23 май 2014, 02:17

Приветствую пользователи amx-x
В данной статье я постараюсь рассказать как создавать статистики - /rank и /top на основе данных из nvault

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

Ну чтож - приступим.
Для начала будет работать с nvault

Для этого нам потребуется не только стандартный модуль, но и инклуд nvault_util, с которым вы можете познакомиться здесь Вы должны зарегистрироваться, чтобы видеть ссылки.

Советую прочитать всё крайне внимательно, потому что так вы мало что поймете
Надеюсь вы прочитали. Молодцы. Теперь создадим новый sma файл и добавим в него начальный код, который мы будем дополнять

[pawn]
  1. #include <amxmodx>

  2. #include <amxmisc>

  3. #include <nvault> //Подключаем стандартный nvault

  4. #include <nvault_util> //Подключаем инклуд

  5.  

  6. #define PLUGIN  "[TUT]StatsNvault(amx-x)"

  7. #define VERSION         "1.0"

  8. #define AUTHOR  "BaJIeHoK"

  9.  

  10. public plugin_init()

  11. {

  12.         register_plugin(PLUGIN, VERSION, AUTHOR)

  13. }

  14.  
[/pawn]

На примере мы будет сохранять/загружать 2 произвольных числа игрока. В качестве тестеров будут незаменимые podbot

Для начала создадим массив для хранение этих 2-х произвольных чисел
[pawn]
  1. new iPlayerNum[33][3]
[/pawn]

Теперь создадим команду для присвоение этих 2-х чисел игрокам.
[pawn]
  1. register_clcmd("say /set_num", "SetPlayerNum")
[/pawn]

Ну и создадим функцию SetPlayerNum
[pawn]
  1. public SetPlayerNum(id)

  2. {

  3.         new iPlayers[32] //Сюда запишем все id игроков

  4.         new iPlayer, iNum //А здесь будем хранить отдельного игрока и всех игроков

  5.  

  6.         get_players(iPlayers, iNum) //Получаем игроков

  7.  

  8.         for(new i; i < iNum; i++) //Прогоняем через цикл

  9.         {

  10.                 iPlayer = iPlayers[i] //Для удобности записываем игрока отдельно

  11.  

  12.                 iPlayerNum[iPlayer][1] += random_num(1, 1000) //Присваиваем 1 число

  13.                 iPlayerNum[iPlayer][2] += random_num(1, 1000) //Присваиваем 2 число

  14.         }

  15. }
[/pawn]

Ну чтож - у нас есть с чем работать - теперь давайте создадим сами функции получение и сохранение данных

Сначала напишем получение, создав функцию client_putinserver
[pawn]
  1. public client_putinserver(id)

  2. {

  3.         g_Vault = nvault_open("StatsNvault") //Открывает базу

  4.        

  5.         if(g_Vault == INVALID_HANDLE) //Если ошибка

  6.         {

  7.                 set_fail_state("NVault Error") //Делать нефиг, валим и отключаем плаг

  8.         }

  9.        

  10.         new szData[32] //Для хранение данных из базы

  11.  

  12.         new szName[32] //Сюда запишем ник

  13.         get_user_name(id, szName, charsmax( szName )) //Получаем ник

  14.  

  15.         nvault_get(g_Vault, szName, szData, charsmax( szData )) //Получаем данные

  16.         nvault_close( g_Vault ) //Закрываем базу

  17.  

  18.         replace_all(szData, charsmax( szData ), "#", " ") //Заменяем # на пробел(# - будет разделителям данных)

  19.  

  20.         new szParse[3][32] //Будем хранить спарсенные числа

  21.         parse(szData, //Откуда парсим

  22.                 szParse[1], 31, //Куда запишем 1 число

  23.                 szParse[2], 31 //Куда запишем 2 число

  24.         )

  25.  

  26.         iPlayerNum[id][1] = str_to_num( szParse[1] ) //Присваиваем 1 число игроку

  27.         iPlayerNum[id][2] = str_to_num( szParse[2] ) //Присваиваем 2 число игроку

  28. }
[/pawn]

Как вы наверное заметили переменная g_Vault - глобальная, поэтому её нужно создать
[pawn]
  1. new g_Vault
[/pawn]

Теперь нужно написать сохранение, для чего и создадим функцию client_disconnect
[pawn]
  1. public client_disconnect(id)

  2. {

  3.         g_Vault = nvault_open("StatsNvault") //Открывает базу

  4.        

  5.         if(g_Vault == INVALID_HANDLE) //Если ошибка

  6.         {

  7.                 set_fail_state("NVault Error") //Делать нефиг, валим и отключаем плаг

  8.         }

  9.        

  10.         new szData[32] //Для записи данных в базу

  11.  

  12.         new szName[32] //Сюда запишем ник

  13.         get_user_name(id, szName, charsmax( szName )) //Получаем ник

  14.  

  15.         formatex(szData, charsmax( szData ), "%i#%i", iPlayerNum[id][1], iPlayerNum[id][2]) //записываем

  16.  

  17.         nvault_set(g_Vault, szName, szData) //Сохраняем

  18.         nvault_close( g_Vault ) //Закрываем базу

  19. }
[/pawn]

Ну вот и сохранение готово. Не так уж и сложно, правда? Я думаю вы легко с этим справились, потому что самое сложное впереди.

Всё, что мы сделали показываю в целом коде
[pawn]
  1. #include <amxmodx>

  2. #include <amxmisc>

  3. #include <nvault> //Подключаем стандартный nvault

  4. #include <nvault_util> //Подключаем инклуд

  5.  

  6. #define PLUGIN  "[TUT]StatsNvault(amx-x)"

  7. #define VERSION         "1.0"

  8. #define AUTHOR  "BaJIeHoK"

  9.  

  10. new g_Vault

  11. new iPlayerNum[33][3]

  12.  

  13. public plugin_init()

  14. {

  15.         register_plugin(PLUGIN, VERSION, AUTHOR)

  16.  

  17.         register_clcmd("say /set_num", "SetPlayerNum") //Команда для присвоение чисел

  18. }

  19.  

  20. public SetPlayerNum(id)

  21. {

  22.         new iPlayers[32] //Сюда запишем все id игроков

  23.         new iPlayer, iNum //А здесь будем хранить отдельного игрока и всех игроков

  24.  

  25.         get_players(iPlayers, iNum) //Получаем игроков

  26.  

  27.         for(new i; i < iNum; i++) //Прогоняем через цикл

  28.         {

  29.                 iPlayer = iPlayers[i] //Для удобности записываем игрока отдельно

  30.  

  31.                 iPlayerNum[iPlayer][1] += random_num(1, 1000) //Присваиваем 1 число

  32.                 iPlayerNum[iPlayer][2] += random_num(1, 1000) //Присваиваем 2 число

  33.         }

  34. }

  35.  

  36. public client_putinserver(id)

  37. {

  38.         g_Vault = nvault_open("StatsNvault") //Открывает базу

  39.        

  40.         if(g_Vault == INVALID_HANDLE) //Если ошибка

  41.         {

  42.                 set_fail_state("NVault Error") //Делать нефиг, валим и отключаем плаг

  43.         }

  44.        

  45.         new szData[32] //Для хранение данных из базы

  46.  

  47.         new szName[32] //Сюда запишем ник

  48.         get_user_name(id, szName, charsmax( szName )) //Получаем ник

  49.  

  50.         nvault_get(g_Vault, szName, szData, charsmax( szData )) //Получаем данные

  51.         nvault_close( g_Vault ) //Закрываем базу

  52.  

  53.         replace_all(szData, charsmax( szData ), "#", " ") //Заменяем # на пробел(# - будет разделителям данных)

  54.  

  55.         new szParse[3][32] //Будем хранить спарсенные числа

  56.         parse(szData, //Откуда парсим

  57.                 szParse[1], 31, //Куда запишем 1 число

  58.                 szParse[2], 31 //Куда запишем 2 число

  59.         )

  60.  

  61.         iPlayerNum[id][1] = str_to_num( szParse[1] ) //Присваиваем 1 число игроку

  62.         iPlayerNum[id][2] = str_to_num( szParse[2] ) //Присваиваем 2 число игроку

  63. }

  64.  

  65. public client_disconnect(id)

  66. {

  67.         g_Vault = nvault_open("StatsNvault") //Открывает базу

  68.        

  69.         if(g_Vault == INVALID_HANDLE) //Если ошибка

  70.         {

  71.                 set_fail_state("NVault Error") //Делать нефиг, валим и отключаем плаг

  72.         }

  73.        

  74.         new szData[32] //Для записи данных в базу

  75.  

  76.         new szName[32] //Сюда запишем ник

  77.         get_user_name(id, szName, charsmax( szName )) //Получаем ник

  78.  

  79.         formatex(szData, charsmax( szData ), "%i#%i", iPlayerNum[id][1], iPlayerNum[id][2]) //записываем

  80.  

  81.         nvault_set(g_Vault, szName, szData) //Сохраняем

  82.         nvault_close( g_Vault ) //Закрываем базу

  83. }
[/pawn]

Теперь мы будет создавать получение ранга и топ игроков.
Перед продолжением прочтение я советую вам прочитать про array массивы, а то вам будет тяжко вникнуть в то, что будет расписано.

Прочитали?Надеюсь - приступаем.
Создаем функцию показа ранга игрока. Ранг будет вычисляться по 1-му числу(массив iPlayerNum[id][1]). 2 число создано для примера на топе и здесь нам не пригодится.

[pawn]
  1. public ShowRank(id)

  2. {

  3.         new iPlayers[32] //Сюда запишем все id игроков

  4.         new iPlayer, iNum //А здесь будем хранить отдельного игрока и всех игроков

  5.  

  6.         get_players(iPlayers, iNum) //Получаем игроков

  7.        

  8.         for(new i; i < iNum; i++) //Прогоняем через цикл

  9.         {

  10.                 iPlayer = iPlayers[i] //Для удобности записываем игрока отдельно

  11.  

  12.                 client_disconnect(iPlayer) //Вызываем всем принудительное сохранение

  13.         }

  14.  

  15.         new Array:aNames  = ArrayCreate(32) //Здесь будем ники хранить

  16.         new Array:aNums = ArrayCreate(1) //А тут числа

  17.  

  18.         new iPos, iCount, iTime //Всякая хрень

  19.  

  20.         g_Vault = nvault_util_open("StatsNvault") //Открываем базу

  21.         iCount = nvault_util_count( g_Vault ) //Получаем сколько всего записей

  22.  

  23.         for(new i; i < iCount; i++) //Прогоняем всех через цикл

  24.         {

  25.                 new szName[32], szData[10] //Для хранение данных

  26.                 iPos = nvault_util_read(g_Vault, iPos, szName, charsmax( szName ), szData, charsmax( szData ), iTime) //Получаем данные из базы

  27.  

  28.                 ArrayPushString(aNames, szName) //Записываем ник

  29.                 ArrayPushCell(aNums, str_to_num( szData )) //Записываем число

  30.  

  31.                 //Если сравнение нужно не по 1-ому числу, то нужно парсить строку =)

  32.         }

  33.  

  34.         nvault_util_close( g_Vault ) //Закрываем базу

  35.        

  36.         new iCheckNum //Будет служить временной меткой

  37.         for(new i,  j; i < ( iCount - 1 ); i++) //Прогоняем все данные, чтоюы сложить их по возврастанию

  38.         {

  39.                 iCheckNum = ArrayGetCell(aNums, i) //Получаем

  40.                

  41.                 for( j = i + 1; j < iCount; j++ ) //Начинаем прогонять хД

  42.                 {

  43.                         if(iCheckNum < ArrayGetCell(aNums, j)) //Если новое число больше

  44.                         {

  45.                                 ArraySwap(aNames, i,  j) //Сдвигаем ник

  46.                                 ArraySwap(aNums, i,  j)  //Сдвигаем число

  47.  

  48.                                 i-- //Пропускаем эту проверку

  49.                                 break //Заканчиваем цикл

  50.                         }

  51.                 }

  52.         }

  53.  

  54.         new szName[32], szParseName[32] //Сюда запишем ники

  55.         get_user_name(id, szName, charsmax( szName )) //Получаем ник

  56.  

  57.         for(new i; i < iCount; i++) //Снова прогоняем

  58.         {

  59.                 ArrayGetString(aNames, i, szParseName, charsmax( szParseName )) //Получаем ник

  60.            

  61.                 if(equal(szParseName, szName)) //Если совпадает

  62.                 {

  63.                         client_print(id, print_chat, "you rank %d is %d", (i + 1), iCount)

  64.                         break

  65.                 }

  66.         }

  67.  

  68.         ArrayDestroy(aNames) //Уничтожаем данные

  69.         ArrayDestroy(aNums) //Уничтожаем данные

  70.  

  71.         return PLUGIN_HANDLED

  72. }
[/pawn]

Ух, замутили ранк. На будующее скажу, что в mysql всё будет гораздо проще :crazy:
Ну сделали мы ранг - надо бы для него команду сделать
[pawn]
  1. register_clcmd("say /rank", "ShowRank")
[/pawn]

Теперь приступаем к топу.
Создание топа будет намного проще, потому что всю основу мы сделали в ранге =)

[pawn]
  1. public ShowTop(id)

  2. {

  3.         new iPlayers[32] //Сюда запишем все id игроков

  4.         new iPlayer, iNum //А здесь будем хранить отдельного игрока и всех игроков

  5.  

  6.         get_players(iPlayers, iNum) //Получаем игроков

  7.        

  8.         for(new i; i < iNum; i++) //Прогоняем через цикл

  9.         {

  10.                 iPlayer = iPlayers[i] //Для удобности записываем игрока отдельно

  11.  

  12.                 client_disconnect(iPlayer) //Вызываем всем принудительное сохранение

  13.         }

  14.  

  15.         new Array:aNames  = ArrayCreate(32) //Здесь будем ники хранить

  16.         new Array:aNum1 = ArrayCreate(1) //Тут число 1

  17.         new Array:aNum2 = ArrayCreate(1) //А тут число 2

  18.  

  19.         new iPos, iCount, iTime //Всякая хрень

  20.  

  21.         g_Vault = nvault_util_open("StatsNvault") //Открываем базу

  22.         iCount = nvault_util_count( g_Vault ) //Получаем сколько всего записей

  23.  

  24.         for(new i; i < iCount; i++) //Прогоняем всех через цикл

  25.         {

  26.                 new szName[32], szData[10] //Для хранение данных

  27.                 iPos = nvault_util_read(g_Vault, iPos, szName, charsmax( szName ), szData, charsmax( szData ), iTime) //Получаем данные из базы

  28.  

  29.                 replace_all(szData, charsmax( szData ), "#", " ") //Заменяем # на пробел(# - будет разделителям данных)

  30.        

  31.                 new szParseNum1[32], szParseNum2[32]

  32.                 parse(szData, //Откуда парсим

  33.                         szParseNum1, charsmax( szParseNum1 ), //Куда запишем 1 число

  34.                         szParseNum2, charsmax( szParseNum2 ) //Куда запишем 2 число

  35.                 )

  36.  

  37.                 ArrayPushString(aNames, szName) //Записываем ник

  38.                 ArrayPushCell(aNum1, str_to_num( szParseNum1 )) //Записываем 1 число

  39.                 ArrayPushCell(aNum2, str_to_num( szParseNum2 )) //Записываем 2 число

  40.         }

  41.  

  42.         nvault_util_close( g_Vault ) //Закрываем базу

  43.        

  44.         new iCheckNum //Будет служить временной меткой

  45.         for(new i,  j; i < ( iCount - 1 ); i++) //Прогоняем все данные, чтоюы сложить их по возврастанию

  46.         {

  47.                 iCheckNum = ArrayGetCell(aNum1, i) //Получаем

  48.                

  49.                 for( j = i + 1; j < iCount; j++ ) //Начинаем прогонять хД

  50.                 {

  51.                         if(iCheckNum < ArrayGetCell(aNum1, j)) //Если новое число больше

  52.                         {

  53.                                 ArraySwap(aNames, i,  j) //Сдвигаем ник

  54.                                 ArraySwap(aNum1, i,  j)  //Сдвигаем 1 число

  55.                                 ArraySwap(aNum2, i,  j)  //Сдвигаем 2 число

  56.  

  57.                                 i-- //Пропускаем эту проверку

  58.                                 break //Заканчиваем цикл

  59.                         }

  60.                 }

  61.         }

  62.  

  63.         new szName[32], szParseName[32] //Сюда запишем ники

  64.         new iParseNum[3] //А сюда цисла

  65.  

  66.         new szMotd[1540] //А здесь будем хранить структуру html motd

  67.         new iLen //Здесь его длину

  68.  

  69.         //Шаблон скомунизден из stats_shell

  70.         iLen += formatex(szMotd[iLen], charsmax( szMotd ) - iLen, "<meta charset=UTF-8><style>body{background:#E6E6E6;font-family:Verdana}th{background:#F5F5F5;color:#A70000;padding:6px;text-align:left}td{padding:2px 6px}table{color:#333;background:#E6E6E6;font-size:10px;font-family:Georgia;border:2px solid #D9D9D9}h2,h3{color:#333;}#c{background:#FFF}img{height:10px;background:#14CC00;margin:0 3px}#r{height:10px;background:#CC8A00}#clr{background:none;color:#A70000;font-size:20px;border:0}</style>" )

  71.         iLen += formatex(szMotd[iLen], charsmax( szMotd ) - iLen, "<table width=100%% height=100%% border=0 align=center cellpadding=0 cellspacing=1>")

  72.         iLen += formatex(szMotd[iLen], charsmax( szMotd ) - iLen, "<tr><th>#<th>Nick<th>Num1<th>Num2</tr>")

  73.  

  74.         get_user_name(id, szName, charsmax( szName )) //Получаем ник

  75.  

  76.         new iMax

  77.         if(iCount < 15)

  78.         {

  79.                 iMax = iCount

  80.         }else{

  81.                 iMax = 15

  82.         }

  83.  

  84.         for(new i; i < iMax; i++) //Снова прогоняем

  85.         {

  86.                 ArrayGetString(aNames, i, szParseName, charsmax( szParseName )) //Получаем ник

  87.                 iParseNum[1] = ArrayGetCell(aNum1, i) //Получаем 1 число

  88.                 iParseNum[2] = ArrayGetCell(aNum2, i) //Получаем 1 число

  89.  

  90.                 iLen += formatex(szMotd[iLen], charsmax( szMotd ) - iLen, "<tr><td>%d</td><td>%s</td><td>%d</td><td>%d</td></tr>", (i + 1), szParseName, iParseNum[1], iParseNum[2]) //Создаем строки в топе

  91.         }

  92.        

  93.         show_motd(id, szMotd, "StatsNvaultTop") //Непосредственно выводим наш топ

  94.  

  95.         ArrayDestroy(aNames) //Уничтожаем данные

  96.         ArrayDestroy(aNum1) //Уничтожаем данные

  97.         ArrayDestroy(aNum2) //Уничтожаем данные

  98.  

  99.         return PLUGIN_HANDLED

  100. }
[/pawn]

Могу вас поздравить - мы это сделали. Ранк и топ готовы. Вот целый плагин

[pawn]
  1. #include <amxmodx>

  2. #include <amxmisc>

  3. #include <nvault> //Подключаем стандартный nvault

  4. #include <nvault_util> //Подключаем инклуд

  5.  

  6. #define PLUGIN  "[TUT]StatsNvault(amx-x)"

  7. #define VERSION         "1.0"

  8. #define AUTHOR  "BaJIeHoK"

  9.  

  10. new g_Vault

  11. new iPlayerNum[33][3]

  12.  

  13. public plugin_init()

  14. {

  15.         register_plugin(PLUGIN, VERSION, AUTHOR)

  16.  

  17.         register_clcmd("say /set_num", "SetPlayerNum") //Команда для присвоение чисел

  18.         register_clcmd("say /rank", "ShowRank") //Команда для вывода ранга

  19.         register_clcmd("say /top", "ShowTop") //Команда для вывода топа

  20. }

  21.  

  22. public SetPlayerNum(id)

  23. {

  24.         new iPlayers[32] //Сюда запишем все id игроков

  25.         new iPlayer, iNum //А здесь будем хранить отдельного игрока и всех игроков

  26.  

  27.         get_players(iPlayers, iNum) //Получаем игроков

  28.  

  29.         for(new i; i < iNum; i++) //Прогоняем через цикл

  30.         {

  31.                 iPlayer = iPlayers[i] //Для удобности записываем игрока отдельно

  32.  

  33.                 iPlayerNum[iPlayer][1] += random_num(1, 5) //Присваиваем 1 число

  34.                 iPlayerNum[iPlayer][2] += random_num(1, 5) //Присваиваем 2 число

  35.         }

  36. }

  37.  

  38. public client_putinserver(id)

  39. {

  40.         g_Vault = nvault_open("StatsNvault") //Открывает базу

  41.        

  42.         if(g_Vault == INVALID_HANDLE) //Если ошибка

  43.         {

  44.                 set_fail_state("NVault Error") //Делать нефиг, валим и отключаем плаг

  45.         }

  46.        

  47.         new szData[32] //Для хранение данных из базы

  48.  

  49.         new szName[32] //Сюда запишем ник

  50.         get_user_name(id, szName, charsmax( szName )) //Получаем ник

  51.  

  52.         nvault_get(g_Vault, szName, szData, charsmax( szData )) //Получаем данные

  53.         nvault_close( g_Vault ) //Закрываем базу

  54.  

  55.         replace_all(szData, charsmax( szData ), "#", " ") //Заменяем # на пробел(# - будет разделителям данных)

  56.  

  57.         new szParse[3][32] //Будем хранить спарсенные числа

  58.         parse(szData, //Откуда парсим

  59.                 szParse[1], 31, //Куда запишем 1 число

  60.                 szParse[2], 31 //Куда запишем 2 число

  61.         )

  62.  

  63.         iPlayerNum[id][1] = str_to_num( szParse[1] ) //Присваиваем 1 число игроку

  64.         iPlayerNum[id][2] = str_to_num( szParse[2] ) //Присваиваем 2 число игроку

  65. }

  66.  

  67. public client_disconnect(id)

  68. {

  69.         g_Vault = nvault_open("StatsNvault") //Открывает базу

  70.        

  71.         if(g_Vault == INVALID_HANDLE) //Если ошибка

  72.         {

  73.                 set_fail_state("NVault Error") //Делать нефиг, валим и отключаем плаг

  74.         }

  75.        

  76.         new szData[32] //Для записи данных в базу

  77.  

  78.         new szName[32] //Сюда запишем ник

  79.         get_user_name(id, szName, charsmax( szName )) //Получаем ник

  80.  

  81.         formatex(szData, charsmax( szData ), "%i#%i", iPlayerNum[id][1], iPlayerNum[id][2]) //записываем

  82.  

  83.         nvault_set(g_Vault, szName, szData) //Сохраняем

  84.         nvault_close( g_Vault ) //Закрываем базу

  85. }

  86.  

  87. public ShowRank(id)

  88. {

  89.         new iPlayers[32] //Сюда запишем все id игроков

  90.         new iPlayer, iNum //А здесь будем хранить отдельного игрока и всех игроков

  91.  

  92.         get_players(iPlayers, iNum) //Получаем игроков

  93.        

  94.         for(new i; i < iNum; i++) //Прогоняем через цикл

  95.         {

  96.                 iPlayer = iPlayers[i] //Для удобности записываем игрока отдельно

  97.  

  98.                 client_disconnect(iPlayer) //Вызываем всем принудительное сохранение

  99.         }

  100.  

  101.         new Array:aNames  = ArrayCreate(32) //Здесь будем ники хранить

  102.         new Array:aNums = ArrayCreate(1) //А тут числа

  103.  

  104.         new iPos, iCount, iTime //Всякая хрень

  105.  

  106.         g_Vault = nvault_util_open("StatsNvault") //Открываем базу

  107.         iCount = nvault_util_count( g_Vault ) //Получаем сколько всего записей

  108.  

  109.         for(new i; i < iCount; i++) //Прогоняем всех через цикл

  110.         {

  111.                 new szName[32], szData[10] //Для хранение данных

  112.                 iPos = nvault_util_read(g_Vault, iPos, szName, charsmax( szName ), szData, charsmax( szData ), iTime) //Получаем данные из базы

  113.  

  114.                 ArrayPushString(aNames, szName) //Записываем ник

  115.                 ArrayPushCell(aNums, str_to_num( szData )) //Записываем число

  116.  

  117.                 //Если сравнение нужно не по 1-ому числу, то нужно парсить строку =)

  118.         }

  119.  

  120.         nvault_util_close( g_Vault ) //Закрываем базу

  121.        

  122.         new iCheckNum //Будет служить временной меткой

  123.         for(new i,  j; i < ( iCount - 1 ); i++) //Прогоняем все данные, чтоюы сложить их по возврастанию

  124.         {

  125.                 iCheckNum = ArrayGetCell(aNums, i) //Получаем

  126.                

  127.                 for( j = i + 1; j < iCount; j++ ) //Начинаем прогонять хД

  128.                 {

  129.                         if(iCheckNum < ArrayGetCell(aNums, j))  //Если новое число больше

  130.                         {

  131.                                 ArraySwap(aNames, i,  j) //Сдвигаем ник

  132.                                 ArraySwap(aNums, i,  j)  //Сдвигаем число

  133.  

  134.                                 i-- //Пропускаем эту проверку

  135.                                 break //Заканчиваем цикл

  136.                         }

  137.                 }

  138.         }

  139.  

  140.         new szName[32], szParseName[32] //Сюда запишем ники

  141.         get_user_name(id, szName, charsmax( szName )) //Получаем ник

  142.  

  143.         for(new i; i < iCount; i++) //Снова прогоняем

  144.         {

  145.                 ArrayGetString(aNames, i, szParseName, charsmax( szParseName )) //Получаем ник

  146.            

  147.                 if(equal(szParseName, szName)) //Если совпадает

  148.                 {

  149.                         client_print(id, print_chat, "you rank %d is %d", (i + 1), iCount)

  150.                         break

  151.                 }

  152.         }

  153.  

  154.         ArrayDestroy(aNames) //Уничтожаем данные

  155.         ArrayDestroy(aNums) //Уничтожаем данные

  156.  

  157.         return PLUGIN_HANDLED

  158. }

  159.  

  160. public ShowTop(id)

  161. {

  162.         new iPlayers[32] //Сюда запишем все id игроков

  163.         new iPlayer, iNum //А здесь будем хранить отдельного игрока и всех игроков

  164.  

  165.         get_players(iPlayers, iNum) //Получаем игроков

  166.        

  167.         for(new i; i < iNum; i++) //Прогоняем через цикл

  168.         {

  169.                 iPlayer = iPlayers[i] //Для удобности записываем игрока отдельно

  170.  

  171.                 client_disconnect(iPlayer) //Вызываем всем принудительное сохранение

  172.         }

  173.  

  174.         new Array:aNames  = ArrayCreate(32) //Здесь будем ники хранить

  175.         new Array:aNum1 = ArrayCreate(1) //Тут число 1

  176.         new Array:aNum2 = ArrayCreate(1) //А тут число 2

  177.  

  178.         new iPos, iCount, iTime //Всякая хрень

  179.  

  180.         g_Vault = nvault_util_open("StatsNvault") //Открываем базу

  181.         iCount = nvault_util_count( g_Vault ) //Получаем сколько всего записей

  182.  

  183.         for(new i; i < iCount; i++) //Прогоняем всех через цикл

  184.         {

  185.                 new szName[32], szData[10] //Для хранение данных

  186.                 iPos = nvault_util_read(g_Vault, iPos, szName, charsmax( szName ), szData, charsmax( szData ), iTime) //Получаем данные из базы

  187.  

  188.                 replace_all(szData, charsmax( szData ), "#", " ") //Заменяем # на пробел(# - будет разделителям данных)

  189.        

  190.                 new szParseNum1[32], szParseNum2[32]

  191.                 parse(szData, //Откуда парсим

  192.                         szParseNum1, charsmax( szParseNum1 ), //Куда запишем 1 число

  193.                         szParseNum2, charsmax( szParseNum2 ) //Куда запишем 2 число

  194.                 )

  195.  

  196.                 ArrayPushString(aNames, szName) //Записываем ник

  197.                 ArrayPushCell(aNum1, str_to_num( szParseNum1 )) //Записываем 1 число

  198.                 ArrayPushCell(aNum2, str_to_num( szParseNum2 )) //Записываем 2 число

  199.         }

  200.  

  201.         nvault_util_close( g_Vault ) //Закрываем базу

  202.        

  203.         new iCheckNum //Будет служить временной меткой

  204.         for(new i,  j; i < ( iCount - 1 ); i++) //Прогоняем все данные, чтоюы сложить их по возврастанию

  205.         {

  206.                 iCheckNum = ArrayGetCell(aNum1, i) //Получаем

  207.                

  208.                 for( j = i + 1; j < iCount; j++ ) //Начинаем прогонять хД

  209.                 {

  210.                         if(iCheckNum < ArrayGetCell(aNum1, j)) //Если новое число больше

  211.                         {

  212.                                 ArraySwap(aNames, i,  j) //Сдвигаем ник

  213.                                 ArraySwap(aNum1, i,  j)  //Сдвигаем 1 число

  214.                                 ArraySwap(aNum2, i,  j)  //Сдвигаем 2 число

  215.  

  216.                                 i-- //Пропускаем эту проверку

  217.                                 break //Заканчиваем цикл

  218.                         }

  219.                 }

  220.         }

  221.  

  222.         new szName[32], szParseName[32] //Сюда запишем ники

  223.         new iParseNum[3] //А сюда цисла

  224.  

  225.         new szMotd[1540] //А здесь будем хранить структуру html motd

  226.         new iLen //Здесь его длину

  227.  

  228.         //Шаблон скомунизден из stats_shell

  229.         iLen += formatex(szMotd[iLen], charsmax( szMotd ) - iLen, "<meta charset=UTF-8><style>body{background:#E6E6E6;font-family:Verdana}th{background:#F5F5F5;color:#A70000;padding:6px;text-align:left}td{padding:2px 6px}table{color:#333;background:#E6E6E6;font-size:10px;font-family:Georgia;border:2px solid #D9D9D9}h2,h3{color:#333;}#c{background:#FFF}img{height:10px;background:#14CC00;margin:0 3px}#r{height:10px;background:#CC8A00}#clr{background:none;color:#A70000;font-size:20px;border:0}</style>" )

  230.         iLen += formatex(szMotd[iLen], charsmax( szMotd ) - iLen, "<table width=100%% height=100%% border=0 align=center cellpadding=0 cellspacing=1>")

  231.         iLen += formatex(szMotd[iLen], charsmax( szMotd ) - iLen, "<tr><th>#<th>Nick<th>Num1<th>Num2</tr>")

  232.  

  233.         get_user_name(id, szName, charsmax( szName )) //Получаем ник

  234.  

  235.         new iMax

  236.         if(iCount < 15)

  237.         {

  238.                 iMax = iCount

  239.         }else{

  240.                 iMax = 15

  241.         }

  242.  

  243.         for(new i; i < iMax; i++) //Снова прогоняем

  244.         {

  245.                 ArrayGetString(aNames, i, szParseName, charsmax( szParseName )) //Получаем ник

  246.                 iParseNum[1] = ArrayGetCell(aNum1, i) //Получаем 1 число

  247.                 iParseNum[2] = ArrayGetCell(aNum2, i) //Получаем 1 число

  248.  

  249.                 iLen += formatex(szMotd[iLen], charsmax( szMotd ) - iLen, "<tr><td>%d</td><td>%s</td><td>%d</td><td>%d</td></tr>", (i + 1), szParseName, iParseNum[1], iParseNum[2]) //Создаем строки в топе

  250.         }

  251.        

  252.         show_motd(id, szMotd, "StatsNvaultTop") //Непосредственно выводим наш топ

  253.  

  254.         ArrayDestroy(aNames) //Уничтожаем данные

  255.         ArrayDestroy(aNum1) //Уничтожаем данные

  256.         ArrayDestroy(aNum2) //Уничтожаем данные

  257.  

  258.         return PLUGIN_HANDLED

  259. }
[/pawn]

Результат нашей работы:
2014-05-23_00002.jpg

2014-05-23_00003.jpg


По началу планировалось сделать сразу и для mysql, но что-то я малеха устал, поэтому как сделать тоже самое с mysql расскажу потом.

Данный метод можно применить, скажем - в armyranks.
Там уж топ вообще "мега продвинутый" :-D

Удачи
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
BaJIeHoK
 
Сообщения: 80
Зарегистрирован: 03 апр 2014, 23:49
Откуда: Москва
Забанен
Благодарил (а): 12 раз.
Поблагодарили: 55 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6

Re: Создание статистик на основе nvault

Сообщение abdobiskra » 06 май 2018, 15:19

спасибо
У меня проблема при попытке сэкономить id ?
Код: Выделить всё
 
ShowTop(id, szMotd[2048], topnum){
   
   new iPlayers[32]
   new iPlayer, iNum
   
   get_players(iPlayers, iNum)
   
   for(new i; i < iNum; i++)
   {
      iPlayer = iPlayers[i]
   
      client_disconnect(iPlayer)
   }
   
   new Array:g_SteamID = ArrayCreate(32, 1)
   new Trie: g_Name = TrieCreate()
   //new Array:aNames  = ArrayCreate(32)
   new Array:aNum1 = ArrayCreate(1)
   new Array:aNum2 = ArrayCreate(1)
   
   new iPos, iCount, iTime
   
   g_Vault = nvault_util_open("level_xp_rank")
   iCount = nvault_util_count( g_Vault )
   
   for(new i; i < iCount; i++)
   {
      
      new szName[32], szData[10]
      
      iPos = nvault_util_read(g_Vault, iPos, szName, charsmax( szName ), szData, charsmax( szData ), iTime)
      
      replace_all(szData, charsmax( szData ), "#", " ")
      
      new szParseNum1[32], szParseNum2[32]
      
      parse(szData, szParseNum1, charsmax( szParseNum1 ), szParseNum2, charsmax( szParseNum2 ))
      
      ArrayPushString(g_SteamID, szName)
      ArrayPushCell(aNum1, str_to_num( szParseNum1 ))
      ArrayPushCell(aNum2, str_to_num( szParseNum2 ))
      
   }
   
   nvault_util_close( g_Vault )
   
   new iCheckNum
   
   for(new i,  j; i < ( iCount - 1 ); i++)
   {
      
      iCheckNum = ArrayGetCell(aNum1, i)
      
      
      
      for( j = i + 1; j < iCount; j++ )
      {
         
         if(iCheckNum < ArrayGetCell(aNum1, j))
         {
            
            ArraySwap(g_SteamID, i,  j)
            ArraySwap(aNum1, i,  j) 
            
            ArraySwap(aNum2, i,  j) 
            
            i--
            
            break
         }
         
      }
      
   }
   
   new szName[32], szParseName[32], SteamID[32]
   new iParseNum[3]
   new iLen, size, Position
   
   iLen += formatex(szMotd[iLen], charsmax( szMotd ) - iLen,"%5s  %30s %25s %25s %25s" , "Rank", "Name", "XP", "Level", "Contry");
   
   
   size = min(ArraySize(g_SteamID), topnum)
   
   //for (Position = 0, Size = min(ArraySize(aNames), topnum); Position < Size; Position++)
   //{
   for(Position = size - 15 < 0 ? 0 : size - 15; Position < size && charsmax(szMotd) - iLen > 0; Position++)
   {
      ArrayGetString(g_SteamID , Position, SteamID, charsmax( SteamID ))
      //ArrayGetString(aNames, Position, szParseName, charsmax( szParseName ))
      TrieGetString(g_Name, SteamID, szParseName, charsmax(szParseName));
      //get_user_name(id, szParseName, charsmax( szParseName )) //???????? ???
      
      iParseNum[1] = ArrayGetCell(aNum1, Position)
      iParseNum[2] = ArrayGetCell(aNum2, Position)
      
      iLen += formatex(szMotd[iLen], charsmax( szMotd ) - iLen, "^n%5d  %25s %6.0d/%d", (Position + 1), szParseName, iParseNum[1], iParseNum[2])
   }
   
   //show_motd(id, szMotd, "Zombie Infection Top 15")
   
//   ArrayDestroy(g_SteamID)
//   ArrayDestroy(aNum1)
//   ArrayDestroy(aNum2)
   
   
   return size// PLUGIN_HANDLED
   
}
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
abdobiskra
 
Сообщения: 3
Зарегистрирован: 24 июн 2016, 16:56
Благодарил (а): 0 раз.
Поблагодарили: 0 раз.
Языки программирования: Half-Life 1

Пред.

Вернуться в Статьи / фрагменты кода

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 10