2020-08-18 20:42:30 +00:00
|
|
|
#include "CNLoginServer.hpp"
|
|
|
|
#include "CNShardServer.hpp"
|
|
|
|
#include "PlayerManager.hpp"
|
|
|
|
#include "ChatManager.hpp"
|
2020-09-16 19:46:15 +00:00
|
|
|
#include "MobManager.hpp"
|
2020-08-21 02:10:14 +00:00
|
|
|
#include "ItemManager.hpp"
|
2020-08-24 21:04:56 +00:00
|
|
|
#include "MissionManager.hpp"
|
2020-08-20 15:43:37 +00:00
|
|
|
#include "NanoManager.hpp"
|
2020-08-20 21:43:48 +00:00
|
|
|
#include "NPCManager.hpp"
|
2020-08-29 11:43:33 +00:00
|
|
|
#include "TransportManager.hpp"
|
2020-09-19 19:08:03 +00:00
|
|
|
#include "BuddyManager.hpp"
|
2020-08-28 18:02:03 +00:00
|
|
|
#include "Database.hpp"
|
2020-09-09 17:06:22 +00:00
|
|
|
#include "TableData.hpp"
|
2020-09-17 22:45:43 +00:00
|
|
|
#include "ChunkManager.hpp"
|
2020-10-04 23:54:08 +00:00
|
|
|
#include "GroupManager.hpp"
|
2020-08-18 20:42:30 +00:00
|
|
|
|
|
|
|
#include "settings.hpp"
|
|
|
|
|
2020-09-16 18:12:12 +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"
|
2020-09-14 13:53:48 +00:00
|
|
|
#else
|
2020-08-24 21:04:56 +00:00
|
|
|
#include <thread>
|
2020-08-18 20:42:30 +00:00
|
|
|
#endif
|
|
|
|
#include <string>
|
2020-09-16 19:46:15 +00:00
|
|
|
#include <chrono>
|
2020-08-30 22:30:15 +00:00
|
|
|
#include <signal.h>
|
2020-08-18 20:42:30 +00:00
|
|
|
|
2020-09-10 22:01:35 +00:00
|
|
|
// HACK
|
|
|
|
#ifdef __has_feature
|
|
|
|
#if __has_feature(address_sanitizer)
|
|
|
|
#define __SANITIZE_ADDRESS__ 1
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2020-09-12 20:43:04 +00:00
|
|
|
CNShardServer *shardServer = nullptr;
|
|
|
|
std::thread *shardThread = nullptr;
|
2020-08-27 19:42:04 +00:00
|
|
|
|
2020-08-19 00:52:02 +00:00
|
|
|
void startShard(CNShardServer* server) {
|
|
|
|
server->start();
|
2020-08-18 20:42:30 +00:00
|
|
|
}
|
|
|
|
|
2020-08-27 19:42:04 +00:00
|
|
|
// terminate gracefully on SIGINT (for gprof)
|
|
|
|
void terminate(int arg) {
|
2020-08-30 22:30:15 +00:00
|
|
|
std::cout << "OpenFusion: terminating." << std::endl;
|
2020-09-12 20:43:04 +00:00
|
|
|
|
|
|
|
if (shardServer != nullptr && shardThread != nullptr) {
|
|
|
|
shardServer->kill();
|
|
|
|
shardThread->join();
|
|
|
|
}
|
2020-09-10 22:01:35 +00:00
|
|
|
|
2020-08-27 19:42:04 +00:00
|
|
|
exit(0);
|
|
|
|
}
|
|
|
|
|
2020-10-13 19:57:41 +00:00
|
|
|
#ifndef _WIN32
|
2020-08-30 22:30:15 +00:00
|
|
|
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
|
|
|
|
|
2020-08-18 20:42:30 +00:00
|
|
|
int main() {
|
|
|
|
#ifdef _WIN32
|
|
|
|
WSADATA wsaData;
|
2020-08-24 21:04:56 +00:00
|
|
|
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
|
|
|
}
|
2020-08-26 19:38:09 +00:00
|
|
|
#else
|
2020-08-30 22:30:15 +00:00
|
|
|
initsignals();
|
2020-08-18 20:42:30 +00:00
|
|
|
#endif
|
2020-09-22 18:32:40 +00:00
|
|
|
srand(getTime());
|
2020-08-18 20:42:30 +00:00
|
|
|
settings::init();
|
2020-09-16 18:12:12 +00:00
|
|
|
std::cout << "[INFO] OpenFusion v" GIT_VERSION << std::endl;
|
2020-08-21 17:38:45 +00:00
|
|
|
std::cout << "[INFO] Protocol version: " << PROTOCOL_VERSION << std::endl;
|
2020-08-18 20:42:30 +00:00
|
|
|
std::cout << "[INFO] Intializing Packet Managers..." << std::endl;
|
2020-09-09 19:09:01 +00:00
|
|
|
TableData::init();
|
2020-08-18 20:42:30 +00:00
|
|
|
PlayerManager::init();
|
|
|
|
ChatManager::init();
|
2020-09-16 19:46:15 +00:00
|
|
|
MobManager::init();
|
2020-08-21 02:10:14 +00:00
|
|
|
ItemManager::init();
|
2020-08-24 21:04:56 +00:00
|
|
|
MissionManager::init();
|
2020-08-20 15:43:37 +00:00
|
|
|
NanoManager::init();
|
2020-08-20 21:43:48 +00:00
|
|
|
NPCManager::init();
|
2020-08-29 11:43:33 +00:00
|
|
|
TransportManager::init();
|
2020-10-27 15:28:37 +00:00
|
|
|
BuddyManager::init(); // stubbed until we have database integration + lots of bug fixes
|
2020-10-04 23:54:08 +00:00
|
|
|
GroupManager::init();
|
2020-08-28 18:02:03 +00:00
|
|
|
Database::open();
|
|
|
|
|
2020-10-17 23:19:05 +00:00
|
|
|
switch (settings::EVENTMODE) {
|
|
|
|
case 0: break; // no event
|
functional crates (no more plungers) (#133)
* FM, Taros and Boosts awards from killing mobs should be pretty
accurate now. A temporary formula for adjusting player/mob level gap is
implemented, but it will probably need to be adjusted in the future
* Mobs now drop correct crates
* Crates can be opened and give you correct items This includes
regular mob crates, world boss crates, mission crates, IZ race crates,
E.G.G.E.R.s, golden Eggs, and Event Crates. Keep in mind that neither
IZ races or golden Eggs are implemented, but if you spawn such a crate
it can be opened.
* All data is read from a json file, for which I'm going to release a
tool soon so it's easily adjustable
* There is a new setting for enabling events, which enables dropping
extra event crates These are Knishmas, Halloween and Easter
2020-10-10 17:18:47 +00:00
|
|
|
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;
|
2020-10-17 23:19:05 +00:00
|
|
|
default:
|
|
|
|
std::cout << "[FATAL] Unknown event set in config file." << std::endl;
|
|
|
|
terminate(0);
|
|
|
|
/* not reached */
|
functional crates (no more plungers) (#133)
* FM, Taros and Boosts awards from killing mobs should be pretty
accurate now. A temporary formula for adjusting player/mob level gap is
implemented, but it will probably need to be adjusted in the future
* Mobs now drop correct crates
* Crates can be opened and give you correct items This includes
regular mob crates, world boss crates, mission crates, IZ race crates,
E.G.G.E.R.s, golden Eggs, and Event Crates. Keep in mind that neither
IZ races or golden Eggs are implemented, but if you spawn such a crate
it can be opened.
* All data is read from a json file, for which I'm going to release a
tool soon so it's easily adjustable
* There is a new setting for enabling events, which enables dropping
extra event crates These are Knishmas, Halloween and Easter
2020-10-10 17:18:47 +00:00
|
|
|
}
|
|
|
|
|
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);
|
2020-08-27 19:42:04 +00:00
|
|
|
shardServer = new CNShardServer(settings::SHARDPORT);
|
2020-08-19 00:52:02 +00:00
|
|
|
|
2020-08-27 19:42:04 +00:00
|
|
|
shardThread = new std::thread(startShard, (CNShardServer*)shardServer);
|
2020-08-24 21:04:56 +00:00
|
|
|
|
2020-08-19 00:52:02 +00:00
|
|
|
loginServer.start();
|
|
|
|
|
2020-08-27 19:42:04 +00:00
|
|
|
shardServer->kill();
|
|
|
|
shardThread->join();
|
2020-08-24 21:04:56 +00:00
|
|
|
|
2020-08-18 20:42:30 +00:00
|
|
|
#ifdef _WIN32
|
|
|
|
WSACleanup();
|
|
|
|
#endif
|
|
|
|
return 0;
|
2020-08-21 17:38:45 +00:00
|
|
|
}
|
2020-09-16 19:46:15 +00:00
|
|
|
|
|
|
|
// 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
|
2020-10-04 17:50:58 +00:00
|
|
|
size_t U8toU16(std::string src, char16_t* des, size_t max) {
|
2020-09-16 19:46:15 +00:00
|
|
|
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());
|
2020-09-16 19:46:15 +00:00
|
|
|
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();
|
|
|
|
}
|
2020-09-22 19:15:47 +00:00
|
|
|
|
2020-09-23 09:21:32 +00:00
|
|
|
// returns system time in seconds
|
2020-09-22 19:15:47 +00:00
|
|
|
time_t getTimestamp() {
|
|
|
|
using namespace std::chrono;
|
|
|
|
|
2020-09-23 09:05:18 +00:00
|
|
|
seconds value = duration_cast<seconds>((time_point_cast<seconds>(system_clock::now())).time_since_epoch());
|
2020-09-22 19:15:47 +00:00
|
|
|
|
|
|
|
return (time_t)value.count();
|
|
|
|
}
|