[Scheduler] Event scheduler implementation (#1257)

* Event scheduler implementation

* Create 2021_02_17_server_scheduled_events.sql

* Tweak

* Remove unused event [skip ci]

* Cleanup [skip ci]

* PR adjustments

* Database manifest
This commit is contained in:
Chris Miles
2021-03-29 02:52:57 -05:00
committed by GitHub
parent f51bc4daaf
commit 7aa5308f9c
31 changed files with 2053 additions and 50 deletions
+2
View File
@@ -25,6 +25,7 @@ SET(world_sources
web_interface.cpp
web_interface_eqw.cpp
wguild_mgr.cpp
world_event_scheduler.cpp
world_config.cpp
world_console_connection.cpp
world_server_command_handler.cpp
@@ -65,6 +66,7 @@ SET(world_headers
world_tcp_connection.h
world_server_command_handler.h
worlddb.h
world_event_scheduler.h
world_store.h
zonelist.h
zoneserver.h
+6
View File
@@ -97,6 +97,7 @@ union semun {
#include "../common/content/world_content_service.h"
#include "../common/repositories/merchantlist_temp_repository.h"
#include "world_store.h"
#include "world_event_scheduler.h"
WorldStore world_store;
ClientList client_list;
@@ -107,6 +108,7 @@ UCSConnection UCSLink;
QueryServConnection QSLink;
LauncherList launcher_list;
AdventureManager adventure_manager;
WorldEventScheduler event_scheduler;
EQ::Random emu_random;
volatile bool RunLoops = true;
uint32 numclients = 0;
@@ -442,6 +444,8 @@ int main(int argc, char** argv) {
content_db.LoadCharacterCreateAllocations();
content_db.LoadCharacterCreateCombos();
event_scheduler.SetDatabase(&database)->LoadScheduledEvents();
std::unique_ptr<EQ::Net::ConsoleServer> console;
if (Config->TelnetEnabled) {
LogInfo("Console (TCP) listener started");
@@ -603,6 +607,8 @@ int main(int argc, char** argv) {
}
}
event_scheduler.Process(&zoneserver_list);
client_list.Process();
if (PurgeInstanceTimer.Check()) {
+64
View File
@@ -0,0 +1,64 @@
#include "world_event_scheduler.h"
#include "../common/servertalk.h"
void WorldEventScheduler::Process(ZSList *zs_list)
{
std::time_t time = std::time(nullptr);
std::tm *now = std::localtime(&time);
// once a minute polling
if (m_last_polled_minute != now->tm_min) {
// refresh; world polls and tells zones if they should update if there is a change
if (CheckIfEventsChanged()) {
LogSchedulerDetail("Event changes detected, forcing zones to refresh their schedules...");
auto pack = new ServerPacket(ServerOP_UpdateSchedulerEvents, 0);
zs_list->SendPacket(pack);
safe_delete(pack);
}
int month = (now->tm_mon + 1);
int year = (now->tm_year + 1900);
LogSchedulerDetail(
"Polling year [{}] month [{}] day [{}] hour [{}] minute [{}]",
year,
month,
now->tm_mday,
now->tm_hour,
now->tm_min
);
for (auto &e: m_events) {
// discard uninteresting events as its less work to calculate time on events we don't care about
// different processes are interested in different events
if (
e.event_type != ServerEvents::EVENT_TYPE_BROADCAST &&
e.event_type != ServerEvents::EVENT_TYPE_RELOAD_WORLD
) {
continue;
}
// validate event is ready to activate and run it
if (ValidateEventReadyToActivate(e)) {
if (e.event_type == ServerEvents::EVENT_TYPE_BROADCAST) {
LogScheduler("Sending broadcast [{}]", e.event_data.c_str());
zs_list->SendEmoteMessage(nullptr, 0, 0, 15, e.event_data.c_str());
}
if (e.event_type == ServerEvents::EVENT_TYPE_RELOAD_WORLD) {
LogScheduler("Sending reload world event [{}]", e.event_data.c_str());
auto pack = new ServerPacket(ServerOP_ReloadWorld, sizeof(ReloadWorld_Struct));
auto *reload_world = (ReloadWorld_Struct *) pack->pBuffer;
reload_world->Option = 1;
zs_list->SendPacket(pack);
safe_delete(pack);
}
}
}
m_last_polled_minute = now->tm_min;
}
}
+12
View File
@@ -0,0 +1,12 @@
#ifndef EQEMU_EVENT_SCHEDULER_H
#define EQEMU_EVENT_SCHEDULER_H
#include "../common/server_event_scheduler.h"
#include "zonelist.h"
class WorldEventScheduler : public ServerEventScheduler {
public:
void Process(ZSList *zs_list);
};
#endif //EQEMU_EVENT_SCHEDULER_H