Копирайт © DSTR!
Доброго времени суток!
Хотел бы немного рассказать (и показать) о взаимодействии со Steam WEB Api средствами Qt и C++.
Пишите, если хотите продолжение: статью о работе с инвентарем Steam: получение цены предметов и т.п
Версия, которую мы получим в конце этого урока отлично подходит для повседневного использования тем пользователям, кому часто необходимо узнать оригинальный SteamID64 и дату регистрации.
Ниже пример окончательной программы:
Исходный код, а также скомпилированный проект доступен по ссылке: https://goo.gl/TCivNm
ВЕРСИИ:
— SteamUserInfoFull — скомпилированная полная версия этой программы (как на скриншоте выше).
— SteamUserInfoLite — скомпилированная версия из статьи.
— SteamUserInfoSource — исходный код из статьи.
В этой статье описана самая малая часть, так как всего очень много и за один раз всё не покажешь.
Мы не будем рассматривать то, как устроен формат ответа Json-файла от Steam.
Всё это можете посмотреть самостоятельно, вставив запрос в браузер.
Я использую компилятор MinGW32.
У вас должна быть поддержка SSL (если нет - скачайте эти два файла и добавьте в папку с компилируемым проектом): https://yadi.sk/d/lZZrpzoH3afXY8
Итак, мы рассмотрим:
— получение оригинальной ссылки на профиль (SteamID64);
— получение аватарки профиля;
— получение даты регистрации аккаунта;
— получение даты последней активности;
— получение статуса VAC, количество игровых блокировок, дней с момента последней блокировки и статус профиля в сообществе Steam (в простонародье — КТ).
Приступим.
1)
Для начала работы нам понадобится наш уникальный API ключ для доступа к сервисам Steam.
Чтобы его получить нужен БЕЗЛИМИТНЫЙ аккаунт Steam.
Переходим по ссылке https://steamcommunity.com/dev/apikey и вводим рандомный адрес (к примеру, qwertyabc@abcd.com), нажимаем на кнопочку регистрации и сохраняем наш ключ.
2)
Теперь запускаем Qt, создаем проект Qt Widgets Application -> указываем название как у меня, чтобы не было разногласий: SteamUserInfo и дальше указываете свой путь.
Проект создался.
В файле SteamUserInfo.pro прописываете: QT += network (скрин)
3)
Теперь создаем первый класс. Кликаем на название проекта -> Add new... -> слева выбираем C++, а справа C++ Class.
Назовем его SteamUserProfileLink
4)
Реализуем наш класс.
В файле SteamUserProfileLink.h создаем переменные и прототипы функций:
Реализуем эти функции.
Файл SteamUserProfileLink.cpp:
5)
Теперь по той же схеме создаем следующий класс SteamPlayerSummaries
Файл SteamPlayerSummaries.h:
Файл SteamPlayerSummaries.cpp:
6)
Теперь создадим файлик для получения информации о блокировках аккаунта.
Создадим класс SteamPlayerBans:
Файл SteamPlayerBans.h:
Реализация SteamPlayerBans.cpp
Теперь осталось самое простое — создать графический интерфейс для взаимодействия.
Файл MainWindow.h
Файл MainWindow.cpp:
Готово! Теперь компилируем и любуемся результатом:
Доброго времени суток!
Хотел бы немного рассказать (и показать) о взаимодействии со Steam WEB Api средствами Qt и C++.
Пишите, если хотите продолжение: статью о работе с инвентарем Steam: получение цены предметов и т.п
Версия, которую мы получим в конце этого урока отлично подходит для повседневного использования тем пользователям, кому часто необходимо узнать оригинальный SteamID64 и дату регистрации.
Ниже пример окончательной программы:
Исходный код, а также скомпилированный проект доступен по ссылке: https://goo.gl/TCivNm
ВЕРСИИ:
— SteamUserInfoFull — скомпилированная полная версия этой программы (как на скриншоте выше).
— SteamUserInfoLite — скомпилированная версия из статьи.
— SteamUserInfoSource — исходный код из статьи.
В этой статье описана самая малая часть, так как всего очень много и за один раз всё не покажешь.
Мы не будем рассматривать то, как устроен формат ответа Json-файла от Steam.
Всё это можете посмотреть самостоятельно, вставив запрос в браузер.
Я использую компилятор MinGW32.
У вас должна быть поддержка SSL (если нет - скачайте эти два файла и добавьте в папку с компилируемым проектом): https://yadi.sk/d/lZZrpzoH3afXY8
Итак, мы рассмотрим:
— получение оригинальной ссылки на профиль (SteamID64);
— получение аватарки профиля;
— получение даты регистрации аккаунта;
— получение даты последней активности;
— получение статуса VAC, количество игровых блокировок, дней с момента последней блокировки и статус профиля в сообществе Steam (в простонародье — КТ).
Приступим.
1)
Для начала работы нам понадобится наш уникальный API ключ для доступа к сервисам Steam.
Чтобы его получить нужен БЕЗЛИМИТНЫЙ аккаунт Steam.
Переходим по ссылке https://steamcommunity.com/dev/apikey и вводим рандомный адрес (к примеру, qwertyabc@abcd.com), нажимаем на кнопочку регистрации и сохраняем наш ключ.
2)
Теперь запускаем Qt, создаем проект Qt Widgets Application -> указываем название как у меня, чтобы не было разногласий: SteamUserInfo и дальше указываете свой путь.
Проект создался.
В файле SteamUserInfo.pro прописываете: QT += network (скрин)
3)
Теперь создаем первый класс. Кликаем на название проекта -> Add new... -> слева выбираем C++, а справа C++ Class.
Назовем его SteamUserProfileLink
4)
Реализуем наш класс.
В файле SteamUserProfileLink.h создаем переменные и прототипы функций:
C++:
#include <QtNetwork/QtNetwork>
#include <QString>
class SteamUserProfileLink
{
QString apiKey;
QString steamID64;
public:
SteamUserProfileLink();
void setApiKey(QString key);
bool setConnection(const QString &steamUrl);
QString getSteamID64() const;
};
Реализуем эти функции.
Файл SteamUserProfileLink.cpp:
C++:
#include "SteamUserProfileLink.h"
SteamUserProfileLink::SteamUserProfileLink() { }
void SteamUserProfileLink::setApiKey(QString key)
{
apiKey = key;
}
//true - соединение успешно: вся информация загружена.
//false - не удалось получить ответ от сервера.
bool SteamUserProfileLink::setConnection(const QString &steamUrl)
{
QNetworkAccessManager manager;
QNetworkReply &reply = *manager.get(
//Отправляем запрос.
QNetworkRequest(QString
("http://api.steampowered.com/ISteamUser/ResolveVanityURL/v0001/?key=%1&vanityurl=%2").arg(apiKey).arg(steamUrl)));
QEventLoop loop; //Ждем ответ от сервера.
QObject::connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
loop.exec();
const QJsonDocument document = QJsonDocument::fromJson(reply.readAll()); //Загружаем Json документ.
//Если ответ равен 1, значит SteamID64 успешно получен.
if (document.object().value("response").toObject().value("success").toDouble() == 1.0) {
steamID64 = document.object().value("response").toObject().value("steamid").toString(); //Запоминаем.
return true; //Возвращаем true: успешно.
}
//Иначе считаем, что такого steamUrl не существует и возвращаем false.
return false;
}
QString SteamUserProfileLink::getSteamID64() const
{
return steamID64;
}
5)
Теперь по той же схеме создаем следующий класс SteamPlayerSummaries
Файл SteamPlayerSummaries.h:
C++:
#include <QtNetwork/QtNetwork>
#include <QString>
#include <QPixmap>
class SteamPlayerSummaries
{
QString apiKey;
uint timeCreated;//Дата создания аккаунта в формате UTC.
uint lastLogOff; //Дата последней активности в формате UTC.
QPixmap avatar; //Аватарка профиля.
void loadAvatar(const QString &avatarUrl);
public:
SteamPlayerSummaries();
void setApiKey(QString key);
bool setConnection(const QString &steamID64);
QString getLastLofOff() const; //Дата последней активности в формате дата-месяц-год.
QString getTimeCreated() const; //Дата создания профиля в формате дата-месяц-год.
QPixmap getAvatar() const;
};
Файл SteamPlayerSummaries.cpp:
C++:
#include "SteamPlayerSummaries.h"
SteamPlayerSummaries::SteamPlayerSummaries() { }
void SteamPlayerSummaries::setApiKey(QString key)
{
apiKey = key;
}
//true - соединение успешно: вся информация загружена.
//false - не удалось получить ответ от сервера.
bool SteamPlayerSummaries::setConnection(const QString &steamID64)
{
QNetworkAccessManager manager;
QNetworkReply &reply = *manager.get(
//Отправляем запрос.
QNetworkRequest(QString
("http://api.steampowered.com/ISteamUser/GetPlayerSummaries/v0002/?key=%1&steamids=%2").arg(apiKey).arg(steamID64)));
QEventLoop loop; //Ждем ответ от сервера.
QObject::connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
loop.exec();
const QJsonDocument document = QJsonDocument::fromJson(reply.readAll());
if (document.isEmpty()) //ApiKey неправильный.
return false;
//Конвертируем массив в object для обращения к элементам по имени, а не индексах.
const QJsonObject object = document.object().value("response").toObject().value("players").toArray()[0].toObject();
if (object.isEmpty()) //SteamID не найден.
return false;
loadAvatar(object["avatarfull"].toString()); //Загружаем аватарку.
timeCreated = static_cast<unsigned int>(object["timecreated"].toInt()); //Получаем дату регистрации аккаунта.
lastLogOff = static_cast<unsigned int>(object["lastlogoff"].toInt()); //Последняя активность.
return true; //Возвращаем true: успешно загружено.
}
void SteamPlayerSummaries::loadAvatar(const QString &avatarUrl) //Загрузка аватарки.
{
QNetworkAccessManager manager;
QNetworkReply &reply = *manager.get(QNetworkRequest(avatarUrl));
QEventLoop loop; //Ждем ответ от сервера.
QObject::connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
loop.exec();
const QByteArray header = reply.readAll();
avatar.loadFromData(header,"jpg");
}
QString SteamPlayerSummaries::getLastLofOff() const
{
//Конвертируем UTC в обычное представление времени.
static const QString c = QDateTime::fromTime_t(lastLogOff).toString("dd-MM-yyyy");
return c;
}
QString SteamPlayerSummaries::getTimeCreated() const
{
//Конвертируем UTC в обычное представление времени.
static const QString c = QDateTime::fromTime_t(timeCreated).toString("dd-MM-yyyy");
return c;
}
QPixmap SteamPlayerSummaries::getAvatar() const
{
return avatar;
}
6)
Теперь создадим файлик для получения информации о блокировках аккаунта.
Создадим класс SteamPlayerBans:
Файл SteamPlayerBans.h:
C++:
#include <QtNetwork/QtNetwork>
class SteamPlayerBans
{
QString apiKey;
bool communityBanned; //Блокировка в сообществе (КТ).
bool VACBanned; //Блокировка VAC.
QString economyBanned;//Блокировка обмена.
int numberOfGameBans;//Количество игровых блокировок.
int numberOfVACBans; //Количество VAC блокировок.
int daysSinceLastBan;//Дней с момента последней блокировки.
public:
SteamPlayerBans();
void setApiKey(QString key);
bool setConnection(const QString &steamID64);
bool isCommunityBanned() const;
bool isVACBanned() const;
QString getEconomyBan() const;
int getNumberOfGameBans() const;
int getNumberOfVACBans() const;
int getDaysSinceLastBan() const;
};
Реализация SteamPlayerBans.cpp
C++:
#include "SteamPlayerBans.h"
SteamPlayerBans::SteamPlayerBans() { }
void SteamPlayerBans::setApiKey(QString key)
{
apiKey = key;
}
//true - соединение успешно: вся информация загружена.
//false - не удалось получить ответ от сервера.
bool SteamPlayerBans::setConnection(const QString &steamID64)
{
QNetworkAccessManager manager;
QNetworkReply &reply = *manager.get(
//Отправляем запрос.
QNetworkRequest(QString
("http://api.steampowered.com/ISteamUser/GetPlayerBans/v1/?key=%1&steamids=%2&format=json").arg(apiKey).arg(steamID64)));
QEventLoop loop; //Ждем ответ от сервера.
QObject::connect(&manager, &QNetworkAccessManager::finished, &loop, &QEventLoop::quit);
loop.exec();
QJsonDocument document = QJsonDocument::fromJson(reply.readAll());
if (document.isEmpty()) //ApiKey неправильный.
return false;
const QJsonObject object = document.object().value("players")[0].toObject();
if (object.isEmpty()) //SteamID не найден.
return false;
communityBanned = object["CommunityBanned"].toBool();
VACBanned = object["VACBanned"].toBool();
economyBanned = object["EconomyBan"].toBool();
numberOfGameBans = object["NumberOfGameBans"].toInt();
numberOfVACBans = object["NumberOfVACBans"].toInt();
daysSinceLastBan = object["DaysSinceLastBan"].toInt();
return true;
}
bool SteamPlayerBans::isCommunityBanned() const
{
return communityBanned;
}
bool SteamPlayerBans::isVACBanned() const
{
return VACBanned;
}
QString SteamPlayerBans::getEconomyBan() const
{
return economyBanned;
}
int SteamPlayerBans::getNumberOfGameBans() const
{
return numberOfGameBans;
}
int SteamPlayerBans::getNumberOfVACBans() const
{
return numberOfVACBans;
}
int SteamPlayerBans::getDaysSinceLastBan() const
{
return daysSinceLastBan;
}
Теперь осталось самое простое — создать графический интерфейс для взаимодействия.
Файл MainWindow.h
C++:
#include <QMainWindow>
#include <QLineEdit>
#include <QWidget>
#include <QPushButton>
#include <QLabel>
#include <QLayout>
#include <QGroupBox>
#include <QMessageBox>
#include "SteamUserProfileLink.h"
#include "SteamPlayerSummaries.h"
#include "SteamPlayerBans.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
//Функция обработки.
void setup();
//Парс ссылки: получаем только url: steamcommunity.com/id/abcd -> abcd
QString getUrl(QString steamProfileUrl);
private:
Ui::MainWindow *ui;
};
Файл MainWindow.cpp:
C++:
#include "MainWindow.h"
#include "ui_MainWindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QFont font;
setWindowTitle("SteamUserInfo");
font.setPointSize(10);
setFont(font);
QPalette palette;
palette.setBrush(QPalette::Background, QColor(0xFCE7FC));
setPalette(palette);
setFixedSize(500, 600);
setup();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::setup()
{
QWidget *mainWidget = new QWidget(this);
QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget);
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
QGroupBox *boxSettings = new QGroupBox("Конфигурация:");
QGridLayout *boxLayout = new QGridLayout(boxSettings);
boxLayout->addWidget(new QLabel("Вставьте ApiKey:"), 0, 0);
QLineEdit *lineApiKey = new QLineEdit();
boxLayout->addWidget(lineApiKey, 0, 1);
boxLayout->addWidget(new QLabel("Вставьте ссылку на аккаунт:"), 1, 0);
QLineEdit *lineSteamProfileLink = new QLineEdit();
boxLayout->addWidget(lineSteamProfileLink, 1, 1);
QPushButton *btnFind = new QPushButton("Найти профиль");
boxLayout->addWidget(btnFind);
mainLayout->addWidget(boxSettings);
QGroupBox *boxAccountInfo = new QGroupBox("Информация про аккаунт");
QGridLayout *layoutAccount = new QGridLayout(boxAccountInfo);
layoutAccount->addWidget(new QLabel("Аватарка:"), 0, 0);
QLabel *lblAvatar = new QLabel();
lblAvatar->setFixedSize(184, 184);
layoutAccount->addWidget(lblAvatar, 0, 1);
layoutAccount->addWidget(new QLabel("Оригинальная ссылка (SteamID64):"), 1, 0);
QLineEdit *lineOriginalSteamLink = new QLineEdit();
lineOriginalSteamLink->setReadOnly(true);
layoutAccount->addWidget(lineOriginalSteamLink, 1, 1);
layoutAccount->addWidget(new QLabel("Дата регистрации:"), 2, 0);
QLineEdit *lineTimeCreated = new QLineEdit();
lineTimeCreated->setReadOnly(true);
layoutAccount->addWidget(lineTimeCreated, 2, 1);
layoutAccount->addWidget(new QLabel("Последняя активность:"), 3, 0);
QLineEdit *lineLastLogOff = new QLineEdit();
lineLastLogOff->setReadOnly(true);
layoutAccount->addWidget(lineLastLogOff, 3, 1);
layoutAccount->addWidget(new QLabel("VAC блокировка:"), 4, 0);
QLineEdit *lineVacBanned = new QLineEdit();
lineVacBanned->setReadOnly(true);
layoutAccount->addWidget(lineVacBanned, 4, 1);
layoutAccount->addWidget(new QLabel("Кол-во игровых блокировок:"), 5, 0);
QLineEdit *lineGamebans = new QLineEdit();
lineGamebans->setReadOnly(true);
layoutAccount->addWidget(lineGamebans, 5, 1);
layoutAccount->addWidget(new QLabel("Дней с последней блокировки:"), 6, 0);
QLineEdit *lineDaysSinceLastBan = new QLineEdit();
lineDaysSinceLastBan->setReadOnly(true);
layoutAccount->addWidget(lineDaysSinceLastBan, 6, 1);
layoutAccount->addWidget(new QLabel("Блокировка в сообществе (КТ):"), 7, 0);
QLineEdit *lineCommunityBan = new QLineEdit();
lineCommunityBan ->setReadOnly(true);
layoutAccount->addWidget(lineCommunityBan , 7, 1);
mainLayout->addWidget(boxAccountInfo);
connect(btnFind, &QPushButton::clicked, this, [=]() {
btnFind->setEnabled(false);
const QString apiKey = lineApiKey->text();
const QString steamName = MainWindow::getUrl(lineSteamProfileLink->text());
QString steamID64;
if (lineSteamProfileLink->text().contains("id")) {
SteamUserProfileLink steamLink;
steamLink.setApiKey(apiKey);
if (steamLink.setConnection(steamName)) {
steamID64 = steamLink.getSteamID64();
}
else {
QMessageBox::information(this, "Сообщение", "Ошибка. Пользователя найти не удалось.\nПроверье ApiKey и ссылку на профиль.");
btnFind->setEnabled(true);
return ;
}
}
else
steamID64 = steamName;
SteamPlayerSummaries playerSummaries;
playerSummaries.setApiKey(apiKey);
if (!playerSummaries.setConnection(steamID64)) {
QMessageBox::information(this, "Сообщение", "Ошибка. Пользователя найти не удалось.\nПроверье ApiKey и ссылку на профиль.");
btnFind->setEnabled(true);
return ;
}
lineOriginalSteamLink->setText("https://steamcommunity.com/profiles/" + steamID64);
lblAvatar->setPixmap(playerSummaries.getAvatar());
lineTimeCreated->setText(playerSummaries.getTimeCreated());
lineLastLogOff->setText(playerSummaries.getLastLofOff());
SteamPlayerBans bans;
bans.setApiKey(apiKey);
bans.setConnection(steamID64);
lineVacBanned->setText(bans.isVACBanned()? "ДА | " + QString::number(bans.getNumberOfVACBans()): "НЕТ");
lineGamebans->setText(QString::number(bans.getNumberOfGameBans()));
lineDaysSinceLastBan->setText(QString::number(bans.getDaysSinceLastBan()));
lineCommunityBan->setText(bans.isCommunityBanned()? "ДА" : "НЕТ");
btnFind->setEnabled(true);
});
}
QString MainWindow::getUrl(QString steamProfileUrl)
{
if (steamProfileUrl.back() == '/')
steamProfileUrl = steamProfileUrl.left(steamProfileUrl.length() - 1);
steamProfileUrl = steamProfileUrl.right(steamProfileUrl.length() - steamProfileUrl.lastIndexOf('/') - 1);
return steamProfileUrl;
}
Готово! Теперь компилируем и любуемся результатом: