Merge branch 'sql_update' into 'noggit-shadowlands'
update and fix MySQL UID feature. See merge request prophecy-rp/noggit-red!37
This commit is contained in:
@@ -13,25 +13,94 @@ namespace
|
||||
std::unique_ptr<sql::Connection> connect()
|
||||
{
|
||||
QSettings settings;
|
||||
std::unique_ptr<sql::Connection> Con
|
||||
(get_driver_instance()->connect
|
||||
( settings.value("project/mysql/server").toString().toStdString()
|
||||
, settings.value("project/mysql/user").toString().toStdString()
|
||||
, settings.value("project/mysql/pwd").toString().toStdString()
|
||||
)
|
||||
);
|
||||
Con->setSchema(settings.value("project/mysql/db").toString().toStdString());
|
||||
|
||||
return Con;
|
||||
// if using release SQL binaries in debug mode it will crash https://bugs.mysql.com/bug.php?id=91238 unless using sql strings
|
||||
// tcp://127.0.0.1:3306
|
||||
sql::SQLString hostname = "tcp://" + settings.value("project/mysql/server").toString().toStdString() + ":" + settings.value("project/mysql/port", "3306").toString().toStdString();
|
||||
sql::SQLString userName = settings.value("project/mysql/user").toString().toStdString();
|
||||
sql::SQLString password = settings.value("project/mysql/pwd").toString().toStdString();
|
||||
sql::SQLString schema = settings.value("project/mysql/db").toString().toStdString();
|
||||
|
||||
try
|
||||
{
|
||||
std::unique_ptr<sql::Connection> Con(get_driver_instance()->connect(hostname, userName, password));
|
||||
|
||||
// crete database if it doesn't exist
|
||||
std::string createdb_statement = "CREATE DATABASE IF NOT EXISTS " + schema;
|
||||
std::unique_ptr<sql::PreparedStatement> dbpstmt(Con->prepareStatement(createdb_statement));
|
||||
std::unique_ptr<sql::ResultSet> res(dbpstmt->executeQuery());
|
||||
|
||||
Con->setSchema(schema);
|
||||
|
||||
// create table if it doesn't exist, querries from src/sql
|
||||
std::unique_ptr<sql::PreparedStatement> tablepstmt(Con->prepareStatement("CREATE TABLE IF NOT EXISTS `UIDs` ("
|
||||
"`_map_id` int(11) NOT NULL,"
|
||||
"`UID` int(11) NOT NULL,"
|
||||
"PRIMARY KEY(`_map_id`)"
|
||||
") ENGINE = InnoDB DEFAULT CHARSET = latin1;"));
|
||||
std::unique_ptr<sql::ResultSet> tableres(tablepstmt->executeQuery());
|
||||
|
||||
return Con;
|
||||
}
|
||||
catch (sql::SQLException& e)
|
||||
{
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
bool testConnection(bool report_only_err)
|
||||
{
|
||||
QSettings settings;
|
||||
// if using release SQL binaries in debug mode it will crash https://bugs.mysql.com/bug.php?id=91238 unless using sql strings
|
||||
sql::SQLString hostname = "tcp://" + settings.value("project/mysql/server").toString().toStdString() + ":" + settings.value("project/mysql/port", "3306").toString().toStdString();
|
||||
sql::SQLString userName = settings.value("project/mysql/user").toString().toStdString();
|
||||
sql::SQLString password = settings.value("project/mysql/pwd").toString().toStdString();
|
||||
sql::SQLString schema = settings.value("project/mysql/db").toString().toStdString();
|
||||
|
||||
|
||||
QMessageBox prompt;
|
||||
prompt.setWindowFlag(Qt::WindowStaysOnTopHint);
|
||||
try
|
||||
{
|
||||
std::unique_ptr<sql::Connection> Con(get_driver_instance()->connect(hostname, userName, password));
|
||||
|
||||
prompt.setIcon(QMessageBox::Information);
|
||||
prompt.setText("Succesfully connected to MySQL database.");
|
||||
prompt.setWindowTitle("Success");
|
||||
|
||||
if (!report_only_err)
|
||||
prompt.exec();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (sql::SQLException& e)
|
||||
{
|
||||
|
||||
prompt.setIcon(QMessageBox::Warning);
|
||||
prompt.setText("Failed to load MySQL database, check your settings.");
|
||||
prompt.setWindowTitle("Noggit Database Error");
|
||||
std::stringstream promptText;
|
||||
|
||||
promptText << "\n# ERR: " << e.what();
|
||||
promptText << "\n (MySQL error code: " << e.getErrorCode() + ")";
|
||||
|
||||
prompt.setInformativeText(promptText.str().c_str());
|
||||
prompt.exec();
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool hasMaxUIDStoredDB(std::size_t mapID)
|
||||
{
|
||||
auto Con(connect());
|
||||
std::unique_ptr<sql::PreparedStatement> pstmt(Con->prepareStatement("SELECT * FROM UIDs WHERE MapId=(?)"));
|
||||
if (Con == nullptr)
|
||||
return false;
|
||||
std::unique_ptr<sql::PreparedStatement> pstmt(Con->prepareStatement("SELECT * FROM `UIDs` WHERE `_map_id`=(?)"));
|
||||
pstmt->setInt(1, mapID);
|
||||
std::unique_ptr<sql::ResultSet> res(pstmt->executeQuery());
|
||||
return res->rowsCount();
|
||||
@@ -40,7 +109,9 @@ namespace mysql
|
||||
std::uint32_t getGUIDFromDB(std::size_t mapID)
|
||||
{
|
||||
auto Con(connect());
|
||||
std::unique_ptr<sql::PreparedStatement> pstmt(Con->prepareStatement("SELECT UID FROM UIDs WHERE MapId=(?)"));
|
||||
if (Con == nullptr)
|
||||
return 0;
|
||||
std::unique_ptr<sql::PreparedStatement> pstmt(Con->prepareStatement("SELECT `UID` FROM `UIDs` WHERE `_map_id`=(?)"));
|
||||
pstmt->setInt(1, mapID);
|
||||
std::unique_ptr<sql::ResultSet> res(pstmt->executeQuery());
|
||||
|
||||
@@ -60,7 +131,9 @@ namespace mysql
|
||||
void insertUIDinDB(std::size_t mapID, std::uint32_t NewUID)
|
||||
{
|
||||
auto Con(connect());
|
||||
std::unique_ptr<sql::PreparedStatement> pstmt(Con->prepareStatement("INSERT INTO UIDs SET MapId=(?), UID=(?)"));
|
||||
if (Con == nullptr)
|
||||
return;
|
||||
std::unique_ptr<sql::PreparedStatement> pstmt(Con->prepareStatement("INSERT INTO `UIDs` SET `_map_id`=(?), `UID`=(?)"));
|
||||
pstmt->setInt(1, mapID);
|
||||
pstmt->setInt(2, NewUID);
|
||||
pstmt->executeUpdate();
|
||||
@@ -69,7 +142,9 @@ namespace mysql
|
||||
void updateUIDinDB (std::size_t mapID, std::uint32_t NewUID)
|
||||
{
|
||||
auto Con(connect());
|
||||
std::unique_ptr<sql::PreparedStatement> pstmt(Con->prepareStatement("UPDATE UIDs SET UID=(?) WHERE MapId=(?)"));
|
||||
if (Con == nullptr)
|
||||
return;
|
||||
std::unique_ptr<sql::PreparedStatement> pstmt(Con->prepareStatement("UPDATE `UIDs` SET `UID`=(?) WHERE `_map_id`=(?)"));
|
||||
pstmt->setInt(1, NewUID);
|
||||
pstmt->setInt(2, mapID);
|
||||
pstmt->executeUpdate();
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
|
||||
namespace mysql
|
||||
{
|
||||
bool testConnection(bool report_only_err = false);
|
||||
bool hasMaxUIDStoredDB(std::size_t mapID);
|
||||
std::uint32_t getGUIDFromDB(std::size_t mapID);
|
||||
void insertUIDinDB(std::size_t mapID, std::uint32_t NewUID);
|
||||
|
||||
@@ -302,6 +302,26 @@ public:
|
||||
static std::vector<std::string> getWMOAreaNames(int WMOId);
|
||||
};
|
||||
|
||||
class GameObjectDisplayInfoDB : public DBCFile
|
||||
{
|
||||
public:
|
||||
GameObjectDisplayInfoDB() :
|
||||
DBCFile("DBFilesClient\\GameObjectDisplayInfo.dbc")
|
||||
{ }
|
||||
|
||||
/// Fields
|
||||
static const size_t ID = 0; // uint
|
||||
static const size_t ModelName = 1; // string
|
||||
static const size_t Sounds = 2; // int[10]
|
||||
static const size_t GeoBoxMinX = 12; // float
|
||||
static const size_t GeoBoxMinY = 13; // float
|
||||
static const size_t GeoBoxMinZ = 14; // float
|
||||
static const size_t GeoBoxMaxX = 15; // float
|
||||
static const size_t GeoBoxMaxY = 16; // float
|
||||
static const size_t GeoBoxMaxZ = 17; // float
|
||||
static const size_t ObjectEffectPackageID = 18; // int
|
||||
};
|
||||
|
||||
void OpenDBs(std::shared_ptr<BlizzardArchive::ClientData> clientData);
|
||||
|
||||
const char * getGroundEffectDoodad(unsigned int effectID, int DoodadNum);
|
||||
@@ -323,3 +343,4 @@ extern ZoneMusicDB gZoneMusicDB;
|
||||
extern ZoneIntroMusicTableDB gZoneIntroMusicTableDB;
|
||||
extern SoundEntriesDB gSoundEntriesDB;
|
||||
extern WMOAreaTableDB gWMOAreaTableDB;
|
||||
extern GameObjectDisplayInfoDB gGameObjectDisplayInfoDB;
|
||||
|
||||
@@ -50,6 +50,12 @@
|
||||
#include <variant>
|
||||
#include <noggit/Selection.h>
|
||||
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
#include <mysql/mysql.h>
|
||||
|
||||
#include <QtCore/QSettings>
|
||||
#endif
|
||||
|
||||
#include <noggit/scripting/scripting_tool.hpp>
|
||||
#include <noggit/scripting/script_settings.hpp>
|
||||
|
||||
@@ -2597,6 +2603,19 @@ void MapView::createGUI()
|
||||
connect(_main_window, &Noggit::Ui::Windows::NoggitWindow::exitPromptOpened, this, &MapView::on_exit_prompt);
|
||||
|
||||
set_editing_mode (editing_mode::ground);
|
||||
|
||||
// do we need to do this every tick ?
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
if (_settings->value("project/mysql/enabled").toBool())
|
||||
{
|
||||
if (mysql::hasMaxUIDStoredDB(_world->getMapID()))
|
||||
{
|
||||
_status_database->setText("MySQL UID sync enabled: "
|
||||
+ _settings->value("project/mysql/server").toString() + ":"
|
||||
+ _settings->value("project/mysql/port").toString());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MapView::on_exit_prompt()
|
||||
@@ -2638,6 +2657,7 @@ MapView::MapView( math::degrees camera_yaw0
|
||||
, _status_time (new QLabel (this))
|
||||
, _status_fps (new QLabel (this))
|
||||
, _status_culling (new QLabel (this))
|
||||
, _status_database(new QLabel(this))
|
||||
, _texBrush{new OpenGL::texture{}}
|
||||
, _transform_gizmo(Noggit::Ui::Tools::ViewportGizmo::GizmoContext::MAP_VIEW)
|
||||
, _tablet_manager(Noggit::TabletManager::instance()),
|
||||
@@ -2695,6 +2715,12 @@ MapView::MapView( math::degrees camera_yaw0
|
||||
, _main_window
|
||||
, [=] { _main_window->statusBar()->removeWidget (_status_culling); }
|
||||
);
|
||||
_main_window->statusBar()->addWidget(_status_database);
|
||||
connect(this
|
||||
, &QObject::destroyed
|
||||
, _main_window
|
||||
, [=] { _main_window->statusBar()->removeWidget(_status_database); }
|
||||
);
|
||||
|
||||
moving = strafing = updown = lookat = turn = 0.0f;
|
||||
|
||||
|
||||
@@ -367,6 +367,7 @@ private:
|
||||
QLabel* _status_time;
|
||||
QLabel* _status_fps;
|
||||
QLabel* _status_culling;
|
||||
QLabel* _status_database;
|
||||
|
||||
Noggit::BoolToggleProperty _locked_cursor_mode = {false};
|
||||
Noggit::BoolToggleProperty _move_model_to_cursor_position = {true};
|
||||
|
||||
@@ -681,7 +681,7 @@ uint32_t MapIndex::newGUID()
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
QSettings settings;
|
||||
|
||||
if (settings->value ("project/mysql/enabled", false).toBool())
|
||||
if (settings.value ("project/mysql/enabled", false).toBool())
|
||||
{
|
||||
mysql::updateUIDinDB(_map_id, highestGUID + 1); // update the highest uid in db, note that if the user don't save these uid won't be used (not really a problem tho)
|
||||
}
|
||||
@@ -1025,7 +1025,7 @@ void MapIndex::saveMaxUID()
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
QSettings settings;
|
||||
|
||||
if (settings->value ("project/mysql/enabled", false).toBool())
|
||||
if (settings.value ("project/mysql/enabled", false).toBool())
|
||||
{
|
||||
if (mysql::hasMaxUIDStoredDB(_map_id))
|
||||
{
|
||||
@@ -1047,9 +1047,9 @@ void MapIndex::loadMaxUID()
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
QSettings settings;
|
||||
|
||||
if (settings->value ("project/mysql/enabled", false).toBool())
|
||||
if (settings.value ("project/mysql/enabled", false).toBool())
|
||||
{
|
||||
highestGUID = std::max(mysql::getGUIDFromDB(map_id), highestGUID);
|
||||
highestGUID = std::max(mysql::getGUIDFromDB(_map_id), highestGUID);
|
||||
// save to make sure the db and disk uid are synced
|
||||
saveMaxUID();
|
||||
}
|
||||
|
||||
@@ -126,12 +126,14 @@ namespace Noggit::Ui::Windows
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
bool use_mysql = settings.value("project/mysql/enabled", false).toBool();
|
||||
|
||||
if ((use_myqsl && mysql::hasMaxUIDStoredDB(_world->getMapID()))
|
||||
mysql::testConnection(true);
|
||||
|
||||
if ((use_mysql && mysql::hasMaxUIDStoredDB(_world->getMapID()))
|
||||
|| uid_storage::hasMaxUIDStored(_world->getMapID())
|
||||
)
|
||||
{
|
||||
_world->mapIndex.loadMaxUID();
|
||||
enterMapAt(pos, camera_pitch, camera_yaw, from_bookmark);
|
||||
enterMapAt(pos, camera_pitch, camera_yaw, uid_fix_mode::none, from_bookmark);
|
||||
}
|
||||
#else
|
||||
if (uid_storage::hasMaxUIDStored(_world->getMapID()))
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
#include <QDir>
|
||||
#include <QApplication>
|
||||
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
#include <mysql/mysql.h>
|
||||
#endif
|
||||
|
||||
#include <ui_SettingsPanel.h>
|
||||
#include <ui_TitleBar.h>
|
||||
|
||||
@@ -85,6 +89,7 @@ namespace Noggit
|
||||
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
ui->MySQL_box->setEnabled(true);
|
||||
ui->MySQL_box->setCheckable(true);
|
||||
ui->mysql_warning->setVisible(false);
|
||||
#endif
|
||||
|
||||
@@ -157,6 +162,13 @@ namespace Noggit
|
||||
}
|
||||
);
|
||||
|
||||
connect(ui->mysql_connect_test, &QPushButton::clicked, [this]
|
||||
{
|
||||
save_changes();
|
||||
mysql::testConnection();
|
||||
}
|
||||
);
|
||||
|
||||
// load the values in the fields
|
||||
discard_changes();
|
||||
}
|
||||
@@ -200,11 +212,31 @@ namespace Noggit
|
||||
|
||||
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
ui->_mysql_box->setChecked (_settings->value ("project/mysql/enabled").toBool());
|
||||
ui->_mysql_server_field->setText (_settings->value ("project/mysql/server").toString());
|
||||
ui->_mysql_user_field->setText(_settings->value ("project/mysql/user").toString());
|
||||
ui->_mysql_pwd_field->setText (_settings->value ("project/mysql/pwd").toString());
|
||||
ui->_mysql_db_field->setText (_settings->value ("project/mysql/db").toString());
|
||||
ui->MySQL_box->setChecked (_settings->value ("project/mysql/enabled").toBool());
|
||||
|
||||
auto server_str = _settings->value("project/mysql/server", "127.0.0.1").toString();
|
||||
auto user_str = _settings->value("project/mysql/user", "127.0.0.1").toString();
|
||||
auto pwd_str = _settings->value("project/mysql/pwd", "127.0.0.1").toString();
|
||||
auto db_str = _settings->value("project/mysql/db", "127.0.0.1").toString();
|
||||
auto port_int = _settings->value("project/mysql/port", "127.0.0.1").toInt();
|
||||
|
||||
// set some default
|
||||
if (server_str.isEmpty())
|
||||
server_str = "127.0.0.1";
|
||||
if (user_str.isEmpty())
|
||||
user_str = "root";
|
||||
if (pwd_str.isEmpty())
|
||||
pwd_str = "root";
|
||||
if (db_str.isEmpty())
|
||||
db_str = "noggit";
|
||||
if (!port_int)
|
||||
port_int = 3306;
|
||||
|
||||
ui->_mysql_server_field->setText (server_str);
|
||||
ui->_mysql_user_field->setText(user_str);
|
||||
ui->_mysql_pwd_field->setText (pwd_str);
|
||||
ui->_mysql_db_field->setText (db_str);
|
||||
ui->_mysql_port_field->setValue (port_int);
|
||||
#endif
|
||||
|
||||
int wireframe_type = _settings->value("wireframe/type", 0).toInt();
|
||||
@@ -245,11 +277,12 @@ namespace Noggit
|
||||
_settings->setValue("nativeMenubar", ui->_nativeMenubar->isChecked());
|
||||
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
_settings->setValue ("project/mysql/enabled", _mysql_box->isChecked());
|
||||
_settings->setValue ("project/mysql/server", _mysql_server_field->text());
|
||||
_settings->setValue ("project/mysql/user", _mysql_user_field->text());
|
||||
_settings->setValue ("project/mysql/pwd", _mysql_pwd_field->text());
|
||||
_settings->setValue ("project/mysql/db", _mysql_db_field->text());
|
||||
_settings->setValue ("project/mysql/enabled", ui->MySQL_box->isChecked());
|
||||
_settings->setValue ("project/mysql/server", ui->_mysql_server_field->text());
|
||||
_settings->setValue ("project/mysql/user", ui->_mysql_user_field->text());
|
||||
_settings->setValue ("project/mysql/pwd", ui->_mysql_pwd_field->text());
|
||||
_settings->setValue ("project/mysql/db", ui->_mysql_db_field->text());
|
||||
_settings->setValue ("project/mysql/port", ui->_mysql_port_field->text());
|
||||
#endif
|
||||
|
||||
_settings->setValue("wireframe/type", ui->radio_wire_cursor->isChecked());
|
||||
|
||||
@@ -1201,7 +1201,7 @@
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>MySQL</string>
|
||||
<string>MySQL (Noggit UID storage)</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
@@ -1295,6 +1295,36 @@
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_66">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_48">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>60</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Port</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="_mysql_port_field">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>65535</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="mysql_warning">
|
||||
<property name="minimumSize">
|
||||
@@ -1311,6 +1341,36 @@
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_12">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_5">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="mysql_connect_test">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>93</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Test Connection</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
|
||||
Reference in New Issue
Block a user