OpenFusion/src/main.cpp

239 lines
5.9 KiB
C++
Raw Normal View History

#include "servers/CNLoginServer.hpp"
#include "servers/CNShardServer.hpp"
2020-08-18 20:42:30 +00:00
#include "PlayerManager.hpp"
#include "PlayerMovement.hpp"
#include "BuiltinCommands.hpp"
#include "Buddies.hpp"
#include "CustomCommands.hpp"
#include "Combat.hpp"
#include "Items.hpp"
#include "Missions.hpp"
#include "Nanos.hpp"
2020-08-20 21:43:48 +00:00
#include "NPCManager.hpp"
#include "Transport.hpp"
#include "Buddies.hpp"
#include "db/Database.hpp"
#include "TableData.hpp"
#include "Groups.hpp"
#include "servers/Monitor.hpp"
#include "Racing.hpp"
#include "Trading.hpp"
#include "Email.hpp"
2021-04-16 17:28:59 +00:00
#include "Vendors.hpp"
#include "Chat.hpp"
#include "Eggs.hpp"
#include "Rand.hpp"
2020-08-18 20:42:30 +00:00
#include "settings.hpp"
#include "sandbox/Sandbox.hpp"
2020-08-18 20:42:30 +00:00
#include "../version.h"
2020-08-19 20:42:44 +00:00
#if defined(__MINGW32__) && !defined(_GLIBCXX_HAS_GTHREADS)
2020-08-18 20:42:30 +00:00
#include "mingw/mingw.thread.h"
#else
#include <thread>
2020-08-18 20:42:30 +00:00
#endif
#include <string>
#include <chrono>
2020-08-30 22:30:15 +00:00
#include <signal.h>
2020-08-18 20:42:30 +00:00
// HACK
#ifdef __has_feature
#if __has_feature(address_sanitizer)
#define __SANITIZE_ADDRESS__ 1
#endif
#endif
CNShardServer *shardServer = nullptr;
std::thread *shardThread = nullptr;
2020-08-19 00:52:02 +00:00
void startShard(CNShardServer* server) {
server->start();
2020-08-18 20:42:30 +00:00
}
// terminate gracefully on SIGINT (for gprof & DB saving)
void terminate(int arg) {
2020-08-30 22:30:15 +00:00
std::cout << "OpenFusion: terminating." << std::endl;
if (shardServer != nullptr && shardThread != nullptr)
shardServer->kill();
2020-12-04 00:22:53 +00:00
Database::close();
exit(0);
}
#ifdef _WIN32
static BOOL WINAPI winTerminate(DWORD arg) {
terminate(0);
return FALSE;
}
#endif
2020-08-30 22:30:15 +00:00
void initsignals() {
#ifdef _WIN32
if (!SetConsoleCtrlHandler(winTerminate, TRUE)) {
std::cerr << "[FATAL] Failed to set control handler" << std::endl;
exit(1);
}
#else
2020-08-30 22:30:15 +00:00
struct sigaction act;
memset((void*)&act, 0, sizeof(act));
sigemptyset(&act.sa_mask);
// tell the OS to not kill us if you use a broken pipe, just let us know thru recv() or send()
act.sa_handler = SIG_IGN;
if (sigaction(SIGPIPE, &act, NULL) < 0) {
perror("sigaction");
exit(1);
}
act.sa_handler = terminate;
if (sigaction(SIGINT, &act, NULL) < 0) {
perror("sigaction");
exit(1);
}
#endif
}
2020-08-30 22:30:15 +00:00
2020-08-18 20:42:30 +00:00
int main() {
std::cout << "[INFO] OpenFusion v" GIT_VERSION << std::endl;
std::cout << "[INFO] Protocol version: " << PROTOCOL_VERSION << std::endl;
2020-08-18 20:42:30 +00:00
#ifdef _WIN32
WSADATA wsaData;
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
std::cerr << "OpenFusion: WSAStartup failed" << std::endl;
exit(EXIT_FAILURE);
2020-08-18 20:42:30 +00:00
}
#endif
initsignals();
2020-08-18 20:42:30 +00:00
settings::init();
Database::init();
Rand::init(getTime());
TableData::init();
2020-08-18 20:42:30 +00:00
std::cout << "[INFO] Intializing Packet Managers..." << std::endl;
2020-08-18 20:42:30 +00:00
PlayerManager::init();
PlayerMovement::init();
BuiltinCommands::init();
Buddies::init();
CustomCommands::init();
Combat::init();
Chat::init();
Items::init();
Eggs::init();
Missions::init();
Nanos::init();
2020-08-20 21:43:48 +00:00
NPCManager::init();
2021-04-16 17:28:59 +00:00
Vendors::init();
Transport::init();
Buddies::init();
Email::init();
Groups::init();
Racing::init();
Trading::init();
Database::open();
switch (settings::EVENTMODE) {
case 0: break; // no event
case 1: std::cout << "[INFO] Event active. Hey, Hey It's Knishmas!" << std::endl; break;
case 2: std::cout << "[INFO] Event active. Wishing you a spook-tacular Halloween!" << std::endl; break;
case 3: std::cout << "[INFO] Event active. Have a very hoppy Easter!" << std::endl; break;
default:
std::cout << "[FATAL] Unknown event set in config file." << std::endl;
exit(1);
/* not reached */
}
2020-08-18 20:42:30 +00:00
std::cout << "[INFO] Starting Server Threads..." << std::endl;
2020-08-19 01:34:39 +00:00
CNLoginServer loginServer(settings::LOGINPORT);
shardServer = new CNShardServer(settings::SHARDPORT);
2020-08-19 00:52:02 +00:00
shardThread = new std::thread(startShard, (CNShardServer*)shardServer);
sandbox_start();
2020-08-19 00:52:02 +00:00
loginServer.start();
shardServer->kill();
shardThread->join();
2020-08-18 20:42:30 +00:00
#ifdef _WIN32
WSACleanup();
#endif
return 0;
}
// helper functions
std::string U16toU8(char16_t* src, size_t max) {
src[max-1] = '\0'; // force a NULL terminator
try {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
std::string ret = convert.to_bytes(src);
if (ret.size() >= max)
ret.resize(max-2);
return ret;
} catch(const std::exception& e) {
return "";
}
}
// returns number of char16_t that was written at des
2020-10-04 17:50:58 +00:00
size_t U8toU16(std::string src, char16_t* des, size_t max) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
std::u16string tmp = convert.from_bytes(src);
// copy utf16 string to buffer
2020-10-04 17:50:58 +00:00
if (sizeof(char16_t) * tmp.length() > max) // make sure we don't write outside the buffer
memcpy(des, tmp.c_str(), sizeof(char16_t) * max);
else
memcpy(des, tmp.c_str(), sizeof(char16_t) * tmp.length());
des[tmp.length()] = '\0';
return tmp.length();
}
time_t getTime() {
using namespace std::chrono;
milliseconds value = duration_cast<milliseconds>((time_point_cast<milliseconds>(steady_clock::now())).time_since_epoch());
return (time_t)value.count();
}
// returns system time in seconds
time_t getTimestamp() {
using namespace std::chrono;
seconds value = duration_cast<seconds>((time_point_cast<seconds>(system_clock::now())).time_since_epoch());
return (time_t)value.count();
}
2020-11-07 02:10:41 +00:00
// convert integer timestamp (in s) to FF systime struct
sSYSTEMTIME timeStampToStruct(uint64_t time) {
const time_t timeProper = time;
tm ts = *localtime(&timeProper);
sSYSTEMTIME systime;
systime.wMilliseconds = 0;
systime.wSecond = ts.tm_sec;
systime.wMinute = ts.tm_min;
systime.wHour = ts.tm_hour;
systime.wDay = ts.tm_mday;
systime.wDayOfWeek = ts.tm_wday + 1;
systime.wMonth = ts.tm_mon + 1;
systime.wYear = ts.tm_year + 1900;
return systime;
}