From 16a96a2756f7116383e5eb683ce6260f69a2dcd4 Mon Sep 17 00:00:00 2001 From: KimLS Date: Sat, 10 Sep 2016 22:18:52 -0700 Subject: [PATCH] UCS basically works now, really needs to be rewritten. --- common/CMakeLists.txt | 4 + common/net/eqstream.cpp | 6 +- common/net/eqstream.h | 24 ++- common/patch/chat.cpp | 17 ++ common/patch/chat.h | 15 ++ common/patch/login_titanium.cpp | 2 +- common/patch/patch.cpp | 2 +- loginserver/client_manager.cpp | 4 - ucs/CMakeLists.txt | 13 +- ucs/clientlist.cpp | 319 +++++++++++++------------------- ucs/clientlist.h | 30 +-- ucs/ucs.cpp | 23 +-- 12 files changed, 221 insertions(+), 238 deletions(-) create mode 100644 common/patch/chat.cpp create mode 100644 common/patch/chat.h diff --git a/common/CMakeLists.txt b/common/CMakeLists.txt index fd673a8d7..d1469ba54 100644 --- a/common/CMakeLists.txt +++ b/common/CMakeLists.txt @@ -79,6 +79,7 @@ SET(common_sources net/daybreak_connection.cpp net/eqstream.cpp net/packet.cpp + patch/chat.cpp patch/login_sod.cpp patch/login_titanium.cpp patch/patch.cpp @@ -226,6 +227,7 @@ SET(common_headers net/endian.h net/eqstream.h net/packet.h + patch/chat.h patch/login_sod.h patch/login_titanium.h patch/patch.h @@ -303,6 +305,8 @@ SOURCE_GROUP(Net FILES ) SOURCE_GROUP(Patch FILES + patch/chat.cpp + patch/chat.h patch/login_sod.cpp patch/login_sod.h patch/login_titanium.cpp diff --git a/common/net/eqstream.cpp b/common/net/eqstream.cpp index be7caebe2..b2c9864d5 100644 --- a/common/net/eqstream.cpp +++ b/common/net/eqstream.cpp @@ -84,7 +84,7 @@ EQ::Net::EQStream::~EQStream() { } -void EQ::Net::EQStream::QueuePacket(EmuOpcode type, Packet &p) +void EQ::Net::EQStream::QueuePacket(EmuOpcode type, const Packet &p) { if (m_patch) { EQ::Net::WritablePacket trans; @@ -101,14 +101,14 @@ void EQ::Net::EQStream::Close() { } -void EQ::Net::EQStream::QueuePacket(EQApplicationPacket *p) +void EQ::Net::EQStream::QueuePacket(const EQApplicationPacket *p) { EQ::Net::ReadOnlyPacket out(p->pBuffer, p->size); QueuePacket(p->GetOpcode(), out); } -void EQ::Net::EQStream::FastQueuePacket(EQApplicationPacket **p) +void EQ::Net::EQStream::FastQueuePacket(const EQApplicationPacket **p) { QueuePacket(*p); delete *p; diff --git a/common/net/eqstream.h b/common/net/eqstream.h index 04aef0d2a..97a66d713 100644 --- a/common/net/eqstream.h +++ b/common/net/eqstream.h @@ -12,11 +12,25 @@ namespace EQ struct EQStreamManagerOptions { EQStreamManagerOptions() { - compressed = false; + + } + + EQStreamManagerOptions(bool encoded, bool compressed) { + if (encoded) { + daybreak_options.encode_passes[0] = EncodeXOR; + + if (compressed) { + daybreak_options.encode_passes[1] = EncodeCompression; + } + } + else { + if (compressed) { + daybreak_options.encode_passes[0] = EncodeCompression; + } + } } DaybreakConnectionManagerOptions daybreak_options; - bool compressed; }; class EQStream; @@ -55,13 +69,13 @@ namespace EQ const std::string& RemoteEndpoint() const { return m_connection->RemoteEndpoint(); } int RemotePort() const { return m_connection->RemotePort(); } - void QueuePacket(EmuOpcode type, Packet &p); + void QueuePacket(EmuOpcode type, const Packet &p); const DaybreakConnectionStats& GetStats() const { return m_connection->GetStats(); } void ResetStats(); size_t GetRollingPing() const { return m_connection->GetRollingPing(); } void Close(); - void QueuePacket(EQApplicationPacket *p); - void FastQueuePacket(EQApplicationPacket **p); + void QueuePacket(const EQApplicationPacket *p); + void FastQueuePacket(const EQApplicationPacket **p); void RegisterPatch(EQ::Patches::BasePatch *p) { m_patch = p; } EQ::Patches::BasePatch *GetRegisteredPatch() { return m_patch; } diff --git a/common/patch/chat.cpp b/common/patch/chat.cpp new file mode 100644 index 000000000..48cbce345 --- /dev/null +++ b/common/patch/chat.cpp @@ -0,0 +1,17 @@ +#include "chat.h" + +EQ::Patches::ChatPatch::ChatPatch() +{ + m_opcode_manager.reset(new RegularOpcodeManager()); + if (!m_opcode_manager->LoadOpcodes("mail_opcodes.conf")) { + m_opcode_manager.release(); + } + + m_signature.match_message_opcode = 0x0; + m_signature.match_message_size = 0; + m_message_size = 1; +} + +EQ::Patches::ChatPatch::~ChatPatch() +{ +} diff --git a/common/patch/chat.h b/common/patch/chat.h new file mode 100644 index 000000000..d7302ca16 --- /dev/null +++ b/common/patch/chat.h @@ -0,0 +1,15 @@ +#include + +namespace EQ +{ + namespace Patches + { + class ChatPatch : public BasePatch + { + public: + ChatPatch(); + virtual ~ChatPatch(); + virtual std::string GetName() const { return "Chat"; } + }; + } +} \ No newline at end of file diff --git a/common/patch/login_titanium.cpp b/common/patch/login_titanium.cpp index 3ccdaabcf..6df5d3dc3 100644 --- a/common/patch/login_titanium.cpp +++ b/common/patch/login_titanium.cpp @@ -3,7 +3,7 @@ EQ::Patches::LoginTitaniumPatch::LoginTitaniumPatch() { m_opcode_manager.reset(new RegularOpcodeManager()); - if (!m_opcode_manager->LoadOpcodes("login_opcodes_titanium.conf")) { + if (!m_opcode_manager->LoadOpcodes("login_opcodes.conf")) { m_opcode_manager.release(); } diff --git a/common/patch/patch.cpp b/common/patch/patch.cpp index b7bbfef4a..718734cc3 100644 --- a/common/patch/patch.cpp +++ b/common/patch/patch.cpp @@ -19,7 +19,7 @@ EQ::Patches::IdentityMatchStatus EQ::Patches::BasePatch::TryIdentityMatch(const return IdentityMatchFailure; } - if (m_signature.match_message_opcode != raw_opcode) { + if (m_signature.match_message_opcode != 0 && m_signature.match_message_opcode != raw_opcode) { return IdentityMatchFailure; } diff --git a/loginserver/client_manager.cpp b/loginserver/client_manager.cpp index 4961e1c2a..5ecc1f9e9 100644 --- a/loginserver/client_manager.cpp +++ b/loginserver/client_manager.cpp @@ -30,7 +30,6 @@ ClientManager::ClientManager() titanium_patch.reset(new EQ::Patches::LoginTitaniumPatch()); titanium_stream->RegisterPotentialPatch(titanium_patch.get()); - titanium_stream->OnNewConnection(std::bind(&ClientManager::HandleNewConnectionSod, this, std::placeholders::_1)); titanium_stream->OnNewConnection(std::bind(&ClientManager::HandleNewConnectionTitanium, this, std::placeholders::_1)); titanium_stream->OnConnectionStateChange(std::bind(&ClientManager::HandleConnectionChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); titanium_stream->OnPacketRecv(std::bind(&ClientManager::HandlePacket, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); @@ -41,12 +40,9 @@ ClientManager::ClientManager() sod_patch.reset(new EQ::Patches::LoginSoDPatch()); sod_stream->RegisterPotentialPatch(sod_patch.get()); - sod_stream->OnNewConnection(std::bind(&ClientManager::HandleNewConnectionSod, this, std::placeholders::_1)); sod_stream->OnNewConnection(std::bind(&ClientManager::HandleNewConnectionSod, this, std::placeholders::_1)); sod_stream->OnConnectionStateChange(std::bind(&ClientManager::HandleConnectionChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); sod_stream->OnPacketRecv(std::bind(&ClientManager::HandlePacket, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - - } ClientManager::~ClientManager() diff --git a/ucs/CMakeLists.txt b/ucs/CMakeLists.txt index ce0dca0e3..07415afd2 100644 --- a/ucs/CMakeLists.txt +++ b/ucs/CMakeLists.txt @@ -23,16 +23,11 @@ INSTALL(TARGETS ucs RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin) ADD_DEFINITIONS(-DUCS) -TARGET_LINK_LIBRARIES(ucs common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY}) +TARGET_LINK_LIBRARIES(ucs common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} libuv fmt) -IF(MSVC) - SET_TARGET_PROPERTIES(ucs PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF") - TARGET_LINK_LIBRARIES(ucs "Ws2_32.lib") -ENDIF(MSVC) - -IF(MINGW) - TARGET_LINK_LIBRARIES(ucs "WS2_32") -ENDIF(MINGW) +IF(WIN32) + TARGET_LINK_LIBRARIES(ucs "ws2_32" "psapi" "iphlpapi" "userenv") +ENDIF(WIN32) IF(UNIX) TARGET_LINK_LIBRARIES(ucs "${CMAKE_DL_LIBS}") diff --git a/ucs/clientlist.cpp b/ucs/clientlist.cpp index f49e02986..a7ad95d50 100644 --- a/ucs/clientlist.cpp +++ b/ucs/clientlist.cpp @@ -17,15 +17,14 @@ */ -#include "../common/global_define.h" -#include "../common/string_util.h" -#include "../common/eqemu_logsys.h" +#include +#include +#include #include "clientlist.h" #include "database.h" #include "chatchannel.h" -#include "../common/eq_stream_factory.h" #include "../common/emu_tcp_connection.h" #include "../common/emu_tcp_server.h" #include @@ -468,24 +467,20 @@ static void ProcessCommandIgnore(Client *c, std::string Ignoree) { } Clientlist::Clientlist(int ChatPort) { + EQ::Net::EQStreamManagerOptions opts(true, false); + opts.daybreak_options.port = ChatPort; - chatsf = new EQStreamFactory(ChatStream, ChatPort, 45000); + chatsf.reset(new EQ::Net::EQStreamManager(opts)); + chat_patch.reset(new EQ::Patches::ChatPatch()); + chatsf->RegisterPotentialPatch(chat_patch.get()); - ChatOpMgr = new RegularOpcodeManager; - - if(!ChatOpMgr->LoadOpcodes("mail_opcodes.conf")) - exit(1); - - if (chatsf->Open()) - Log.Out(Logs::Detail, Logs::UCS_Server,"Client (UDP) Chat listener started on port %i.", ChatPort); - else { - Log.Out(Logs::Detail, Logs::UCS_Server,"Failed to start client (UDP) listener (port %-4i)", ChatPort); - - exit(1); - } + chatsf->OnNewConnection(std::bind(&Clientlist::HandleNewConnection, this, std::placeholders::_1)); + chatsf->OnConnectionStateChange(std::bind(&Clientlist::HandleConnectionChange, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); + chatsf->OnPacketRecv(std::bind(&Clientlist::HandlePacket, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); } -Client::Client(std::shared_ptr eqs) { +Client::Client(std::shared_ptr eqs) : + AccountGrabUpdateTimer(60000, true, std::bind(&Client::AccountUpdate, this)) { ClientStream = eqs; @@ -509,7 +504,6 @@ Client::Client(std::shared_ptr eqs) { AttemptedMessages = 0; ForceDisconnect = false; - AccountGrabUpdateTimer = new Timer(60000); //check every minute GlobalChatLimiterTimer = new Timer(RuleI(Chat, IntervalDurationMS)); TypeOfConnection = ConnectionTypeUnknown; @@ -523,12 +517,6 @@ Client::~Client() { LeaveAllChannels(false); - if(AccountGrabUpdateTimer) - { - delete AccountGrabUpdateTimer; - AccountGrabUpdateTimer = nullptr; - } - if(GlobalChatLimiterTimer) { delete GlobalChatLimiterTimer; @@ -537,166 +525,96 @@ Client::~Client() { } void Client::CloseConnection() { - - ClientStream->RemoveData(); - ClientStream->Close(); - - ClientStream->ReleaseFromUse(); } void Clientlist::CheckForStaleConnections(Client *c) { - if(!c) return; + if(!c) + return; - std::list::iterator Iterator; + for(auto Iterator = ClientChatConnections.begin(); Iterator != ClientChatConnections.end(); ++Iterator) { - for(Iterator = ClientChatConnections.begin(); Iterator != ClientChatConnections.end(); ++Iterator) { - - if(((*Iterator) != c) && ((c->GetName() == (*Iterator)->GetName()) + if(((*Iterator).get() != c) && ((c->GetName() == (*Iterator)->GetName()) && (c->GetConnectionType() == (*Iterator)->GetConnectionType()))) { Log.Out(Logs::Detail, Logs::UCS_Server, "Removing old connection for %s", c->GetName().c_str()); - struct in_addr in; - - in.s_addr = (*Iterator)->ClientStream->GetRemoteIP(); - - Log.Out(Logs::Detail, Logs::UCS_Server, "Client connection from %s:%d closed.", inet_ntoa(in), - ntohs((*Iterator)->ClientStream->GetRemotePort())); - - safe_delete((*Iterator)); + Log.Out(Logs::Detail, Logs::UCS_Server, "Client connection from %s:%d closed.", (*Iterator)->ClientStream->RemoteEndpoint().c_str(), + (*Iterator)->ClientStream->RemotePort()); Iterator = ClientChatConnections.erase(Iterator); } } } -void Clientlist::Process() +void Clientlist::Process(Client *c, const EQApplicationPacket *app) { - std::shared_ptr eqs; - - while ((eqs = chatsf->Pop())) { - struct in_addr in; - in.s_addr = eqs->GetRemoteIP(); - - Log.Out(Logs::Detail, Logs::UCS_Server, "New Client UDP connection from %s:%d", inet_ntoa(in), - ntohs(eqs->GetRemotePort())); - - eqs->SetOpcodeManager(&ChatOpMgr); - - auto c = new Client(eqs); - ClientChatConnections.push_back(c); - } - - auto it = ClientChatConnections.begin(); - while (it != ClientChatConnections.end()) { - (*it)->AccountUpdate(); - if ((*it)->ClientStream->CheckClosed()) { - struct in_addr in; - in.s_addr = (*it)->ClientStream->GetRemoteIP(); - - Log.Out(Logs::Detail, Logs::UCS_Server, "Client connection from %s:%d closed.", inet_ntoa(in), - ntohs((*it)->ClientStream->GetRemotePort())); - - safe_delete((*it)); - - it = ClientChatConnections.erase(it); - continue; - } - - EQApplicationPacket *app = nullptr; - - bool KeyValid = true; - - while (KeyValid && !(*it)->GetForceDisconnect() && (app = (*it)->ClientStream->PopPacket())) { - EmuOpcode opcode = app->GetOpcode(); - - switch (opcode) { - case OP_MailLogin: { - char *PacketBuffer = (char *)app->pBuffer; - char MailBox[64]; - char Key[64]; - char ConnectionTypeIndicator; - - VARSTRUCT_DECODE_STRING(MailBox, PacketBuffer); - - if (strlen(PacketBuffer) != 9) { - Log.Out(Logs::Detail, Logs::UCS_Server, - "Mail key is the wrong size. Version of world incompatible with UCS."); - KeyValid = false; - break; - } - ConnectionTypeIndicator = VARSTRUCT_DECODE_TYPE(char, PacketBuffer); - - (*it)->SetConnectionType(ConnectionTypeIndicator); - - VARSTRUCT_DECODE_STRING(Key, PacketBuffer); - - std::string MailBoxString = MailBox, CharacterName; - - // Strip off the SOE.EQ.. - // - std::string::size_type LastPeriod = MailBoxString.find_last_of("."); - - if (LastPeriod == std::string::npos) - CharacterName = MailBoxString; - else - CharacterName = MailBoxString.substr(LastPeriod + 1); - - Log.Out(Logs::Detail, Logs::UCS_Server, "Received login for user %s with key %s", - MailBox, Key); - - if (!database.VerifyMailKey(CharacterName, (*it)->ClientStream->GetRemoteIP(), Key)) { - Log.Out(Logs::Detail, Logs::UCS_Server, - "Chat Key for %s does not match, closing connection.", MailBox); - KeyValid = false; - break; - } - - (*it)->SetAccountID(database.FindAccount(CharacterName.c_str(), (*it))); - - database.GetAccountStatus((*it)); - - if ((*it)->GetConnectionType() == ConnectionTypeCombined) - (*it)->SendFriends(); - - (*it)->SendMailBoxes(); - - CheckForStaleConnections((*it)); - break; - } - - case OP_Mail: { - std::string CommandString = (const char *)app->pBuffer; - ProcessOPMailCommand((*it), CommandString); - break; - } - - default: { - Log.Out(Logs::Detail, Logs::UCS_Server, "Unhandled chat opcode %8X", opcode); - break; - } - } - safe_delete(app); - } - if (!KeyValid || (*it)->GetForceDisconnect()) { - struct in_addr in; - in.s_addr = (*it)->ClientStream->GetRemoteIP(); - + EmuOpcode opcode = app->GetOpcode(); + + switch (opcode) { + case OP_MailLogin: { + char *PacketBuffer = (char *)app->pBuffer + 1; + char MailBox[64]; + char Key[64]; + char ConnectionTypeIndicator; + + VARSTRUCT_DECODE_STRING(MailBox, PacketBuffer); + + if (strlen(PacketBuffer) != 9) { Log.Out(Logs::Detail, Logs::UCS_Server, - "Force disconnecting client: %s:%d, KeyValid=%i, GetForceDisconnect()=%i", - inet_ntoa(in), ntohs((*it)->ClientStream->GetRemotePort()), KeyValid, - (*it)->GetForceDisconnect()); - - (*it)->ClientStream->Close(); - - safe_delete((*it)); - - it = ClientChatConnections.erase(it); - continue; + "Mail key is the wrong size. Version of world incompatible with UCS."); + break; } - ++it; + ConnectionTypeIndicator = VARSTRUCT_DECODE_TYPE(char, PacketBuffer); + + c->SetConnectionType(ConnectionTypeIndicator); + + VARSTRUCT_DECODE_STRING(Key, PacketBuffer); + + std::string MailBoxString = MailBox, CharacterName; + + // Strip off the SOE.EQ.. + // + std::string::size_type LastPeriod = MailBoxString.find_last_of("."); + + if (LastPeriod == std::string::npos) + CharacterName = MailBoxString; + else + CharacterName = MailBoxString.substr(LastPeriod + 1); + + Log.Out(Logs::Detail, Logs::UCS_Server, "Received login for user %s with key %s", + MailBox, Key); + + if (!database.VerifyMailKey(CharacterName, inet_addr(c->ClientStream->RemoteEndpoint().c_str()), Key)) { + Log.Out(Logs::Detail, Logs::UCS_Server, + "Chat Key for %s does not match, closing connection.", MailBox); + break; + } + + c->SetAccountID(database.FindAccount(CharacterName.c_str(), c)); + + database.GetAccountStatus(c); + + if (c->GetConnectionType() == ConnectionTypeCombined) + c->SendFriends(); + + c->SendMailBoxes(); + + CheckForStaleConnections(c); + break; + } + + case OP_Mail: { + std::string CommandString = (const char *)app->pBuffer + 1; + ProcessOPMailCommand(c, CommandString); + break; + } + + default: { + Log.Out(Logs::Detail, Logs::UCS_Server, "Unhandled chat opcode %8X", opcode); + break; + } } } @@ -857,10 +775,7 @@ void Clientlist::ProcessOPMailCommand(Client *c, std::string CommandString) void Clientlist::CloseAllConnections() { - - std::list::iterator Iterator; - - for(Iterator = ClientChatConnections.begin(); Iterator != ClientChatConnections.end(); ++Iterator) { + for(auto Iterator = ClientChatConnections.begin(); Iterator != ClientChatConnections.end(); ++Iterator) { Log.Out(Logs::Detail, Logs::UCS_Server, "Removing client %s", (*Iterator)->GetName().c_str()); @@ -916,13 +831,10 @@ void Client::SendMailBoxes() { } Client *Clientlist::FindCharacter(std::string CharacterName) { - - std::list::iterator Iterator; - - for(Iterator = ClientChatConnections.begin(); Iterator != ClientChatConnections.end(); ++Iterator) { + for(auto Iterator = ClientChatConnections.begin(); Iterator != ClientChatConnections.end(); ++Iterator) { if((*Iterator)->GetName() == CharacterName) - return ((*Iterator)); + return ((*Iterator).get()); } @@ -1198,7 +1110,10 @@ void Client::ProcessChannelList(std::string Input) { GeneralChannelMessage("Channel " + Input + " not found."); } - +void Client::AccountUpdate() +{ + database.GetAccountStatus(this); +} void Client::SendChannelList() { @@ -2133,18 +2048,6 @@ void Client::SendHelp() { GeneralChannelMessage(";setowner, ;toggleinvites"); } -void Client::AccountUpdate() -{ - if(AccountGrabUpdateTimer) - { - if(AccountGrabUpdateTimer->Check(false)) - { - AccountGrabUpdateTimer->Start(60000); - database.GetAccountStatus(this); - } - } -} - void Client::SetConnectionType(char c) { switch(c) @@ -2191,9 +2094,8 @@ Client *Clientlist::IsCharacterOnline(std::string CharacterName) { // i.e. for the character they are logged in as, or for the character whose mailbox they have selected in the // mail window. // - std::list::iterator Iterator; - for(Iterator = ClientChatConnections.begin(); Iterator != ClientChatConnections.end(); ++Iterator) { + for(auto Iterator = ClientChatConnections.begin(); Iterator != ClientChatConnections.end(); ++Iterator) { if(!(*Iterator)->IsMailConnection()) continue; @@ -2203,13 +2105,50 @@ Client *Clientlist::IsCharacterOnline(std::string CharacterName) { // If the mail is destined for the primary mailbox for this character, or the one they have selected // if((MailBoxNumber == 0) || (MailBoxNumber == (*Iterator)->GetMailBoxNumber())) - return (*Iterator); + return (*Iterator).get(); } return nullptr; } +void Clientlist::HandleNewConnection(std::shared_ptr connection) +{ + Log.OutF(Logs::Detail, Logs::UCS_Server, "New Client UDP connection from {0}:{1}", connection->RemoteEndpoint(), connection->RemotePort()); + Client *c = new Client(connection); + ClientChatConnections.push_back(std::unique_ptr(c)); +} + +void Clientlist::HandleConnectionChange(std::shared_ptr connection, EQ::Net::DbProtocolStatus old_status, EQ::Net::DbProtocolStatus new_status) +{ + if (new_status == EQ::Net::DbProtocolStatus::StatusDisconnected) { + Log.OutF(Logs::Detail, Logs::UCS_Server, "Client connection from {0}:{1} closed.", connection->RemoteEndpoint(), connection->RemotePort()); + auto iter = ClientChatConnections.begin(); + while (iter != ClientChatConnections.end()) { + if ((*iter)->ClientStream == connection) { + ClientChatConnections.erase(iter); + break; + } + ++iter; + } + } +} + +void Clientlist::HandlePacket(std::shared_ptr connection, EmuOpcode opcode, EQ::Net::Packet &p) +{ + auto iter = ClientChatConnections.begin(); + while (iter != ClientChatConnections.end()) { + if ((*iter)->ClientStream == connection) { + Log.OutF(Logs::General, Logs::UCS_Server, "{0}", p.ToString()); + EQApplicationPacket app(opcode, (unsigned char*)p.Data(), (uint32)p.Length()); + Process((*iter).get(), &app); + return; + } + + ++iter; + } +} + int Client::GetMailBoxNumber(std::string CharacterName) { for(unsigned int i = 0; i < Characters.size(); i++) diff --git a/ucs/clientlist.h b/ucs/clientlist.h index 79b1359b7..0cb2b2034 100644 --- a/ucs/clientlist.h +++ b/ucs/clientlist.h @@ -20,13 +20,14 @@ #ifndef CHATSERVER_CLIENTLIST_H #define CHATSERVER_CLIENTLIST_H -#include "../common/opcodemgr.h" -#include "../common/eq_stream_type.h" -#include "../common/eq_stream_factory.h" -#include "../common/rulesys.h" +#include +#include +#include +#include #include "chatchannel.h" #include #include +#include #define MAX_JOINED_CHANNELS 10 @@ -84,14 +85,14 @@ struct CharacterEntry { class Client { public: - Client(std::shared_ptr eqs); + Client(std::shared_ptr eqs); ~Client(); - std::shared_ptr ClientStream; + std::shared_ptr ClientStream; void AddCharacter(int CharID, const char *CharacterName, int Level); void ClearCharacters() { Characters.clear(); } void SendMailBoxes(); - inline void QueuePacket(const EQApplicationPacket *p, bool ack_req=true) { ClientStream->QueuePacket(p, ack_req); } + inline void QueuePacket(const EQApplicationPacket *p) { ClientStream->QueuePacket(p); } std::string GetName() { if(Characters.size()) return Characters[0].Name; else return ""; } void JoinChannels(std::string ChannelList); void LeaveChannels(std::string ChannelList); @@ -162,10 +163,10 @@ private: bool Revoked; //Anti Spam Stuff - Timer *AccountGrabUpdateTimer; uint32 TotalKarma; Timer *GlobalChatLimiterTimer; //60 seconds + EQ::Timer AccountGrabUpdateTimer; int AttemptedMessages; bool ForceDisconnect; ConnectionType TypeOfConnection; @@ -176,7 +177,7 @@ class Clientlist { public: Clientlist(int MailPort); - void Process(); + void Process(Client *c, const EQApplicationPacket *app); void CloseAllConnections(); Client *FindCharacter(std::string CharacterName); void CheckForStaleConnections(Client *c); @@ -184,12 +185,13 @@ public: void ProcessOPMailCommand(Client *c, std::string CommandString); private: + void HandleNewConnection(std::shared_ptr connection); + void HandleConnectionChange(std::shared_ptr connection, EQ::Net::DbProtocolStatus old_status, EQ::Net::DbProtocolStatus new_status); + void HandlePacket(std::shared_ptr connection, EmuOpcode opcode, EQ::Net::Packet &p); - EQStreamFactory *chatsf; - - std::list ClientChatConnections; - - OpcodeManager *ChatOpMgr; + std::unique_ptr chatsf; + std::unique_ptr chat_patch; + std::list> ClientChatConnections; }; #endif diff --git a/ucs/ucs.cpp b/ucs/ucs.cpp index 877ff0d0c..3668695e4 100644 --- a/ucs/ucs.cpp +++ b/ucs/ucs.cpp @@ -17,15 +17,15 @@ */ -#include "../common/eqemu_logsys.h" -#include "../common/global_define.h" +#include +#include +#include #include "clientlist.h" -#include "../common/opcodemgr.h" -#include "../common/eq_stream_factory.h" -#include "../common/rulesys.h" -#include "../common/servertalk.h" -#include "../common/platform.h" -#include "../common/crash.h" +#include +#include +#include +#include +#include #include "database.h" #include "ucsconfig.h" #include "chatchannel.h" @@ -143,12 +143,11 @@ int main() { worldserver->Connect(); + auto &loop = EQ::EventLoop::Get(); while(RunLoops) { Timer::SetCurrentTime(); - g_Clientlist->Process(); - if(ChannelListProcessTimer.Check()) ChannelList->Process(); @@ -160,7 +159,9 @@ int main() { timeout_manager.CheckTimeouts(); - Sleep(100); + loop.Process(); + + Sleep(1); } ChannelList->RemoveAllChannels();