mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-04 14:08:37 +00:00
RPCN Client (#8663)
This commit is contained in:
parent
d000d648b0
commit
190822c2b2
45 changed files with 8365 additions and 431 deletions
229
rpcs3/rpcs3qt/rpcn_settings_dialog.cpp
Normal file
229
rpcs3/rpcs3qt/rpcn_settings_dialog.cpp
Normal file
|
|
@ -0,0 +1,229 @@
|
|||
#include <QMessageBox>
|
||||
#include <QVBoxLayout>
|
||||
#include <QHBoxLayout>
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QRegExpValidator>
|
||||
#include <QInputDialog>
|
||||
#include <thread>
|
||||
|
||||
#include "rpcn_settings_dialog.h"
|
||||
#include "Emu/NP/rpcn_config.h"
|
||||
#include "Emu/NP/rpcn_client.h"
|
||||
|
||||
#include <wolfssl/ssl.h>
|
||||
#include <wolfssl/openssl/evp.h>
|
||||
|
||||
rpcn_settings_dialog::rpcn_settings_dialog(QWidget* parent)
|
||||
: QDialog(parent)
|
||||
{
|
||||
setWindowTitle(tr("RPCN Configuration"));
|
||||
setObjectName("rpcn_settings_dialog");
|
||||
setMinimumSize(QSize(400, 200));
|
||||
|
||||
QVBoxLayout* vbox_global = new QVBoxLayout();
|
||||
QHBoxLayout* hbox_labels_and_edits = new QHBoxLayout();
|
||||
QVBoxLayout* vbox_labels = new QVBoxLayout();
|
||||
QVBoxLayout* vbox_edits = new QVBoxLayout();
|
||||
QHBoxLayout* hbox_buttons = new QHBoxLayout();
|
||||
|
||||
QLabel* label_host = new QLabel(tr("Host:"));
|
||||
m_edit_host = new QLineEdit();
|
||||
QLabel* label_npid = new QLabel(tr("NPID (username):"));
|
||||
m_edit_npid = new QLineEdit();
|
||||
m_edit_npid->setMaxLength(16);
|
||||
m_edit_npid->setValidator(new QRegExpValidator(QRegExp("^[a-zA-Z0-9_\\-]*$"), this));
|
||||
QLabel* label_pass = new QLabel(tr("Password:"));
|
||||
QPushButton* btn_chg_pass = new QPushButton(tr("Set Password"));
|
||||
QLabel *label_token = new QLabel(tr("Token:"));
|
||||
m_edit_token = new QLineEdit();
|
||||
|
||||
QPushButton* btn_create = new QPushButton(tr("Create Account"), this);
|
||||
QPushButton* btn_save = new QPushButton(tr("Save"), this);
|
||||
|
||||
vbox_labels->addWidget(label_host);
|
||||
vbox_labels->addWidget(label_npid);
|
||||
vbox_labels->addWidget(label_pass);
|
||||
vbox_labels->addWidget(label_token);
|
||||
|
||||
vbox_edits->addWidget(m_edit_host);
|
||||
vbox_edits->addWidget(m_edit_npid);
|
||||
vbox_edits->addWidget(btn_chg_pass);
|
||||
vbox_edits->addWidget(m_edit_token);
|
||||
|
||||
hbox_buttons->addWidget(btn_create);
|
||||
hbox_buttons->addStretch();
|
||||
hbox_buttons->addWidget(btn_save);
|
||||
|
||||
hbox_labels_and_edits->addLayout(vbox_labels);
|
||||
hbox_labels_and_edits->addLayout(vbox_edits);
|
||||
|
||||
vbox_global->addLayout(hbox_labels_and_edits);
|
||||
vbox_global->addLayout(hbox_buttons);
|
||||
|
||||
setLayout(vbox_global);
|
||||
|
||||
connect(btn_chg_pass, &QAbstractButton::clicked, [this]()
|
||||
{
|
||||
QString password;
|
||||
|
||||
while (true)
|
||||
{
|
||||
bool clicked_ok = false;
|
||||
password = QInputDialog::getText(this, "Set/Change Password", "Set your password", QLineEdit::Password, "", &clicked_ok);
|
||||
if (!clicked_ok)
|
||||
return;
|
||||
|
||||
if (password.isEmpty())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Wrong input"), tr("You need to enter a password!"), QMessageBox::Ok);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
std::string pass_str = password.toStdString();
|
||||
std::string salt_str = "No matter where you go, everybody's connected.";
|
||||
|
||||
u8 salted_pass[SHA_DIGEST_SIZE];
|
||||
|
||||
wolfSSL_PKCS5_PBKDF2_HMAC_SHA1(pass_str.c_str(), pass_str.size(), reinterpret_cast<const u8*>(salt_str.c_str()), salt_str.size(), 1000, SHA_DIGEST_SIZE, salted_pass);
|
||||
|
||||
std::string hash("0000000000000000000000000000000000000000");
|
||||
for (u32 i = 0; i < 20; i++)
|
||||
{
|
||||
constexpr auto pal = "0123456789abcdef";
|
||||
hash[i * 2] = pal[salted_pass[i] >> 4];
|
||||
hash[1 + i * 2] = pal[salted_pass[i] & 15];
|
||||
}
|
||||
|
||||
g_cfg_rpcn.set_password(hash);
|
||||
g_cfg_rpcn.save();
|
||||
});
|
||||
|
||||
connect(btn_save, &QAbstractButton::clicked, [this]()
|
||||
{
|
||||
if (this->save_config())
|
||||
this->close();
|
||||
});
|
||||
connect(btn_create, &QAbstractButton::clicked, [this]() { this->create_account(); });
|
||||
|
||||
g_cfg_rpcn.load();
|
||||
|
||||
m_edit_host->setText(QString::fromStdString(g_cfg_rpcn.get_host()));
|
||||
m_edit_npid->setText(QString::fromStdString(g_cfg_rpcn.get_npid()));
|
||||
m_edit_token->setText(QString::fromStdString(g_cfg_rpcn.get_token()));
|
||||
}
|
||||
|
||||
bool rpcn_settings_dialog::save_config()
|
||||
{
|
||||
const auto host = m_edit_host->text().toStdString();
|
||||
const auto npid = m_edit_npid->text().toStdString();
|
||||
const auto token = m_edit_token->text().toStdString();
|
||||
|
||||
auto validate = [](const std::string& input) -> bool
|
||||
{
|
||||
if (input.length() < 3 || input.length() > 16)
|
||||
return false;
|
||||
|
||||
for (const auto c : input)
|
||||
{
|
||||
if (!std::isalnum(c) && c != '-' && c != '_')
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
if (host.empty())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Missing host"), tr("You need to enter a host for rpcn!"), QMessageBox::Ok);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (npid.empty() || g_cfg_rpcn.get_password().empty())
|
||||
{
|
||||
QMessageBox::critical(this, tr("Wrong input"), tr("You need to enter a username and a password!"), QMessageBox::Ok);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!validate(npid))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Invalid character"), tr("NPID must be between 3 and 16 characters and can only contain '-', '_' or alphanumeric characters."), QMessageBox::Ok);
|
||||
return false;
|
||||
}
|
||||
|
||||
g_cfg_rpcn.set_host(host);
|
||||
g_cfg_rpcn.set_npid(npid);
|
||||
g_cfg_rpcn.set_token(token);
|
||||
|
||||
g_cfg_rpcn.save();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool rpcn_settings_dialog::create_account()
|
||||
{
|
||||
// Validate and save
|
||||
if (!save_config())
|
||||
return false;
|
||||
|
||||
QString email;
|
||||
QRegExpValidator simple_email_validator(QRegExp("^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$"));
|
||||
|
||||
while (true)
|
||||
{
|
||||
bool clicked_ok = false;
|
||||
email = QInputDialog::getText(this, "Email address", "An email address is required, please note:\n*A valid email is needed to validate your account.\n*Your email won't be used for anything beyond sending you the token.\n*Upon successful creation a token will be sent to your email which you'll need to login.\n\n", QLineEdit::Normal, "", &clicked_ok);
|
||||
if (!clicked_ok)
|
||||
return false;
|
||||
|
||||
int pos = 0;
|
||||
if (email.isEmpty() || simple_email_validator.validate(email, pos) != QValidator::Acceptable)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Wrong input"), tr("You need to enter a valid email!"), QMessageBox::Ok);
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto rpcn = std::make_shared<rpcn_client>(true);
|
||||
|
||||
const auto host = g_cfg_rpcn.get_host();
|
||||
const auto npid = g_cfg_rpcn.get_npid();
|
||||
const auto online_name = npid;
|
||||
const auto avatar_url = "https://rpcs3.net/cdn/netplay/DefaultAvatar.png";
|
||||
const auto password = g_cfg_rpcn.get_password();
|
||||
|
||||
std::thread(
|
||||
[](const std::shared_ptr<rpcn_client> rpcn)
|
||||
{
|
||||
while (rpcn.use_count() != 1)
|
||||
rpcn->manage_connection();
|
||||
|
||||
rpcn->disconnect();
|
||||
},
|
||||
rpcn)
|
||||
.detach();
|
||||
|
||||
if (!rpcn->connect(host))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error Connecting"), tr("Failed to connect to RPCN server"), QMessageBox::Ok);
|
||||
rpcn->abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!rpcn->create_user(npid, password, online_name, avatar_url, email.toStdString()))
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error Creating Account"), tr("Failed to create the account"), QMessageBox::Ok);
|
||||
rpcn->abort();
|
||||
return false;
|
||||
}
|
||||
|
||||
QMessageBox::information(this, tr("Account created!"), tr("Your account has been created successfully!\nCheck your email for your token!"), QMessageBox::Ok);
|
||||
rpcn->abort();
|
||||
return true;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue