mirror of
https://github.com/OpenFusionProject/OpenFusion.git
synced 2024-11-05 15:00:06 +00:00
dongresource
a55a34e09a
CNProtocol, CNShared, CNStructs and Defines are now in core/. CNLoginServer, CNShardServer and Monitor are now in servers/. core/Core.hpp wraps all the core headers except for CNShared.hpp. Defines.cpp has been renamed to Packets.cpp, and so has its corresponding namespace, but not the header file. This is in preparation for upcoming changes.
210 lines
5.4 KiB
C++
210 lines
5.4 KiB
C++
#include "servers/CNLoginServer.hpp"
|
|
#include "servers/CNShardServer.hpp"
|
|
#include "PlayerManager.hpp"
|
|
#include "PlayerMovement.hpp"
|
|
#include "BuiltinCommands.hpp"
|
|
#include "Buddies.hpp"
|
|
#include "CustomCommands.hpp"
|
|
#include "Combat.hpp"
|
|
#include "MobAI.hpp"
|
|
#include "Items.hpp"
|
|
#include "Missions.hpp"
|
|
#include "Nanos.hpp"
|
|
#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"
|
|
#include "Vendor.hpp"
|
|
|
|
#include "settings.hpp"
|
|
|
|
#include "../version.h"
|
|
|
|
#if defined(__MINGW32__) && !defined(_GLIBCXX_HAS_GTHREADS)
|
|
#include "mingw/mingw.thread.h"
|
|
#else
|
|
#include <thread>
|
|
#endif
|
|
#include <string>
|
|
#include <chrono>
|
|
#include <signal.h>
|
|
|
|
// HACK
|
|
#ifdef __has_feature
|
|
#if __has_feature(address_sanitizer)
|
|
#define __SANITIZE_ADDRESS__ 1
|
|
#endif
|
|
#endif
|
|
|
|
CNShardServer *shardServer = nullptr;
|
|
std::thread *shardThread = nullptr;
|
|
|
|
void startShard(CNShardServer* server) {
|
|
server->start();
|
|
}
|
|
|
|
// terminate gracefully on SIGINT (for gprof & DB saving)
|
|
void terminate(int arg) {
|
|
std::cout << "OpenFusion: terminating." << std::endl;
|
|
|
|
if (shardServer != nullptr && shardThread != nullptr)
|
|
shardServer->kill();
|
|
|
|
Database::close();
|
|
exit(0);
|
|
}
|
|
|
|
#ifndef _WIN32
|
|
void initsignals() {
|
|
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
|
|
|
|
int main() {
|
|
#ifdef _WIN32
|
|
WSADATA wsaData;
|
|
if (WSAStartup(MAKEWORD(1, 1), &wsaData) != 0) {
|
|
std::cerr << "OpenFusion: WSAStartup failed" << std::endl;
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
#else
|
|
initsignals();
|
|
#endif
|
|
srand(getTime());
|
|
settings::init();
|
|
std::cout << "[INFO] OpenFusion v" GIT_VERSION << std::endl;
|
|
std::cout << "[INFO] Protocol version: " << PROTOCOL_VERSION << std::endl;
|
|
std::cout << "[INFO] Intializing Packet Managers..." << std::endl;
|
|
TableData::init();
|
|
PlayerManager::init();
|
|
PlayerMovement::init();
|
|
BuiltinCommands::init();
|
|
Buddies::init();
|
|
CustomCommands::init();
|
|
Combat::init();
|
|
MobAI::init();
|
|
Items::init();
|
|
Missions::init();
|
|
Nanos::init();
|
|
NPCManager::init();
|
|
Vendor::init();
|
|
Transport::init();
|
|
Buddies::init();
|
|
Email::init();
|
|
Groups::init();
|
|
Racing::init();
|
|
Database::open();
|
|
Trading::init();
|
|
|
|
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 */
|
|
}
|
|
|
|
std::cout << "[INFO] Starting Server Threads..." << std::endl;
|
|
CNLoginServer loginServer(settings::LOGINPORT);
|
|
shardServer = new CNShardServer(settings::SHARDPORT);
|
|
|
|
shardThread = new std::thread(startShard, (CNShardServer*)shardServer);
|
|
|
|
loginServer.start();
|
|
|
|
shardServer->kill();
|
|
shardThread->join();
|
|
|
|
#ifdef _WIN32
|
|
WSACleanup();
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
// helper functions
|
|
|
|
std::string U16toU8(char16_t* src) {
|
|
try {
|
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>,char16_t> convert;
|
|
return convert.to_bytes(src);
|
|
} catch(const std::exception& e) {
|
|
return "";
|
|
}
|
|
}
|
|
|
|
// returns number of char16_t that was written at des
|
|
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
|
|
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>(high_resolution_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();
|
|
}
|
|
|
|
// 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;
|
|
}
|