mirror of
https://github.com/EQEmu/Server.git
synced 2026-05-17 03:08:26 +00:00
Updated UCS versioning code - update your *.conf files
This commit is contained in:
+49
-104
@@ -512,7 +512,6 @@ Client::Client(std::shared_ptr<EQStreamInterface> eqs) {
|
||||
AccountGrabUpdateTimer = new Timer(60000); //check every minute
|
||||
GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS));
|
||||
|
||||
RawConnectionType = '\0';
|
||||
TypeOfConnection = ConnectionTypeUnknown;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::Unknown;
|
||||
|
||||
@@ -645,10 +644,6 @@ void Clientlist::Process()
|
||||
|
||||
database.GetAccountStatus((*it));
|
||||
|
||||
// give world packet a chance to arrive and be processed
|
||||
if ((*it)->GetCharID())
|
||||
ClientVersionRequestQueue[(*it)->GetCharID()] = (Timer::GetCurrentTime() + (RuleI(Chat, ExpireClientVersionRequests) * 1000));
|
||||
|
||||
if ((*it)->GetConnectionType() == ConnectionTypeCombined)
|
||||
(*it)->SendFriends();
|
||||
|
||||
@@ -688,34 +683,8 @@ void Clientlist::Process()
|
||||
continue;
|
||||
}
|
||||
|
||||
// initiate request if we don't already have a reply from 'world enter' (ucs crash recovery protocol)
|
||||
if ((*it)->GetClientVersion() == EQEmu::versions::ClientVersion::Unknown) {
|
||||
if (!CheckForClientVersionReply((*it)))
|
||||
RequestClientVersion((*it)->GetCharID());
|
||||
}
|
||||
|
||||
++it;
|
||||
}
|
||||
|
||||
// delete expired replies
|
||||
auto repiter = ClientVersionReplyQueue.begin();
|
||||
while (repiter != ClientVersionReplyQueue.end()) {
|
||||
if ((*repiter).second.second <= Timer::GetCurrentTime()) {
|
||||
repiter = ClientVersionReplyQueue.erase(repiter);
|
||||
continue;
|
||||
}
|
||||
++repiter;
|
||||
}
|
||||
|
||||
// delete expired requests
|
||||
auto reqiter = ClientVersionRequestQueue.begin();
|
||||
while (reqiter != ClientVersionRequestQueue.end()) {
|
||||
if ((*reqiter).second <= Timer::GetCurrentTime()) {
|
||||
reqiter = ClientVersionRequestQueue.erase(reqiter);
|
||||
continue;
|
||||
}
|
||||
++reqiter;
|
||||
}
|
||||
}
|
||||
|
||||
void Clientlist::ProcessOPMailCommand(Client *c, std::string CommandString)
|
||||
@@ -873,55 +842,6 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string CommandString)
|
||||
}
|
||||
}
|
||||
|
||||
void Clientlist::RequestClientVersion(uint32 character_id) {
|
||||
if (!character_id)
|
||||
return;
|
||||
|
||||
if (ClientVersionRequestQueue.find(character_id) != ClientVersionRequestQueue.end()) {
|
||||
if (ClientVersionRequestQueue[character_id] > Timer::GetCurrentTime())
|
||||
return;
|
||||
}
|
||||
|
||||
if (LogSys.log_settings[Logs::UCS_Server].is_category_enabled) {
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Requesting ClientVersion reply for character id: %u",
|
||||
character_id);
|
||||
}
|
||||
ClientVersionRequestIDs.push_back(character_id);
|
||||
ClientVersionRequestQueue[character_id] = (Timer::GetCurrentTime() + (RuleI(Chat, ExpireClientVersionRequests) * 1000));
|
||||
}
|
||||
|
||||
bool Clientlist::QueueClientVersionReply(uint32 character_id, EQEmu::versions::ClientVersion client_version) {
|
||||
if (!character_id)
|
||||
return true;
|
||||
if (client_version < EQEmu::versions::ClientVersion::Titanium || client_version > EQEmu::versions::ClientVersion::RoF2)
|
||||
return false;
|
||||
|
||||
if (LogSys.log_settings[Logs::UCS_Server].is_category_enabled) {
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Queueing ClientVersion %u reply for character id: %u",
|
||||
static_cast<uint32>(client_version), character_id);
|
||||
}
|
||||
ClientVersionReplyQueue[character_id] = cvt_pair(client_version, (Timer::GetCurrentTime() + (RuleI(Chat, ExpireClientVersionReplies) * 1000)));
|
||||
ClientVersionRequestQueue.erase(character_id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Clientlist::CheckForClientVersionReply(Client* c) {
|
||||
if (!c)
|
||||
return true;
|
||||
if (ClientVersionReplyQueue.find(c->GetCharID()) == ClientVersionReplyQueue.end())
|
||||
return false;
|
||||
|
||||
if (LogSys.log_settings[Logs::UCS_Server].is_category_enabled) {
|
||||
Log(Logs::General, Logs::UCS_Server, "Registering ClientVersion %s for stream %s:%u",
|
||||
EQEmu::versions::ClientVersionName(ClientVersionReplyQueue[c->GetCharID()].first), c->ClientStream->GetRemoteAddr().c_str(), c->ClientStream->GetRemotePort());
|
||||
}
|
||||
c->SetClientVersion(ClientVersionReplyQueue[c->GetCharID()].first);
|
||||
ClientVersionReplyQueue.erase(c->GetCharID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void Clientlist::CloseAllConnections() {
|
||||
|
||||
|
||||
@@ -2214,39 +2134,64 @@ void Client::AccountUpdate()
|
||||
|
||||
void Client::SetConnectionType(char c) {
|
||||
|
||||
RawConnectionType = c;
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case 'S':
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (SoF/SoD)");
|
||||
break;
|
||||
}
|
||||
case 'U':
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
UnderfootOrLater = true;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (Underfoot+)");
|
||||
break;
|
||||
}
|
||||
case 'M':
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeMail;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Mail (6.2 or Titanium client)");
|
||||
break;
|
||||
}
|
||||
case 'C':
|
||||
case EQEmu::versions::ucsTitaniumChat:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeChat;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Chat (6.2 or Titanium client)");
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::Titanium;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Chat (Titanium)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsTitaniumMail:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeMail;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::Titanium;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Mail (Titanium)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsSoFCombined:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::SoF;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (SoF)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsSoDCombined:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::SoD;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (SoD)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsUFCombined:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::UF;
|
||||
UnderfootOrLater = true;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (Underfoot)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsRoFCombined:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::RoF;
|
||||
UnderfootOrLater = true;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (RoF)");
|
||||
break;
|
||||
}
|
||||
case EQEmu::versions::ucsRoF2Combined:
|
||||
{
|
||||
TypeOfConnection = ConnectionTypeCombined;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::RoF2;
|
||||
UnderfootOrLater = true;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is Combined (RoF2)");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
RawConnectionType = '\0';
|
||||
TypeOfConnection = ConnectionTypeUnknown;
|
||||
ClientVersion_ = EQEmu::versions::ClientVersion::Unknown;
|
||||
Log(Logs::Detail, Logs::UCS_Server, "Connection type is unknown.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,10 +140,8 @@ public:
|
||||
int GetMailBoxNumber() { return CurrentMailBox; }
|
||||
int GetMailBoxNumber(std::string CharacterName);
|
||||
|
||||
char GetRawConnectionType() { return RawConnectionType; }
|
||||
void SetConnectionType(char c);
|
||||
ConnectionType GetConnectionType() { return TypeOfConnection; }
|
||||
void SetClientVersion(EQEmu::versions::ClientVersion client_version) { ClientVersion_ = client_version; }
|
||||
EQEmu::versions::ClientVersion GetClientVersion() { return ClientVersion_; }
|
||||
|
||||
inline bool IsMailConnection() { return (TypeOfConnection == ConnectionTypeMail) || (TypeOfConnection == ConnectionTypeCombined); }
|
||||
@@ -173,7 +171,6 @@ private:
|
||||
int AttemptedMessages;
|
||||
bool ForceDisconnect;
|
||||
|
||||
char RawConnectionType;
|
||||
ConnectionType TypeOfConnection;
|
||||
EQEmu::versions::ClientVersion ClientVersion_;
|
||||
bool UnderfootOrLater;
|
||||
@@ -190,22 +187,11 @@ public:
|
||||
Client *IsCharacterOnline(std::string CharacterName);
|
||||
void ProcessOPMailCommand(Client *c, std::string CommandString);
|
||||
|
||||
std::list<uint32> ClientVersionRequestIDs;
|
||||
|
||||
void RequestClientVersion(uint32 character_id);
|
||||
bool QueueClientVersionReply(uint32 character_id, EQEmu::versions::ClientVersion client_version);
|
||||
bool CheckForClientVersionReply(Client* c);
|
||||
|
||||
private:
|
||||
typedef std::pair<EQEmu::versions::ClientVersion, uint32> cvt_pair;
|
||||
|
||||
EQ::Net::EQStreamManager *chatsf;
|
||||
|
||||
std::list<Client*> ClientChatConnections;
|
||||
|
||||
std::map<uint32, uint32> ClientVersionRequestQueue;
|
||||
std::map<uint32, cvt_pair> ClientVersionReplyQueue;
|
||||
|
||||
OpcodeManager *ChatOpMgr;
|
||||
};
|
||||
|
||||
|
||||
@@ -140,19 +140,12 @@ int main() {
|
||||
|
||||
worldserver = new WorldServer;
|
||||
|
||||
worldserver->ActivateBroadcastServerReadyTimer();
|
||||
|
||||
while(RunLoops) {
|
||||
// this triggers clients to 'reconnect' to ucs after server crash
|
||||
if (worldserver->HasBroadcastServerReadyTimer())
|
||||
worldserver->ProcessBroadcastServerReady();
|
||||
|
||||
Timer::SetCurrentTime();
|
||||
|
||||
g_Clientlist->Process();
|
||||
|
||||
worldserver->ProcessClientVersionRequests(g_Clientlist->ClientVersionRequestIDs);
|
||||
|
||||
if(ChannelListProcessTimer.Check())
|
||||
ChannelList->Process();
|
||||
|
||||
|
||||
@@ -50,8 +50,6 @@ WorldServer::WorldServer()
|
||||
{
|
||||
m_connection.reset(new EQ::Net::ServertalkClient(Config->WorldIP, Config->WorldTCPPort, false, "UCS", Config->SharedKey));
|
||||
m_connection->OnMessage(std::bind(&WorldServer::ProcessMessage, this, std::placeholders::_1, std::placeholders::_2));
|
||||
|
||||
m_bsr_timer = nullptr;
|
||||
}
|
||||
|
||||
WorldServer::~WorldServer()
|
||||
@@ -140,59 +138,7 @@ void WorldServer::ProcessMessage(uint16 opcode, EQ::Net::Packet &p)
|
||||
std::string());
|
||||
break;
|
||||
}
|
||||
|
||||
case ServerOP_UCSClientVersionReply:
|
||||
{
|
||||
UCSClientVersionReply_Struct* cvr = (UCSClientVersionReply_Struct*)pack->pBuffer;
|
||||
g_Clientlist->QueueClientVersionReply(cvr->character_id, cvr->client_version);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void WorldServer::ProcessClientVersionRequests(std::list<uint32>& id_list) {
|
||||
UCSClientVersionRequest_Struct cvr;
|
||||
EQ::Net::DynamicPacket dp_cvr;
|
||||
for (auto iter : id_list) {
|
||||
cvr.character_id = iter;
|
||||
dp_cvr.PutData(0, &cvr, sizeof(cvr));
|
||||
m_connection->Send(ServerOP_UCSClientVersionRequest, dp_cvr);
|
||||
}
|
||||
id_list.clear();
|
||||
}
|
||||
|
||||
void WorldServer::ProcessBroadcastServerReady() {
|
||||
if (m_bsr_timer && (*m_bsr_timer) <= Timer::GetCurrentTime()) {
|
||||
UCSBroadcastServerReady_Struct bsr;
|
||||
memset(&bsr, 0, sizeof(UCSBroadcastServerReady_Struct));
|
||||
|
||||
sprintf(bsr.chat_prefix, "%s,%i,%s.",
|
||||
Config->ChatHost.c_str(),
|
||||
Config->ChatPort,
|
||||
Config->ShortName.c_str()
|
||||
);
|
||||
sprintf(bsr.mail_prefix, "%s,%i,%s.",
|
||||
Config->ChatHost.c_str(),
|
||||
Config->MailPort,
|
||||
Config->ShortName.c_str()
|
||||
);
|
||||
|
||||
EQ::Net::DynamicPacket dp_bsr;
|
||||
dp_bsr.PutData(0, &bsr, sizeof(UCSBroadcastServerReady_Struct));
|
||||
m_connection->Send(ServerOP_UCSBroadcastServerReady, dp_bsr);
|
||||
|
||||
safe_delete(m_bsr_timer);
|
||||
}
|
||||
}
|
||||
|
||||
void WorldServer::ActivateBroadcastServerReadyTimer() {
|
||||
safe_delete(m_bsr_timer);
|
||||
m_bsr_timer = new uint32;
|
||||
|
||||
// clients do not drop their connection to ucs immediately...
|
||||
// it can take upwards of 60 seconds to process the drop
|
||||
// and clients will not re-connect to ucs until that occurs
|
||||
*m_bsr_timer = (Timer::GetCurrentTime() + (RuleI(Chat, UCSBroadcastServerReadyDelay) * 1000));
|
||||
}
|
||||
|
||||
void Client45ToServerSayLink(std::string& serverSayLink, const std::string& clientSayLink) {
|
||||
|
||||
@@ -29,14 +29,7 @@ public:
|
||||
~WorldServer();
|
||||
void ProcessMessage(uint16 opcode, EQ::Net::Packet &);
|
||||
|
||||
void ProcessClientVersionRequests(std::list<uint32>& id_list);
|
||||
|
||||
void ProcessBroadcastServerReady();
|
||||
bool HasBroadcastServerReadyTimer() { return (m_bsr_timer != nullptr); }
|
||||
void ActivateBroadcastServerReadyTimer();
|
||||
|
||||
private:
|
||||
uint32* m_bsr_timer;
|
||||
|
||||
std::unique_ptr<EQ::Net::ServertalkClient> m_connection;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user