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

Создание статистик на основе 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

Сообщение Safety1st » 23 май 2014, 10:07

BaJIeHoK, с разделителями в виде '#' - лишняя работа, не надо так ;)
Каждый раз открывать/закрывать vault - зачем?
Если делать rank - то весь vault при старте карты лучше загружать в память, работать с данными в ней и сохранять в конце карты, а не мучать vault, особенно предварительным принудительным сохранением на каждый /rank и /top.

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

Большая часть гайда показывает, как НЕ надо делать. УжОс.
GoldSrc Gaming Community
Аватара пользователя
Safety1st
 
Сообщения: 1958
Зарегистрирован: 08 окт 2011, 05:41
Откуда: Moscow
Благодарил (а): 1690 раз.
Поблагодарили: 933 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Half-Life

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

Сообщение KORD_12.7 » 23 май 2014, 10:36

BaJIeHoK, в будущем, для сортировки массива юзай натив ArraySort.

Добавлено спустя 3 минуты 31 секунду:
А в новой версии АМХХ даже атив ArraySortEx запилили, который вроде как работает быстрее ArraySort-а.

_http://aghl.ru/ - Half-Life и Adrenaline Gamer: за пределами возможного
Аватара пользователя
KORD_12.7
Скриптер
 
Сообщения: 298
Зарегистрирован: 28 сен 2009, 10:14
Откуда: Владивосток
Благодарил (а): 142 раз.
Поблагодарили: 257 раз.
Опыт программирования: Больше трех лет
Языки программирования: Half-Life
Opposing Force
Adrenaline Gamer
Counter-Strike

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

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

KORD_12.7 писал(а):BaJIeHoK, в будущем, для сортировки массива юзай натив ArraySort.

Добавлено спустя 3 минуты 31 секунду:
А в новой версии АМХХ даже атив ArraySortEx запилили, который вроде как работает быстрее ArraySort-а.

Скрывать не буду - вообще не слышал. Буду изучать.
Спасибо

Добавлено спустя 2 минуты 21 секунду:
Developer писал(а):

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

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

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

Сообщение Safety1st » 23 май 2014, 12:39

BaJIeHoK, а ещё полезно сначала изучить имеющееся, прежде чем создавать что-то своё.
GoldSrc Gaming Community
Аватара пользователя
Safety1st
 
Сообщения: 1958
Зарегистрирован: 08 окт 2011, 05:41
Откуда: Moscow
Благодарил (а): 1690 раз.
Поблагодарили: 933 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Half-Life

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

Сообщение Radius » 23 май 2014, 12:44

BaJIeHoK, маленькая рекомендация, наладить отношения с опытными скриптерами и консультироваться с ними при написании статьи, а также давать им прочитать текст перед публикацией. Уверен Ваши статьи будут намного лучше и Вы сами бесплатно узнаете много нового.
Аватара пользователя
Radius
 
Сообщения: 530
Зарегистрирован: 12 июн 2013, 12:15
Откуда: Казань
Забанен
Благодарил (а): 71 раз.
Поблагодарили: 369 раз.
Опыт программирования: Около года
Языки программирования: Counter-Strike 1.6

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

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

Возникли такие вопросы: а при создании всяких top15, опять же, стандартными средствами CS Stats, там тоже в тупую проход по всем элементам в файле?
Аватара пользователя
Cloun
 
Сообщения: 89
Зарегистрирован: 28 мар 2013, 16:52
Благодарил (а): 17 раз.
Поблагодарили: 6 раз.
Опыт программирования: Около 3 месяцев
Языки программирования: Counter-Strike 1.6
C++ / Pure C

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

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

Нет, конечно. Файл читается раз за карту.
GoldSrc Gaming Community
Аватара пользователя
Safety1st
 
Сообщения: 1958
Зарегистрирован: 08 окт 2011, 05:41
Откуда: Moscow
Благодарил (а): 1690 раз.
Поблагодарили: 933 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Half-Life

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

Сообщение Cloun » 23 май 2014, 19:42

Где в памяти помещается топ? Посредством Array? А если в файле >10000 записей?
Аватара пользователя
Cloun
 
Сообщения: 89
Зарегистрирован: 28 мар 2013, 16:52
Благодарил (а): 17 раз.
Поблагодарили: 6 раз.
Опыт программирования: Около 3 месяцев
Языки программирования: Counter-Strike 1.6
C++ / Pure C

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

Сообщение Safety1st » 23 май 2014, 21:00

Давайте не будем более оффтопить в теме.
GoldSrc Gaming Community
Аватара пользователя
Safety1st
 
Сообщения: 1958
Зарегистрирован: 08 окт 2011, 05:41
Откуда: Moscow
Благодарил (а): 1690 раз.
Поблагодарили: 933 раз.
Опыт программирования: Больше трех лет
Языки программирования: Counter-Strike 1.6
Half-Life

След.

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

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

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