Some work on compression, the way the client does it is... bizarre and not how i orig thought it would be.

This commit is contained in:
KimLS 2016-09-28 23:51:37 -07:00
parent f2be05f47f
commit a76149c8e3
7 changed files with 200 additions and 184 deletions

View File

@ -41,12 +41,12 @@ void EQ::Net::DaybreakConnectionManager::Attach(uv_loop_t *loop)
uv_timer_start(&m_timer, [](uv_timer_t *handle) { uv_timer_start(&m_timer, [](uv_timer_t *handle) {
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data; DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
c->Process(); c->Process();
}, 5, 5); }, 2, 2);
uv_timer_start(&m_resend_timer, [](uv_timer_t *handle) { uv_timer_start(&m_resend_timer, [](uv_timer_t *handle) {
DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data; DaybreakConnectionManager *c = (DaybreakConnectionManager*)handle->data;
c->ProcessResend(); c->ProcessResend();
}, 50, 50); }, 10, 10);
uv_udp_init(loop, &m_socket); uv_udp_init(loop, &m_socket);
m_socket.data = this; m_socket.data = this;
@ -88,6 +88,16 @@ void EQ::Net::DaybreakConnectionManager::Detach()
void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int port) void EQ::Net::DaybreakConnectionManager::Connect(const std::string &addr, int port)
{ {
//todo dns resolution
auto connection = std::shared_ptr<DaybreakConnection>(new DaybreakConnection(this, addr, port));
connection->m_self = connection;
if (m_on_new_connection) {
m_on_new_connection(connection);
}
m_connections.insert(std::make_pair(std::make_pair(addr, port), connection));
} }
void EQ::Net::DaybreakConnectionManager::Process() void EQ::Net::DaybreakConnectionManager::Process()
@ -252,6 +262,7 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
m_buffered_packets_length = 0; m_buffered_packets_length = 0;
m_resend_delay = m_owner->m_options.resend_delay_ms; m_resend_delay = m_owner->m_options.resend_delay_ms;
m_rolling_ping = 100; m_rolling_ping = 100;
m_last_session_stats = Clock::now();
} }
//new connection made as client //new connection made as client
@ -271,6 +282,7 @@ EQ::Net::DaybreakConnection::DaybreakConnection(DaybreakConnectionManager *owner
m_buffered_packets_length = 0; m_buffered_packets_length = 0;
m_resend_delay = m_owner->m_options.resend_delay_ms; m_resend_delay = m_owner->m_options.resend_delay_ms;
m_rolling_ping = 100; m_rolling_ping = 100;
m_last_session_stats = Clock::now();
} }
EQ::Net::DaybreakConnection::~DaybreakConnection() EQ::Net::DaybreakConnection::~DaybreakConnection()
@ -284,7 +296,6 @@ void EQ::Net::DaybreakConnection::Close()
disconnect.zero = 0; disconnect.zero = 0;
disconnect.opcode = OP_SessionDisconnect; disconnect.opcode = OP_SessionDisconnect;
disconnect.connect_code = HostToNetwork(m_connect_code); disconnect.connect_code = HostToNetwork(m_connect_code);
disconnect.disconnect_code = 6;
WritablePacket out; WritablePacket out;
out.PutSerialize(0, disconnect); out.PutSerialize(0, disconnect);
InternalSend(out); InternalSend(out);
@ -344,7 +355,7 @@ void EQ::Net::DaybreakConnection::Process()
ProcessQueue(); ProcessQueue();
auto time_since_stats = (size_t)std::chrono::duration_cast<std::chrono::milliseconds>(now - m_last_stats).count(); auto time_since_stats = (size_t)std::chrono::duration_cast<std::chrono::milliseconds>(now - m_last_stats).count();
if (time_since_stats >= m_owner->m_options.stats_delay_ms) { if (m_owner->m_options.stats_delay_ms > 0 && time_since_stats >= m_owner->m_options.stats_delay_ms) {
SendStatSync(); SendStatSync();
m_last_stats = now; m_last_stats = now;
} }
@ -376,40 +387,24 @@ void EQ::Net::DaybreakConnection::ProcessPacket(Packet &p)
return; return;
} }
if (m_encode_passes[0] == EncodeCompression || m_encode_passes[1] == EncodeCompression) { EQ::Net::WritablePacket temp;
EQ::Net::WritablePacket temp; temp.PutPacket(0, p);
temp.PutPacket(0, p); temp.Resize(temp.Length() - m_crc_bytes);
for (int i = 0; i < 2; ++i) { for (int i = 1; i >= 0; --i) {
switch (m_encode_passes[i]) { switch (m_encode_passes[i]) {
case EncodeCompression: case EncodeCompression:
Log.OutF(Logs::General, Logs::Debug, "Decompressing packet on pass {1}\n{0}", temp.ToString(), i); Decompress(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
Decompress(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size() - m_crc_bytes); break;
Log.OutF(Logs::General, Logs::Debug, "Decompressed packet on pass {1}\n{0}", temp.ToString(), i); case EncodeXOR:
break; Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size());
case EncodeXOR: break;
Decode(temp, DaybreakHeader::size(), temp.Length() - DaybreakHeader::size() - m_crc_bytes); default:
break; break;
default:
break;
}
} }
ProcessDecodedPacket(ReadOnlyPacket(temp.Data(), temp.Length() - m_crc_bytes));
} }
else {
for (int i = 0; i < 2; ++i) {
switch (m_encode_passes[i]) {
case EncodeXOR:
Decode(p, DaybreakHeader::size(), p.Length() - DaybreakHeader::size() - m_crc_bytes);
break;
default:
break;
}
}
ProcessDecodedPacket(ReadOnlyPacket(p.Data(), p.Length() - m_crc_bytes)); ProcessDecodedPacket(ReadOnlyPacket(temp.Data(), temp.Length()));
}
} }
else { else {
ProcessDecodedPacket(p); ProcessDecodedPacket(p);
@ -667,7 +662,6 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
disconnect.zero = 0; disconnect.zero = 0;
disconnect.opcode = OP_SessionDisconnect; disconnect.opcode = OP_SessionDisconnect;
disconnect.connect_code = HostToNetwork(m_connect_code); disconnect.connect_code = HostToNetwork(m_connect_code);
disconnect.disconnect_code = 6;
WritablePacket out; WritablePacket out;
out.PutSerialize(0, disconnect); out.PutSerialize(0, disconnect);
InternalSend(out); InternalSend(out);
@ -685,6 +679,24 @@ void EQ::Net::DaybreakConnection::ProcessDecodedPacket(const Packet &p)
} }
break; break;
} }
case OP_SessionStatRequest:
{
auto request = p.GetSerialize<DaybreakSessionStatRequest>(0);
DaybreakSessionStatResponse response;
response.zero = 0;
response.opcode = OP_SessionStatResponse;
response.timestamp = request.timestamp;
response.our_timestamp = EQ::Net::HostToNetwork(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
response.client_sent = request.packets_sent;
response.client_recv = request.packets_recv;
response.server_sent = EQ::Net::HostToNetwork(m_stats.sent_packets);
response.server_recv = EQ::Net::HostToNetwork(m_stats.recv_packets);
WritablePacket out;
out.PutSerialize(0, response);
InternalSend(out);
break;
}
default: default:
Log.OutF(Logs::Detail, Logs::Netcode, "Unhandled opcode {0:#x}", p.GetInt8(1)); Log.OutF(Logs::Detail, Logs::Netcode, "Unhandled opcode {0:#x}", p.GetInt8(1));
break; break;
@ -916,11 +928,13 @@ void EQ::Net::DaybreakConnection::Compress(Packet &p, size_t offset, size_t leng
uint32_t new_length = 0; uint32_t new_length = 0;
if (length > 30) { if (length > 30) {
new_length = Deflate(buffer, (uint32_t)length, new_buffer + 1, 2048); new_length = Deflate(buffer, (uint32_t)length, new_buffer + 1, 2048) + 1;
new_buffer[0] = 0x5a; new_buffer[0] = 0x5a;
} }
else { else {
memcpy(new_buffer + 1, buffer, length);
new_buffer[0] = 0xa5; new_buffer[0] = 0xa5;
new_length = length + 1;
} }
p.Resize(offset); p.Resize(offset);
@ -1013,7 +1027,21 @@ void EQ::Net::DaybreakConnection::SendOutOfOrderAck(int stream_id, uint16_t seq)
void EQ::Net::DaybreakConnection::SendStatSync() void EQ::Net::DaybreakConnection::SendStatSync()
{ {
//todo DaybreakSessionStatRequest request;
request.zero = 0;
request.opcode = OP_SessionStatRequest;
request.timestamp = EQ::Net::HostToNetwork(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() & 0xFFFFLL);
request.stat_ping = m_stats.last_stat_ping;
if (m_stats.total_stat_count > 0)
request.avg_ping = m_stats.total_stat_ping / m_stats.total_stat_count;
else
request.avg_ping = 0;
request.min_ping = m_stats.min_stat_ping;
request.max_ping = m_stats.max_stat_ping;
request.last_ping = m_stats.last_stat_ping;
request.packets_sent = m_stats.sent_packets + 1;
request.packets_recv = m_stats.recv_packets;
m_last_session_stats = Clock::now();
} }
void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p) void EQ::Net::DaybreakConnection::InternalBufferedSend(Packet &p)

View File

@ -82,6 +82,11 @@ namespace EQ
total_acks = 0; total_acks = 0;
min_ping = 0xFFFFFFFFFFFFFFFFUL; min_ping = 0xFFFFFFFFFFFFFFFFUL;
max_ping = 0; max_ping = 0;
total_stat_ping = 0;
total_stat_count = 0;
min_stat_ping = 0xFFFFFFFFFFFFFFFFUL;
max_stat_ping = 0;
last_stat_ping = 0;
created = Clock::now(); created = Clock::now();
} }
@ -93,6 +98,11 @@ namespace EQ
uint64_t total_acks; uint64_t total_acks;
uint64_t min_ping; uint64_t min_ping;
uint64_t max_ping; uint64_t max_ping;
uint64_t total_stat_ping;
uint64_t total_stat_count;
uint64_t min_stat_ping;
uint64_t max_stat_ping;
uint64_t last_stat_ping;
Timestamp created; Timestamp created;
}; };
@ -135,7 +145,6 @@ namespace EQ
Timestamp m_last_stats; Timestamp m_last_stats;
DaybreakConnectionStats m_stats; DaybreakConnectionStats m_stats;
Timestamp m_last_session_stats; Timestamp m_last_session_stats;
uint64_t m_last_session_stats_ping;
size_t m_resend_delay; size_t m_resend_delay;
size_t m_rolling_ping; size_t m_rolling_ping;
@ -209,7 +218,7 @@ namespace EQ
max_connection_count = 0; max_connection_count = 0;
keepalive_delay_ms = 0; keepalive_delay_ms = 0;
resend_delay_ms = 1000; resend_delay_ms = 1000;
stats_delay_ms = 10000; stats_delay_ms = 0;
connect_delay_ms = 1000; connect_delay_ms = 1000;
stale_connection_ms = 60000; stale_connection_ms = 60000;
crc_length = 2; crc_length = 2;

