Бот вывода статистики игрового сервера battlefield, для Discord сервера.

battlefieldarm

Customer
13 Апр 2016
249
20
54
Москва
Discord Bot работает с базой данных MySQL, информация берется от плагина прокона "CChatGUIDStatsLogger", соответственно настройки коннекта берем там.
На данном этапе бот запускается в виде консольного приложения, далее планируется переделка в службу Windows. Минимальные требования для запуска - наличие в системе установленного .Net Framework 4.7.2. Бот предоставляется "как есть". Если кого преследует тётя паранойя берем VisualStudio не ниже 2017 изучаем исходники и пересобираем самостоятельно.
Перед началом работы необходимо отредактировать файл конфигурации bot.json.

m_strHost - адрес сервера,
m_strDBPort - порт БД MySQL,
m_strDatabase - имя БД,
m_strUserName,m_strPassword - логин и пароль для соединения,
tableSuffix - суффикс, если используется,
botToken - токен берем здесь Discord Developer Portal — API Docs for Bots and Developers,
RolesHasPermission_SoldierInfo - перечисление дискорд-ролей вашего сервера через '|' имеющих право вызывать команды серии "SoldierInfo",
RolesHasPermission_SoldierStats - см. выше, то же, только "SoldierStats",
serverIndex - ServerID из tbl_server для которого будут работать команды.
(префикс '!')

"ping","test","hello" - проверка бота, параметры не требуются;

"fName","findName","searchName" - поиск игрока по имени, если нужно искать по частичному совпадению используем '*', при этом в результате будет выведен список совпадений без подробной информации о каждом игроке;
"fGuid","findGuid","searchGuid" - тоже что и выше, но уже по EA_GUID, поиск только по точному совпадению параметра.

"top10","top","topt" - Топ лист игроков, построенный на основе счета("Очки сетевой игры").
"stats" - статистика отдельного игрока.

Для работы этих команд необходимо внести изменения в структуру БД, описанных ниже.
"IpHistory" - просмотр истории изменений ip адресов игрока.
"NameHistory" - история изменений имени.
Для большинства команд надо указывать параметр, например:
"!fName Yugo_Amaryl", "!searchName yugo*", "!ipHistory Yugo_Amaryl", "!fGuid EA_D7DDBF43623E8E55C071EBCFABD094B2"
при этом регистр символов не учитывается.

Команда "stats" может вызываться в двух вариантах - без параметров, в этом случае поиск в базе производится по имени в дискорде; а также с указанием имени игрока в качестве параметра, в этом случае в конфигурации в RolesHasPermission_SoldierStats перечисляются дискорд-роли вашего сервера, которым будет доступен такой вызов, если ограничивать не требуется, то пишем туда "@everyone".

