mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 21:01:29 +00:00
[UCS] Auto Client Reconnection (#2154)
This commit is contained in:
parent
9f9eaed983
commit
07b46ed445
63
ucs/ucs.cpp
63
ucs/ucs.cpp
@ -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) {
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -231,6 +231,8 @@ public:
|
||||
|
||||
bool is_client_moving;
|
||||
|
||||
void ReconnectUCS();
|
||||
|
||||
void SetDisplayMobInfoWindow(bool display_mob_info_window);
|
||||
bool GetDisplayMobInfoWindow() const;
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user