eqemu-server/eqlaunch/eqlaunch.cpp
Knightly 7ab909ee47 Standardize Licensing
- License was intended to be GPLv3 per earlier commit of GPLv3 LICENSE FILE
- This is confirmed by the inclusion of libraries that are incompatible with GPLv2
- This is also confirmed by KLS and the agreement of KLS's predecessors
- Added GPLv3 license headers to the compilable source files
- Removed Folly licensing in strings.h since the string functions do not match the Folly functions and are standard functions - this must have been left over from previous implementations
- Removed individual contributor license headers since the project has been under the "developer" mantle for many years
- Removed comments on files that were previously automatically generated since they've been manually modified multiple times and there are no automatic scripts referencing them (removed in 2023)
2026-04-01 17:09:57 -07:00

199 lines
4.3 KiB
C++

/* EQEmu: EQEmulator
Copyright (C) 2001-2026 EQEmu Development Team
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "common/crash.h"
#include "common/eqemu_config.h"
#include "common/eqemu_logsys.h"
#include "common/path_manager.h"
#include "common/platform.h"
#include "common/proc_launcher.h"
#include "common/servertalk.h"
#include "common/unix.h"
#include "eqlaunch/worldserver.h"
#include "eqlaunch/zone_launch.h"
#include <csignal>
#include <ctime>
#include <map>
#include <set>
bool RunLoops = false;
void CatchSignal(int sig_num);
int main(int argc, char *argv[]) {
RegisterExecutablePlatform(ExePlatformLaunch);
EQEmuLogSys::Instance()->LoadLogSettingsDefaults();
set_exception_handler();
PathManager::Instance()->Init();
std::string launcher_name;
if(argc == 2) {
launcher_name = argv[1];
}
if(launcher_name.length() < 1) {
Log(Logs::Detail, Logs::Launcher, "You must specfify a launcher name as the first argument to this program.");
return 1;
}
Log(Logs::Detail, Logs::Launcher, "Loading server configuration..");
if (!EQEmuConfig::LoadConfig()) {
Log(Logs::Detail, Logs::Launcher, "Loading server configuration failed.");
return 1;
}
auto Config = EQEmuConfig::get();
/*
* Setup nice signal handlers
*/
if (signal(SIGINT, CatchSignal) == SIG_ERR) {
Log(Logs::Detail, Logs::Launcher, "Could not set signal handler");
return 1;
}
if (signal(SIGTERM, CatchSignal) == SIG_ERR) {
Log(Logs::Detail, Logs::Launcher, "Could not set signal handler");
return 1;
}
#ifndef WIN32
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR) {
Log(Logs::Detail, Logs::Launcher, "Could not set signal handler");
return 1;
}
/*
* Add '.' to LD_LIBRARY_PATH
*/
//the storage passed to putenv must remain valid... crazy unix people
const char *pv = getenv("LD_LIBRARY_PATH");
if(pv == nullptr) {
putenv(strdup("LD_LIBRARY_PATH=."));
} else {
char *v = (char *) malloc(strlen(pv) + 19);
sprintf(v, "LD_LIBRARY_PATH=.:%s", pv);
putenv(v);
}
#endif
std::map<std::string, ZoneLaunch *> zones;
WorldServer world(zones, launcher_name.c_str(), Config);
std::map<std::string, ZoneLaunch *>::iterator zone, zend;
std::set<std::string> to_remove;
Timer InterserverTimer(INTERSERVER_TIMER); // does auto-reconnect
Log(Logs::Detail, Logs::Launcher, "Starting main loop...");
ProcLauncher *launch = ProcLauncher::get();
RunLoops = true;
auto loop_fn = [&](EQ::Timer* t) {
//Advance the timer to our current point in time
Timer::SetCurrentTime();
if (!RunLoops) {
EQ::EventLoop::Get().Shutdown();
return;
}
/*
* Let the process manager look for dead children
*/
launch->Process();
/*
* Give all zones a chance to process.
*/
zone = zones.begin();
zend = zones.end();
for (; zone != zend; ++zone) {
if (!zone->second->Process())
to_remove.insert(zone->first);
}
/*
* Kill off any zones which have stopped
*/
while (!to_remove.empty()) {
std::string rem = *to_remove.begin();
to_remove.erase(rem);
zone = zones.find(rem);
if (zone == zones.end()) {
//wtf...
continue;
}
delete zone->second;
zones.erase(rem);
}
};
EQ::Timer process_timer(loop_fn);
process_timer.Start(32, true);
EQ::EventLoop::Get().Run();
//try to be semi-nice about this... without waiting too long
zone = zones.begin();
zend = zones.end();
for(; zone != zend; ++zone) {
zone->second->Stop();
}
Sleep(1);
launch->Process();
launch->TerminateAll(false);
Sleep(1);
launch->Process();
//kill anybody left
launch->TerminateAll(true);
for(; zone != zend; ++zone) {
delete zone->second;
}
EQEmuLogSys::Instance()->CloseFileLogs();
return 0;
}
void CatchSignal(int sig_num) {
Log(Logs::Detail, Logs::Launcher, "Caught signal %d", sig_num);
RunLoops = false;
}