Теперь о доработке базы данных для сохранения статистики о смене ip и имен:
1. Необходимо создать таблицу "ip_history" и "soldiername_history":
SQL:
    CREATE TABLE `ip_history` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `PlayerID` int(11) NOT NULL,
    `IP_Address` varchar(15) NOT NULL,
    `IPv6_Address` varchar(16) DEFAULT NULL,
    `RecStamp` datetime NOT NULL,
    UNIQUE KEY `id_UNIQUE` (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

    CREATE TABLE `soldiername_history` (
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `PlayerID` int(11) NOT NULL,
    `Old_SoldierName` varchar(45) DEFAULT NULL,
    `New_SoldierName` varchar(45) NOT NULL,
    `RecStamp` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
    PRIMARY KEY (`id`),
    KEY `old_sldr` (`PlayerID`,`Old_SoldierName`),
    KEY `new_sldr` (`PlayerID`,`New_SoldierName`)
    ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

2. И добавить триггеры на таблицу "tbl_playerdata":
SQL:
    CREATE DEFINER = CURRENT_USER  TRIGGER `Имя_вашей_БД`.`tbl_playerdata_AFTER_UPDATE` AFTER UPDATE ON `tbl_playerdata` FOR EACH ROW
    BEGIN
        IF (NEW.IP_Address <> Old.IP_Address)
        THEN
            INSERT INTO `Имя_вашей_БД`.ip_history (PlayerID, IP_Address, IPv6_Address, RecStamp) VALUES (NEW.PlayerID, NEW.IP_Address, NEW.IPv6_Address, NOW());
        END IF;
        IF (NEW.SoldierName <> Old.SoldierName)
        THEN
            INSERT INTO `Имя_вашей_БД`.soldiername_history (PlayerID, New_SoldierName, Old_SoldierName) VALUES (NEW.PlayerID, NEW.SoldierName, OLD.SoldierName);
        END IF;
    END
Второй триггер не обязателен, добавляйте по желанию. Он блокирует замену значений полей "IP_Address", "PBGUID", "EAGUID", "SoldierName" на пустые.

SQL:
    CREATE DEFINER = CURRENT_USER TRIGGER `Имя_вашей_БД`.`tbl_playerdata_BEFORE_UPDATE` BEFORE UPDATE ON `tbl_playerdata` FOR EACH ROW
    BEGIN
        IF ((NEW.IP_Address = '') or (length(NEW.IP_Address) = 0)) and (OLD.IP_Address <> '') and (length(OLD.IP_Address) <> 0) THEN
            SET NEW.IP_Address = OLD.IP_Address;
        END IF;
        IF ((NEW.PBGUID = '') or (length(NEW.PBGUID) = 0)) and (OLD.PBGUID <> '') and (length(OLD.PBGUID) <> 0) THEN
            SET NEW.PBGUID = OLD.PBGUID;
        END IF;
        IF ((NEW.EAGUID = '') or (length(NEW.EAGUID) = 0)) and (OLD.EAGUID <> '') and (length(OLD.EAGUID) <> 0) THEN
            SET NEW.EAGUID = OLD.EAGUID;
        END IF;
        IF ((NEW.SoldierName = '') or (length(NEW.SoldierName) = 0)) and (OLD.SoldierName <> '') and (length(OLD.SoldierName) <> 0) THEN
            SET NEW.SoldierName = OLD.SoldierName;
        END IF;
    END
Обратите внимание, что после ключевого слова "TRIGGER" в коде должно быть указанно имя вашей БД.
Если история вам не интересна, то вносить изменения не нужно, бот должен работать без особых проблем, но при вызове соответствующих команд в консоль программы будут выводиться сообщения об ошибках выполнения запроса MySQL.

Перед внесением изменений в структуру вашей базы данных настоятельно рекомендую сделать бэкап!

Для сборки проекта в него необходимо установить следующий набор пакетов используя для этого панель управления NuGet:
MySql.Data
Discord.Net
Discord.Net.Commands
Discord.Net.Providers.WS4Net
Microsoft.Extensions.DependencyInjection версии не ниже 2.0.0
и еще ряд других, которые подтянутся автоматом, как зависимости к тем что вверху.

Для запуска бота в качестве службы windows необходимо выполнить его установку, одним из 2 способов: с помощью утилиты "installutil.exe", которая идет вместе с .Net или командой windows "sc create"
Опишу только первый вариант, т.к. он наиболее простой. Предположим, что бот находится в каталоге C:\Bot, в этом случае в консоли запущенной с правами администратора выполняем следующую команду "c:\Windows\Microsoft.NET\Framework\v4.0.30319\InstallUtil.exe C:\Bot\StatBotService.exe".
Если не возникнет каких-либо ошибок в процессе инсталляции службы, то в диспетчере служб ("services.msc") вы обнаружите "Discord bot service".
Если такое имя вас не устраивает или если необходимо установить несколько ботов в одной системе, то используем второй вариант.
Как устанавливать службу с помощью "sc" можно найти в интернете или прочитать во встроенной справке вызвав команду без параметров.

upd 10.03.19:
- изменена версия платформы .Net на 4.7.2
- привел в порядок исходники и набор пакетов в проекте, что привело к уменьшению количества файлов идущих в нагрузку к программе;
- добавил более корректное завершение сеанса клиента дискорда, для этого в консоли нажимаем кнопку "Esc" на клавиатуре, вместо красного крестика самого окна, после завершения сеанса программа закрывается автоматически.


upd 11.03.19:
- упаковка бота в windows сервис.
 

Вложения

Последнее редактирование:
  • Like
Реакции: Slawter

Slawter

Support team
5 Сен 2014
22.536
871
Завтра-после завтра посмотрю.
Тем кто арендует прокон как доп.услугу, а не держит собственный сервер на виндовс, надо просить нас установить бота?
 

battlefieldarm

Customer
13 Апр 2016
249
20
54
Москва
Закончил перенос бота в windows-сервис. Пока к сожалению сервис остался без логирования вызова команд, в будущем будет добавлен файл-лог. Так же прорабатываю механизм связки бота с прокон-сервером. Попробую научить бота рулить проконом.
Если есть пожелания касаемо запросов статистики пишите здесь или мне (Yugo_Amaryl) в дискорд.
Наш сервер в дискорде [ARM] Battlefield 4.
 
  • Like
Реакции: Slawter и Clin4

Slawter

Support team
5 Сен 2014
22.536
871
Это все очень круто.
Но как тот, кто предоставляет услуги по прокону, БД к игровым серверам, скажу так, что 90% владельцев именно заказывают услугу прокона и базы данных, а не поднимают их на своих мощностях.
Таким образом я думаю популяризация у данной версии плагина будет низкой, потому что во первых не все обладают своим Windows сервером, во вторых, большинство не справится с установкой и не станет заморачиваться. Это конечно только мои предположения, и просто я так думаю.
Для большинства было бы проще, если бы это было плагином к прокону, но это наверное уже совсем другая история.

В целом отлично, спасибо за старания. Я сам еще не пробовал, пока не дошел ни как до этого.
 
  • Like
Реакции: Clin4

battlefieldarm

Customer
13 Апр 2016
249
20
54
Москва
Есть у меня мысли по поводу интеграции бота во внутрь проконовского плагина, но могут возникнуть проблемы с разными версиями платформы .Net и, если такое случится, то вариант только один, пересобирать прокон целиком под последнюю версию фрэймворка. И в любом случае потребуется установка дотнета (4.7 минимум) в винде где все это крутится, если там версия ниже. На выходных займусь плотнее тестами и проверкой разных вариантов, если время будет. И если тут появляются люди с опытом программирования на c# или программирования вообще, прошу не прятаться, а делиться своими соображениями. Как вариант, если интеграцией не срастется можно хостить ботов в одной виртуальной машине, благо ресурсов бот жрет не много.
 
  • Like
Реакции: Clin4 и wanderer_rover

wanderer_rover

Customer
10 Июл 2017
129
3
43
Сделал все по инструкции.Бот работает.Но теперь ошибки в Adkats и статс логере.
[AdKats] UPDATE IGNORE
`tbl_playerdata`
SET
`SoldierName` = "Marlboro_Smoke",
`EAGUID` = "EA_A0B5B64FD87FF0996E51A52CD6F06787",
`ClanTag` = "",
`IP_Address` = "62.182.204.157",
`DiscordID` = NULL
WHERE
`PlayerID` = "110251"
[19:02:06 11] [AdKats] EXCEPTION-7500-A0.01-D-UpdatePlayer-Main11: [Error while updating player.][MySql.Data.MySqlClient.MySqlException: INSERT command denied to user 'user'@'localhost' for table 'ip_history'

У пользователя все права,почему нет доступа,непонятно.Была проблема с импортом триггера,но когда создал вручную,заработало.Только вот эта ошибка с доступом к таблице и осталась..Как вылечить,посоветуйте.
 

battlefieldarm

Customer
13 Апр 2016
249
20
54
Москва
Перепроверил текст триггеров в первом посте. Я видимо по невнимательности пропустил еще пару мест, где нужно указывать имя вашей базы данных. Проверьте их.
2. И добавить триггеры на таблицу "tbl_playerdata":
CREATE DEFINER = CURRENT_USER TRIGGER `Имя_вашей_БД`.`tbl_playerdata_AFTER_UPDATE` AFTER UPDATE ON `tbl_playerdata` FOR EACH ROW
BEGIN
IF (NEW.IP_Address <> Old.IP_Address)
THEN
INSERT INTO `Имя_вашей_БД`.ip_history (PlayerID, IP_Address, IPv6_Address, RecStamp) VALUES (NEW.PlayerID, NEW.IP_Address, NEW.IPv6_Address, NOW());
END IF;
IF (NEW.SoldierName <> Old.SoldierName)
THEN
INSERT INTO `Имя_вашей_БД`.SoldierName_history (PlayerID, New_SoldierName, Old_SoldierName) VALUES (NEW.PlayerID, NEW.SoldierName, OLD.SoldierName);
END IF;
END
 

wanderer_rover

Customer
10 Июл 2017
129
3
43
Перепроверил текст триггеров в первом посте. Я видимо по невнимательности пропустил еще пару мест, где нужно указывать имя вашей базы данных. Проверьте их.
А скажите изменение префикса и команд возможно?или все скомпилировано в приложение?или есть версия где эти файлы конфига можно праввить?
Триггер создал вручную,но пока проверить не могу,лежат сервера...
 

wanderer_rover

Customer
10 Июл 2017
129
3
43
ясно.жду как поднимутся сервера.о результате напишу.спасибо за помощь
 

battlefieldarm

Customer
13 Апр 2016
249
20
54
Москва
Всегда пожалуйста, обращайтесь.
Удивительно, что только сейчас ошибка обнаружилась. Похоже до сих пор еще никто не модифицировал бд предложенным вверху кодом, либо вовсе не используют бота.
 

Slawter

Support team
5 Сен 2014
22.536
871
Всегда пожалуйста, обращайтесь.
Удивительно, что только сейчас ошибка обнаружилась. Похоже до сих пор еще никто не модифицировал бд предложенным вверху кодом, либо вовсе не используют бота.
Как я говорил, в основном кто тут хостится, именно арендуют Layer Procon и у них нет доступа к Windows. Лишь малая часть держит под прокон и БД свой собственный сервер, ведь это не целесообразно, если не имеешь во владении серверов или не занимаешься этим. Проще арендовать Layer и готовую БД, где ты можешь нажать старт стоп, чем устанавливать Windows, подключаться по RDP и что то там настраивать.
 

wanderer_rover

Customer
10 Июл 2017
129
3
43
Всегда пожалуйста, обращайтесь.
Удивительно, что только сейчас ошибка обнаружилась. Похоже до сих пор еще никто не модифицировал бд предложенным вверху кодом, либо вовсе не используют бота.
Теперь таблица ip_hystory доступна,запись пошла..В проконе ошибок тоже пока не наблюдаю.Вторая таблица пустая,видимо еще никто не сменил имя.Общем все работает.Спасибо.Еще бы смену команд и префикса,было бы замечательно.Но раз нет,так нет.
 

wanderer_rover

Customer
10 Июл 2017
129
3
43
Хотя только написал и увидел в прокон ошибку ,теперь связанную с другой таблицей :)
[Statslogger]Error: Error in Startstreaming:
[19:08:04 25] Message: Table 'user.SoldierName_history' doesn't exist
[19:08:04 25] Native: -2147467259
[19:08:04 25] Source: MySql.Data
[19:08:04 25] StackTrace: at MySql.Data.MySqlClient.MySqlStream.ReadPacket()
at MySql.Data.MySqlClient.NativeDriver.GetResult(Int32& affectedRow, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.GetResult(Int32 statementId, Int32& affectedRows, Int64& insertedId)
at MySql.Data.MySqlClient.Driver.NextResult(Int32 statementId, Boolean force)
at MySql.Data.MySqlClient.MySqlDataReader.NextResult()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteNonQuery()
at PRoConEvents.CChatGUIDStatsLogger.StartStreaming()
Видимо регистр сыграл роль.в вашем скрипте-Soldiername....Удалил и создал таблицу SoldierName.Смотрю результат
 
Последнее редактирование:

battlefieldarm

Customer
13 Апр 2016
249
20
54
Москва
wanderer_rover, Возможно дело в этом, я точно не помню в mysql регистро-зависимые имена объектов или нет. У меня в базе так же как и здесь прописано - в триггере две заглавных, а сама таблица все маленькие. Версия сервера 5.6.
01.jpg
 
Последнее редактирование:

wanderer_rover

Customer
10 Июл 2017
129
3
43
Исправив название таблицы-теперь все норм.У меня MariaDB.Хотя записей нет в таблице.Может я смотрю в прокон,когда эта ошибка не пролетает :) понаблюдаю еще
 

wanderer_rover

Customer
10 Июл 2017
129
3
43
Рано радовался...есть ошибка,как и было с ип_хистори
-7500-A0.01-D-UpdatePlayer-Main52: [Error while updating player.][MySql.Data.MySqlClient.MySqlException: Table 'user.SoldierName_history' doesn't exist
at PRoConEvents.AdKats.SafeExecuteNonQuery(MySqlCommand command)