[Discord Integration] Native Discord Integration (#2140)

* Start of discord integration work

* more testing

* Discord client work

* More discord work

* Cleanup

* Handle retry timer response and max retries

* Update base retry timer

* Move Discord queue handler to UCS, add queuer to own thread

* Post merge

* Send up Zone::SendDiscordMessage

* Start of discord integration work

* more testing

* Discord client work

* More discord work

* Cleanup

* Move Discord queue handler to UCS, add queuer to own thread

* Post merge

* Push up tables

* Quest API stuff.

* Update 2022_05_07_discord_webhooks.sql

* Post merge fixes

* Push up manifest

* Flip logging signs in logic from copy / paste of inverse logic before

* Make sure we add new line to quest api sourced messages

Co-authored-by: Kinglykrab <kinglykrab@gmail.com>
This commit is contained in:
Chris Miles
2022-06-09 17:22:23 -05:00
committed by GitHub
parent 8ef3e87370
commit 4639405fdf
32 changed files with 1052 additions and 259 deletions
+9 -9
View File
@@ -1,18 +1,18 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
SET(qserv_sources
database.cpp
lfguild.cpp
queryserv.cpp
queryservconfig.cpp
worldserver.cpp
database.cpp
lfguild.cpp
queryserv.cpp
queryservconfig.cpp
worldserver.cpp
)
SET(qserv_headers
database.h
lfguild.h
queryservconfig.h
worldserver.h
database.h
lfguild.h
queryservconfig.h
worldserver.h
)
ADD_EXECUTABLE(queryserv ${qserv_sources} ${qserv_headers})
+21 -14
View File
@@ -24,6 +24,7 @@
#include "../common/servertalk.h"
#include "../common/platform.h"
#include "../common/crash.h"
#include "../common/string_util.h"
#include "../common/event/event_loop.h"
#include "../common/timer.h"
#include "database.h"
@@ -32,21 +33,24 @@
#include "worldserver.h"
#include <list>
#include <signal.h>
#include <thread>
volatile bool RunLoops = true;
Database database;
LFGuildManager lfguildmanager;
std::string WorldShortName;
Database database;
LFGuildManager lfguildmanager;
std::string WorldShortName;
const queryservconfig *Config;
WorldServer *worldserver = 0;
EQEmuLogSys LogSys;
WorldServer *worldserver = 0;
EQEmuLogSys LogSys;
void CatchSignal(int sig_num) {
void CatchSignal(int sig_num)
{
RunLoops = false;
}
int main() {
int main()
{
RegisterExecutablePlatform(ExePlatformQueryServ);
LogSys.LoadLogSettingsDefaults();
set_exception_handler();
@@ -58,7 +62,7 @@ int main() {
return 1;
}
Config = queryservconfig::get();
Config = queryservconfig::get();
WorldShortName = Config->ShortName;
LogInfo("Connecting to MySQL");
@@ -69,7 +73,8 @@ int main() {
Config->QSDatabaseUsername.c_str(),
Config->QSDatabasePassword.c_str(),
Config->QSDatabaseDB.c_str(),
Config->QSDatabasePort)) {
Config->QSDatabasePort
)) {
LogInfo("Cannot continue without a database connection");
return 1;
}
@@ -78,11 +83,11 @@ int main() {
->LoadLogDatabaseSettings()
->StartFileLogs();
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
LogInfo("Could not set signal handler");
return 1;
}
if (signal(SIGTERM, CatchSignal) == SIG_ERR) {
if (signal(SIGTERM, CatchSignal) == SIG_ERR) {
LogInfo("Could not set signal handler");
return 1;
}
@@ -94,10 +99,11 @@ int main() {
/* Load Looking For Guild Manager */
lfguildmanager.LoadDatabase();
while(RunLoops) {
while (RunLoops) {
Timer::SetCurrentTime();
if(LFGuildExpireTimer.Check())
if (LFGuildExpireTimer.Check()) {
lfguildmanager.ExpireEntries();
}
EQ::EventLoop::Get().Process();
Sleep(5);
@@ -105,7 +111,8 @@ int main() {
LogSys.CloseFileLogs();
}
void UpdateWindowTitle(char* iNewTitle) {
void UpdateWindowTitle(char *iNewTitle)
{
#ifdef _WINDOWS
char tmp[500];
if (iNewTitle) {
+104 -98
View File
@@ -37,10 +37,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#include <string.h>
#include <time.h>
extern WorldServer worldserver;
extern WorldServer worldserver;
extern const queryservconfig *Config;
extern Database database;
extern LFGuildManager lfguildmanager;
extern Database database;
extern LFGuildManager lfguildmanager;
WorldServer::WorldServer()
{
@@ -52,7 +52,13 @@ WorldServer::~WorldServer()
void WorldServer::Connect()
{
m_connection = std::make_unique<EQ::Net::ServertalkClient>(Config->WorldIP, Config->WorldTCPPort, false, "QueryServ", Config->SharedKey);
m_connection = std::make_unique<EQ::Net::ServertalkClient>(
Config->WorldIP,
Config->WorldTCPPort,
false,
"QueryServ",
Config->SharedKey
);
m_connection->OnMessage(std::bind(&WorldServer::HandleMessage, this, std::placeholders::_1, std::placeholders::_2));
}
@@ -80,109 +86,109 @@ bool WorldServer::Connected() const
void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
{
switch (opcode) {
case 0: {
break;
}
case ServerOP_KeepAlive: {
break;
}
case ServerOP_Speech: {
Server_Speech_Struct *SSS = (Server_Speech_Struct*)p.Data();
std::string tmp1 = SSS->from;
std::string tmp2 = SSS->to;
database.AddSpeech(tmp1.c_str(), tmp2.c_str(), SSS->message, SSS->minstatus, SSS->guilddbid, SSS->type);
break;
}
case ServerOP_QSPlayerLogTrades: {
QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct*)p.Data();
database.LogPlayerTrade(QS, QS->_detail_count);
break;
}
case ServerOP_QSPlayerDropItem: {
QSPlayerDropItem_Struct *QS = (QSPlayerDropItem_Struct *) p.Data();
database.LogPlayerDropItem(QS);
break;
}
case ServerOP_QSPlayerLogHandins: {
QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct*)p.Data();
database.LogPlayerHandin(QS, QS->_detail_count);
break;
}
case ServerOP_QSPlayerLogNPCKills: {
QSPlayerLogNPCKill_Struct *QS = (QSPlayerLogNPCKill_Struct*)p.Data();
uint32 Members = (uint32)(p.Length() - sizeof(QSPlayerLogNPCKill_Struct));
if (Members > 0) Members = Members / sizeof(QSPlayerLogNPCKillsPlayers_Struct);
database.LogPlayerNPCKill(QS, Members);
break;
}
case ServerOP_QSPlayerLogDeletes: {
QSPlayerLogDelete_Struct *QS = (QSPlayerLogDelete_Struct*)p.Data();
uint32 Items = QS->char_count;
database.LogPlayerDelete(QS, Items);
break;
}
case ServerOP_QSPlayerLogMoves: {
QSPlayerLogMove_Struct *QS = (QSPlayerLogMove_Struct*)p.Data();
uint32 Items = QS->char_count;
database.LogPlayerMove(QS, Items);
break;
}
case ServerOP_QSPlayerLogMerchantTransactions: {
QSMerchantLogTransaction_Struct *QS = (QSMerchantLogTransaction_Struct*)p.Data();
uint32 Items = QS->char_count + QS->merchant_count;
database.LogMerchantTransaction(QS, Items);
break;
}
case ServerOP_QueryServGeneric: {
/*
The purpose of ServerOP_QueryServerGeneric is so that we don't have to add code to world just to relay packets
each time we add functionality to queryserv.
case 0: {
break;
}
case ServerOP_KeepAlive: {
break;
}
case ServerOP_Speech: {
Server_Speech_Struct *SSS = (Server_Speech_Struct *) p.Data();
std::string tmp1 = SSS->from;
std::string tmp2 = SSS->to;
database.AddSpeech(tmp1.c_str(), tmp2.c_str(), SSS->message, SSS->minstatus, SSS->guilddbid, SSS->type);
break;
}
case ServerOP_QSPlayerLogTrades: {
QSPlayerLogTrade_Struct *QS = (QSPlayerLogTrade_Struct *) p.Data();
database.LogPlayerTrade(QS, QS->_detail_count);
break;
}
case ServerOP_QSPlayerDropItem: {
QSPlayerDropItem_Struct *QS = (QSPlayerDropItem_Struct *) p.Data();
database.LogPlayerDropItem(QS);
break;
}
case ServerOP_QSPlayerLogHandins: {
QSPlayerLogHandin_Struct *QS = (QSPlayerLogHandin_Struct *) p.Data();
database.LogPlayerHandin(QS, QS->_detail_count);
break;
}
case ServerOP_QSPlayerLogNPCKills: {
QSPlayerLogNPCKill_Struct *QS = (QSPlayerLogNPCKill_Struct *) p.Data();
uint32 Members = (uint32) (p.Length() - sizeof(QSPlayerLogNPCKill_Struct));
if (Members > 0) { Members = Members / sizeof(QSPlayerLogNPCKillsPlayers_Struct); }
database.LogPlayerNPCKill(QS, Members);
break;
}
case ServerOP_QSPlayerLogDeletes: {
QSPlayerLogDelete_Struct *QS = (QSPlayerLogDelete_Struct *) p.Data();
uint32 Items = QS->char_count;
database.LogPlayerDelete(QS, Items);
break;
}
case ServerOP_QSPlayerLogMoves: {
QSPlayerLogMove_Struct *QS = (QSPlayerLogMove_Struct *) p.Data();
uint32 Items = QS->char_count;
database.LogPlayerMove(QS, Items);
break;
}
case ServerOP_QSPlayerLogMerchantTransactions: {
QSMerchantLogTransaction_Struct *QS = (QSMerchantLogTransaction_Struct *) p.Data();
uint32 Items = QS->char_count + QS->merchant_count;
database.LogMerchantTransaction(QS, Items);
break;
}
case ServerOP_QueryServGeneric: {
/*
The purpose of ServerOP_QueryServerGeneric is so that we don't have to add code to world just to relay packets
each time we add functionality to queryserv.
A ServerOP_QueryServGeneric packet has the following format:
A ServerOP_QueryServGeneric packet has the following format:
uint32 SourceZoneID
uint32 SourceInstanceID
char OriginatingCharacterName[0]
- Null terminated name of the character this packet came from. This could be just
- an empty string if it has no meaning in the context of a particular packet.
uint32 Type
uint32 SourceZoneID
uint32 SourceInstanceID
char OriginatingCharacterName[0]
- Null terminated name of the character this packet came from. This could be just
- an empty string if it has no meaning in the context of a particular packet.
uint32 Type
The 'Type' field is a 'sub-opcode'. A value of 0 is used for the LFGuild packets. The next feature to be added
to queryserv would use 1, etc.
The 'Type' field is a 'sub-opcode'. A value of 0 is used for the LFGuild packets. The next feature to be added
to queryserv would use 1, etc.
Obviously, any fields in the packet following the 'Type' will be unique to the particular type of packet. The
'Generic' in the name of this ServerOP code relates to the four header fields.
*/
Obviously, any fields in the packet following the 'Type' will be unique to the particular type of packet. The
'Generic' in the name of this ServerOP code relates to the four header fields.
*/
auto from = p.GetCString(8);
uint32 Type = p.GetUInt32(8 + from.length() + 1);
auto from = p.GetCString(8);
uint32 Type = p.GetUInt32(8 + from.length() + 1);
switch (Type) {
case QSG_LFGuild: {
switch (Type) {
case QSG_LFGuild: {
ServerPacket pack;
pack.pBuffer = (uchar *) p.Data();
pack.opcode = opcode;
pack.size = (uint32) p.Length();
lfguildmanager.HandlePacket(&pack);
pack.pBuffer = nullptr;
break;
}
default:
LogInfo("Received unhandled ServerOP_QueryServGeneric", Type);
break;
}
break;
}
case ServerOP_QSSendQuery: {
/* Process all packets here */
ServerPacket pack;
pack.pBuffer = (uchar*)p.Data();
pack.opcode = opcode;
pack.size = (uint32)p.Length();
lfguildmanager.HandlePacket(&pack);
pack.pBuffer = (uchar *) p.Data();
pack.opcode = opcode;
pack.size = (uint32) p.Length();
database.GeneralQueryReceive(&pack);
pack.pBuffer = nullptr;
break;
}
default:
LogInfo("Received unhandled ServerOP_QueryServGeneric", Type);
break;
}
break;
}
case ServerOP_QSSendQuery: {
/* Process all packets here */
ServerPacket pack;
pack.pBuffer = (uchar*)p.Data();
pack.opcode = opcode;
pack.size = (uint32)p.Length();
database.GeneralQueryReceive(&pack);
pack.pBuffer = nullptr;
break;
}
}
}
+14 -13
View File
@@ -18,24 +18,25 @@
#ifndef WORLDSERVER_H
#define WORLDSERVER_H
#include <mutex>
#include "../common/eq_packet_structs.h"
#include "../common/net/servertalk_client_connection.h"
class WorldServer
{
public:
WorldServer();
~WorldServer();
class WorldServer {
public:
WorldServer();
~WorldServer();
void Connect();
bool SendPacket(ServerPacket* pack);
std::string GetIP() const;
uint16 GetPort() const;
bool Connected() const;
void Connect();
bool SendPacket(ServerPacket *pack);
std::string GetIP() const;
uint16 GetPort() const;
bool Connected() const;
void HandleMessage(uint16 opcode, const EQ::Net::Packet &p);
private:
std::unique_ptr<EQ::Net::ServertalkClient> m_connection;
void HandleMessage(uint16 opcode, const EQ::Net::Packet &p);
private:
std::unique_ptr<EQ::Net::ServertalkClient> m_connection;
};
#endif