mirror of
https://github.com/EQEmu/Server.git
synced 2026-02-18 14:52:25 +00:00
UCS basically works now, really needs to be rewritten.
This commit is contained in:
parent
4bbc22cc24
commit
16a96a2756
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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; }
|
||||
|
||||
17
common/patch/chat.cpp
Normal file
17
common/patch/chat.cpp
Normal file
@ -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()
|
||||
{
|
||||
}
|
||||
15
common/patch/chat.h
Normal file
15
common/patch/chat.h
Normal file
@ -0,0 +1,15 @@
|
||||
#include <patch/patch.h>
|
||||
|
||||
namespace EQ
|
||||
{
|
||||
namespace Patches
|
||||
{
|
||||
class ChatPatch : public BasePatch
|
||||
{
|
||||
public:
|
||||
ChatPatch();
|
||||
virtual ~ChatPatch();
|
||||
virtual std::string GetName() const { return "Chat"; }
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -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();
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -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()
|
||||
|
||||
@ -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}")
|
||||
|
||||
@ -17,15 +17,14 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "../common/global_define.h"
|
||||
#include "../common/string_util.h"
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include <global_define.h>
|
||||
#include <string_util.h>
|
||||
#include <eqemu_logsys.h>
|
||||
|
||||
#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 <list>
|
||||
@ -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<EQStream> eqs) {
|
||||
Client::Client(std::shared_ptr<EQ::Net::EQStream> eqs) :
|
||||
AccountGrabUpdateTimer(60000, true, std::bind(&Client::AccountUpdate, this)) {
|
||||
|
||||
ClientStream = eqs;
|
||||
|
||||
@ -509,7 +504,6 @@ Client::Client(std::shared_ptr<EQStream> 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<Client*>::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<EQStream> 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.<shortname>.
|
||||
//
|
||||
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.<shortname>.
|
||||
//
|
||||
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<Client*>::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<Client*>::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<Client*>::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<EQ::Net::EQStream> 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<Client>(c));
|
||||
}
|
||||
|
||||
void Clientlist::HandleConnectionChange(std::shared_ptr<EQ::Net::EQStream> 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<EQ::Net::EQStream> 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++)
|
||||
|
||||
@ -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 <net/eqstream.h>
|
||||
#include <rulesys.h>
|
||||
#include <patch/chat.h>
|
||||
#include <event/timer.h>
|
||||
#include "chatchannel.h"
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
#define MAX_JOINED_CHANNELS 10
|
||||
|
||||
@ -84,14 +85,14 @@ struct CharacterEntry {
|
||||
class Client {
|
||||
|
||||
public:
|
||||
Client(std::shared_ptr<EQStream> eqs);
|
||||
Client(std::shared_ptr<EQ::Net::EQStream> eqs);
|
||||
~Client();
|
||||
|
||||
std::shared_ptr<EQStream> ClientStream;
|
||||
std::shared_ptr<EQ::Net::EQStream> 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<EQ::Net::EQStream> connection);
|
||||
void HandleConnectionChange(std::shared_ptr<EQ::Net::EQStream> connection, EQ::Net::DbProtocolStatus old_status, EQ::Net::DbProtocolStatus new_status);
|
||||
void HandlePacket(std::shared_ptr<EQ::Net::EQStream> connection, EmuOpcode opcode, EQ::Net::Packet &p);
|
||||
|
||||
EQStreamFactory *chatsf;
|
||||
|
||||
std::list<Client*> ClientChatConnections;
|
||||
|
||||
OpcodeManager *ChatOpMgr;
|
||||
std::unique_ptr<EQ::Net::EQStreamManager> chatsf;
|
||||
std::unique_ptr<EQ::Patches::BasePatch> chat_patch;
|
||||
std::list<std::unique_ptr<Client>> ClientChatConnections;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
23
ucs/ucs.cpp
23
ucs/ucs.cpp
@ -17,15 +17,15 @@
|
||||
|
||||
*/
|
||||
|
||||
#include "../common/eqemu_logsys.h"
|
||||
#include "../common/global_define.h"
|
||||
#include <eqemu_logsys.h>
|
||||
#include <global_define.h>
|
||||
#include <timeoutmgr.h>
|
||||
#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 <rulesys.h>
|
||||
#include <servertalk.h>
|
||||
#include <platform.h>
|
||||
#include <crash.h>
|
||||
#include <event/event_loop.h>
|
||||
#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();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user