View File

@ -74,15 +74,13 @@ namespace EQ
uint8_t zero; uint8_t zero;
uint8_t opcode; uint8_t opcode;
uint32_t connect_code; uint32_t connect_code;
uint16_t disconnect_code;
template <class Archive> template <class Archive>
void serialize(Archive & archive) void serialize(Archive & archive)
{ {
archive(CEREAL_NVP(zero), archive(CEREAL_NVP(zero),
CEREAL_NVP(opcode), CEREAL_NVP(opcode),
CEREAL_NVP(connect_code), CEREAL_NVP(connect_code));
CEREAL_NVP(disconnect_code));
} }
}; };
@ -116,7 +114,7 @@ namespace EQ
} }
}; };
struct DaybreakSessionStatRequestHeader struct DaybreakSessionStatRequest
{ {
static size_t size() { return 40; } static size_t size() { return 40; }
uint8_t zero; uint8_t zero;
@ -146,7 +144,7 @@ namespace EQ
} }
}; };
struct DaybreakSessionStatResponseHeader struct DaybreakSessionStatResponse
{ {
static size_t size() { return 40; } static size_t size() { return 40; }
uint8_t zero; uint8_t zero;

View File

@ -17,20 +17,21 @@ namespace EQ
opcode_size = 2; opcode_size = 2;
} }
EQStreamManagerOptions(bool encoded, bool compressed) { EQStreamManagerOptions(int port, bool encoded, bool compressed) {
opcode_size = 2; opcode_size = 2;
if (encoded) {
daybreak_options.encode_passes[0] = EncodeXOR;
if (compressed) { //World seems to support both compression and xor zone supports one or the others.
daybreak_options.encode_passes[1] = EncodeCompression; //Enforce one or the other in the convienence construct
} //Login I had trouble getting to recognize compression at all
//but that might be because it was still a bit buggy when i was testing that.
if (compressed) {
daybreak_options.encode_passes[0] = EncodeCompression;
} }
else { else if (encoded) {
if (compressed) { daybreak_options.encode_passes[0] = EncodeXOR;
daybreak_options.encode_passes[0] = EncodeCompression;
}
} }
daybreak_options.port = port;
} }
int opcode_size; int opcode_size;

