[UCS] Auto Client Reconnection (#2154)

This commit is contained in:
Chris Miles 2022-05-07 22:24:11 -05:00 committed by GitHub
parent 9f9eaed983
commit 07b46ed445
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 129 additions and 25 deletions

View File

@ -32,6 +32,8 @@
#include "worldserver.h"
#include <list>
#include <signal.h>
#include <csignal>
#include <thread>
#include "../common/net/tcp_server.h"
#include "../common/net/servertalk_client_connection.h"
@ -49,19 +51,43 @@ std::string WorldShortName;
uint32 ChatMessagesSent = 0;
uint32 MailMessagesSent = 0;
volatile bool RunLoops = true;
void CatchSignal(int sig_num) {
RunLoops = false;
}
std::string GetMailPrefix() {
return "SOE.EQ." + WorldShortName + ".";
}
void crash_func() {
std::this_thread::sleep_for(std::chrono::milliseconds(10000));
int* p=0;
*p=0;
}
void Shutdown() {
LogInfo("Shutting down...");
ChannelList->RemoveAllChannels();
g_Clientlist->CloseAllConnections();
LogSys.CloseFileLogs();
}
int caught_loop = 0;
void CatchSignal(int sig_num) {
LogInfo("Caught signal [{}]", sig_num);
EQ::EventLoop::Get().Shutdown();
caught_loop++;
// when signal handler is incapable of exiting properly
if (caught_loop > 1) {
LogInfo("In a signal handler loop and process is incapable of exiting properly, forcefully cleaning up");
ChannelList->RemoveAllChannels();
g_Clientlist->CloseAllConnections();
LogSys.CloseFileLogs();
std::exit(0);
}
}
int main() {
RegisterExecutablePlatform(ExePlatformUCS);
LogSys.LoadLogSettingsDefaults();
@ -134,17 +160,17 @@ int main() {
database.LoadChatChannels();
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
LogInfo("Could not set signal handler");
return 1;
}
if (signal(SIGTERM, CatchSignal) == SIG_ERR) {
LogInfo("Could not set signal handler");
return 1;
}
std::signal(SIGINT, CatchSignal);
std::signal(SIGTERM, CatchSignal);
std::signal(SIGKILL, CatchSignal);
std::signal(SIGSEGV, CatchSignal);
worldserver = new WorldServer;
// uncomment to simulate timed crash for catching SIGSEV
// std::thread crash_test(crash_func);
// crash_test.detach();
auto loop_fn = [&](EQ::Timer* t) {
Timer::SetCurrentTime();
@ -166,12 +192,7 @@ int main() {
EQ::EventLoop::Get().Run();
ChannelList->RemoveAllChannels();
g_Clientlist->CloseAllConnections();
LogSys.CloseFileLogs();
Shutdown();
}
void UpdateWindowTitle(char* iNewTitle) {

View File

@ -10971,3 +10971,80 @@ uint16 Client::GetClassTrackingDistanceMultiplier(uint16 class_) {
bool Client::CanThisClassTrack() {
return (GetClassTrackingDistanceMultiplier(GetClass()) > 0) ? true : false;
}
void Client::ReconnectUCS()
{
EQApplicationPacket *outapp = nullptr;
std::string buffer;
std::string mail_key = database.GetMailKey(CharacterID(), true);
EQ::versions::UCSVersion connection_type = EQ::versions::ucsUnknown;
// chat server packet
switch (ClientVersion()) {
case EQ::versions::ClientVersion::Titanium:
connection_type = EQ::versions::ucsTitaniumChat;
break;
case EQ::versions::ClientVersion::SoF:
connection_type = EQ::versions::ucsSoFCombined;
break;
case EQ::versions::ClientVersion::SoD:
connection_type = EQ::versions::ucsSoDCombined;
break;
case EQ::versions::ClientVersion::UF:
connection_type = EQ::versions::ucsUFCombined;
break;
case EQ::versions::ClientVersion::RoF:
connection_type = EQ::versions::ucsRoFCombined;
break;
case EQ::versions::ClientVersion::RoF2:
connection_type = EQ::versions::ucsRoF2Combined;
break;
default:
connection_type = EQ::versions::ucsUnknown;
break;
}
buffer = StringFormat(
"%s,%i,%s.%s,%c%s",
Config->ChatHost.c_str(),
Config->ChatPort,
Config->ShortName.c_str(),
GetName(),
connection_type,
mail_key.c_str()
);
outapp = new EQApplicationPacket(OP_SetChatServer, (buffer.length() + 1));
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
outapp->pBuffer[buffer.length()] = '\0';
QueuePacket(outapp);
safe_delete(outapp);
// mail server packet
switch (ClientVersion()) {
case EQ::versions::ClientVersion::Titanium:
connection_type = EQ::versions::ucsTitaniumMail;
break;
default:
// retain value from previous switch
break;
}
buffer = StringFormat(
"%s,%i,%s.%s,%c%s",
Config->MailHost.c_str(),
Config->MailPort,
Config->ShortName.c_str(),
GetName(),
connection_type,
mail_key.c_str()
);
outapp = new EQApplicationPacket(OP_SetChatServer2, (buffer.length() + 1));
memcpy(outapp->pBuffer, buffer.c_str(), buffer.length());
outapp->pBuffer[buffer.length()] = '\0';
QueuePacket(outapp);
safe_delete(outapp);
}

View File

@ -231,6 +231,8 @@ public:
bool is_client_moving;
void ReconnectUCS();
void SetDisplayMobInfoWindow(bool display_mob_info_window);
bool GetDisplayMobInfoWindow() const;
@ -1025,7 +1027,7 @@ public:
void SetLinkedSpellReuseTimer(uint32 timer_id, uint32 duration);
bool IsLinkedSpellReuseTimerReady(uint32 timer_id);
void ResetCastbarCooldownBySlot(int slot);
void ResetAllCastbarCooldowns();
void ResetCastbarCooldownBySpellID(uint32 spell_id);
@ -1894,7 +1896,7 @@ private:
Timer pick_lock_timer;
Timer heroforge_wearchange_timer;
glm::vec3 m_Proximity;
glm::vec4 last_position_before_bulk_update;

View File

@ -659,7 +659,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
if (database.GetInstanceID(client->CharacterID(), ZoneID(szp->zone))) {
client->RemoveFromInstance(database.GetInstanceID(client->CharacterID(), ZoneID(szp->zone)));
}
client->AssignToInstance(szp->instance_id);
client->MovePC(ZoneID(szp->zone), szp->instance_id, szp->x_pos, szp->y_pos, szp->z_pos, client->GetHeading(), szp->ignorerestrictions, GMSummon);
}
@ -1917,7 +1917,7 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
LogSys.LoadLogDatabaseSettings();
break;
}
case ServerOP_ReloadMerchants: {
case ServerOP_ReloadMerchants: {
zone->SendReloadMessage("Merchants");
entity_list.ReloadMerchants();
break;
@ -2016,6 +2016,10 @@ void WorldServer::HandleMessage(uint16 opcode, const EQ::Net::Packet &p)
if (zone) {
zone->SetUCSServerAvailable((ucsss->available != 0), ucsss->timestamp);
LogInfo("UCS Server is now [{}]", (ucsss->available == 1 ? "online" : "offline"));
for (auto &e : entity_list.GetClientList()) {
e.second->ReconnectUCS();
}
}
break;
}