<commit_before>// Copyright 2016 <NAME> (Raven), L3nn0x
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http ://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cxxopts.hpp>
#include "cloginserver.h"
#include "config.h"
#include "logconsole.h"
#include "version.h"

namespace {
void DisplayTitle()
{
  auto console = Core::CLog::GetLogger(Core::log_type::GENERAL);
  if(auto log = console.lock())
  {
    log->notice( "--------------------------------" );
    log->notice( "        osIROSE 2 Alpha         " );
    log->notice( "  http://forum.dev-osrose.com/  " );
    log->notice( "--------------------------------" );
    log->notice( "Git Branch/Revision: {}/{}", GIT_BRANCH, GIT_COMMIT_HASH );
  }
}

void CheckUser()
{
#ifndef _WIN32
  auto console = Core::CLog::GetLogger(Core::log_type::GENERAL);
  if(auto log = console.lock())
  {
    if ((getuid() == 0) && (getgid() == 0)) {
      log->warn( "You are running as the root superuser." );
      log->warn( "It is unnecessary and unsafe to run with root privileges." );
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(2000));
  }
#endif
}
}

int main(int argc, char* argv[]) {

  cxxopts::Options options("LoginServer", "OsIROSE Login Server");
  
  options.add_options()
  ("d,debug", "Enable extra debugging info")
  ("f,file",  "Config file path", cxxopts::value<std::string>(), "server.ini")
  ("l,level", "Logging level", cxxopts::value<int>())
  ("h,help",  "Print this help text")
  ;
  
  try {
  options.parse(argc, argv);
  
  if (options.count("help"))
  {
    std::cout << options.help({"", "Group"}) << std::endl;
    exit(0);
  }
    
  auto console = Core::CLog::GetLogger(Core::log_type::GENERAL);
  if(auto log = console.lock())
    log->notice( "Starting up server..." );

  Core::Config& config = Core::Config::getInstance();
  if( options.count("level") != 0 )
    Core::CLog::SetLevel((spdlog::level::level_enum)options["level"].as<int>());
  else
    Core::CLog::SetLevel((spdlog::level::level_enum)config.login_server().log_level());
  DisplayTitle();
  CheckUser();
  
  if(auto log = console.lock()) {
    if( options.count("level") != 0 )
      log->set_level((spdlog::level::level_enum)options["level"].as<int>());
    else
      log->set_level((spdlog::level::level_enum)config.login_server().log_level());
    log->trace("Trace logs are enabled.");
    log->debug("Debug logs are enabled.");
    log->info("Info logs are enabled.");
  }

  Core::NetworkThreadPool::GetInstance(config.serverdata().maxthreads());

  CLoginServer clientServer;
  CLoginServer iscServer(true);

  clientServer.Init(config.serverdata().ip(), config.login_server().clientport());
  clientServer.Listen();

  iscServer.Init(config.serverdata().ip(), config.login_server().iscport());
  iscServer.Listen();

  while (clientServer.IsActive()) {
    std::this_thread::sleep_for(std::chrono::milliseconds(100));
  }

  if(auto log = console.lock())
    log->notice( "Server shutting down..." );
  Core::NetworkThreadPool::DeleteInstance();
  spdlog::drop_all();
  
  }
  catch (const cxxopts::option_not_exists_exception& ex) {
    std::cout << options.help({"", "Group"}) << std::endl;
    return 1;
  }
  catch (const spdlog::spdlog_ex& ex) {<commit_msg>Moved command line options into its own function. Added new command line options to override the config file<commit_after>// Copyright 2016 <NAME> (Raven), L3nn0x
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http ://www.apache.org/licenses/LICENSE-2.0
// 
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <cxxopts.hpp>
#include "cloginserver.h"
#include "config.h"
#include "logconsole.h"
#include "version.h"

namespace {
void DisplayTitle()
{
  auto console = Core::CLog::GetLogger(Core::log_type::GENERAL);
  if(auto log = console.lock())
  {
    log->notice( "--------------------------------" );
    log->notice( "        osIROSE 2 Alpha         " );
    log->notice( "  http://forum.dev-osrose.com/  " );
    log->notice( "--------------------------------" );
    log->notice( "Git Branch/Revision: {}/{}", GIT_BRANCH, GIT_COMMIT_HASH );
  }
}

void CheckUser()
{
#ifndef _WIN32
  auto console = Core::CLog::GetLogger(Core::log_type::GENERAL);
  if(auto log = console.lock())
  {
    if ((getuid() == 0) && (getgid() == 0)) {
      log->warn( "You are running as the root superuser." );
      log->warn( "It is unnecessary and unsafe to run with root privileges." );
    }
    std::this_thread::sleep_for(std::chrono::milliseconds(2000));
  }
#endif
}

void ParseCommandLine(int argc, char** argv)
{
  cxxopts::Options options(argv[0], "osIROSE login server");
  
  try {
    std::string config_file_path = "";
    options.add_options()
    ("f,file",  "Config file path", cxxopts::value<std::string>(config_file_path)
      ->default_value("server.ini"), "FILE_PATH")
    ("l,level", "Logging level (0-9)", cxxopts::value<int>()
      ->default_value("3"), "LEVEL")
    ("ip", "Client listen IP Address", cxxopts::value<std::string>()
      ->default_value("0.0.0.0"), "IP")
    ("port", "Client listen port", cxxopts::value<int>()
      ->default_value("29000"), "PORT")
    ("iscip", "ISC listen IP Address", cxxopts::value<std::string>()
      ->default_value("127.0.0.1"), "IP")
    ("iscport", "ISC listen port", cxxopts::value<int>()
      ->default_value("29010"), "PORT")
    ("t,maxthreads", "Max thread count", cxxopts::value<int>()
      ->default_value("512"), "COUNT")
    ("h,help",  "Print this help text")
    ;
  
    options.parse(argc, argv);
    
    // Check to see if the user wants to see the help text
    if (options.count("help"))
    {
      std::cout << options.help({"", "Group"}) << std::endl;
      exit(0);
    }
    
    Core::Config& config = Core::Config::getInstance(config_file_path);
    
    // We are using if checks here because we only want to override the config file if the option was supplied
    // Since this is a login server startup function we can get away with a little bit of overhead
    if( options.count("level") )
      config.mutable_login_server()->set_log_level( options["level"].as<int>() );
      
    if( options.count("ip") )
      config.mutable_serverdata()->set_ip( options["ip"].as<std::string>() );
    
    if( options.count("maxthreads") )
      config.mutable_serverdata()->set_maxthreads( options["maxthreads"].as<int>() );
  }
  catch (const cxxopts::OptionException& ex) {
    std::cout << ex.what() << std::endl;
    std::cout << options.help({"", "Group"}) << std::endl;
    exit(1);
  }
}
}

int main(int argc, char* argv[]) {
  try {
    ParseCommandLine(argc, argv);

    auto console = Core::CLog::GetLogger(Core::log_type::GENERAL);
    if(auto log = console.lock())
      log->notice( "Starting up server..." );

    Core::Config& config = Core::Config::getInstance();
    Core::CLog::SetLevel((spdlog::level::level_enum)config.login_server().log_level());
    DisplayTitle();
    CheckUser();
  
    if(auto log = console.lock()) {
      log->set_level((spdlog::level::level_enum)config.login_server().log_level());
      log->trace("Trace logs are enabled.");
      log->debug("Debug logs are enabled.");
      log->info("Info logs are enabled.");
    }

    Core::NetworkThreadPool::GetInstance(config.serverdata().maxthreads());

    CLoginServer clientServer;
    CLoginServer iscServer(true);

    clientServer.Init(config.serverdata().ip(), config.login_server().clientport());
    clientServer.Listen();

    iscServer.Init(config.serverdata().ip(), config.login_server().iscport());
    iscServer.Listen();

    while (clientServer.IsActive()) {
      std::this_thread::sleep_for(std::chrono::milliseconds(100));
    }

    if(auto log = console.lock())
      log->notice( "Server shutting down..." );
    Core::NetworkThreadPool::DeleteInstance();
    spdlog::drop_all();
  
  }
  catch (const spdlog::spdlog_ex& ex) {
{'fraction_non_alphanumeric': 0.18686348552465956, 'fraction_numerical': 0.00881107678224053, 'mean_word_length': 3.585519412381952, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2845982', 'n_tokens_mistral': 2827, 'n_tokens_neox': 2749, 'n_words': 666}