434 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
		
		
			
		
	
	
			434 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| 
								 | 
							
								#include <client/linux/handler/exception_handler.h>
							 | 
						||
| 
								 | 
							
								#include <iostream>
							 | 
						||
| 
								 | 
							
								#include <misc/endianness.h>
							 | 
						||
| 
								 | 
							
								#include <CXXTerminal/QuickTerminal.h>
							 | 
						||
| 
								 | 
							
								#include <event2/thread.h>
							 | 
						||
| 
								 | 
							
								#include <log/LogUtils.h>
							 | 
						||
| 
								 | 
							
								#include <ThreadPool/Timer.h>
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include "src/Configuration.h"
							 | 
						||
| 
								 | 
							
								#include "src/TSServer.h"
							 | 
						||
| 
								 | 
							
								#include "src/InstanceHandler.h"
							 | 
						||
| 
								 | 
							
								#include "src/server/QueryServer.h"
							 | 
						||
| 
								 | 
							
								#include "src/server/file/FileServer.h"
							 | 
						||
| 
								 | 
							
								#include "src/terminal/CommandHandler.h"
							 | 
						||
| 
								 | 
							
								#include "src/client/InternalClient.h"
							 | 
						||
| 
								 | 
							
								#include "src/SignalHandler.h"
							 | 
						||
| 
								 | 
							
								#include "src/build.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								using namespace std;
							 | 
						||
| 
								 | 
							
								using namespace std::chrono;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define BUILD_CREATE_TABLE(tblName, types) "CREATE TABLE IF NOT EXISTS `" tblName "` (" types ")"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define CREATE_TABLE(table, types)   \
							 | 
						||
| 
								 | 
							
								result = sql::command(sqlData, BUILD_CREATE_TABLE(table, types)).execute();\
							 | 
						||