View File

@ -116,9 +116,6 @@ void CatchSignal(int sig_num);
int main(int argc, char** argv) { int main(int argc, char** argv) {
RegisterExecutablePlatform(ExePlatformWorld); RegisterExecutablePlatform(ExePlatformWorld);
Log.LoadLogSettingsDefaults(); Log.LoadLogSettingsDefaults();
set_exception_handler(); set_exception_handler();
/* Database Version Check */ /* Database Version Check */
@ -398,10 +395,7 @@ int main(int argc, char** argv) {
return 1; return 1;
} }
EQ::Net::EQStreamManagerOptions opts(false, true); EQ::Net::EQStreamManagerOptions opts(9000, false, true);
opts.daybreak_options.port = 9000;
opts.opcode_size = 2;
EQ::Net::EQStreamManager eqsm(opts); EQ::Net::EQStreamManager eqsm(opts);
//register all the patches we have avaliable with the stream identifier. //register all the patches we have avaliable with the stream identifier.

View File

@ -231,7 +231,11 @@ INSTALL(TARGETS zone RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
ADD_DEFINITIONS(-DZONE) ADD_DEFINITIONS(-DZONE)
TARGET_LINK_LIBRARIES(zone common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY}) TARGET_LINK_LIBRARIES(zone common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY} libuv fmt)
IF(WIN32)
TARGET_LINK_LIBRARIES(zone "ws2_32" "psapi" "iphlpapi" "userenv")
ENDIF(WIN32)
IF(EQEMU_BUILD_PERL) IF(EQEMU_BUILD_PERL)
TARGET_LINK_LIBRARIES(zone ${PERL_LIBRARY}) TARGET_LINK_LIBRARIES(zone ${PERL_LIBRARY})
@ -241,16 +245,6 @@ IF(EQEMU_BUILD_LUA)
TARGET_LINK_LIBRARIES(zone luabind ${LUA_LIBRARY}) TARGET_LINK_LIBRARIES(zone luabind ${LUA_LIBRARY})
ENDIF(EQEMU_BUILD_LUA) ENDIF(EQEMU_BUILD_LUA)
IF(MSVC)
SET_TARGET_PROPERTIES(zone PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF")
TARGET_LINK_LIBRARIES(zone "Ws2_32.lib")
ENDIF(MSVC)
IF(MINGW)
TARGET_LINK_LIBRARIES(zone "WS2_32")
ENDIF(MINGW)
IF(UNIX) IF(UNIX)
TARGET_LINK_LIBRARIES(zone "${CMAKE_DL_LIBS}") TARGET_LINK_LIBRARIES(zone "${CMAKE_DL_LIBS}")
TARGET_LINK_LIBRARIES(zone "z") TARGET_LINK_LIBRARIES(zone "z")

View File

@ -65,6 +65,10 @@
#include "lua_parser.h" #include "lua_parser.h"
#include "questmgr.h" #include "questmgr.h"
#include "../common/event/event_loop.h"
#include "../common/event/timer.h"
#include "../common/net/eqstream.h"
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <fstream> #include <fstream>
@ -73,6 +77,7 @@
#include <signal.h> #include <signal.h>
#include <time.h> #include <time.h>
#include <ctime> #include <ctime>
#include <thread>
#ifdef _CRTDBG_MAP_ALLOC #ifdef _CRTDBG_MAP_ALLOC
#undef new #undef new
@ -97,7 +102,6 @@ WorldServer worldserver;
uint32 numclients = 0; uint32 numclients = 0;
char errorname[32]; char errorname[32];
extern Zone* zone; extern Zone* zone;
EQStreamFactory eqsf(ZoneStream);
npcDecayTimes_Struct npcCorpseDecayTimes[100]; npcDecayTimes_Struct npcCorpseDecayTimes[100];
TitleManager title_manager; TitleManager title_manager;
QueryServ *QServ = 0; QueryServ *QServ = 0;
@ -431,122 +435,111 @@ int main(int argc, char** argv) {
uint8 ZONEUPDATE = 10; uint8 ZONEUPDATE = 10;
Timer zoneupdate_timer(ZONEUPDATE); Timer zoneupdate_timer(ZONEUPDATE);
zoneupdate_timer.Start(); zoneupdate_timer.Start();
while(RunLoops) { bool eqsf_open = false;
{ //profiler block to omit the sleep from times std::unique_ptr<EQ::Net::EQStreamManager> eqsm;
//Advance the timer to our current point in time EQ::Timer process_timer(33, true, [&eqsf_open, &eqsm, &stream_identifier, &eqsi, &worldwasconnected,
Timer::SetCurrentTime(); &zoneupdate_timer, &IDLEZONEUPDATE, &ZONEUPDATE, &quest_timers, &InterserverTimer]() {
//Advance the timer to our current point in time
worldserver.Process(); Timer::SetCurrentTime();
if (!eqsf.IsOpen() && Config->ZonePort != 0) { worldserver.Process();
Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d", Config->ZonePort);
if (!eqsf.Open(Config->ZonePort)) { if (!eqsf_open && Config->ZonePort != 0) {
Log.Out(Logs::General, Logs::Error, "Failed to open port %d", Config->ZonePort); Log.Out(Logs::General, Logs::Zone_Server, "Starting EQ Network server on port %d", Config->ZonePort);
ZoneConfig::SetZonePort(0);
worldserver.Disconnect(); EQ::Net::EQStreamManagerOptions opts(Config->ZonePort, false, true);
eqsm.reset(new EQ::Net::EQStreamManager(opts));
eqsf_open = true;
eqsm->OnNewConnection([&stream_identifier](std::shared_ptr<EQ::Net::EQStream> stream) {
stream_identifier.AddStream(stream);
Log.OutF(Logs::Detail, Logs::World_Server, "New connection from IP {0}:{1}", stream->RemoteEndpoint(), ntohs(stream->GetRemotePort()));
});
}
//give the stream identifier a chance to do its work....
stream_identifier.Process();
//check the stream identifier for any now-identified streams
while((eqsi = stream_identifier.PopIdentified())) {
//now that we know what patch they are running, start up their client object
struct in_addr in;
in.s_addr = eqsi->GetRemoteIP();
Log.Out(Logs::Detail, Logs::World_Server, "New client from %s:%d", inet_ntoa(in), ntohs(eqsi->GetRemotePort()));
auto client = new Client(eqsi);
entity_list.AddClient(client);
}
if ( numclients < 1 && zoneupdate_timer.GetDuration() != IDLEZONEUPDATE )
zoneupdate_timer.SetTimer(IDLEZONEUPDATE);
else if ( numclients > 0 && zoneupdate_timer.GetDuration() == IDLEZONEUPDATE )
{
zoneupdate_timer.SetTimer(ZONEUPDATE);
zoneupdate_timer.Trigger();
}
//check for timeouts in other threads
timeout_manager.CheckTimeouts();
if (worldserver.Connected()) {
worldwasconnected = true;
}
else {
if (worldwasconnected && is_zone_loaded)
entity_list.ChannelMessageFromWorld(0, 0, 6, 0, 0, "WARNING: World server connection lost");
worldwasconnected = false; worldwasconnected = false;
} }
}
if (is_zone_loaded && zoneupdate_timer.Check()) {
//check the factory for any new incoming streams. {
while ((eqss = eqsf.Pop())) { if(net.group_timer.Enabled() && net.group_timer.Check())
//pull the stream out of the factory and give it to the stream identifier entity_list.GroupProcess();
//which will figure out what patch they are running, and set up the dynamic
//structures and opcodes for that patch. if(net.door_timer.Enabled() && net.door_timer.Check())
struct in_addr in; entity_list.DoorProcess();
in.s_addr = eqss->GetRemoteIP();
Log.Out(Logs::Detail, Logs::World_Server, "New connection from %s:%d", inet_ntoa(in), ntohs(eqss->GetRemotePort())); if(net.object_timer.Enabled() && net.object_timer.Check())
stream_identifier.AddStream(eqss); //takes the stream entity_list.ObjectProcess();
}
if(net.corpse_timer.Enabled() && net.corpse_timer.Check())
//give the stream identifier a chance to do its work.... entity_list.CorpseProcess();
stream_identifier.Process();
if(net.trap_timer.Enabled() && net.trap_timer.Check())
//check the stream identifier for any now-identified streams entity_list.TrapProcess();
while((eqsi = stream_identifier.PopIdentified())) {
//now that we know what patch they are running, start up their client object if(net.raid_timer.Enabled() && net.raid_timer.Check())
struct in_addr in; entity_list.RaidProcess();
in.s_addr = eqsi->GetRemoteIP();
Log.Out(Logs::Detail, Logs::World_Server, "New client from %s:%d", inet_ntoa(in), ntohs(eqsi->GetRemotePort())); entity_list.Process();
auto client = new Client(eqsi); entity_list.MobProcess();
entity_list.AddClient(client); entity_list.BeaconProcess();
} entity_list.EncounterProcess();
if ( numclients < 1 && zoneupdate_timer.GetDuration() != IDLEZONEUPDATE ) if (zone) {
zoneupdate_timer.SetTimer(IDLEZONEUPDATE); if(!zone->Process()) {
else if ( numclients > 0 && zoneupdate_timer.GetDuration() == IDLEZONEUPDATE ) Zone::Shutdown();
{ }
zoneupdate_timer.SetTimer(ZONEUPDATE);
zoneupdate_timer.Trigger();
}
//check for timeouts in other threads
timeout_manager.CheckTimeouts();
if (worldserver.Connected()) {
worldwasconnected = true;
}
else {
if (worldwasconnected && is_zone_loaded)
entity_list.ChannelMessageFromWorld(0, 0, 6, 0, 0, "WARNING: World server connection lost");
worldwasconnected = false;
}
if (is_zone_loaded && zoneupdate_timer.Check()) {
{
if(net.group_timer.Enabled() && net.group_timer.Check())
entity_list.GroupProcess();
if(net.door_timer.Enabled() && net.door_timer.Check())
entity_list.DoorProcess();
if(net.object_timer.Enabled() && net.object_timer.Check())
entity_list.ObjectProcess();
if(net.corpse_timer.Enabled() && net.corpse_timer.Check())
entity_list.CorpseProcess();
if(net.trap_timer.Enabled() && net.trap_timer.Check())
entity_list.TrapProcess();
if(net.raid_timer.Enabled() && net.raid_timer.Check())
entity_list.RaidProcess();
entity_list.Process();
entity_list.MobProcess();
entity_list.BeaconProcess();
entity_list.EncounterProcess();
if (zone) {
if(!zone->Process()) {
Zone::Shutdown();
} }
if(quest_timers.Check())
quest_manager.Process();
} }
if(quest_timers.Check())
quest_manager.Process();
} }
} if (InterserverTimer.Check()) {
if (InterserverTimer.Check()) { InterserverTimer.Start();
InterserverTimer.Start(); database.ping();
database.ping(); // AsyncLoadVariables(dbasync, &database);
// AsyncLoadVariables(dbasync, &database); entity_list.UpdateWho();
entity_list.UpdateWho(); if (worldserver.TryReconnect() && (!worldserver.Connected()))
if (worldserver.TryReconnect() && (!worldserver.Connected())) worldserver.AsyncConnect();
worldserver.AsyncConnect(); }
} });
#ifdef EQPROFILE while(RunLoops) {
#ifdef PROFILE_DUMP_TIME EQ::EventLoop::Get().Process();
if(profile_dump_timer.Check()) { Sleep(1);
DumpZoneProfile();
}
#endif
#endif
} //end extra profiler block
Sleep(ZoneTimerResolution);
} }
entity_list.Clear(); entity_list.Clear();
@ -566,7 +559,6 @@ int main(int argc, char** argv) {
if (zone != 0) if (zone != 0)
Zone::Shutdown(true); Zone::Shutdown(true);
//Fix for Linux world server problem. //Fix for Linux world server problem.
eqsf.Close();
worldserver.Disconnect(); worldserver.Disconnect();
safe_delete(taskmanager); safe_delete(taskmanager);
command_deinit(); command_deinit();