| 
								 | 
							
								if(!result){\
							 | 
						||
| 
								 | 
							
								    logger::logger(0)->critical("Could not setup sql tables. Command '{}' returns {}", BUILD_CREATE_TABLE(table, types), result.fmtStr());\
							 | 
						||
| 
								 | 
							
								    goto stopApp;\
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								bool mainThreadActive = true;
							 | 
						||
| 
								 | 
							
								bool mainThreadDone = false;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								ts::server::InstanceHandler* serverInstance = nullptr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								extern void testTomMath();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#ifndef FUCK_CLION
							 | 
						||
| 
								 | 
							
								    #define DB_NAME_BEG "TeaData"
							 | 
						||
| 
								 | 
							
								    #define DB_NAME_END ".sqlite"
							 | 
						||
| 
								 | 
							
								    #define DB_NAME DB_NAME_BEG DB_NAME_END
							 | 
						||
| 
								 | 
							
								#else
							 | 
						||
| 
								 | 
							
								    #define DB_NAME "TeaData.sqlite"
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#include <regex>
							 | 
						||
| 
								 | 
							
								#include <codecvt>
							 | 
						||
| 
								 | 
							
								#include "src/client/music/internal_provider/channel_replay/ChannelProvider.h"
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								class CLIParser{
							 | 
						||
| 
								 | 
							
								    public:
							 | 
						||
| 
								 | 
							
								        CLIParser (int &argc, char **argv){
							 | 
						||
| 
								 | 
							
								            for (int i = 1; i < argc; i++)
							 | 
						||
| 
								 | 
							
								                this->tokens.emplace_back(argv[i]);
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										std::deque<std::string> getCmdOptions(const std::string &option) const {
							 | 
						||
| 
								 | 
							
											std::deque<std::string> result;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											auto itr = this->tokens.begin();
							 | 
						||
| 
								 | 
							
											while(true) {
							 | 
						||
| 
								 | 
							
												itr = std::find(itr, this->tokens.end(), option);
							 | 
						||
| 
								 | 
							
												if (itr != this->tokens.end() && ++itr != this->tokens.end()){
							 | 
						||
| 
								 | 
							
													result.push_back(*itr);
							 | 
						||
| 
								 | 
							
													itr++;
							 | 
						||
| 
								 | 
							
												} else break;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											return result;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										std::deque<std::string> getCmdOptionsBegins(const std::string &option) const {
							 | 
						||
| 
								 | 
							
											std::deque<std::string> result;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											for(const auto& token : this->tokens)
							 | 
						||
| 
								 | 
							
												if(token.find(option) == 0)
							 | 
						||
| 
								 | 
							
													result.push_back(token);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											return result;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        const std::string& get_option(const std::string &option) const {
							 | 
						||
| 
								 | 
							
								            auto itr =  std::find(this->tokens.begin(), this->tokens.end(), option);
							 | 
						||
| 
								 | 
							
								            if (itr != this->tokens.end() && ++itr != this->tokens.end()){
							 | 
						||
| 
								 | 
							
								                return *itr;
							 | 
						||
| 
								 | 
							
								            }
							 | 
						||
| 
								 | 
							
								            static const std::string empty_string;
							 | 
						||
| 
								 | 
							
								            return empty_string;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        bool cmdOptionExists(const std::string &option) const{
							 | 
						||
| 
								 | 
							
								            return std::find(this->tokens.begin(), this->tokens.end(), option) != this->tokens.end();
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    private:
							 | 
						||
| 
								 | 
							
								        std::vector <std::string> tokens;
							 | 
						||
| 
								 | 
							
								};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/* addr is where the exception identifier is stored
							 | 
						||
| 
								 | 
							
								   id is the exception identifier.  */
							 | 
						||
| 
								 | 
							
								void __raise_exception (void **addr, void *id);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define T(address) \
							 | 
						||
| 
								 | 
							
								std::cout << "Testing: " << address << " => "; \
							 | 
						||
| 
								 | 
							
								{\
							 | 
						||
| 
								 | 
							
									sockaddr_storage storage;\
							 | 
						||
| 
								 | 
							
									net::resolve_address(address, storage);\
							 | 
						||
| 
								 | 
							
									std::cout << manager.contains(storage) << std::endl;\
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								#define CONFIG_NAME "config.yml"
							 | 
						||
| 
								 | 
							
								const char *malloc_conf = ""; //retain:false"; //,dirty_decay_ms:0";
							 | 
						||
| 
								 | 
							
								int main(int argc, char** argv) {
							 | 
						||
| 
								 | 
							
								#ifdef HAVE_JEMALLOC
							 | 
						||
| 
								 | 
							
									(void*) malloc_conf;
							 | 
						||
| 
								 | 
							
								#endif
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    CLIParser arguments(argc, argv);
							 | 
						||
| 
								 | 
							
								    SSL_load_error_strings();
							 | 
						||
| 
								 | 
							
								    OpenSSL_add_ssl_algorithms();
							 | 
						||
| 
								 | 
							
									ts::permission::setup_permission_resolve();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										u_char buffer[SHA512_DIGEST_LENGTH];
							 | 
						||
| 
								 | 
							
										SHA512_CTX md{};
							 | 
						||
| 
								 | 
							
										SHA512_Init(&md);
							 | 
						||
| 
								 | 
							
										SHA512_Update(&md, "Hello World", 11);
							 | 
						||
| 
								 | 
							
										SHA512_Final(buffer,&md);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										auto evthread_use_pthreads_result = evthread_use_pthreads();
							 | 
						||
| 
								 | 
							
										assert(evthread_use_pthreads_result == 0);
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									terminal::install();
							 | 
						||
| 
								 | 
							
								    if(!terminal::active()){ cerr << "could not setup terminal!" << endl; return -1; }
							 | 
						||
| 
								 | 
							
								    assert(ts::property::impl::validateUnique());
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(arguments.cmdOptionExists("--help") || arguments.cmdOptionExists("-h")) {
							 | 
						||
| 
								 | 
							
								        #define HELP_FMT "  {} {} | {}"
							 | 
						||
| 
								 | 
							
								        logMessageFmt(true, LOG_GENERAL, "Available command line parameters:");
							 | 
						||
| 
								 | 
							
								        logMessageFmt(true, LOG_GENERAL, HELP_FMT, "-h", "--help", "Shows this page");
							 | 
						||
| 
								 | 
							
								        logMessageFmt(true, LOG_GENERAL, HELP_FMT, "-q", "--set_query_password", "Changed the server admin query password");
							 | 
						||
| 
								 | 
							
									    logMessageFmt(true, LOG_GENERAL, HELP_FMT, "-P<property>=<value>", "--property:<property>=<value>", "Override a config value manual");
							 | 
						||
| 
								 | 
							
									    logMessageFmt(true, LOG_GENERAL, HELP_FMT, "-l", "--property-list", "List all available properties");
							 | 
						||
| 
								 | 
							
								        terminal::uninstall();
							 | 
						||
| 
								 | 
							
								        return 0;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
									if(arguments.cmdOptionExists("--property-list") || arguments.cmdOptionExists("-l")) {
							 | 
						||
| 
								 | 
							
										logMessageFmt(true, LOG_GENERAL, "Available properties:");
							 | 
						||
| 
								 | 
							
										auto properties = ts::config::create_bindings();
							 | 
						||
| 
								 | 
							
										for(const auto& property : properties) {
							 | 
						||
| 
								 | 
							
											logMessageFmt(true, LOG_GENERAL, "  " + property->key);
							 | 
						||
| 
								 | 
							
											for(const auto& entry : property->description) {
							 | 
						||
| 
								 | 
							
												if(entry.first.empty()) {
							 | 
						||
| 
								 | 
							
													for(const auto& line : entry.second)
							 | 
						||
| 
								 | 
							
														logMessageFmt(true, LOG_GENERAL, "    " + line);
							 | 
						||
| 
								 | 
							
												} else {
							 | 
						||
| 
								 | 
							
													logMessageFmt(true, LOG_GENERAL, "    " + entry.first + ":");
							 | 
						||
| 
								 | 
							
													for(const auto& line : entry.second)
							 | 
						||
| 
								 | 
							
														logMessageFmt(true, LOG_GENERAL, "      " + line);
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
											logMessageFmt(true, LOG_GENERAL, "    " + property->value_description());
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										return 0;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									if(!arguments.cmdOptionExists("--valgrind")) {
							 | 
						||
| 
								 | 
							
										ts::syssignal::setup();
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									ts::syssignal::setup_threads();
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									map<string, string> override_settings;
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										auto short_override = arguments.getCmdOptionsBegins("-P");
							 | 
						||
| 
								 | 
							
										for(const auto& entry : short_override) {
							 | 
						||
| 
								 | 
							
											if(entry.length() < 2) continue;
							 | 
						||
| 
								 | 
							
											auto ei = entry.find('=');
							 | 
						||
| 
								 | 
							
											if(ei == string::npos || ei == 2) {
							 | 
						||
| 
								 | 
							
												logErrorFmt(true, LOG_GENERAL, "Invalid command line parameter. (\"" + entry + "\")");
							 | 
						||
| 
								 | 
							
												return 1;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											auto key = entry.substr(2, ei - 2);
							 | 
						||
| 
								 | 
							
											auto value = entry.substr(ei + 1);
							 | 
						||
| 
								 | 
							
											override_settings[key] = value;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										auto short_override = arguments.getCmdOptionsBegins("--property:");
							 | 
						||
| 
								 | 
							
										for(const auto& entry : short_override) {
							 | 
						||
| 
								 | 
							
											if(entry.length() < 11) continue;
							 | 
						||
| 
								 | 
							
											auto ei = entry.find('=');
							 | 
						||
| 
								 | 
							
											if(ei == string::npos || ei == 11) {
							 | 
						||
| 
								 | 
							
												logErrorFmt(true, LOG_GENERAL, "Invalid command line parameter. (\"" + entry + "\")");
							 | 
						||
| 
								 | 
							
												return 1;
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
											auto key = entry.substr(11, ei - 11);
							 | 
						||
| 
								 | 
							
											auto value = entry.substr(ei + 1);
							 | 
						||
| 
								 | 
							
											override_settings[key] = value;
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									{
							 | 
						||
| 
								 | 
							
										auto bindings = ts::config::create_bindings();
							 | 
						||
| 
								 | 
							
										for(const auto& setting : bindings) {
							 | 
						||
| 
								 | 
							
											for(auto it = override_settings.begin(); it != override_settings.end(); it++) {
							 | 
						||
| 
								 | 
							
												if(it->first == setting->key) {
							 | 
						||
| 
								 | 
							
													try {
							 | 
						||
| 
								 | 
							
														setting->read_argument(it->second);
							 | 
						||
| 
								 | 
							
													} catch(const std::exception& ex) {
							 | 
						||
| 
								 | 
							
														logErrorFmt(true, LOG_GENERAL, "Failed to apply value for given property '" + it->first + "': " + ex.what());
							 | 
						||
| 
								 | 
							
													}
							 | 
						||
| 
								 | 
							
													override_settings.erase(it);
							 | 
						||
| 
								 | 
							
													break;
							 | 
						||
| 
								 | 
							
												}
							 | 
						||
| 
								 | 
							
											}
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										for(const auto& entry : override_settings) {
							 | 
						||
| 
								 | 
							
											logMessageFmt(true, LOG_GENERAL, "Missing property " + entry.first + ". Value unused!");
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								    /*
							 | 
						||
| 
								 | 
							
								    std::string error;
							 | 
						||
| 
								 | 
							
								    if(!interaction::waitForAttach(error)){
							 | 
						||
| 
								 | 
							
								        cerr << "Rsult: " << error << endl;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    while(interaction::memoryInfo()){
							 | 
						||
| 
								 | 
							
								        usleep(1 * 1000 * 1000);
							 | 
						||
| 
								 | 
							
								        logMessage("Current instances: " + to_string(interaction::memoryInfo()->instanceCount) + "/" + to_string(interaction::memoryInfo()->maxInstances));
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    interaction::removeMemoryHook();
							 | 
						||
| 
								 | 
							
								     if(true) return 0;
							 | 
						||
| 
								 | 
							
								     */
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    //debugMessage(LOG_GENERAL, "Sizeof ViewEntry {} Sizeof LinkedTreeEntry {} Sizeof shared_ptr<ViewEntry> {} Sizeof ClientChannelView {}", sizeof(ts::ViewEntry), sizeof(ts::TreeView::LinkedTreeEntry), sizeof(shared_ptr<ts::ViewEntry>), sizeof(ts::ClientChannelView));
							 | 
						||
| 
								 | 
							
								    {
							 | 
						||
| 
								 | 
							
								        //http://git.mcgalaxy.de/WolverinDEV/tomcrypt/blob/develop/src/misc/crypt/crypt_inits.c#L40-86
							 | 
						||
| 
								 | 
							
								        std::string descriptors = "LTGE";
							 | 
						||
| 
								 | 
							
								        bool crypt_init = false;
							 | 
						||
| 
								 | 
							
								        for(const auto& c : descriptors)
							 | 
						||
| 
								 | 
							
								            if(crypt_init |= crypt_mp_init(&c))
							 | 
						||
| 
								 | 
							
								                break;
							 | 
						||
| 
								 | 
							
								        if(!crypt_init) {
							 | 
						||
| 
								 | 
							
								            logCritical(LOG_GENERAL, "Could not initialise libtomcrypt mp descriptors!");
							 | 
						||
| 
								 | 
							
								            return 1;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if(register_prng(&sprng_desc) == -1) {
							 | 
						||
| 
								 | 
							
								            cerr << "could not setup prng" << endl;
							 | 
						||
| 
								 | 
							
								            return EXIT_FAILURE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if (register_cipher(&rijndael_desc) == -1) {
							 | 
						||
| 
								 | 
							
								            cerr << "could not setup rijndael" << endl;
							 | 
						||
| 
								 | 
							
								            return EXIT_FAILURE;
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        testTomMath();
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									ts::server::SqlDataManager* sql = nullptr;
							 | 
						||
| 
								 | 
							
									std::string errorMessage;
							 | 
						||
| 
								 | 
							
								    shared_ptr<logger::LoggerConfig> logConfig = nullptr;
							 | 
						||
| 
								 | 
							
									std::string line;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    logMessage("Loading configuration");
							 | 
						||
| 
								 | 
							
								    terminal::instance()->writeMessage("Loading configuration");
							 | 
						||
| 
								 | 
							
								    auto cfgErrors = ts::config::parseConfig(CONFIG_NAME);
							 | 
						||
| 
								 | 
							
								    if(!cfgErrors.empty()){
							 | 
						||
| 
								 | 
							
								        logError("Could not load configuration. Errors: (" + to_string(cfgErrors.size()) + ")");
							 | 
						||
| 
								 | 
							
								        for(const auto& entry : cfgErrors)
							 | 
						||
| 
								 | 
							
								            logError(" - " + entry);
							 | 
						||
| 
								 | 
							
								        logError("Stopping server...");
							 | 
						||
| 
								 | 
							
								        goto stopApp;
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    logMessage("Setting up log");
							 | 
						||
| 
								 | 
							
								    logConfig = make_shared<logger::LoggerConfig>();
							 | 
						||
| 
								 | 
							
								    logConfig->logfileLevel = (spdlog::level::level_enum) ts::config::log::logfileLevel;
							 | 
						||
| 
								 | 
							
								    logConfig->terminalLevel = (spdlog::level::level_enum) ts::config::log::terminalLevel;
							 | 
						||
| 
								 | 
							
								    logConfig->file_colored = ts::config::log::logfileColored;
							 | 
						||
| 
								 | 
							
								    logConfig->logPath = ts::config::log::path;
							 | 
						||
| 
								 | 
							
								    logConfig->vs_group_size = ts::config::log::vs_size;
							 | 
						||
| 
								 | 
							
								    logger::setup(logConfig);
							 | 
						||
| 
								 | 
							
									threads::timer::function_log = [](const std::string& message, bool debug) {
							 | 
						||
| 
								 | 
							
										if(debug)
							 | 
						||
| 
								 | 
							
											debugMessage(LOG_GENERAL, message);
							 | 
						||
| 
								 | 
							
										else
							 | 
						||
| 
								 | 
							
											logWarning(LOG_GENERAL, message);
							 | 
						||
| 
								 | 
							
									};
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    logger::updateLogLevels();
							 | 
						||
| 
								 | 
							
									if(ts::config::license_original && ts::config::license_original->data.type != license::LicenseType::DEMO){
							 | 
						||
| 
								 | 
							
										logMessageFmt(true, LOG_GENERAL, "[]---------------------------------------------------------[]");
							 | 
						||
| 
								 | 
							
										logMessageFmt(true, LOG_GENERAL, "  §aThank you for buying the TeaSpeak-§lPremium-§aSoftware!  ");
							 | 
						||
| 
								 | 
							
										logMessageFmt(true, LOG_GENERAL, "  §aLicense information:");
							 | 
						||
| 
								 | 
							
										logMessageFmt(true, LOG_GENERAL, "     §aLicense owner  : §e" + ts::config::license_original->owner());
							 | 
						||
| 
								 | 
							
										logMessageFmt(true, LOG_GENERAL, "     §aLicense type   : §e" + license::LicenseTypeNames[ts::config::license_original->data.type]);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
										if(ts::config::license_original->end().time_since_epoch().count() == 0){
							 | 
						||
| 
								 | 
							
											logMessageFmt(true, LOG_GENERAL, "     §aLicense expires: §enever");
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
											char timeBuffer[32];
							 | 
						||
| 
								 | 
							
											time_t t = duration_cast<seconds>(ts::config::license_original->end().time_since_epoch()).count();
							 | 
						||
| 
								 | 
							
											tm* stime = localtime(&t);
							 | 
						||
| 
								 | 
							
											strftime(timeBuffer, 32, "%c", stime);
							 | 
						||
| 
								 | 
							
											logMessageFmt(true, LOG_GENERAL, "     §aLicense expires: §e" + string(timeBuffer));
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										logMessage(string() + "     §aLicense valid  : " + (ts::config::license_original->isValid() ? "§ayes" : "§cno"));
							 | 
						||
| 
								 | 
							
										logMessageFmt(true, LOG_GENERAL, "[]---------------------------------------------------------[]");
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    logMessage(LOG_GENERAL, "Starting TeaSpeak-Server v{}", build::version()->string(true));
							 | 
						||
| 
								 | 
							
									logMessage(LOG_GENERAL, "Starting music providers");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									terminal::instance()->setPrompt("§aStarting server. §7[§aloading music§7]");
							 | 
						||
| 
								 | 
							
									if(ts::config::music::enabled && !arguments.cmdOptionExists("--valgrind")) {
							 | 
						||
| 
								 | 
							
										::music::manager::loadProviders("providers");
							 | 
						||
| 
								 | 
							
										::music::manager::register_provider(::music::provider::ChannelProvider::create_provider());
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    terminal::instance()->setPrompt("§aStarting server. §7[§aloading geoloc§7]");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(!ts::config::geo::staticFlag) {
							 | 
						||
| 
								 | 
							
								        if(ts::config::geo::type == geoloc::PROVIDER_SOFTWARE77)
							 | 
						||
| 
								 | 
							
								            geoloc::provider = new geoloc::Software77Provider(ts::config::geo::mappingFile);
							 | 
						||
| 
								 | 
							
								        else if(ts::config::geo::type == geoloc::PROVIDER_IP2LOCATION)
							 | 
						||
| 
								 | 
							
								            geoloc::provider = new geoloc::IP2LocationProvider(ts::config::geo::mappingFile);
							 | 
						||
| 
								 | 
							
								        else {
							 | 
						||
| 
								 | 
							
								            logCritical("Invalid geo resolver type!");
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								        if(geoloc::provider && !geoloc::provider->load(errorMessage)) {
							 | 
						||
| 
								 | 
							
								            logCritical("Could not setup geoloc! Fallback to default flag!");
							 | 
						||
| 
								 | 
							
								            logCritical("Message: " + errorMessage);
							 | 
						||
| 
								 | 
							
								            geoloc::provider = nullptr;
							 | 
						||
| 
								 | 
							
									        errorMessage = "";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    if(ts::config::geo::vpn_block) {
							 | 
						||
| 
								 | 
							
								        geoloc::provider_vpn = new geoloc::IPCatBlocker(ts::config::geo::vpn_file);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if(geoloc::provider_vpn && !geoloc::provider_vpn->load(errorMessage)) {
							 | 
						||
| 
								 | 
							
								            logCritical("Could not setup vpn detector!");
							 | 
						||
| 
								 | 
							
								            logCritical("Message: " + errorMessage);
							 | 
						||
| 
								 | 
							
								            geoloc::provider_vpn = nullptr;
							 | 
						||
| 
								 | 
							
								            errorMessage = "";
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								    terminal::instance()->setPrompt("§aStarting server. §7[§aloading sql§7]");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
									sql = new ts::server::SqlDataManager();
							 | 
						||
| 
								 | 
							
									if(!sql->initialize(errorMessage)) {
							 | 
						||
| 
								 | 
							
										logCritical("Could not initialize SQL!");
							 | 
						||
| 
								 | 
							
										if(errorMessage.find("database is locked") != string::npos) {
							 | 
						||
| 
								 | 
							
											logCriticalFmt(true, LOG_GENERAL, "----------------------------[ ATTENTION ]----------------------------");
							 | 
						||
| 
								 | 
							
								            logCriticalFmt(true, LOG_GENERAL, "{:^69}", "You're database is already in use!");
							 | 
						||
| 
								 | 
							
											logCriticalFmt(true, LOG_GENERAL, "{:^69}", "Stop the other instance first!");
							 | 
						||
| 
								 | 
							
											logCriticalFmt(true, LOG_GENERAL, "----------------------------[ ATTENTION ]----------------------------");
							 | 
						||
| 
								 | 
							
										} else {
							 | 
						||
| 
								 | 
							
								            logCriticalFmt(true, LOG_GENERAL, errorMessage);
							 | 
						||
| 
								 | 
							
										}
							 | 
						||
| 
								 | 
							
										goto stopApp;
							 | 
						||
| 
								 | 
							
									}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    terminal::instance()->setPrompt("§aStarting server. §7[§astarting instance§7]");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    serverInstance = new ts::server::InstanceHandler(sql); //if error than mainThreadActive = false
							 | 
						||
| 
								 | 
							
								    if(!mainThreadActive || !serverInstance->startInstance())
							 | 
						||
| 
								 | 
							
								        goto stopApp;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(arguments.cmdOptionExists("-q") || arguments.cmdOptionExists("--set_query_password")) {
							 | 
						||
| 
								 | 
							
								    	auto password = arguments.cmdOptionExists("-q") ? arguments.get_option("-q") : arguments.get_option("--set_query_password");
							 | 
						||
| 
								 | 
							
								    	if(!password.empty()) {
							 | 
						||
| 
								 | 
							
										    logMessageFmt(true, LOG_GENERAL, "Updating server admin query password to \"{}\"", password);
							 | 
						||
| 
								 | 
							
										    auto accounts = serverInstance->getQueryServer()->find_query_accounts_by_unique_id(serverInstance->getInitalServerAdmin()->getUid());
							 | 
						||
| 
								 | 
							
										    bool found = false;
							 | 
						||
| 
								 | 
							
										    for(const auto& account : accounts) {
							 | 
						||
| 
								 | 
							
										    	if(account->bound_server != 0) continue;
							 | 
						||
| 
								 | 
							
											    if(!serverInstance->getQueryServer()->change_query_password(account, password)) {
							 | 
						||
| 
								 | 
							
												    logErrorFmt(true, LOG_GENERAL, "Failed to update server admin query password! (Internal error)");
							 | 
						||
| 
								 | 
							
											    }
							 | 
						||
| 
								 | 
							
											    found = true;
							 | 
						||
| 
								 | 
							
											    break;
							 | 
						||
| 
								 | 
							
										    }
							 | 
						||
| 
								 | 
							
										    if(!found) {
							 | 
						||
| 
								 | 
							
										    	logErrorFmt(true, LOG_GENERAL, "Failed to update server admin query password! Login does not exists!");
							 | 
						||
| 
								 | 
							
										    }
							 | 
						||
| 
								 | 
							
									    }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    terminal::instance()->setPrompt("§7> §f");
							 | 
						||
| 
								 | 
							
								    while(mainThreadActive) {
							 | 
						||
| 
								 | 
							
								        usleep(5 * 1000);
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if(terminal::instance()->linesAvailable() > 0){
							 | 
						||
| 
								 | 
							
								            while(!(line = terminal::instance()->readLine("§7> §f")).empty())
							 | 
						||
| 
								 | 
							
								                threads::Thread(THREAD_DETACHED, [line](){ terminal::chandler::handleCommand(line); });
							 | 
						||
| 
								 | 
							
								        }
							 | 
						||
| 
								 | 
							
								    }
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    stopApp:
							 | 
						||
| 
								 | 
							
								    logMessage("Stopping application");
							 | 
						||
| 
								 | 
							
								    if(serverInstance)
							 | 
						||
| 
								 | 
							
								        serverInstance->stopInstance();
							 | 
						||
| 
								 | 
							
								    delete serverInstance;
							 | 
						||
| 
								 | 
							
									serverInstance = nullptr;
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if(sql)
							 | 
						||
| 
								 | 
							
									    sql->finalize();
							 | 
						||
| 
								 | 
							
									delete sql;
							 | 
						||
| 
								 | 
							
								    logMessage("Application suspend successful!");
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    logger::uninstall();
							 | 
						||
| 
								 | 
							
								    terminal::uninstall();
							 | 
						||
| 
								 | 
							
									mainThreadDone = true;
							 | 
						||
| 
								 | 
							
								    return 0;
							 | 
						||
| 
								 | 
							
								}
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								/*
							 | 
						||
| 
								 | 
							
								 * 2][OUT] (188.225.34.225:9988) ftinitdownload clientftfid=4096 name=\/icon_166694597 cid=0 cpw seekpos=0 proto=1 return_code=
							 | 
						||
| 
								 | 
							
								[02][OUT] (188.225.34.225:9988) ftinitdownload clientftfid=4095 name=\/icon_4113966246 cid=0 cpw seekpos=0 proto=1 return_code=
							 | 
						||
| 
								 | 
							
								[02][OUT] (188.225.34.225:9988) ftinitdownload clientftfid=4094 name=\/icon_3002705295 cid=0 cpw seekpos=0 proto=1 return_code=
							 | 
						||
| 
								 | 
							
								[02][OUT] (188.225.34.225:9988) ftinitdownload clientftfid=4093 name=\/icon_494035633 cid=0 cpw seekpos=0 proto=1 return_code=
							 | 
						||
| 
								 | 
							
								[02][OUT] (188.225.34.225:9988) ftinitdownload clientftfid=4092 name=\/icon_847789427 cid=0 cpw seekpos=0 proto=1 return_code=
							 | 
						||
| 
								 | 
							
								[02][ IN] (188.225.34.225:9988) notifyclientupdated clid=5 client_version=3.2.0\s[Build:\s1533739581] client_platform=Linux client_login_name=WolverinDEV client_created=1536521950 client_lastconnected=1536522252 client_totalconnections=2 client_month_bytes_uploaded=0 client_month_bytes_downloaded=0 client_total_bytes_uploaded=0 client_total_bytes_downloaded=0 client_icon_id=0 client_country=DE
							 | 
						||
| 
								 | 
							
								[02][ IN] (188.225.34.225:9988) notifystartdownload clientftfid=4096 proto=1 serverftfid=1 ftkey=R0Vcnx4fNdrXuMFg port=30303 size=1086
							 | 
						||
| 
								 | 
							
								[02][ IN] (188.225.34.225:9988) notifystartdownload clientftfid=4095 proto=1 serverftfid=1 ftkey=3eYwsuviQvTWme42 port=30303 size=822
							 | 
						||
| 
								 | 
							
								[02][ IN] (188.225.34.225:9988) notifystartdownload clientftfid=4094 proto=1 serverftfid=1 ftkey=dM5oaVuLYLwia2me port=30303 size=852
							 | 
						||
| 
								 | 
							
								[02][ IN] (188.225.34.225:9988) notifystartdownload clientftfid=4093 proto=1 serverftfid=1 ftkey=60BltUu8fbUqgLhj port=30303 size=3441
							 | 
						||
| 
								 | 
							
								[02][ IN] (188.225.34.225:9988) notifystartdownload clientftfid=4092 proto=1 serverftfid=1 ftkey=a0wmURVHqhNE71H2 port=30303 size=1452
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								 */
							 |