void CProcessViewerApp::ChangeProcessPriority() { HANDLE hProcessViewerProc = GetCurrentProcess(); SetPriorityClass( hProcessViewerProc, ABOVE_NORMAL_PRIORITY_CLASS ); SetProcessPriorityBoost( hProcessViewerProc, FALSE ); }
static F64 calculate_cpu_frequency(U32 measure_msecs) { if(measure_msecs == 0) { return 0; } // After that we declare some vars and check the frequency of the high // resolution timer for the measure process. // If there"s no high-res timer, we exit. unsigned __int64 starttime, endtime, timedif, freq, start, end, dif; if (!QueryPerformanceFrequency((LARGE_INTEGER *) &freq)) { return 0; } // Now we can init the measure process. We set the process and thread priority // to the highest available level (Realtime priority). Also we focus the // first processor in the multiprocessor system. HANDLE hProcess = GetCurrentProcess(); HANDLE hThread = GetCurrentThread(); unsigned long dwCurPriorityClass = GetPriorityClass(hProcess); int iCurThreadPriority = GetThreadPriority(hThread); unsigned long dwProcessMask, dwSystemMask, dwNewMask = 1; GetProcessAffinityMask(hProcess, &dwProcessMask, &dwSystemMask); SetPriorityClass(hProcess, REALTIME_PRIORITY_CLASS); SetThreadPriority(hThread, THREAD_PRIORITY_TIME_CRITICAL); SetProcessAffinityMask(hProcess, dwNewMask); //// Now we call a CPUID to ensure, that all other prior called functions are //// completed now (serialization) //__asm cpuid int cpu_info[4] = {-1}; __cpuid(cpu_info, 0); // We ask the high-res timer for the start time QueryPerformanceCounter((LARGE_INTEGER *) &starttime); // Then we get the current cpu clock and store it start = __rdtsc(); // Now we wart for some msecs _Delay(measure_msecs); // Sleep(uiMeasureMSecs); // We ask for the end time QueryPerformanceCounter((LARGE_INTEGER *) &endtime); // And also for the end cpu clock end = __rdtsc(); // Now we can restore the default process and thread priorities SetProcessAffinityMask(hProcess, dwProcessMask); SetThreadPriority(hThread, iCurThreadPriority); SetPriorityClass(hProcess, dwCurPriorityClass); // Then we calculate the time and clock differences dif = end - start; timedif = endtime - starttime; // And finally the frequency is the clock difference divided by the time // difference. F64 frequency = (F64)dif / (((F64)timedif) / freq); // At last we just return the frequency that is also stored in the call // member var uqwFrequency - converted to MHz return frequency / (F64)1000000; }
/// Launch the realm server extern int main(int argc, char** argv) { ///- Command line parsing char const* cfg_file = _REALMD_CONFIG; char const* options = ":c:s:"; ACE_Get_Opt cmd_opts(argc, argv, options); cmd_opts.long_option("version", 'v'); char serviceDaemonMode = '\0'; int option; while ((option = cmd_opts()) != EOF) { switch (option) { case 'c': cfg_file = cmd_opts.opt_arg(); break; case 'v': printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID)); return 0; case 's': { const char* mode = cmd_opts.opt_arg(); if (!strcmp(mode, "run")) serviceDaemonMode = 'r'; #ifdef WIN32 else if (!strcmp(mode, "install")) serviceDaemonMode = 'i'; else if (!strcmp(mode, "uninstall")) serviceDaemonMode = 'u'; #else else if (!strcmp(mode, "stop")) serviceDaemonMode = 's'; #endif else { sLog.outError("Runtime-Error: -%c unsupported argument %s", cmd_opts.opt_opt(), mode); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } break; } case ':': sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt()); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; default: sLog.outError("Runtime-Error: bad format of commandline arguments"); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } } #ifdef WIN32 // windows service command need execute before config read switch (serviceDaemonMode) { case 'i': if (WinServiceInstall()) sLog.outString("Installing service"); return 1; case 'u': if (WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; case 'r': WinServiceRun(); break; } #endif if (!sConfig.SetSource(cfg_file)) { sLog.outError("Could not find configuration file %s.", cfg_file); Log::WaitBeforeContinueIfNeed(); return 1; } #ifndef WIN32 // posix daemon commands need apply after config read switch (serviceDaemonMode) { case 'r': startDaemon(); break; case 's': stopDaemon(); break; } #endif sLog.Initialize(); sLog.outString("%s [realm-daemon]", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID)); sLog.outString("<Ctrl-C> to stop.\n"); sLog.outString("Using configuration file %s.", cfg_file); ///- Check the version of the configuration file uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); if (confVersion < _REALMDCONFVERSION) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: Your realmd.conf version indicates your conf file is out of date!"); sLog.outError(" Please check for updates, as your current default values may cause"); sLog.outError(" strange behavior."); sLog.outError("*****************************************************************************"); Log::WaitBeforeContinueIfNeed(); } DETAIL_LOG("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); if (SSLeay() < 0x009080bfL) { DETAIL_LOG("WARNING: Outdated version of OpenSSL lib. Logins to server may not work!"); DETAIL_LOG("WARNING: Minimal required version [OpenSSL 0.9.8k]"); } DETAIL_LOG("Using ACE: %s", ACE_VERSION); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog.outBasic("Max allowed open files is %d", ACE::max_handles()); /// realmd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog.outError("Cannot create PID file %s.\n", pidfile.c_str()); Log::WaitBeforeContinueIfNeed(); return 1; } sLog.outString("Daemon PID: %u\n", pid); } ///- Initialize the database connection if (!StartDB()) { Log::WaitBeforeContinueIfNeed(); return 1; } ///- Get the list of realms for the server sRealmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList.size() == 0) { sLog.outError("No valid realms specified."); Log::WaitBeforeContinueIfNeed(); return 1; } // cleanup query // set expired bans to inactive LoginDatabase.BeginTransaction(); LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.CommitTransaction(); ///- Launch the listening network socket ACE_Acceptor<AuthSocket, ACE_SOCK_Acceptor> acceptor; uint16 rmport = sConfig.GetIntDefault("RealmServerPort", DEFAULT_REALMSERVER_PORT); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog.outError("MaNGOS realmd can not bind to %s:%d", bind_ip.c_str(), rmport); Log::WaitBeforeContinueIfNeed(); return 1; } ///- Catch termination signals HookSignals(); ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess,&appAff,&sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); } else { if (SetProcessAffinityMask(hProcess,curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) sLog.outString("realmd process priority class set to HIGH"); else sLog.outError("Can't set realmd process priority class."); sLog.outString(); } } #endif //server has started up successfully => enable async DB requests LoginDatabase.AllowAsyncTransactions(); // maximum counter for next ping uint32 numLoops = (sConfig.GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; #ifndef WIN32 detachDaemon(); #endif ///- Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ((++loopCounter) == numLoops) { loopCounter = 0; DETAIL_LOG("Ping MySQL to keep connection alive"); LoginDatabase.Ping(); } #ifdef WIN32 if (m_ServiceStatus == 0) stopEvent = true; while (m_ServiceStatus == 2) Sleep(1000); #endif } ///- Wait for the delay thread to exit LoginDatabase.HaltDelayThread(); ///- Remove signal handling before leaving UnhookSignals(); sLog.outString("Halting process..."); return 0; }
void mainLoader(int, char*[], ServiceManager* services) { //dispatcher thread g_game.setGameState(GAME_STATE_STARTUP); srand((unsigned int)OTSYS_TIME()); #ifdef _WIN32 SetConsoleTitle(STATUS_SERVER_NAME); #endif std::cout << STATUS_SERVER_NAME << " - Version " << STATUS_SERVER_VERSION << std::endl; std::cout << "Compiled with: " << BOOST_COMPILER << std::endl; std::cout << "Compiled on " << __DATE__ << ' ' << __TIME__ << " for arch "; #if defined(__amd64__) || defined(_M_X64) std::cout << "x64" << std::endl; #elif defined(__i386__) || defined(_M_IX86) || defined(_X86_) std::cout << "x86" << std::endl; #elif defined(__arm__) std::cout << "ARM" << std::endl; #elif defined(__mips__) std::cout << "MIPS" << std::endl; #else std::cout << "unk" << std::endl; #endif std::cout << std::endl; std::cout << "A server developed by " << STATUS_SERVER_DEVELOPERS << std::endl; std::cout << "Visit our forum for updates, support, and resources: http://otland.net/." << std::endl; std::cout << std::endl; // read global config std::cout << ">> Loading config" << std::endl; if (!g_config.load()) { startupErrorMessage("Unable to load config.lua!"); return; } #ifdef _WIN32 std::string defaultPriority = asLowerCaseString(g_config.getString(ConfigManager::DEFAULT_PRIORITY)); if (defaultPriority == "realtime") { SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); } else if (defaultPriority == "high") { SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); } else if (defaultPriority == "higher") { SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); } #endif //set RSA key const char* p("14299623962416399520070177382898895550795403345466153217470516082934737582776038882967213386204600674145392845853859217990626450972452084065728686565928113"); const char* q("7630979195970404721891201847792002125535401292779123937207447574596692788513647179235335529307251350570728407373705564708871762033017096809910315212884101"); g_RSA.setKey(p, q); std::cout << ">> Establishing database connection..." << std::flush; Database* db = Database::getInstance(); if (!db->connect()) { startupErrorMessage("Failed to connect to database."); return; } std::cout << " MySQL " << Database::getClientVersion() << std::endl; // run database manager std::cout << ">> Running database manager" << std::endl; if (!DatabaseManager::isDatabaseSetup()) { startupErrorMessage("The database you have specified in config.lua is empty, please import the schema.sql to your database."); return; } DatabaseManager::updateDatabase(); if (g_config.getBoolean(ConfigManager::OPTIMIZE_DATABASE) && !DatabaseManager::optimizeTables()) { std::cout << "> No tables were optimized." << std::endl; } //load vocations std::cout << ">> Loading vocations" << std::endl; if (!g_vocations.loadFromXml()) { startupErrorMessage("Unable to load vocations!"); return; } // load item data std::cout << ">> Loading items" << std::endl; if (Item::items.loadFromOtb("data/items/items.otb")) { startupErrorMessage("Unable to load items (OTB)!"); return; } if (!Item::items.loadFromXml()) { startupErrorMessage("Unable to load items (XML)!"); return; } std::cout << ">> Loading script systems" << std::endl; if (!ScriptingManager::getInstance()->loadScriptSystems()) { startupErrorMessage("Failed to load script systems"); return; } std::cout << ">> Loading monsters" << std::endl; if (!g_monsters.loadFromXml()) { startupErrorMessage("Unable to load monsters!"); return; } std::cout << ">> Loading outfits" << std::endl; Outfits* outfits = Outfits::getInstance(); if (!outfits->loadFromXml()) { startupErrorMessage("Unable to load outfits!"); return; } std::cout << ">> Checking world type... " << std::flush; std::string worldType = asLowerCaseString(g_config.getString(ConfigManager::WORLD_TYPE)); if (worldType == "pvp") { g_game.setWorldType(WORLD_TYPE_PVP); } else if (worldType == "no-pvp") { g_game.setWorldType(WORLD_TYPE_NO_PVP); } else if (worldType == "pvp-enforced") { g_game.setWorldType(WORLD_TYPE_PVP_ENFORCED); } else { std::cout << std::endl; std::ostringstream ss; ss << "> ERROR: Unknown world type: " << g_config.getString(ConfigManager::WORLD_TYPE) << ", valid world types are: pvp, no-pvp and pvp-enforced."; startupErrorMessage(ss.str()); return; } std::cout << asUpperCaseString(worldType) << std::endl; std::cout << ">> Loading map" << std::endl; if (!g_game.loadMainMap(g_config.getString(ConfigManager::MAP_NAME))) { startupErrorMessage("Failed to load map"); return; } std::cout << ">> Initializing gamestate" << std::endl; g_game.setGameState(GAME_STATE_INIT); // Game client protocols services->add<ProtocolGame>(g_config.getNumber(ConfigManager::GAME_PORT)); services->add<ProtocolLogin>(g_config.getNumber(ConfigManager::LOGIN_PORT)); // OT protocols services->add<ProtocolStatus>(g_config.getNumber(ConfigManager::STATUS_PORT)); // Legacy protocols services->add<ProtocolOldLogin>(g_config.getNumber(ConfigManager::LOGIN_PORT)); services->add<ProtocolOldGame>(g_config.getNumber(ConfigManager::LOGIN_PORT)); Houses::getInstance().payHouses(); g_game.checkExpiredMarketOffers(); IOMarket::getInstance()->updateStatistics(); std::cout << ">> Loaded all modules, server starting up..." << std::endl; #ifndef WIN32 if (getuid() == 0 || geteuid() == 0) { std::cout << "> Warning: " << STATUS_SERVER_NAME << " has been executed as root user, please consider running it as a normal user." << std::endl; } #endif g_game.start(services); g_game.setGameState(GAME_STATE_NORMAL); g_loaderSignal.notify_all(); }
/* * main */ int main(int argc, char** argv) { fluid_settings_t* settings; int arg1 = 1; char buf[512]; int c, i; int interactive = 1; int midi_in = 1; fluid_player_t* player = NULL; fluid_midi_router_t* router = NULL; //fluid_sequencer_t* sequencer = NULL; fluid_midi_driver_t* mdriver = NULL; fluid_audio_driver_t* adriver = NULL; fluid_synth_t* synth = NULL; fluid_server_t* server = NULL; char* config_file = NULL; int audio_groups = 0; int audio_channels = 0; int with_server = 0; int dump = 0; int fast_render = 0; int connect_lash = 1; char *optchars = "a:C:c:dE:f:F:G:g:hijK:L:lm:nO:o:p:R:r:sT:Vvz:"; #ifdef LASH_ENABLED int enabled_lash = 0; /* set to TRUE if lash gets enabled */ fluid_lash_args_t *lash_args; lash_args = fluid_lash_extract_args (&argc, &argv); #endif print_welcome (); settings = new_fluid_settings(); #ifdef GETOPT_SUPPORT /* pre section of GETOPT supported argument handling */ opterr = 0; while (1) { int option_index = 0; static struct option long_options[] = { {"audio-bufcount", 1, 0, 'c'}, {"audio-bufsize", 1, 0, 'z'}, {"audio-channels", 1, 0, 'L'}, {"audio-driver", 1, 0, 'a'}, {"audio-file-endian", 1, 0, 'E'}, {"audio-file-format", 1, 0, 'O'}, {"audio-file-type", 1, 0, 'T'}, {"audio-groups", 1, 0, 'G'}, {"chorus", 1, 0, 'C'}, {"connect-jack-outputs", 0, 0, 'j'}, {"disable-lash", 0, 0, 'l'}, {"dump", 0, 0, 'd'}, {"fast-render", 1, 0, 'F'}, {"gain", 1, 0, 'g'}, {"help", 0, 0, 'h'}, {"load-config", 1, 0, 'f'}, {"midi-channels", 1, 0, 'K'}, {"midi-driver", 1, 0, 'm'}, {"no-midi-in", 0, 0, 'n'}, {"no-shell", 0, 0, 'i'}, {"option", 1, 0, 'o'}, {"portname", 1, 0, 'p'}, {"reverb", 1, 0, 'R'}, {"sample-rate", 1, 0, 'r'}, {"server", 0, 0, 's'}, {"verbose", 0, 0, 'v'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, optchars, long_options, &option_index); if (c == -1) { break; } #else /* "pre" section to non getopt argument handling */ for (i = 1; i < argc; i++) { char *optarg; /* Skip non switch arguments (assume they are file names) */ if ((argv[i][0] != '-') || (argv[i][1] == '\0')) break; c = argv[i][1]; optarg = strchr (optchars, c); /* find the option character in optchars */ if (optarg && optarg[1] == ':') /* colon follows if switch argument expected */ { if (++i >= argc) { printf ("Option -%c requires an argument\n", c); print_usage(); exit(0); } else { optarg = argv[i]; if (optarg[0] == '-') { printf ("Expected argument to option -%c found switch instead\n", c); print_usage(); exit(0); } } } else optarg = ""; #endif switch (c) { #ifdef GETOPT_SUPPORT case 0: /* shouldn't normally happen, a long option's flag is set to NULL */ printf ("option %s", long_options[option_index].name); if (optarg) { printf (" with arg %s", optarg); } printf ("\n"); break; #endif case 'a': if (FLUID_STRCMP (optarg, "help") == 0) { printf ("-a options (audio driver):\n "); show_settings_str_options (settings, "audio.driver"); exit (0); } else fluid_settings_setstr(settings, "audio.driver", optarg); break; case 'C': if ((optarg != NULL) && ((strcmp(optarg, "0") == 0) || (strcmp(optarg, "no") == 0))) { fluid_settings_setint(settings, "synth.chorus.active", FALSE); } else { fluid_settings_setint(settings, "synth.chorus.active", TRUE); } break; case 'c': fluid_settings_setint(settings, "audio.periods", atoi(optarg)); break; case 'd': fluid_settings_setint(settings, "synth.dump", TRUE); dump = 1; break; case 'E': if (FLUID_STRCMP (optarg, "help") == 0) { printf ("-E options (audio file byte order):\n "); show_settings_str_options (settings, "audio.file.endian"); #if LIBSNDFILE_SUPPORT printf ("\nauto: Use audio file format's default endian byte order\n" "cpu: Use CPU native byte order\n"); #else printf ("\nNOTE: No libsndfile support!\n" "cpu: Use CPU native byte order\n"); #endif exit (0); } else fluid_settings_setstr(settings, "audio.file.endian", optarg); break; case 'f': config_file = optarg; break; case 'F': fluid_settings_setstr(settings, "audio.file.name", optarg); fast_render = 1; break; case 'G': audio_groups = atoi(optarg); break; case 'g': fluid_settings_setnum(settings, "synth.gain", atof(optarg)); break; case 'h': print_help(settings); break; case 'i': interactive = 0; break; case 'j': fluid_settings_setint(settings, "audio.jack.autoconnect", 1); break; case 'K': fluid_settings_setint(settings, "synth.midi-channels", atoi(optarg)); break; case 'L': audio_channels = atoi(optarg); fluid_settings_setint(settings, "synth.audio-channels", audio_channels); break; case 'l': /* disable LASH */ connect_lash = 0; break; case 'm': if (FLUID_STRCMP (optarg, "help") == 0) { printf ("-m options (MIDI driver):\n "); show_settings_str_options (settings, "midi.driver"); exit (0); } else fluid_settings_setstr(settings, "midi.driver", optarg); break; case 'n': midi_in = 0; break; case 'O': if (FLUID_STRCMP (optarg, "help") == 0) { printf ("-O options (audio file format):\n "); show_settings_str_options (settings, "audio.file.format"); #if LIBSNDFILE_SUPPORT printf ("\ns8, s16, s24, s32: Signed PCM audio of the given number of bits\n"); printf ("float, double: 32 bit and 64 bit floating point audio\n"); printf ("u8: Unsigned 8 bit audio\n"); #else printf ("\nNOTE: No libsndfile support!\n"); #endif exit (0); } else fluid_settings_setstr(settings, "audio.file.format", optarg); break; case 'o': process_o_cmd_line_option(settings, optarg); break; case 'p' : fluid_settings_setstr(settings, "midi.portname", optarg); break; case 'R': if ((optarg != NULL) && ((strcmp(optarg, "0") == 0) || (strcmp(optarg, "no") == 0))) { fluid_settings_setint(settings, "synth.reverb.active", FALSE); } else { fluid_settings_setint(settings, "synth.reverb.active", TRUE); } break; case 'r': fluid_settings_setnum(settings, "synth.sample-rate", atof(optarg)); break; case 's': with_server = 1; break; case 'T': if (FLUID_STRCMP (optarg, "help") == 0) { printf ("-T options (audio file type):\n "); show_settings_str_options (settings, "audio.file.type"); #if LIBSNDFILE_SUPPORT printf ("\nauto: Determine type from file name extension, defaults to \"wav\"\n"); #else printf ("\nNOTE: No libsndfile support!\n"); #endif exit (0); } else fluid_settings_setstr(settings, "audio.file.type", optarg); break; case 'V': printf("FluidSynth %s\n", VERSION); exit (0); break; case 'v': fluid_settings_setint(settings, "synth.verbose", TRUE); break; case 'z': fluid_settings_setint(settings, "audio.period-size", atoi(optarg)); break; #ifdef GETOPT_SUPPORT case '?': printf ("Unknown option %c\n", optopt); print_usage(); exit(0); break; default: printf ("?? getopt returned character code 0%o ??\n", c); break; #else /* Non getopt default case */ default: printf ("Unknown switch '%c'\n", c); print_usage(); exit(0); break; #endif } /* end of switch statement */ } /* end of loop */ #ifdef GETOPT_SUPPORT arg1 = optind; #else arg1 = i; #endif /* option help requested? "-o help" */ if (option_help) { printf ("FluidSynth settings:\n"); fluid_settings_foreach (settings, settings, settings_foreach_func); exit (0); } #ifdef WIN32 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); #endif #ifdef LASH_ENABLED /* connect to the lash server */ if (connect_lash) { enabled_lash = fluid_lash_connect (lash_args); fluid_settings_setint (settings, "lash.enable", enabled_lash ? 1 : 0); } #endif /* The 'groups' setting is only relevant for LADSPA operation * If not given, set number groups to number of audio channels, because * they are the same (there is nothing between synth output and 'sound card') */ if ((audio_groups == 0) && (audio_channels != 0)) { audio_groups = audio_channels; } fluid_settings_setint(settings, "synth.audio-groups", audio_groups); if (fast_render) { midi_in = 0; interactive = 0; with_server = 0; fluid_settings_setstr(settings, "player.timing-source", "sample"); fluid_settings_setint(settings, "synth.parallel-render", 1); /* TODO: Fast_render should not need this, but currently do */ } /* create the synthesizer */ synth = new_fluid_synth(settings); if (synth == NULL) { fprintf(stderr, "Failed to create the synthesizer\n"); exit(-1); } cmd_handler = new_fluid_cmd_handler(synth); if (cmd_handler == NULL) { fprintf(stderr, "Failed to create the command handler\n"); goto cleanup; } /* load the soundfonts (check that all non options are SoundFont or MIDI files) */ for (i = arg1; i < argc; i++) { if (fluid_is_soundfont(argv[i])) { if (fluid_synth_sfload(synth, argv[i], 1) == -1) fprintf(stderr, "Failed to load the SoundFont %s\n", argv[i]); } else if (!fluid_is_midifile(argv[i])) fprintf (stderr, "Parameter '%s' not a SoundFont or MIDI file or error occurred identifying it.\n", argv[i]); } #ifdef HAVE_SIGNAL_H /* signal(SIGINT, handle_signal); */ #endif /* start the synthesis thread */ if (!fast_render) { adriver = new_fluid_audio_driver(settings, synth); if (adriver == NULL) { fprintf(stderr, "Failed to create the audio driver\n"); goto cleanup; } } /* start the midi router and link it to the synth */ #if WITH_MIDI if (midi_in) { /* In dump mode, text output is generated for events going into and out of the router. * The example dump functions are put into the chain before and after the router.. */ //sequencer = new_fluid_sequencer2(0); router = new_fluid_midi_router( settings, dump ? fluid_midi_dump_postrouter : fluid_synth_handle_midi_event, (void*)synth); if (router == NULL) { fprintf(stderr, "Failed to create the MIDI input router; no MIDI input\n" "will be available. You can access the synthesizer \n" "through the console.\n"); } else { fluid_synth_set_midi_router(synth, router); /* Fixme, needed for command handler */ // fluid_sequencer_register_fluidsynth(sequencer, synth); mdriver = new_fluid_midi_driver( settings, dump ? fluid_midi_dump_prerouter : fluid_midi_router_handle_midi_event, (void*) router); if (mdriver == NULL) { fprintf(stderr, "Failed to create the MIDI thread; no MIDI input\n" "will be available. You can access the synthesizer \n" "through the console.\n"); } } } #endif /* run commands specified in config file */ if (config_file != NULL) { fluid_source(cmd_handler, config_file); } else if (fluid_get_userconf(buf, 512) != NULL) { fluid_source(cmd_handler, buf); } else if (fluid_get_sysconf(buf, 512) != NULL) { fluid_source(cmd_handler, buf); } /* play the midi files, if any */ for (i = arg1; i < argc; i++) { if ((argv[i][0] != '-') && fluid_is_midifile(argv[i])) { if (player == NULL) { player = new_fluid_player(synth); if (player == NULL) { fprintf(stderr, "Failed to create the midifile player.\n" "Continuing without a player.\n"); break; } } fluid_player_add(player, argv[i]); } } if (player != NULL) { fluid_player_play(player); } /* run the server, if requested */ #if !defined(MACINTOSH) if (with_server) { server = new_fluid_server(settings, newclient, synth); if (server == NULL) { fprintf(stderr, "Failed to create the server.\n" "Continuing without it.\n"); } } #endif #ifdef LASH_ENABLED if (enabled_lash) fluid_lash_create_thread (synth); #endif /* run the shell */ if (interactive) { printf ("Type 'help' for help topics.\n\n"); /* In dump mode we set the prompt to "". The UI cannot easily * handle lines, which don't end with CR. Changing the prompt * cannot be done through a command, because the current shell * does not handle empty arguments. The ordinary case is dump == * 0. */ fluid_settings_setstr(settings, "shell.prompt", dump ? "" : "> "); fluid_usershell(settings, cmd_handler); } if (fast_render) { char *filename; if (player == NULL) { fprintf(stderr, "No midi file specified!\n"); goto cleanup; } fluid_settings_dupstr (settings, "audio.file.name", &filename); printf ("Rendering audio to file '%s'..\n", filename); if (filename) FLUID_FREE (filename); fast_render_loop(settings, synth, player); } cleanup: #if !defined(MACINTOSH) && !defined(WIN32) if (server != NULL) { /* if the user typed 'quit' in the shell, kill the server */ if (!interactive) { fluid_server_join(server); } delete_fluid_server(server); } #endif if (cmd_handler != NULL) { delete_fluid_cmd_handler(cmd_handler); } if (player != NULL) { /* if the user typed 'quit' in the shell, stop the player */ if (interactive) { fluid_player_stop(player); } if (adriver != NULL || !fluid_settings_str_equal(settings, "player.timing-source", "sample")) { /* if no audio driver and sample timers are used, nothing makes the player advance */ fluid_player_join(player); } delete_fluid_player(player); } if (router) { #if WITH_MIDI if (mdriver) { delete_fluid_midi_driver(mdriver); } delete_fluid_midi_router(router); #endif } /*if (sequencer) { delete_fluid_sequencer(sequencer); }*/ if (adriver) { delete_fluid_audio_driver(adriver); } if (synth) { delete_fluid_synth(synth); } if (settings) { delete_fluid_settings(settings); } return 0; } static fluid_cmd_handler_t* newclient(void* data, char* addr) { fluid_synth_t* synth = (fluid_synth_t*) data; return new_fluid_cmd_handler(synth); }
int GoProcessing(const tagCMDL & cmdl) { int mode = cmdl.mode; CreateDirectory(cmdl.temppath, NULL); wchar_t tempfile[MAX_PATH]; if( lstrlen(cmdl.temppath) == 0 ) { // кодируем в файл по умолчанию StringCchCopy(tempfile, MAX_PATH, cmdl.outputfilename); }else { StringCchCopy(tempfile, MAX_PATH, cmdl.temppath); if( tempfile[ lstrlen(tempfile) -1 ] != L'\\') StringCchCat(tempfile, MAX_PATH, L"\\"); StringCchCat(tempfile, MAX_PATH, PathFindFileName(cmdl.outputfilename)); } HWND fwwnd = FindWindow(wndclassnameW, NULL); if(fwwnd == NULL) return 4; int pos = -1; while( pos < 0 ) { if( !isProcessExist() ) // проверяем мьютекс return 0; // преждевременный выход pos = (int)SendMessage(fwwnd, MES_ONNEWTHREAD, 0, 0); if( pos >= 0 ) break; Sleep(200); } ////////////////////////////////////////////////////////////////////////// // название файла if( !SendFileName(fwwnd, cmdl.outputfilename, pos) ) return 0; // выход, лажа. ////////////////////////////////////////////////////////////////////////// // читаем файл из stdin и создаём временный wav-файл if( !ReadAndCreateFile(tempfile) ) return 5; DWORD len = CorrectHeader(tempfile); ////////////////////////////////////////////////////////////////////////// // сообщаем длинну трэка: sec * 4 * 44100 if( !MySendMessage(fwwnd, MES_SENDLENGTH, pos, len) ) { DeleteFile(tempfile); return 0; } if( len ) { UINT newpriority = (UINT)SendMessage(fwwnd, MES_GETPRIORITY, 0, 0); SetPriorityClass(GetCurrentProcess(), newpriority ); if( !RunProcessing(tempfile, mode, fwwnd, pos) ) { DeleteFile(tempfile); return 0; // пытаемся безболезненно свалить :D } } DeleteFile(tempfile); if( !TrimFile(cmdl.outputfilename, pos) ) return 6; return 0; }
void Startup(LPSTR lpCmdLine) { char cmd[512],name[256]; BOOL bModifyOptions = FALSE; strcpy(cmd,lpCmdLine); strlwr(cmd); if (strstr(cmd,"-?") || strstr(cmd,"-h")) { Help(); return; } if (strstr(cmd,"-f")==0) { Help(); return; } if (strstr(cmd,"-o")) bModifyOptions = TRUE; if (strstr(cmd,"-gi")) b_radiosity = TRUE; if (strstr(cmd,"-noise")) b_noise = TRUE; if (strstr(cmd,"-nosun")) b_nosun = TRUE; // Give a LOG-thread a chance to startup //_set_sbh_threshold(1920); InitCommonControls (); thread_spawn (logThread, "log-update", 1024*1024,0); Sleep (150); // Faster FPU SetPriorityClass (GetCurrentProcess(),NORMAL_PRIORITY_CLASS); /* u32 dwMin = 1800*(1024*1024); u32 dwMax = 1900*(1024*1024); if (0==SetProcessWorkingSetSize(GetCurrentProcess(),dwMin,dwMax)) { clMsg("*** Failed to expand working set"); }; */ // Load project name[0]=0; sscanf(strstr(cmd,"-f")+2,"%s",name); string256 prjName; FS.update_path (prjName,"$game_levels$",strconcat(prjName,name,"\\build.prj")); string256 phaseName; Phase (strconcat(phaseName,"Reading project [",name,"]...")); string256 inf; extern HWND logWindow; IReader* F = FS.r_open(prjName); if (NULL==F){ sprintf (inf,"Build failed!\nCan't find level: '%s'",name); clMsg (inf); MessageBox (logWindow,inf,"Error!",MB_OK|MB_ICONERROR); return; } // Version u32 version; F->r_chunk (EB_Version,&version); clMsg ("version: %d",version); R_ASSERT(XRCL_CURRENT_VERSION==version); // Header b_params Params; F->r_chunk (EB_Parameters,&Params); // Show options if needed if (bModifyOptions) { Phase ("Project options..."); HMODULE L = LoadLibrary ("xrLC_Options.dll"); void* P = GetProcAddress (L,"_frmScenePropertiesRun"); R_ASSERT (P); xrOptions* O = (xrOptions*)P; int R = O(&Params,version,false); FreeLibrary (L); if (R==2) { ExitProcess(0); } } // Conversion Phase ("Converting data structures..."); pBuild = xr_new<CBuild>(); pBuild->Load (Params,*F); xr_delete (F); // Call for builder string256 lfn; CTimer dwStartupTime; dwStartupTime.Start(); FS.update_path (lfn,_game_levels_,name); pBuild->Run (lfn); xr_delete (pBuild); // Show statistic extern std::string make_time(u32 sec); u32 dwEndTime = dwStartupTime.GetElapsed_ms(); sprintf (inf,"Time elapsed: %s",make_time(dwEndTime/1000).c_str()); clMsg ("Build succesful!\n%s",inf); MessageBox (logWindow,inf,"Congratulation!",MB_OK|MB_ICONINFORMATION); // Close log bClose = TRUE; Sleep (500); }
void CDoWaveConvert::OnButton1() //------------------------------ { //XXXih: onbutton1 : - ( FILE *f; WAVEFILEHEADER header; WAVEDATAHEADER datahdr, fmthdr; MSG msg; uint8_t buffer[WAVECONVERTBUFSIZE]; CHAR s[80]; HWND progress = ::GetDlgItem(m_hWnd, IDC_PROGRESS1); UINT ok = IDOK, pos; ULONGLONG ullSamples, ullMaxSamples; uint32_t dwDataOffset; LONG lMax = 256; if ((!m_pSndFile) || (!m_lpszFileName) || ((f = fopen(m_lpszFileName, "w+b")) == NULL)) { ::AfxMessageBox("Could not open file for writing. Is it open in another application?"); EndDialog(IDCANCEL); return; } SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); int oldVol = m_pSndFile->GetMasterVolume(); int nOldRepeat = m_pSndFile->GetRepeatCount(); module_renderer::deprecated_global_sound_setup_bitmask |= SNDMIX_DIRECTTODISK; if ((!m_dwFileLimit) && (!m_dwSongLimit)) module_renderer::deprecated_global_sound_setup_bitmask |= SNDMIX_NOBACKWARDJUMPS; module_renderer::deprecated_global_mixing_freq = m_pWaveFormat->nSamplesPerSec; module_renderer::deprecated_global_bits_per_sample = m_pWaveFormat->wBitsPerSample; module_renderer::deprecated_global_channels = m_pWaveFormat->nChannels; // -> CODE#0024 // -> DESC="wav export update" // if ((m_bNormalize) && (m_pWaveFormat->wBitsPerSample <= 16)) if ((m_bNormalize) && (m_pWaveFormat->wBitsPerSample <= 24)) // -! NEW_FEATURE#0024 { m_pSndFile->deprecated_global_bits_per_sample = 24; if (oldVol > 128) m_pSndFile->SetMasterVolume(128); } else { m_bNormalize = false; } m_pSndFile->ResetChannels(); module_renderer::InitPlayer(TRUE); m_pSndFile->SetRepeatCount(0); if ((!m_dwFileLimit) || (m_dwFileLimit > 2047*1024)) m_dwFileLimit = 2047*1024; // 2GB m_dwFileLimit <<= 10; // File Header header.id_RIFF = IFFID_RIFF; header.filesize = sizeof(WAVEFILEHEADER) - 8; header.id_WAVE = IFFID_WAVE; // Wave Format Header fmthdr.id_data = IFFID_fmt; fmthdr.length = 16; if (m_pWaveFormat->cbSize) fmthdr.length += 2 + m_pWaveFormat->cbSize; header.filesize += sizeof(fmthdr) + fmthdr.length; // Data header datahdr.id_data = IFFID_data; datahdr.length = 0; header.filesize += sizeof(datahdr); // Writing Headers fwrite(&header, 1, sizeof(header), f); fwrite(&fmthdr, 1, sizeof(fmthdr), f); fwrite(m_pWaveFormat, 1, fmthdr.length, f); fwrite(&datahdr, 1, sizeof(datahdr), f); dwDataOffset = ftell(f); pos = 0; ullSamples = 0; ullMaxSamples = m_dwFileLimit / (m_pWaveFormat->nChannels * m_pWaveFormat->wBitsPerSample / 8); if (m_dwSongLimit) { ULONGLONG l = (ULONGLONG)m_dwSongLimit * m_pWaveFormat->nSamplesPerSec; if (l < ullMaxSamples) ullMaxSamples = l; } // calculate maximum samples ULONGLONG bad_max = ullMaxSamples; ULONGLONG l = ((ULONGLONG)m_pSndFile->GetSongTime()) * m_pWaveFormat->nSamplesPerSec; if (m_nMaxPatterns > 0) { uint32_t dwOrds = m_pSndFile->Order.GetLengthFirstEmpty(); if ((m_nMaxPatterns < dwOrds) && (dwOrds > 0)) l = (l*m_nMaxPatterns) / dwOrds; } if (l < bad_max) bad_max = l; if (progress != NULL) { ::SendMessage(progress, PBM_SETRANGE, 0, MAKELPARAM(0, (uint32_t)(bad_max >> 14))); }
void OBS::Start() { if(bRunning) return; OSEnterMutex (hStartupShutdownMutex); scenesConfig.Save(); //------------------------------------------------------------- fps = AppConfig->GetInt(TEXT("Video"), TEXT("FPS"), 30); frameTime = 1000/fps; //------------------------------------------------------------- if(!bLoggedSystemStats) { LogSystemStats(); bLoggedSystemStats = TRUE; } //------------------------------------------------------------- retryHookTest: bool alreadyWarnedAboutModules = false; if (OSIncompatibleModulesLoaded()) { Log(TEXT("Incompatible modules (pre-D3D) detected.")); int ret = MessageBox(hwndMain, Str("IncompatibleModules"), NULL, MB_ICONERROR | MB_ABORTRETRYIGNORE); if (ret == IDABORT) { OSLeaveMutex (hStartupShutdownMutex); return; } else if (ret == IDRETRY) { goto retryHookTest; } alreadyWarnedAboutModules = true; } String strPatchesError; if (OSIncompatiblePatchesLoaded(strPatchesError)) { OSLeaveMutex (hStartupShutdownMutex); MessageBox(hwndMain, strPatchesError.Array(), NULL, MB_ICONERROR); Log(TEXT("Incompatible patches detected.")); return; } //------------------------------------------------------------- String processPriority = AppConfig->GetString(TEXT("General"), TEXT("Priority"), TEXT("Normal")); if (!scmp(processPriority, TEXT("Idle"))) SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); else if (!scmp(processPriority, TEXT("Above Normal"))) SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); else if (!scmp(processPriority, TEXT("High"))) SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); int networkMode = AppConfig->GetInt(TEXT("Publish"), TEXT("Mode"), 2); DWORD delayTime = (DWORD)AppConfig->GetInt(TEXT("Publish"), TEXT("Delay")); String strError; bFirstConnect = !bReconnecting; if(bTestStream) network = CreateNullNetwork(); else { switch(networkMode) { case 0: network = (delayTime > 0) ? CreateDelayedPublisher(delayTime) : CreateRTMPPublisher(); break; case 1: network = CreateNullNetwork(); break; } } if(!network) { OSLeaveMutex (hStartupShutdownMutex); if(!bReconnecting) MessageBox(hwndMain, strError, NULL, MB_ICONERROR); else DialogBox(hinstMain, MAKEINTRESOURCE(IDD_RECONNECTING), hwndMain, OBS::ReconnectDialogProc); return; } bReconnecting = false; //------------------------------------------------------------- Log(TEXT("=====Stream Start: %s==============================================="), CurrentDateTimeString().Array()); //------------------------------------------------------------- int monitorID = AppConfig->GetInt(TEXT("Video"), TEXT("Monitor")); if(monitorID >= (int)monitors.Num()) monitorID = 0; RECT &screenRect = monitors[monitorID].rect; int defCX = screenRect.right - screenRect.left; int defCY = screenRect.bottom - screenRect.top; downscaleType = AppConfig->GetInt(TEXT("Video"), TEXT("Filter"), 0); downscale = AppConfig->GetFloat(TEXT("Video"), TEXT("Downscale"), 1.0f); baseCX = AppConfig->GetInt(TEXT("Video"), TEXT("BaseWidth"), defCX); baseCY = AppConfig->GetInt(TEXT("Video"), TEXT("BaseHeight"), defCY); baseCX = MIN(MAX(baseCX, 128), 4096); baseCY = MIN(MAX(baseCY, 128), 4096); scaleCX = UINT(double(baseCX) / double(downscale)); scaleCY = UINT(double(baseCY) / double(downscale)); //align width to 128bit for fast SSE YUV4:2:0 conversion outputCX = scaleCX & 0xFFFFFFFC; outputCY = scaleCY & 0xFFFFFFFE; bUseMultithreadedOptimizations = AppConfig->GetInt(TEXT("General"), TEXT("UseMultithreadedOptimizations"), TRUE) != 0; Log(TEXT(" Multithreaded optimizations: %s"), (CTSTR)(bUseMultithreadedOptimizations ? TEXT("On") : TEXT("Off"))); //------------------------------------------------------------------ Log(TEXT(" Base resolution: %ux%u"), baseCX, baseCY); Log(TEXT(" Output resolution: %ux%u"), outputCX, outputCY); Log(TEXT("------------------------------------------")); //------------------------------------------------------------------ GS = new D3D10System; GS->Init(); //Thanks to ASUS OSD hooking the goddamn user mode driver framework (!!!!), we have to re-check for dangerous //hooks after initializing D3D. retryHookTestV2: if (!alreadyWarnedAboutModules) { if (OSIncompatibleModulesLoaded()) { Log(TEXT("Incompatible modules (post-D3D) detected.")); int ret = MessageBox(hwndMain, Str("IncompatibleModules"), NULL, MB_ICONERROR | MB_ABORTRETRYIGNORE); if (ret == IDABORT) { //FIXME: really need a better way to abort startup than this... delete network; delete GS; OSLeaveMutex (hStartupShutdownMutex); return; } else if (ret == IDRETRY) { goto retryHookTestV2; } } } //------------------------------------------------------------- mainVertexShader = CreateVertexShaderFromFile(TEXT("shaders/DrawTexture.vShader")); mainPixelShader = CreatePixelShaderFromFile(TEXT("shaders/DrawTexture.pShader")); solidVertexShader = CreateVertexShaderFromFile(TEXT("shaders/DrawSolid.vShader")); solidPixelShader = CreatePixelShaderFromFile(TEXT("shaders/DrawSolid.pShader")); if(!mainVertexShader || !mainPixelShader) CrashError(TEXT("Unable to load DrawTexture shaders")); if(!solidVertexShader || !solidPixelShader) CrashError(TEXT("Unable to load DrawSolid shaders")); //------------------------------------------------------------------ CTSTR lpShader; if(CloseFloat(downscale, 1.0)) lpShader = TEXT("shaders/DrawYUVTexture.pShader"); else if(downscale < 2.01) { switch(downscaleType) { case 0: lpShader = TEXT("shaders/DownscaleBilinear1YUV.pShader"); break; case 1: lpShader = TEXT("shaders/DownscaleBicubicYUV.pShader"); break; case 2: lpShader = TEXT("shaders/DownscaleLanczos6tapYUV.pShader"); break; } } else if(downscale < 3.01) lpShader = TEXT("shaders/DownscaleBilinear9YUV.pShader"); else CrashError(TEXT("Invalid downscale value (must be either 1.0, 1.5, 2.0, 2.25, or 3.0)")); yuvScalePixelShader = CreatePixelShaderFromFile(lpShader); if (!yuvScalePixelShader) CrashError(TEXT("Unable to create shader from file %s"), lpShader); //------------------------------------------------------------- for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { mainRenderTextures[i] = CreateRenderTarget(baseCX, baseCY, GS_BGRA, FALSE); yuvRenderTextures[i] = CreateRenderTarget(outputCX, outputCY, GS_BGRA, FALSE); } //------------------------------------------------------------- D3D10_TEXTURE2D_DESC td; zero(&td, sizeof(td)); td.Width = outputCX; td.Height = outputCY; td.Format = DXGI_FORMAT_B8G8R8A8_UNORM; td.MipLevels = 1; td.ArraySize = 1; td.SampleDesc.Count = 1; td.ArraySize = 1; td.Usage = D3D10_USAGE_STAGING; td.CPUAccessFlags = D3D10_CPU_ACCESS_READ; for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { HRESULT err = GetD3D()->CreateTexture2D(&td, NULL, ©Textures[i]); if(FAILED(err)) { CrashError(TEXT("Unable to create copy texture")); //todo - better error handling } } //------------------------------------------------------------- AudioDeviceList playbackDevices; GetAudioDevices(playbackDevices, ADT_PLAYBACK); String strPlaybackDevice = AppConfig->GetString(TEXT("Audio"), TEXT("PlaybackDevice"), TEXT("Default")); if(strPlaybackDevice.IsEmpty() || !playbackDevices.HasID(strPlaybackDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("PlaybackDevice"), TEXT("Default")); strPlaybackDevice = TEXT("Default"); } Log(TEXT("Playback device %s"), strPlaybackDevice.Array()); playbackDevices.FreeData(); desktopAudio = CreateAudioSource(false, strPlaybackDevice); if(!desktopAudio) { CrashError(TEXT("Cannot initialize desktop audio sound, more info in the log file.")); } AudioDeviceList audioDevices; GetAudioDevices(audioDevices, ADT_RECORDING); String strDevice = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), NULL); if(strDevice.IsEmpty() || !audioDevices.HasID(strDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("Device"), TEXT("Disable")); strDevice = TEXT("Disable"); } audioDevices.FreeData(); String strDefaultMic; bool bHasDefault = GetDefaultMicID(strDefaultMic); if(strDevice.CompareI(TEXT("Disable"))) EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE); else { bool bUseDefault = strDevice.CompareI(TEXT("Default")) != 0; if(!bUseDefault || bHasDefault) { if(bUseDefault) strDevice = strDefaultMic; micAudio = CreateAudioSource(true, strDevice); if(!micAudio) MessageBox(hwndMain, Str("MicrophoneFailure"), NULL, 0); else micAudio->SetTimeOffset(AppConfig->GetInt(TEXT("Audio"), TEXT("MicTimeOffset"), 0)); EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), micAudio != NULL); } else EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), FALSE); } //------------------------------------------------------------- bool bDisableEncoding = false; if (bTestStream) bDisableEncoding = GlobalConfig->GetInt(TEXT("General"), TEXT("DisablePreviewEncoding"), false) != 0; //------------------------------------------------------------- UINT bitRate = (UINT)AppConfig->GetInt(TEXT("Audio Encoding"), TEXT("Bitrate"), 96); String strEncoder = AppConfig->GetString(TEXT("Audio Encoding"), TEXT("Codec"), TEXT("AAC")); if (bDisableEncoding) audioEncoder = CreateNullAudioEncoder(); else #ifdef USE_AAC if(strEncoder.CompareI(TEXT("AAC")))// && OSGetVersion() >= 7) audioEncoder = CreateAACEncoder(bitRate); else #endif audioEncoder = CreateMP3Encoder(bitRate); //------------------------------------------------------------- desktopVol = AppConfig->GetFloat(TEXT("Audio"), TEXT("DesktopVolume"), 1.0f); micVol = AppConfig->GetFloat(TEXT("Audio"), TEXT("MicVolume"), 1.0f); //------------------------------------------------------------- bRunning = true; if(sceneElement) { scene = CreateScene(sceneElement->GetString(TEXT("class")), sceneElement->GetElement(TEXT("data"))); XElement *sources = sceneElement->GetElement(TEXT("sources")); if(sources) { UINT numSources = sources->NumElements(); for(UINT i=0; i<numSources; i++) { SceneItem *item = scene->AddImageSource(sources->GetElementByID(i)); if(item) { if(ListView_GetItemState(GetDlgItem(hwndMain, ID_SOURCES), i, LVIS_SELECTED) > 0) item->Select(true); } } } scene->BeginScene(); } if(scene && scene->HasMissingSources()) MessageBox(hwndMain, Str("Scene.MissingSources"), NULL, 0); //------------------------------------------------------------- int maxBitRate = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("MaxBitrate"), 1000); int bufferSize = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("BufferSize"), 1000); int quality = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("Quality"), 8); String preset = AppConfig->GetString(TEXT("Video Encoding"), TEXT("Preset"), TEXT("veryfast")); bUsing444 = AppConfig->GetInt (TEXT("Video Encoding"), TEXT("Use444"), 0) != 0; bDupeFrames = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("DupeFrames"), 0) != 0; if(bUsing444) bDupeFrames = bUseCFR = false; else { bUseCFR = AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseCFR"), 0) != 0; if(bUseCFR) bDupeFrames = true; } //------------------------------------------------------------- bWriteToFile = networkMode == 1 || AppConfig->GetInt(TEXT("Publish"), TEXT("SaveToFile")) != 0; String strOutputFile = AppConfig->GetString(TEXT("Publish"), TEXT("SavePath")); strOutputFile.FindReplace(TEXT("\\"), TEXT("/")); if (bWriteToFile) { OSFindData ofd; HANDLE hFind = NULL; bool bUseDateTimeName = true; if(hFind = OSFindFirstFile(strOutputFile, ofd)) { String strFileExtension = GetPathExtension(strOutputFile); String strFileWithoutExtension = GetPathWithoutExtension(strOutputFile); if(strFileExtension.IsValid() && !ofd.bDirectory) { String strNewFilePath; UINT curFile = 0; do { strNewFilePath.Clear() << strFileWithoutExtension << TEXT(" (") << FormattedString(TEXT("%02u"), ++curFile) << TEXT(").") << strFileExtension; } while(OSFileExists(strNewFilePath)); strOutputFile = strNewFilePath; bUseDateTimeName = false; } if(ofd.bDirectory) strOutputFile.AppendChar('/'); OSFindClose(hFind); } if(bUseDateTimeName) { String strFileName = GetPathFileName(strOutputFile); if(!strFileName.IsValid() || !IsSafeFilename(strFileName)) { SYSTEMTIME st; GetLocalTime(&st); String strDirectory = GetPathDirectory(strOutputFile); strOutputFile = FormattedString(TEXT("%s/%u-%02u-%02u-%02u%02u-%02u.mp4"), strDirectory.Array(), st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond); } } } //------------------------------------------------------------- bufferingTime = GlobalConfig->GetInt(TEXT("General"), TEXT("SceneBufferingTime"), 400); //------------------------------------------------------------- bForceMicMono = AppConfig->GetInt(TEXT("Audio"), TEXT("ForceMicMono")) != 0; bRecievedFirstAudioFrame = false; //hRequestAudioEvent = CreateSemaphore(NULL, 0, 0x7FFFFFFFL, NULL); hSoundDataMutex = OSCreateMutex(); hSoundThread = OSCreateThread((XTHREAD)OBS::MainAudioThread, NULL); //------------------------------------------------------------- StartBlankSoundPlayback(strPlaybackDevice); //------------------------------------------------------------- ctsOffset = 0; videoEncoder = nullptr; if (bDisableEncoding) videoEncoder = CreateNullVideoEncoder(); else if(AppConfig->GetInt(TEXT("Video Encoding"), TEXT("UseQSV")) != 0) videoEncoder = CreateQSVEncoder(fps, outputCX, outputCY, quality, preset, bUsing444, maxBitRate, bufferSize, bUseCFR, bDupeFrames); if(!videoEncoder) videoEncoder = CreateX264Encoder(fps, outputCX, outputCY, quality, preset, bUsing444, maxBitRate, bufferSize, bUseCFR, bDupeFrames); //------------------------------------------------------------- // Ensure that the render frame is properly sized ResizeRenderFrame(true); //------------------------------------------------------------- if(!bTestStream && bWriteToFile && strOutputFile.IsValid()) { String strFileExtension = GetPathExtension(strOutputFile); if(strFileExtension.CompareI(TEXT("flv"))) fileStream = CreateFLVFileStream(strOutputFile); else if(strFileExtension.CompareI(TEXT("mp4"))) fileStream = CreateMP4FileStream(strOutputFile); if(!fileStream) { Log(TEXT("Warning - OBSCapture::Start: Unable to create the file stream. Check the file path in Broadcast Settings.")); MessageBox(hwndMain, Str("Capture.Start.FileStream.Warning"), Str("Capture.Start.FileStream.WarningCaption"), MB_OK | MB_ICONWARNING); } } //------------------------------------------------------------- hMainThread = OSCreateThread((XTHREAD)OBS::MainCaptureThread, NULL); if(bTestStream) { EnableWindow(GetDlgItem(hwndMain, ID_STARTSTOP), FALSE); SetWindowText(GetDlgItem(hwndMain, ID_TESTSTREAM), Str("MainWindow.StopTest")); } else { EnableWindow(GetDlgItem(hwndMain, ID_TESTSTREAM), FALSE); SetWindowText(GetDlgItem(hwndMain, ID_STARTSTOP), Str("MainWindow.StopStream")); } EnableWindow(GetDlgItem(hwndMain, ID_SCENEEDITOR), TRUE); //------------------------------------------------------------- ReportStartStreamTrigger(); SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 0, 0, 0); SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_AWAYMODE_REQUIRED | ES_DISPLAY_REQUIRED); UpdateRenderViewMessage(); //update notification icon to reflect current status UpdateNotificationAreaIcon(); OSLeaveMutex (hStartupShutdownMutex); }
void OBS::Stop() { if(!bRunning) return; OSEnterMutex(hStartupShutdownMutex); //we only want the capture thread to stop first, so we can ensure all packets are flushed bShutdownMainThread = true; if(hMainThread) { OSTerminateThread(hMainThread, 60000); hMainThread = NULL; } bShutdownMainThread = false; bRunning = false; ReportStopStreamTrigger(); for(UINT i=0; i<globalSources.Num(); i++) globalSources[i].source->EndScene(); if(scene) scene->EndScene(); //------------------------------------------------------------- if(hSoundThread) { //ReleaseSemaphore(hRequestAudioEvent, 1, NULL); OSTerminateThread(hSoundThread, 20000); } //if(hRequestAudioEvent) // CloseHandle(hRequestAudioEvent); if(hSoundDataMutex) OSCloseMutex(hSoundDataMutex); hSoundThread = NULL; //hRequestAudioEvent = NULL; hSoundDataMutex = NULL; //------------------------------------------------------------- StopBlankSoundPlayback(); //------------------------------------------------------------- delete network; network = NULL; delete fileStream; fileStream = NULL; delete micAudio; micAudio = NULL; delete desktopAudio; desktopAudio = NULL; delete audioEncoder; audioEncoder = NULL; delete videoEncoder; videoEncoder = NULL; //------------------------------------------------------------- for(UINT i=0; i<pendingAudioFrames.Num(); i++) pendingAudioFrames[i].audioData.Clear(); pendingAudioFrames.Clear(); //------------------------------------------------------------- if(GS) GS->UnloadAllData(); //------------------------------------------------------------- delete scene; scene = NULL; for(UINT i=0; i<globalSources.Num(); i++) globalSources[i].FreeData(); globalSources.Clear(); //------------------------------------------------------------- for(UINT i=0; i<auxAudioSources.Num(); i++) delete auxAudioSources[i]; auxAudioSources.Clear(); //------------------------------------------------------------- for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { delete mainRenderTextures[i]; delete yuvRenderTextures[i]; mainRenderTextures[i] = NULL; yuvRenderTextures[i] = NULL; } for(UINT i=0; i<NUM_RENDER_BUFFERS; i++) { SafeRelease(copyTextures[i]); } delete transitionTexture; transitionTexture = NULL; //------------------------------------------------------------- delete mainVertexShader; delete mainPixelShader; delete yuvScalePixelShader; delete solidVertexShader; delete solidPixelShader; mainVertexShader = NULL; mainPixelShader = NULL; yuvScalePixelShader = NULL; solidVertexShader = NULL; solidPixelShader = NULL; //------------------------------------------------------------- delete GS; GS = NULL; //------------------------------------------------------------- ResizeRenderFrame(false); RedrawWindow(hwndRenderFrame, NULL, NULL, RDW_INVALIDATE|RDW_UPDATENOW); //------------------------------------------------------------- AudioDeviceList audioDevices; GetAudioDevices(audioDevices, ADT_RECORDING); String strDevice = AppConfig->GetString(TEXT("Audio"), TEXT("Device"), NULL); if(strDevice.IsEmpty() || !audioDevices.HasID(strDevice)) { AppConfig->SetString(TEXT("Audio"), TEXT("Device"), TEXT("Disable")); strDevice = TEXT("Disable"); } audioDevices.FreeData(); EnableWindow(GetDlgItem(hwndMain, ID_MICVOLUME), !strDevice.CompareI(TEXT("Disable"))); //------------------------------------------------------------- ClearStreamInfo(); DumpProfileData(); FreeProfileData(); Log(TEXT("=====Stream End: %s================================================="), CurrentDateTimeString().Array()); //update notification icon to reflect current status UpdateNotificationAreaIcon(); SetWindowText(GetDlgItem(hwndMain, ID_TESTSTREAM), Str("MainWindow.TestStream")); EnableWindow(GetDlgItem(hwndMain, ID_STARTSTOP), TRUE); SetWindowText(GetDlgItem(hwndMain, ID_STARTSTOP), Str("MainWindow.StartStream")); EnableWindow(GetDlgItem(hwndMain, ID_TESTSTREAM), TRUE); bEditMode = false; SendMessage(GetDlgItem(hwndMain, ID_SCENEEDITOR), BM_SETCHECK, BST_UNCHECKED, 0); EnableWindow(GetDlgItem(hwndMain, ID_SCENEEDITOR), FALSE); ClearStatusBar(); InvalidateRect(hwndRenderFrame, NULL, TRUE); SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, 0, 0); SetThreadExecutionState(ES_CONTINUOUS); String processPriority = AppConfig->GetString(TEXT("General"), TEXT("Priority"), TEXT("Normal")); if (scmp(processPriority, TEXT("Normal"))) SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); bTestStream = false; UpdateRenderViewMessage(); OSLeaveMutex(hStartupShutdownMutex); }
/// Launch the realm server extern int main(int argc, char **argv) { sLog->SetLogDB(false); ///- Command line parsing to get the configuration file name char const* cfg_file = _ARKCORE_REALM_CONFIG; int c = 1; while(c < argc) { if (strcmp(argv[c], "-c") == 0) { if (++c >= argc) { sLog->outError("Runtime-Error: -c option requires an input argument"); usage(argv[0]); return 1; } else cfg_file = argv[c]; } #ifdef _WIN32 //////////// //Services// //////////// if (strcmp(argv[c], "-s") == 0) { if (++c >= argc) { sLog->outError("Runtime-Error: -s option requires an input argument"); usage(argv[0]); return 1; } if (strcmp(argv[c], "install") == 0) { if (WinServiceInstall()) sLog->outString("Installing service"); return 1; } else if (strcmp(argv[c], "uninstall") == 0) { if (WinServiceUninstall()) sLog->outString("Uninstalling service"); return 1; } else { sLog->outError("Runtime-Error: unsupported option %s", argv[c]); usage(argv[0]); return 1; } } if (strcmp(argv[c], "--service") == 0) WinServiceRun(); #endif ++c; } if (!sConfig->SetSource(cfg_file)) { sLog->outError("Invalid or missing configuration file : %s", cfg_file); sLog->outError("Verify that the file exists and has \'[authserver]\' written in the top of the file!"); return 1; } sLog->Initialize(); sLog->outString("%s (realm-daemon)", _CLIENT_BUILD_REVISION); sLog->outString(" "); sLog->outString("World of Warcraft: Mists of Pandaria"); sLog->outString(" Server emulator"); sLog->outString("This core is based on ArkCORE source."); sLog->outString(" "); sLog->outString("<Ctrl-C> to stop.\n"); sLog->outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog->outBasic("Max allowed open files is %d", ACE::max_handles()); /// realmd PID file creation std::string pidfile = sConfig->GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog->outError("Cannot create PID file %s.\n", pidfile.c_str()); return 1; } sLog->outString("Daemon PID: %u\n", pid); } ///- Initialize the database connection if (!StartDB()) return 1; ///- Initialize the log database sLog->SetLogDBLater(sConfig->GetBoolDefault("EnableLogDB", false));// set var to enable DB logging once startup finished. sLog->SetLogDB(false); sLog->SetRealmID(0);// ensure we've set realm to 0 (realmd realmid) ///- Get the list of realms for the server sRealmList->Initialize(sConfig->GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList->size() == 0) { sLog->outError("No valid realms specified."); return 1; } ///- Launch the listening network socket RealmAcceptor acceptor; uint16 rmport = sConfig->GetIntDefault("RealmServerPort", 3724); std::string bind_ip = sConfig->GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog->outError("ArkCORE Auth can not bind to %s:%d", bind_ip.c_str(), rmport); return 1; } // Initialise the signal handlers RealmdSignalHandler SignalINT, SignalTERM; #ifdef _WIN32 RealmdSignalHandler SignalBREAK; #endif /* _WIN32 */ // Register realmd's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); #ifdef _WIN32 Handler.register_handler(SIGBREAK, &SignalBREAK); #endif /* _WIN32 */ ///- Handle affinity for multiple processors and process priority on Windows #ifdef _WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig->GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) sLog->outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x", Aff, appAff); else if (SetProcessAffinityMask(hProcess, curAff)) sLog->outString("Using processors (bitmask, hex): %x", curAff); else sLog->outError("Can't set used processors (hex): %x", curAff); } sLog->outString(); } bool Prio = sConfig->GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLog->outString("ArkCORE Auth process priority class set to HIGH"); else sLog->outError("Can't set realmd process priority class."); sLog->outString(); } } #endif // maximum counter for next ping uint32 numLoops = (sConfig->GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // possibly enable db logging; avoid massive startup spam by doing it here. if (sLog->GetLogDBLater()) { sLog->outString("Enabling database logging..."); sLog->SetLogDBLater(false); // login db needs thread for logging sLog->SetLogDB(true); } else sLog->SetLogDB(false); ///- Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ((++loopCounter) == numLoops) { loopCounter = 0; sLog->outDetail("Ping MySQL to keep connection alive"); LoginDatabase.KeepAlive(); } #ifdef _WIN32 if (m_ServiceStatus == 0) stopEvent = true; else { while (m_ServiceStatus == 2) Sleep(1000); } #endif } ///- Close the Database Pool LoginDatabase.Close(); sLog->outString("Halting process..."); return 0; }
/* int callsystem(const char * cmd, const char * argv[], const char * env[], callsystem_fd_t in[2], callsystem_fd_t out)[2], callsystem_fd_t err[2], const char * wd, int pri, callsystem_pid_t * child) parameters: cmd command to execute argv zero terminated array of options(only options, without the usual argv[0] == cmd, callsystem handles that internally) envp zero terminated array of environment vars (*in)[2] fds to be connected to the childs stdin (*out)[2] fds to be connected to the childs stdout (*err)[2] fds to be connected to the childs stderr wd working directory for the child process pri priority advise 0=normal, 1=higher, -1=lower *child where to store the childs pid, must be initialized to CALLSYSTEM_ILG_PID returns -1 when forking the child failed the fd's, argv, env and wd might be NULL envp will use defaults if NULL(see callsystem_exportdefaults() below) fd's will be bound to the standard streams when NULL working dir wont be changed if NULL */ int callsystem(const char * cmd, char * argv[], char * env[], callsystem_fd_t in[2], callsystem_fd_t out[2], callsystem_fd_t err[2], const char * wd, const int pri, callsystem_pid_t * const child) { #ifdef unix int ppri = getpriority(PRIO_PROCESS, 0); callsystem_pid_t cpid; if(*child != CALLSYSTEM_ILG_PID) { errno = EBUSY; return -1; } /* pid_t parentPid = getpid(); pid_t parentGroup = GetGroup(); */ cpid = fork(); if(cpid == -1) return -1; /* if (parentPid == getpid()) { SetGroup(cpid, parentGroup); } else { printf("in child"); } */ // --------------- if(cpid == 0){ /* child goes here */ const char* bin; if( setup_fd(in, STDIN_FILENO, 0) == -1) CALLSYSTEM_CHILD_ERROR("illegal stdin"); if( setup_fd(out, STDOUT_FILENO, 1) == -1) CALLSYSTEM_CHILD_ERROR("illegal stdout"); if( setup_fd(err, STDERR_FILENO, 1) == -1) CALLSYSTEM_CHILD_ERROR("illegal stderr"); if(wd && chdir(wd)) CALLSYSTEM_CHILD_ERROR("illegal working directory"); if(!env && callsystem_exportdefaults(&env)) CALLSYSTEM_CHILD_ERROR("callsystem_exportdefaults failed"); bin = alloc_executable_name(&env, &argv, cmd); /* put command name into argv[0]*/ callsystem_argv_pushfront(&argv, strrchr(cmd, '/')?(strrchr(cmd, '/') + 1):cmd); if(pri != 0){ setpriority(PRIO_PROCESS, 0, ppri +(pri>0?-5:5)); errno = 0; } execve(bin,argv,env); CALLSYSTEM_CHILD_ERROR("execve failed"); } /* parent */ /* close fd's */ if(in) { close(in[0]); in[0] = CALLSYSTEM_ILG_FD; } if(out) { close(out[1]); out[1] = CALLSYSTEM_ILG_FD; } if(err) { close(err[1]); err[1] = CALLSYSTEM_ILG_FD; } *child = cpid; return 0; #elif defined(WIN32) char * bin; STARTUPINFO si; PROCESS_INFORMATION pi; LPVOID argvblock; LPVOID envblock; /* we need to copy argv as we're not going to fork on windows. */ char **argv_child; callsystem_argv_dup(argv, &argv_child); ZeroMemory( &si, sizeof(si) ); si.cb = sizeof(si); ZeroMemory( &pi, sizeof(pi) ); si.dwFlags = STARTF_USESTDHANDLES; if(!in) si.hStdInput = GetStdHandle(STD_INPUT_HANDLE); else { si.hStdInput = in[0]; /* make sure the child process doesn't get the other end of the pipe. */ SetHandleInformation( in[1], HANDLE_FLAG_INHERIT, 0); } if(!out) si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); else { si.hStdOutput = out[1]; SetHandleInformation( out[0], HANDLE_FLAG_INHERIT, 0); } if(!err) si.hStdError = GetStdHandle(STD_ERROR_HANDLE); else { si.hStdError = err[1]; SetHandleInformation( err[0], HANDLE_FLAG_INHERIT, 0); } /*environment*/ if(!env && callsystem_exportdefaults(&env)) { CALLSYSTEM_CHILD_ERROR("callsystem_exportdefaults failed"); return -1; } bin = alloc_executable_name(&env, &argv_child, cmd); if(!bin) { CALLSYSTEM_CHILD_ERROR("command not found"); return -1; } /*appname */ callsystem_argv_pushfront(&argv_child, cmd); /*commandline*/ argvblock = alloc_commandline(argv_child); /* don't need this anymore. */ callsystem_argv_clear(&argv_child); if(!argvblock) return -1; envblock = alloc_envblock(env); if(!envblock) return -1; /* * You must have "inherit==TRUE" or the stdin/out/err handles * won't be available to the sub-process. */ if(!CreateProcess(bin, argvblock, NULL, NULL, TRUE, 0, envblock, wd, &si, &pi )) { free(bin); return -1; } free(bin); /* * You must close the "other" end of pipes. * reading will just block if you don't */ if(out) { if(!CloseHandle(out[1])) { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return -1; } out[1] = CALLSYSTEM_ILG_FD; } if(err) { if(!CloseHandle(err[1])) { CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return -1; } err[1] = CALLSYSTEM_ILG_FD; } (void) SetPriorityClass(pi.hProcess, pri<0?IDLE_PRIORITY_CLASS: pri>0?HIGH_PRIORITY_CLASS:NORMAL_PRIORITY_CLASS); CloseHandle(pi.hThread); *child = pi.hProcess; return 0; #endif }
/// Main function int Master::Run() { /// worldd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if(!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if( !pid ) { sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); return 1; } sLog.outString( "Daemon PID: %u\n", pid ); } ///- Start the databases if (!_StartDB()) return 1; ///- Initialize the World sWorld.SetInitialWorldSettings(); ///- Catch termination signals _HookSignals(); ///- Launch WorldRunnable thread ACE_Based::Thread world_thread(new WorldRunnable); world_thread.setPriority(ACE_Based::Highest); // set server online loginDatabase.PExecute("UPDATE realmlist SET color = 0, population = 0 WHERE id = '%d'",realmID); ACE_Based::Thread* cliThread = NULL; #ifdef WIN32 if (sConfig.GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) #else if (sConfig.GetBoolDefault("Console.Enable", true)) #endif { ///- Launch CliRunnable thread cliThread = new ACE_Based::Thread(new CliRunnable); } ACE_Based::Thread rar_thread(new RARunnable); ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if(Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if(!curAff ) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for mangosd. Accessible processors bitmask (hex): %x",Aff,appAff); } else { if(SetProcessAffinityMask(hProcess,curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x",curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); // if(Prio && (m_ServiceStatus == -1)/* need set to default process priority class in service mode*/) if(Prio) { if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) sLog.outString("mangosd process priority class set to HIGH"); else sLog.outError("ERROR: Can't set mangosd process priority class."); sLog.outString(); } } #endif uint32 realCurrTime, realPrevTime; realCurrTime = realPrevTime = getMSTime(); ///- Start up freeze catcher thread if(uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0)) { FreezeDetectorRunnable *fdr = new FreezeDetectorRunnable(); fdr->SetDelayTime(freeze_delay*1000); ACE_Based::Thread freeze_thread(fdr); freeze_thread.setPriority(ACE_Based::Highest); } ///- Launch the world listener socket port_t wsport = sWorld.getConfig (CONFIG_PORT_WORLD); std::string bind_ip = sConfig.GetStringDefault ("BindIP", "0.0.0.0"); if (sWorldSocketMgr->StartNetwork (wsport, bind_ip.c_str ()) == -1) { sLog.outError ("Failed to start network"); World::StopNow(ERROR_EXIT_CODE); // go down and shutdown the server } sWorldSocketMgr->Wait (); // set server offline loginDatabase.PExecute("UPDATE realmlist SET color = 2 WHERE id = '%d'",realmID); ///- Remove signal handling before leaving _UnhookSignals(); // when the main thread closes the singletons get unloaded // since worldrunnable uses them, it will crash if unloaded after master world_thread.wait(); rar_thread.wait (); ///- Clean database before leaving clearOnlineAccounts(); ///- Wait for delay threads to end CharacterDatabase.HaltDelayThread(); WorldDatabase.HaltDelayThread(); loginDatabase.HaltDelayThread(); sLog.outString( "Halting process..." ); if (cliThread) { #ifdef WIN32 // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API) //_exit(1); // send keyboard input to safely unblock the CLI thread INPUT_RECORD b[5]; HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); b[0].EventType = KEY_EVENT; b[0].Event.KeyEvent.bKeyDown = TRUE; b[0].Event.KeyEvent.uChar.AsciiChar = 'X'; b[0].Event.KeyEvent.wVirtualKeyCode = 'X'; b[0].Event.KeyEvent.wRepeatCount = 1; b[1].EventType = KEY_EVENT; b[1].Event.KeyEvent.bKeyDown = FALSE; b[1].Event.KeyEvent.uChar.AsciiChar = 'X'; b[1].Event.KeyEvent.wVirtualKeyCode = 'X'; b[1].Event.KeyEvent.wRepeatCount = 1; b[2].EventType = KEY_EVENT; b[2].Event.KeyEvent.bKeyDown = TRUE; b[2].Event.KeyEvent.dwControlKeyState = 0; b[2].Event.KeyEvent.uChar.AsciiChar = '\r'; b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; b[2].Event.KeyEvent.wRepeatCount = 1; b[2].Event.KeyEvent.wVirtualScanCode = 0x1c; b[3].EventType = KEY_EVENT; b[3].Event.KeyEvent.bKeyDown = FALSE; b[3].Event.KeyEvent.dwControlKeyState = 0; b[3].Event.KeyEvent.uChar.AsciiChar = '\r'; b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; b[3].Event.KeyEvent.wVirtualScanCode = 0x1c; b[3].Event.KeyEvent.wRepeatCount = 1; DWORD numb; BOOL ret = WriteConsoleInput(hStdIn, b, 4, &numb); cliThread->wait(); #else cliThread->destroy(); #endif delete cliThread; } // for some unknown reason, unloading scripts here and not in worldrunnable // fixes a memory leak related to detaching threads from the module UnloadScriptingModule(); // Exit the process with specified return value return World::GetExitCode(); }
PsychError SCREENGetMouseHelper(void) { const char *valuatorInfo[]={"label", "min", "max", "resolution", "mode", "sourceID"}; int numValuatorStructFieldNames = 6; int numIValuators = 0; PsychGenericScriptType *valuatorStruct = NULL; #if PSYCH_SYSTEM == PSYCH_OSX Point mouseXY; UInt32 buttonState; double *buttonArray; int numButtons, i; psych_bool doButtonArray; PsychWindowRecordType *windowRecord; int32_t deltaX, deltaY; double myvaluators[2]; //all subfunctions should have these two lines. PsychPushHelp(useString, synopsisString, seeAlsoString); if (PsychIsGiveHelp()){PsychGiveHelp();return(PsychError_none);}; //cap the numbers of inputs and outputs PsychErrorExit(PsychCapNumInputArgs(3)); //The maximum number of inputs PsychErrorExit(PsychCapNumOutputArgs(6)); //The maximum number of outputs // Buttons. // The only way I know to detect the number number of mouse buttons is directly via HID. The device reports // that information but OS X seems to ignore it above the level of the HID driver, that is, no OS X API above the HID driver // exposes it. So GetMouse.m function calls PsychHID detect the number of buttons and then passes that value to GetMouseHelper // which returns that number of button values in a vector. PsychCopyInIntegerArg(1, kPsychArgRequired, &numButtons); if (numButtons > 32) PsychErrorExitMsg(PsychErorr_argumentValueOutOfRange, "numButtons must not exceed 32"); // Special codes -10 to -15? --> Console keyboard queries: if (numButtons <= -10 && numButtons >= -15) { ConsoleInputHelper((int) numButtons); return(PsychError_none); } if (numButtons < 1) PsychErrorExitMsg(PsychErorr_argumentValueOutOfRange, "numButtons must exceed 1"); doButtonArray=PsychAllocOutDoubleMatArg(3, kPsychArgOptional, (int)1, (int)numButtons, (int)1, &buttonArray); if (doButtonArray) { buttonState=GetCurrentButtonState(); for(i=0;i<numButtons;i++) buttonArray[i]=(double)(buttonState & (1<<i)); } // Get cursor position: HIPoint outPoint; HIGetMousePosition(kHICoordSpaceScreenPixel, NULL, &outPoint); PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) outPoint.x); PsychCopyOutDoubleArg(2, kPsychArgOptional, (double) outPoint.y); // Return optional keyboard input focus status: if (numButtons > 0) { // Window provided? if (PsychIsWindowIndexArg(2)) { // Yes: Check if it has focus. PsychAllocInWindowRecordArg(2, TRUE, &windowRecord); if (!PsychIsOnscreenWindow(windowRecord)) { PsychErrorExitMsg(PsychError_user, "Provided window handle isn't an onscreen window, as required."); } PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) (PsychCocoaGetUserFocusWindow() == windowRecord->targetSpecific.windowHandle) ? 1 : 0); } else { // No. Just always return "has focus": PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) 1); } } // Return optional valuator values: On OSX we use two valuators to return deltaX and deltaY, // the mouse delta movement since last call to this function: CGGetLastMouseDelta(&deltaX, &deltaY); myvaluators[0] = (double) deltaX; myvaluators[1] = (double) deltaY; PsychCopyOutDoubleMatArg(5, kPsychArgOptional, (int) 1, (int) 2, (int) 1, &myvaluators[0]); // Return optional valuator info struct array as argument 6: if (PsychIsArgPresent(PsychArgOut, 6)) { // Usercode wants valuator info structs: PsychAllocOutStructArray(6, TRUE, 2, numValuatorStructFieldNames, valuatorInfo, &valuatorStruct); // Valuator 0: Encodes DeltaX - relative X motion, aka mouse deltaX: PsychSetStructArrayStringElement("label", 0, "DeltaX", valuatorStruct); // Other fields are meaningless or undefined on OSX, so set to 0 default: PsychSetStructArrayDoubleElement("min", 0, (double) 0, valuatorStruct); PsychSetStructArrayDoubleElement("max", 0, (double) 0, valuatorStruct); PsychSetStructArrayDoubleElement("resolution", 0, (double) 0, valuatorStruct); PsychSetStructArrayDoubleElement("mode", 0, (double) 0, valuatorStruct); PsychSetStructArrayDoubleElement("sourceID", 0, (double) 0, valuatorStruct); // Valuator 1: Encodes DeltaY - relative Y motion, aka mouse deltaY: PsychSetStructArrayStringElement("label", 1, "DeltaY", valuatorStruct); // Other fields are meaningless or undefined on OSX, so set to 0 default: PsychSetStructArrayDoubleElement("min", 1, (double) 0, valuatorStruct); PsychSetStructArrayDoubleElement("max", 1, (double) 0, valuatorStruct); PsychSetStructArrayDoubleElement("resolution", 1, (double) 0, valuatorStruct); PsychSetStructArrayDoubleElement("mode", 1, (double) 0, valuatorStruct); PsychSetStructArrayDoubleElement("sourceID", 1, (double) 0, valuatorStruct); } #endif #if PSYCH_SYSTEM == PSYCH_WINDOWS static unsigned char disabledKeys[256]; static unsigned char firsttime = 1; int keysdown, i, priorityLevel; unsigned char keyState[256]; double* buttonArray; double numButtons, timestamp; PsychNativeBooleanType* buttonStates; POINT point; HANDLE currentProcess; DWORD oldPriority = NORMAL_PRIORITY_CLASS; const DWORD realtime_class = REALTIME_PRIORITY_CLASS; PsychWindowRecordType *windowRecord; PsychPushHelp(useString, synopsisString, seeAlsoString); if (PsychIsGiveHelp()) { PsychGiveHelp(); return(PsychError_none); }; // Retrieve optional number of mouse buttons: numButtons = 0; PsychCopyInDoubleArg(1, FALSE, &numButtons); // Are we operating in 'GetMouseHelper' mode? numButtons>=0 indicates this. if (numButtons >= 0) { // GetMouse-Mode: Return mouse button states and mouse cursor position: PsychAllocOutDoubleMatArg(3, kPsychArgOptional, (int)1, (int)3, (int)1, &buttonArray); // Query and return mouse button state: PsychGetMouseButtonState(buttonArray); // Query and return cursor position in global coordinates: GetCursorPos(&point); PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) point.x); PsychCopyOutDoubleArg(2, kPsychArgOptional, (double) point.y); // Window provided? if (PsychIsWindowIndexArg(2)) { // Yes: Check if it has focus. PsychAllocInWindowRecordArg(2, TRUE, &windowRecord); if (!PsychIsOnscreenWindow(windowRecord)) { PsychErrorExitMsg(PsychError_user, "Provided window handle isn't an onscreen window, as required."); } PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) (GetForegroundWindow() == windowRecord->targetSpecific.windowHandle) ? 1 : 0); } else { // No. Just always return "has focus": PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) 1); } // Return optional valuator values: Unimplemented on Windows. Just return an empty matrix. // The ×tamp is just a dummy assignment without any meaning. PsychCopyOutDoubleMatArg(5, kPsychArgOptional, (int) 1, (int) 0, (int) 1, ×tamp); PsychCopyOutDoubleMatArg(6, kPsychArgOptional, (int) 1, (int) 0, (int) 1, buttonArray); } else { // 'KeyboardHelper' mode: We implement either KbCheck() or KbWait() via X11. // This is a hack to provide keyboard queries until a PsychHID() implementation // for Microsoft Windows is available... // Special codes -10 to -15? --> Console keyboard queries: if (numButtons <= -10 && numButtons >= -15) { ConsoleInputHelper((int) numButtons); return(PsychError_none); } if (firsttime) { // First time init: firsttime = 0; memset(keyState, 0, sizeof(keyState)); memset(disabledKeys, 0, sizeof(disabledKeys)); // These keycodes are always disabled: 0, 255: disabledKeys[0]=1; disabledKeys[255]=1; // Mouse buttone (left, right, middle) are also disabled by default: disabledKeys[1]=1; disabledKeys[2]=1; disabledKeys[4]=1; } if (numButtons==-1 || numButtons==-2) { // KbCheck()/KbWait() mode do { // Reset overall key state to "none pressed": keysdown=0; // Request current time of query: PsychGetAdjustedPrecisionTimerSeconds(×tamp); // Query state of all keys: for(i=1;i<255;i++){ keyState[i] = (GetAsyncKeyState(i) & -32768) ? 1 : 0; } // Disable all keys that are registered in disabledKeys. Check if // any non-disabled key is down. for (i=0; i<256; i++) { if (disabledKeys[i]>0) keyState[i] = 0; keysdown+=(unsigned int) keyState[i]; } // We repeat until any key pressed if in KbWait() mode, otherwise we // exit the loop after first iteration in KbCheck mode. if ((numButtons==-1) || ((numButtons==-2) && (keysdown>0))) break; // Sleep for a millisecond before next KbWait loop iteration: PsychWaitIntervalSeconds(0.001); } while(1); if (numButtons==-2) { // KbWait mode: Copy out time value. PsychCopyOutDoubleArg(1, kPsychArgOptional, timestamp); } else { // KbCheck mode: // Copy out overall keystate: PsychCopyOutDoubleArg(1, kPsychArgOptional, (keysdown>0) ? 1 : 0); // Copy out timestamp: PsychCopyOutDoubleArg(2, kPsychArgOptional, timestamp); // Copy out keyboard state: PsychAllocOutBooleanMatArg(3, kPsychArgOptional, 1, 256, 1, &buttonStates); // Build 256 elements return vector: for (i=0; i<255; i++) { buttonStates[i] = (PsychNativeBooleanType)((keyState[i+1]) ? 1 : 0); } // Special case: Null out last element: buttonStates[255] = (PsychNativeBooleanType) 0; } } if (numButtons==-3) { // Priority() - helper mode: The 2nd argument is the priority level: // Determine our processID: currentProcess = GetCurrentProcess(); // Get current scheduling policy: oldPriority = GetPriorityClass(currentProcess); // Map to PTB's scheme: switch(oldPriority) { case NORMAL_PRIORITY_CLASS: priorityLevel = 0; break; case HIGH_PRIORITY_CLASS: priorityLevel = 1; break; case REALTIME_PRIORITY_CLASS: priorityLevel = 2; break; default: priorityLevel = 0; } // Copy it out as optional return argument: PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) priorityLevel); // Query if a new level should be set: priorityLevel = -1; PsychCopyInIntegerArg(2, kPsychArgOptional, &priorityLevel); // Priority level provided? if (priorityLevel > -1) { // Map to new scheduling class: if (priorityLevel > 2) PsychErrorExitMsg(PsychErorr_argumentValueOutOfRange, "Invalid Priority level: Requested Priority() level must not exceed 2."); switch (priorityLevel) { case 0: // Standard scheduling: SetPriorityClass(currentProcess, NORMAL_PRIORITY_CLASS); // Disable any MMCSS scheduling for us: PsychSetThreadPriority((psych_thread*) 0x1, 0, 0); break; case 1: // High priority scheduling: SetPriorityClass(currentProcess, HIGH_PRIORITY_CLASS); // Additionally try to schedule us MMCSS: This will lift us roughly into the // same scheduling range as REALTIME_PRIORITY_CLASS, even if we are non-admin users // on Vista and Windows-7 and later, however with a scheduler safety net applied. PsychSetThreadPriority((psych_thread*) 0x1, 10, 0); break; case 2: // Realtime scheduling: // This can fail if Matlab is not running under a user account with proper permissions: if ((0 == SetPriorityClass(currentProcess, REALTIME_PRIORITY_CLASS)) || (REALTIME_PRIORITY_CLASS != GetPriorityClass(currentProcess))) { // Failed to get RT-Scheduling. Let's try at least high priority scheduling: SetPriorityClass(currentProcess, HIGH_PRIORITY_CLASS); // Additionally try to schedule us MMCSS: This will lift us roughly into the // same scheduling range as REALTIME_PRIORITY_CLASS, even if we are non-admin users // on Vista and Windows-7 and later, however with a scheduler safety net applied. PsychSetThreadPriority((psych_thread*) 0x1, 10, 0); } break; } } // End of Priority() helper for Win32. } } #endif #if PSYCH_SYSTEM == PSYCH_LINUX double myvaluators[100]; int numvaluators; unsigned char keys_return[32]; char* keystring; PsychGenericScriptType *kbNames; CGDirectDisplayID dpy; Window rootwin, childwin, mywin = 0; int i, j, mx, my, dx, dy; double mxd, myd, dxd, dyd; unsigned int mask_return; double timestamp; int numButtons; double* buttonArray; PsychNativeBooleanType* buttonStates; int keysdown; XEvent event_return; XKeyPressedEvent keypressevent; int screenNumber; int priorityLevel; struct sched_param schedulingparam; PsychWindowRecordType *windowRecord = NULL; int mouseIndex; XIButtonState buttons_return; XIModifierState modifiers_return; XIGroupState group_return; PsychPushHelp(useString, synopsisString, seeAlsoString); if (PsychIsGiveHelp()) { PsychGiveHelp(); return(PsychError_none); }; PsychCopyInIntegerArg(1, kPsychArgRequired, &numButtons); // Retrieve optional screenNumber argument: if (numButtons!=-5) { screenNumber = 0; if (PsychIsScreenNumberArg(2)) { PsychCopyInScreenNumberArg(2, FALSE, &screenNumber); } // Map screenNumber to X11 display handle and screenid: PsychGetCGDisplayIDFromScreenNumber(&dpy, screenNumber); if (PsychIsWindowIndexArg(2)) { PsychAllocInWindowRecordArg(2, TRUE, &windowRecord); if (!PsychIsOnscreenWindow(windowRecord)) { PsychErrorExitMsg(PsychError_user, "Provided window handle isn't an onscreen window, as required."); } screenNumber = windowRecord->screenNumber; #ifndef PTB_USE_WAYLAND mywin = windowRecord->targetSpecific.xwindowHandle; #else // TODO Wayland. mywin = None; #endif // Map screenNumber to X11 display handle and screenid: PsychGetCGDisplayIDFromScreenNumber(&dpy, screenNumber); } else { PsychLockDisplay(); #ifndef PTB_USE_WAYLAND mywin = RootWindow(dpy, PsychGetXScreenIdForScreen(screenNumber)); #else // TODO Wayland. mywin = None; #endif PsychUnlockDisplay(); } } // Default to "old school" mouse query - System default mouse via X core protocol: mouseIndex = -1; PsychCopyInIntegerArg(3, FALSE, &mouseIndex); // Are we operating in 'GetMouseHelper' mode? numButtons>=0 indicates this. if (numButtons >= 0) { // Mouse pointer query mode: numvaluators = 0; #ifdef PTB_USE_WAYLAND { void* focusWindow = NULL; // Copy out mouse x and y position: // Alloc out mouse button state: PsychAllocOutDoubleMatArg(3, kPsychArgOptional, (int) 1, (int) numButtons, (int) 1, &buttonArray); // Query Wayland backend for mouse state: if (!PsychWaylandGetMouseState(mouseIndex, &mx, &my, numButtons, &(buttonArray[0]), &focusWindow)) { // Failed: Likely invalid mouseIndex. PsychErrorExitMsg(PsychError_user, "Invalid 'mouseIndex' provided. No such device."); } PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) mx); PsychCopyOutDoubleArg(2, kPsychArgOptional, (double) my); // Return window focus state: Currently simply 0 for "not focused": PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) (windowRecord && (windowRecord->targetSpecific.xwindowHandle == focusWindow)) ? 1 : 0); // Return optional valuator values: Currently empty due to numvaluators == 0: PsychCopyOutDoubleMatArg(5, kPsychArgOptional, (int) 1, (int) numvaluators, (int) 1, &myvaluators[0]); return(PsychError_none); } #endif if (mouseIndex >= 0) { // XInput-2 query for handling of multiple mouse pointers: // Query input device list for screen: int nDevices; XIDeviceInfo* indevs = PsychGetInputDevicesForScreen(screenNumber, &nDevices); // Sanity check: if (NULL == indevs) PsychErrorExitMsg(PsychError_user, "Sorry, your system does not support individual mouse pointer queries."); if (mouseIndex >= nDevices) PsychErrorExitMsg(PsychError_user, "Invalid 'mouseIndex' provided. No such device."); if ((indevs[mouseIndex].use != XIMasterPointer) && (indevs[mouseIndex].use != XISlavePointer) && (indevs[mouseIndex].use != XIFloatingSlave)) { PsychErrorExitMsg(PsychError_user, "Invalid 'mouseIndex' provided. Not a pointer device."); } // We requery the device info struct to retrieve updated live device state: // Crucial for slave pointers to get any state at all, but also needed on // master pointers to get the state of additional valuators, e.g., pen pressure, // touch area, tilt etc. for digitizer tablets, touch pads etc. For master pointers, // the primary 2 axis for 2D (x,y) position and the button/modifier state will be // queried via a dedicated XIQueryPointer() call, so that info gets overriden. PsychLockDisplay(); indevs = XIQueryDevice(dpy, indevs[mouseIndex].deviceid, &numButtons); PsychUnlockDisplay(); modifiers_return.effective = 0; // Query real number of mouse buttons and the raw button and axis state // stored inside the device itself. This is done mostly because slave pointer // devices don't support XIQueryPointer() so we get their relevant info from the // XIDeviceInfo struct itself: numButtons = 0; numvaluators = 0; memset(myvaluators, 0, sizeof(myvaluators)); if (PsychIsArgPresent(PsychArgOut, 6)) { // Usercode wants valuator info structs: for (i = 0; i < indevs->num_classes; i++) if (indevs->classes[i]->type == XIValuatorClass) numIValuators++; PsychAllocOutStructArray(6, TRUE, numIValuators, numValuatorStructFieldNames, valuatorInfo, &valuatorStruct); } for (i = 0; i < indevs->num_classes; i++) { // printf("Class %i: Type %i\n", i, (int) indevs->classes[i]->type); if (indevs->classes[i]->type == XIButtonClass) { // Number of buttons: For all pointers. numButtons = ((XIButtonClassInfo*) indevs->classes[i])->num_buttons; // Button state for slave pointers. Will get overriden for master pointers: buttons_return.mask = ((XIButtonClassInfo*) indevs->classes[i])->state.mask; buttons_return.mask_len = ((XIButtonClassInfo*) indevs->classes[i])->state.mask_len; } // Axis state for slave pointers. First two axis (x,y) will get overriden for master pointers: if (indevs->classes[i]->type == XIValuatorClass) { XIValuatorClassInfo* axis = (XIValuatorClassInfo*) indevs->classes[i]; if (axis->number == 0) mxd = axis->value; // x-Axis. if (axis->number == 1) myd = axis->value; // y-Axis. // Additional axis, e.g., digitizer tablet, touchpads etc.: if (axis->number >= 0 && axis->number < 100) { myvaluators[axis->number] = axis->value; numvaluators = (numvaluators >= axis->number + 1) ? numvaluators : axis->number + 1; } // Assign valuator info struct, if requested: if (valuatorStruct) { if (axis->label != None) { PsychLockDisplay(); char* atomlabel = XGetAtomName(dpy, axis->label); PsychSetStructArrayStringElement("label", axis->number, atomlabel, valuatorStruct); XFree(atomlabel); PsychUnlockDisplay(); } else { PsychSetStructArrayStringElement("label", axis->number, "None", valuatorStruct); } PsychSetStructArrayDoubleElement("min", axis->number, (double) axis->min, valuatorStruct); PsychSetStructArrayDoubleElement("max", axis->number, (double) axis->max, valuatorStruct); PsychSetStructArrayDoubleElement("resolution", axis->number, (double) axis->resolution, valuatorStruct); PsychSetStructArrayDoubleElement("mode", axis->number, (double) axis->mode, valuatorStruct); PsychSetStructArrayDoubleElement("sourceID", axis->number, (double) axis->sourceid, valuatorStruct); } // printf("AXIS %i, LABEL = %s, MIN = %f, MAX = %f, VAL = %f\n", axis->number, (char*) "NONE", (float) axis->min, (float) axis->max, (float) axis->value); } } // Add 32 buttons for modifier key state vector: numButtons += 32; // A real master pointer: Use official query for mouse devices. if (indevs->use == XIMasterPointer) { // Query pointer location and state: PsychLockDisplay(); XIQueryPointer(dpy, indevs->deviceid, RootWindow(dpy, PsychGetXScreenIdForScreen(screenNumber)), &rootwin, &childwin, &mxd, &myd, &dxd, &dyd, &buttons_return, &modifiers_return, &group_return); PsychUnlockDisplay(); } // Copy out mouse x and y position: PsychCopyOutDoubleArg(1, kPsychArgOptional, mxd); PsychCopyOutDoubleArg(2, kPsychArgOptional, myd); // Copy out mouse button state: PsychAllocOutDoubleMatArg(3, kPsychArgOptional, (int)1, (int) numButtons, (int)1, &buttonArray); memset(buttonArray, 0, sizeof(double) * numButtons); if (numButtons > 0) { // Mouse buttons: const int buttonOffset = 1; // Buttons start at bit 1, not 0 for some strange reason? At least so on Ubuntu 10.10 and 11.10 with 2 mice and 1 joystick? for (i = buttonOffset; (i < numButtons - 32) && ((i / 8 ) < buttons_return.mask_len); i++) { buttonArray[i - buttonOffset] = (double) ((buttons_return.mask[i / 8] & (1 << (i % 8))) ? 1 : 0); } // Free mask if retrieved via XIQueryPointer(): if (indevs->use == XIMasterPointer) free(buttons_return.mask); // Append modifier key state from associated master keyboard. Last 32 entries: for (i = 0; i < 32; i++) { buttonArray[numButtons - 32 + i] = (double) ((modifiers_return.effective & (1 << i)) ? 1 : 0); } } // Release live state info structure: XIFreeDeviceInfo(indevs); } else { // Old school core protocol query of virtual core pointer: PsychLockDisplay(); XQueryPointer(dpy, RootWindow(dpy, PsychGetXScreenIdForScreen(screenNumber)), &rootwin, &childwin, &mx, &my, &dx, &dy, &mask_return); PsychUnlockDisplay(); // Copy out mouse x and y position: PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) mx); PsychCopyOutDoubleArg(2, kPsychArgOptional, (double) my); // Copy out mouse button state: PsychAllocOutDoubleMatArg(3, kPsychArgOptional, (int)1, (int)numButtons, (int)1, &buttonArray); // Bits 8, 9 and 10 of mask_return seem to correspond to mouse buttons // 1, 2 and 3 of a mouse for some weird reason. Bits 0-7 describe keyboard modifier keys // like Alt, Ctrl, Shift, ScrollLock, NumLock, CapsLock... // We remap here, so the first three returned entries correspond to the mouse buttons and // the rest is attached behind, if requested... // Mouse buttons: Left, Middle, Right == 0, 1, 2, aka 1,2,3 in Matlab space... for (i=0; i<numButtons && i<3; i++) { buttonArray[i] = (mask_return & (1<<(i+8))) ? 1 : 0; } // Modifier keys 0 to 7 appended: for (i=3; i<numButtons && i<3+8; i++) { buttonArray[i] = (mask_return & (1<<(i-3))) ? 1 : 0; } // Everything else appended: for (i=11; i<numButtons; i++) { buttonArray[i] = (mask_return & (1<<i)) ? 1 : 0; } } // Return optional 4th argument: Focus state. Returns 1 if our window has // keyboard input focus, zero otherwise: PsychLockDisplay(); XGetInputFocus(dpy, &rootwin, &i); PsychUnlockDisplay(); PsychCopyOutDoubleArg(4, kPsychArgOptional, (double) (rootwin == mywin) ? 1 : 0); // Return optional valuator values: PsychCopyOutDoubleMatArg(5, kPsychArgOptional, (int) 1, (int) numvaluators, (int) 1, &myvaluators[0]); } else { // 'KeyboardHelper' mode: We implement either KbCheck() or KbWait() via X11. // This is a hack to provide keyboard queries until a PsychHID() implementation // for Linux is available... // Special codes -10 to -15? --> Console keyboard queries: if(numButtons <= -10 && numButtons >= -15) { ConsoleInputHelper((int) numButtons); return(PsychError_none); } if (numButtons==-1 || numButtons==-2) { // KbCheck()/KbWait() mode: #ifdef PTB_USE_WAYLAND // Only implement KbCheck mode. KbWait mode isn't used anymore... // Alloc out keyboard state: PsychAllocOutBooleanMatArg(3, kPsychArgOptional, 1, 256, 1, &buttonStates); // Query Wayland backend for mouse state: if (!PsychWaylandGetKeyboardState(mouseIndex, 256, &(buttonStates[0]), ×tamp)) { // Failed: Likely invalid mouseIndex. PsychErrorExitMsg(PsychError_user, "Invalid 'keyboardIndex' provided. No such device."); } // Any key down? keysdown = 0; for (i = 0; i < 256; i++) keysdown += (unsigned int) buttonStates[i]; // Copy out overall keystate: PsychCopyOutDoubleArg(1, kPsychArgOptional, (keysdown > 0) ? 1 : 0); // Copy out timestamp: PsychCopyOutDoubleArg(2, kPsychArgOptional, timestamp); return(PsychError_none); #endif // Switch X-Server into synchronous mode: We need this to get // a higher timing precision. PsychLockDisplay(); XSynchronize(dpy, TRUE); PsychUnlockDisplay(); do { // Reset overall key state to "none pressed": keysdown=0; // Request current keyboard state from X-Server: PsychLockDisplay(); XQueryKeymap(dpy, keys_return); PsychUnlockDisplay(); // Request current time of query: PsychGetAdjustedPrecisionTimerSeconds(×tamp); // Any key down? for (i=0; i<32; i++) keysdown+=(unsigned int) keys_return[i]; // We repeat until any key pressed if in KbWait() mode, otherwise we // exit the loop after first iteration in KbCheck mode. if ((numButtons==-1) || ((numButtons==-2) && (keysdown>0))) break; // Sleep for a few milliseconds before next KbWait loop iteration: PsychWaitIntervalSeconds(0.01); } while(1); if (numButtons==-2) { // Copy out time: PsychCopyOutDoubleArg(1, kPsychArgOptional, timestamp); } else { // KbCheck mode: // Copy out overall keystate: PsychCopyOutDoubleArg(1, kPsychArgOptional, (keysdown>0) ? 1 : 0); // copy out timestamp: PsychCopyOutDoubleArg(2, kPsychArgOptional, timestamp); // Copy keyboard state: PsychAllocOutBooleanMatArg(3, kPsychArgOptional, 1, 256, 1, &buttonStates); // Map 32 times 8 bitvector to 256 element return vector: for (i=0; i<32; i++) { for(j=0; j<8; j++) { buttonStates[i*8 + j] = (PsychNativeBooleanType)(keys_return[i] & (1<<j)) ? 1 : 0; } } } } else if (numButtons == -3) { // numButtons == -3 --> KbName mapping mode: // Return the full keyboard keycode to ASCII character code mapping table... PsychAllocOutCellVector(1, kPsychArgOptional, 256, &kbNames); #ifdef PTB_USE_WAYLAND PsychWaylandGetKbNames(kbNames); #else for(i = 0; i < 256; i++) { // Map keyboard scan code to KeySym: PsychLockDisplay(); keystring = XKeysymToString(XKeycodeToKeysym(dpy, i, 0)); PsychUnlockDisplay(); if (keystring) { // Character found: Return its ASCII name string: PsychSetCellVectorStringElement(i, keystring, kbNames); } else { // No character for this keycode: PsychSetCellVectorStringElement(i, "", kbNames); } } #endif } else if (numButtons == -4) { // GetChar() emulation. Dead. } else if (numButtons==-5) { // Priority() - helper mode: The 2nd argument is the priority level: // Query scheduling policy and priority: pthread_getschedparam(pthread_self(), &priorityLevel, &schedulingparam); // If scheduling mode is a realtime mode (RoundRobin realtime RR, or FIFO realtime), // then assign RT priority level (range 1-99) as current priorityLevel, otherwise // assign non realtime priority level zero: priorityLevel = (priorityLevel == SCHED_RR || priorityLevel == SCHED_FIFO) ? schedulingparam.sched_priority : 0; // Copy it out as optional return argument: PsychCopyOutDoubleArg(1, kPsychArgOptional, (double) priorityLevel); // Query if a new level should be set: priorityLevel = -1; PsychCopyInIntegerArg(2, kPsychArgOptional, &priorityLevel); errno=0; // Priority level provided? if (priorityLevel > -1) { // Map to new scheduling class: if (priorityLevel > 99 || priorityLevel < 0) PsychErrorExitMsg(PsychErorr_argumentValueOutOfRange, "Invalid Priority level: Requested Priority() level must be between zero and 99!"); if (priorityLevel > 0) { // Realtime FIFO scheduling and all pages of Matlab/Octave locked into memory: schedulingparam.sched_priority = priorityLevel; priorityLevel = pthread_setschedparam(pthread_self(), SCHED_FIFO, &schedulingparam); if (priorityLevel == -1) { // Failed! if(!PsychPrefStateGet_SuppressAllWarnings()) { printf("PTB-ERROR: Failed to enable realtime-scheduling with Priority(%i) [%s]!\n", schedulingparam.sched_priority, strerror(errno)); if (errno==EPERM) { printf("PTB-ERROR: You need to run Matlab/Octave with root-privileges, or run the script PsychLinuxConfiguration once for this to work.\n"); } } errno=0; } else { // RT-Scheduling active. Lock all current and future memory: priorityLevel = mlockall(MCL_CURRENT | MCL_FUTURE); if (priorityLevel!=0) { // Failed! Report problem as warning, but don't worry further. if(!PsychPrefStateGet_SuppressAllWarnings()) printf("PTB-WARNING: Failed to enable system memory locking with Priority(%i) [%s]!\n", schedulingparam.sched_priority, strerror(errno)); // Undo any possibly partial mlocks.... munlockall(); errno=0; } } } else { // Standard scheduling and no memory locking: schedulingparam.sched_priority = 0; priorityLevel = pthread_setschedparam(pthread_self(), SCHED_OTHER, &schedulingparam); if (priorityLevel == -1) { // Failed! if(!PsychPrefStateGet_SuppressAllWarnings()) { printf("PTB-ERROR: Failed to disable realtime-scheduling with Priority(%i) [%s]!\n", schedulingparam.sched_priority, strerror(errno)); if (errno==EPERM) { printf("PTB-ERROR: You need to run Matlab/Octave with root-privileges, or run the script PsychLinuxConfiguration once for this to work.\n"); } } errno=0; } munlockall(); errno=0; } // End of setup of new Priority... } // End of Priority() helper for Linux. } } // End of special functions handling for Linux... #endif return(PsychError_none); }
void TSysProc::SetLowPriority(){ SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); }
/// Launch the auth server extern int main(int argc, char **argv) { // Command line parsing to get the configuration file name char const* cfg_file = _TRINITY_REALM_CONFIG; int c = 1; while (c < argc) { if (strcmp(argv[c], "-c") == 0) { if (++c >= argc) { printf("Runtime-Error: -c option requires an input argument\n"); usage(argv[0]); return 1; } else cfg_file = argv[c]; } ++c; } if (!ConfigMgr::Load(cfg_file)) { printf("Invalid or missing configuration file : %s\n", cfg_file); printf("Verify that the file exists and has \'[authserver]\' written in the top of the file!\n"); return 1; } sLog->outInfo(LOG_FILTER_AUTHSERVER, "%s (authserver)", _FULLVERSION); sLog->outInfo(LOG_FILTER_AUTHSERVER, "Using configuration file %s.", cfg_file); sLog->outWarn(LOG_FILTER_AUTHSERVER, "%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog->outDebug(LOG_FILTER_AUTHSERVER, "Max allowed open files is %d", ACE::max_handles()); // authserver PID file creation std::string pidfile = ConfigMgr::GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog->outError(LOG_FILTER_AUTHSERVER, "Cannot create PID file %s.\n", pidfile.c_str()); return 1; } sLog->outInfo(LOG_FILTER_AUTHSERVER, "Daemon PID: %u\n", pid); } // Initialize the database connection if (!StartDB()) return 1; sLog->SetRealmID(0); // ensure we've set realm to 0 (authserver realmid) // Get the list of realms for the server sRealmList->Initialize(ConfigMgr::GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList->size() == 0) { sLog->outError(LOG_FILTER_AUTHSERVER, "No valid realms specified."); return 1; } // Launch the listening network socket RealmAcceptor acceptor; int32 rmport = ConfigMgr::GetIntDefault("RealmServerPort", 3724); if (rmport < 0 || rmport > 0xFFFF) { sLog->outError(LOG_FILTER_AUTHSERVER, "Specified port out of allowed range (1-65535)"); return 1; } std::string bind_ip = ConfigMgr::GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(uint16(rmport), bind_ip.c_str()); if (acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog->outError(LOG_FILTER_AUTHSERVER, "Auth server can not bind to %s:%d", bind_ip.c_str(), rmport); return 1; } // Initialise the signal handlers AuthServerSignalHandler SignalINT, SignalTERM; // Register authservers's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); ///- Handle affinity for multiple processors and process priority on Windows #ifdef _WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = ConfigMgr::GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) sLog->outError(LOG_FILTER_AUTHSERVER, "Processors marked in UseProcessors bitmask (hex) %x not accessible for authserver. Accessible processors bitmask (hex): %x", Aff, appAff); else if (SetProcessAffinityMask(hProcess, curAff)) sLog->outInfo(LOG_FILTER_AUTHSERVER, "Using processors (bitmask, hex): %x", curAff); else sLog->outError(LOG_FILTER_AUTHSERVER, "Can't set used processors (hex): %x", curAff); } } bool Prio = ConfigMgr::GetBoolDefault("ProcessPriority", false); if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLog->outInfo(LOG_FILTER_AUTHSERVER, "The auth server process priority class has been set to HIGH"); else sLog->outError(LOG_FILTER_AUTHSERVER, "Can't set auth server process priority class."); } } #endif // maximum counter for next ping uint32 numLoops = (ConfigMgr::GetIntDefault("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; if ((++loopCounter) == numLoops) { loopCounter = 0; sLog->outInfo(LOG_FILTER_AUTHSERVER, "Ping MySQL to keep connection alive"); LoginDatabase.KeepAlive(); } } // Close the Database Pool and library StopDB(); sLog->outInfo(LOG_FILTER_AUTHSERVER, "Halting process..."); return 0; }
int main(int argc, char *argv[]) { int exit_code = 0; slimproto_t slimproto; slimaudio_t slimaudio; PaDeviceIndex output_device_id = PA_DEFAULT_DEVICE; char *output_device_name = NULL; char *hostapi_name = NULL; unsigned int output_predelay = 0; unsigned int output_predelay_amplitude = 0; #ifdef EMPEG bool power_bypass = false, power_last = false; bool geteq = false; long key, ir; #endif #ifdef EMPEG slimaudio_volume_t volume_control = VOLUME_DRIVER; #else slimaudio_volume_t volume_control = VOLUME_SOFTWARE; #endif unsigned int retry_interval = RETRY_DEFAULT; char macaddress[6] = { 0, 0, 0, 0, 0, 1 }; int keepalive_interval = -1; bool listdevs = false; bool listservers = false; bool discover_server = false; unsigned int json_port; #ifdef SLIMPROTO_ZONES bool default_macaddress = true; unsigned int zone = 0; unsigned int num_zones = 1; #endif #ifdef DAEMONIZE bool should_daemonize = false; char *logfile = NULL; #endif #ifdef PORTAUDIO_DEV /* User suggested latency */ bool modify_latency = false; unsigned int user_latency = 0L; #endif char slimserver_address[INET_FQDNSTRLEN] = "127.0.0.1"; char getopt_options[OPTLEN] = "a:FId:Y:e:f:hk:Lm:n:o:P:p:Rr:TO:Vv:"; static struct option long_options[] = { {"predelay_amplitude", required_argument, 0, 'a'}, {"discover", no_argument, 0, 'F'}, {"debug", required_argument, 0, 'd'}, {"debuglog", required_argument, 0, 'Y'}, {"help", no_argument, 0, 'h'}, {"keepalive", required_argument, 0, 'k'}, {"list", no_argument, 0, 'L'}, {"findservers", no_argument, 0, 'I'}, {"mac", required_argument, 0, 'm'}, {"name", required_argument, 0, 'n'}, {"output", required_argument, 0, 'o'}, {"playerid", required_argument, 0, 'e'}, {"firmware", required_argument, 0, 'f'}, {"port", required_argument, 0, 'P'}, {"predelay", required_argument, 0, 'p'}, {"threshold_override", no_argument, 0, 'T'}, {"output_threshold", required_argument, 0, 'O'}, #ifdef EMPEG {"puteq", no_argument, 0, 'Q'}, {"geteq", no_argument, 0, 'q'}, #endif {"retry", no_argument, 0, 'R'}, {"intretry", required_argument, 0, 'r'}, {"version", no_argument, 0, 'V'}, {"volume", required_argument, 0, 'v'}, {"zone", required_argument, 0, 'z'}, #ifdef PORTAUDIO_DEV {"latency", required_argument, 0, 'y'}, {"audiotype", required_argument, 0, 't'}, #else {"paframes", required_argument, 0, 'g'}, {"pabuffers", required_argument, 0, 'j'}, #endif #ifdef DAEMONIZE {"daemonize", required_argument, 0, 'M'}, #endif #ifdef __WIN32__ {"highpriority", no_argument, 0, 'H'}, #ifdef PADEV_WASAPI {"shared", no_argument, 0, 'S'}, #endif #endif #ifdef INTERACTIVE {"lircrc", required_argument, 0, 'c'}, {"lirc", no_argument, 0, 'i'}, {"lcd", no_argument, 0, 'l'}, {"lcdc", no_argument, 0, 'C'}, {"display", no_argument, 0, 'D'}, {"width", required_argument, 0, 'w'}, #endif #ifdef SLIMPROTO_RENICE {"renice", no_argument, 0, 'N'}, #endif #ifdef SLIMPROTO_ZONES {"zone", required_argument, 0, 'z'}, #endif {0, 0, 0, 0} }; #ifdef INTERACTIVE fd_set read_fds; fd_set write_fds; int key = 0; unsigned long ir = 0; int maxfd = 0; char *home; struct timeval timeout; timeout.tv_usec = 0; #ifdef __WIN32__ int WSAerrno; int ptw32_processInitialize (void); ptw32_processInitialize(); #endif /* __WIN32__ */ /* default lircrc file ($HOME/.lircrc) */ home = getenv("HOME"); if (home == NULL) home = ""; lircrc = (char *)malloc((strlen(home) + strlen("/.lircrc") + 1) * sizeof(char)); strcpy(lircrc,home); strcat(lircrc,"/.lircrc"); #endif /* INTERACTIVE */ #ifdef EMPEG strcat (getopt_options, "Qq"); #endif #ifdef PORTAUDIO_DEV strcat (getopt_options, "y:t:"); #else strcat (getopt_options, "g:j:"); #endif #ifdef DAEMONIZE strcat (getopt_options, "M:"); #endif #ifdef INTERACTIVE strcat (getopt_options, "c:CDilw:"); #endif #ifdef __WIN32__ strcat (getopt_options, "H"); #ifdef PADEV_WASAPI strcat (getopt_options, "S"); #endif #endif #ifdef SLIMPROTO_RENICE strcat (getopt_options, "N"); #endif #ifdef SLIMPROTO_ZONES strcat (getopt_options, "z:"); #endif #ifdef EMPEG empeg_getmac(macaddress); #endif while (true) { const char shortopt = getopt_long_only(argc, argv, getopt_options, long_options, NULL); if (shortopt == (char) -1) { break; } switch (shortopt) { case 'a': output_predelay_amplitude = strtoul(optarg, NULL, 0); break; case 'F': discover_server = true; break; case 'd': #ifdef SLIMPROTO_DEBUG if (strcmp(optarg, "all") == 0) { slimproto_debug = true; slimaudio_debug = true; slimaudio_buffer_debug = true; slimaudio_buffer_debug_v = true; slimaudio_decoder_debug = true; slimaudio_decoder_debug_r = true; slimaudio_decoder_debug_v = true; slimaudio_http_debug = true; slimaudio_http_debug_v = true; slimaudio_output_debug = true; slimaudio_output_debug_v = true; } else if (strcmp(optarg, "slimproto") == 0) slimproto_debug = true; else if (strcmp(optarg, "slimaudio") == 0) slimaudio_debug = true; else if (strcmp(optarg, "slimaudio_buffer") == 0) slimaudio_buffer_debug = true; else if (strcmp(optarg, "slimaudio_buffer_v") == 0) slimaudio_buffer_debug_v = true; else if (strcmp(optarg, "slimaudio_decoder") == 0) slimaudio_decoder_debug = true; else if (strcmp(optarg, "slimaudio_decoder_r") == 0) slimaudio_decoder_debug_r = true; else if (strcmp(optarg, "slimaudio_decoder_v") == 0) slimaudio_decoder_debug_v = true; else if (strcmp(optarg, "slimaudio_http") == 0) slimaudio_http_debug = true; else if (strcmp(optarg, "slimaudio_http_v") == 0) slimaudio_http_debug_v = true; else if (strcmp(optarg, "slimaudio_output") == 0) slimaudio_output_debug = true; else if (strcmp(optarg, "slimaudio_output_v") == 0) slimaudio_output_debug_v = true; else fprintf(stderr, "%s: Unknown debug option %s\n", argv[0], optarg); #else fprintf(stderr, "%s: Recompile with -DSLIMPROTO_DEBUG to enable debugging.\n", argv[0]); #endif break; case 'Y': #ifdef SLIMPROTO_DEBUG if ( optarg == NULL ) { fprintf(stderr, "%s: Cannot parse debug log filename %s\n", argv[0], optarg); exit(-1); } else { debuglog = freopen( optarg, "a", stderr); if ( debuglog ) debug_logfile = true; else fprintf(stderr, "%s: Redirection of stderr to %s failed.\n", argv[0], optarg); } #endif break; /* From server/Slim/Networking/Slimproto.pm from 7.5r28596 ** squeezebox(2) ** softsqueeze(3) ** squeezebox2(4) ** transporter(5) ** softsqueeze3(6) ** receiver(7) ** squeezeslave(8) ** controller(9) ** boom(10) ** softboom(11) ** squeezeplay(12) ** radio(13) ** touch(14) */ case 'e': player_type = strtoul(optarg, NULL, 0); if ( (player_type < 2) || (player_type > 14) ) { player_type = PLAYER_TYPE; fprintf(stderr, "%s: Unknown player type, using (%d)\n", argv[0], player_type); } break; case 'f': firmware = strtoul(optarg, NULL, 0); if ( (firmware < 0) || (firmware > 254) ) { firmware = FIRMWARE_VERSION; fprintf(stderr, "%s: Invalid firmware value, using (%d)\n", argv[0], firmware); } break; case 'h': print_help(); exit(0); case 'k': keepalive_interval = strtoul(optarg, NULL, 0); break; case 'T': threshold_override = true; break; case 'O': output_threshold = strtoul(optarg, NULL, 0); if ( (output_threshold < 0) || (output_threshold > 1000000) ) { output_threshold = OUTPUT_THRESHOLD; fprintf(stderr, "%s: Invalid output threshold, using (%d)\n", argv[0], output_threshold); } break; case 'm': if (parse_macaddress(macaddress, optarg) != 0) { fprintf(stderr, "%s: Cannot parse mac address %s\n", argv[0], optarg); exit(-1); } #ifdef SLIMPROTO_ZONES default_macaddress = false; #endif break; #ifdef DAEMONIZE case 'M': if ( optarg == NULL ) { fprintf(stderr, "%s: Cannot parse log filename %s\n", argv[0], optarg); exit(-1); } else { logfile = optarg; } should_daemonize = true; break; #endif #ifdef __WIN32__ case 'H': /* Change Window process priority class to HIGH */ if ( !SetPriorityClass ( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) { int dwError = GetLastError(); fprintf(stderr, "%s: Failed to set priority (%d), using default.\n", argv[0], dwError); } break; #ifdef PADEV_WASAPI case 'S': wasapi_exclusive = false; break; #endif #endif #ifdef SLIMPROTO_RENICE case 'N': renice = true; break; #endif case 'n': output_device_name = optarg; output_change = true; break; case 'o': output_device_id = strtoul(optarg, NULL, 0); output_change = true; break; case 'p': output_predelay = strtoul(optarg, NULL, 0); break; case 'P': port = strtoul(optarg, NULL, 0); if ( (port < 0) || (port > 65535) ) { port = SLIMPROTOCOL_PORT; fprintf(stderr, "%s: Invalid port number, using %d.\n", argv[0], port); } break; break; #ifdef EMPEG case 'Q': empeg_puteq_tofile(); exit(0); break; case 'q': geteq = true; break; #endif case 'R': retry_connection = true; break; case 'r': retry_connection = true; retry_interval = strtoul(optarg, NULL, 0); if ( ( retry_interval < 1 ) || ( retry_interval > 120 ) ) { retry_interval = RETRY_DEFAULT; fprintf (stderr, "Invalid retry interval, using %d seconds.\n", retry_interval ); } break; #ifdef INTERACTIVE case 'c': free(lircrc); lircrc = optarg; break; #ifndef __WIN32__ case 'i': using_lirc = true; break; case 'l': use_lcdd_menu = true; break; case 'C': use_lcdd_menu = true; lcdd_compat = true; break; #endif case 'D': using_curses = 1; break; case 'w': linelen = strtoul(optarg, NULL, 0); break; #endif case 'L': listdevs = true; break; case 'I': listservers = true; break; case 'V': print_version(); exit(0); break; case 'v': if (strcmp(optarg, "sw") == 0) { volume_control = VOLUME_SOFTWARE; } #ifndef PORTAUDIO_DEV else if (strcmp(optarg, "on") == 0 ) { volume_control = VOLUME_DRIVER; } #endif else if (strcmp(optarg, "off") == 0 ) { volume_control = VOLUME_NONE; } break; #ifdef PORTAUDIO_DEV case 'y': modify_latency = true; user_latency = strtoul(optarg, NULL, 0); if ( user_latency > 1000 ) { fprintf (stderr, "Suggested latency invalid, using device default.\n"); modify_latency = false; } break; case 't': hostapi_name = optarg; break; #else case 'g': pa_framesPerBuffer = strtoul(optarg, NULL, 0); if ( (pa_framesPerBuffer > 65536) || (pa_framesPerBuffer < 64) ) { fprintf (stderr, "Portaudio frames per buffer invalid, using default (%d).\n", PA_FRAMES_PER_BUFFER); pa_framesPerBuffer = PA_FRAMES_PER_BUFFER ; } break; case 'j': pa_numberOfBuffers = strtoul(optarg, NULL, 0); if ( (pa_numberOfBuffers > 64) || (pa_numberOfBuffers < 0) ) { fprintf (stderr, "Number of Portaudio buffers invalid, using default (%d).\n", PA_NUM_BUFFERS); pa_numberOfBuffers = PA_NUM_BUFFERS; } break; #endif #ifdef SLIMPROTO_ZONES case 'z': if (sscanf(optarg, "%u/%u", &zone, &num_zones) != 2) { fprintf (stderr, "Invalid zone specification, using default.\n"); } if (num_zones > MAX_ZONES) { fprintf(stderr, "Number of zones > %d not supported\n", MAX_ZONES); zone=0; num_zones=1; } if (num_zones <= zone) { fprintf (stderr, "Invalid zone specification, using default.\n"); zone = 0; num_zones = 1; } break; #endif default: break; } } if (listdevs) { GetAudioDevices(output_device_id, output_device_name, hostapi_name, output_change, true); exit(0); } if (listservers) { slimproto_discover(slimserver_address, sizeof(slimserver_address), port, &json_port, true); exit(0); } if (optind < argc) strncpy(slimserver_address, argv[optind], sizeof(slimserver_address)); #ifdef DAEMONIZE if ( should_daemonize ) { #ifdef INTERACTIVE if ( using_curses || use_lcdd_menu ) { fprintf(stderr, "Daemonize not supported with display modes.\n"); exit(-1); } else #endif init_daemonize(); } #endif signal(SIGTERM, &exit_handler); signal(SIGINT, &exit_handler); install_restart_handler(); #ifdef INTERACTIVE install_toggle_handler(); /*SIGUSR2 to toggle IR/LCD on and off */ #endif if (slimproto_init(&slimproto) < 0) { fprintf(stderr, "Failed to initialize slimproto\n"); exit(-1); } #ifdef SLIMPROTO_ZONES if (slimaudio_init(&slimaudio, &slimproto, output_device_id, output_device_name, hostapi_name, output_change, zone, num_zones) < 0) #else if (slimaudio_init(&slimaudio, &slimproto, output_device_id, output_device_name, hostapi_name, output_change) < 0) #endif { fprintf(stderr, "Failed to initialize slimaudio\n"); exit(-1); } #ifdef SLIMPROTO_ZONES if (default_macaddress) macaddress[5] += zone; #endif #ifdef PORTAUDIO_DEV if( modify_latency ) { slimaudio_set_latency( &slimaudio, user_latency ); } #endif slimaudio_set_renice( &slimaudio, renice ); slimproto_add_connect_callback(&slimproto, connect_callback, macaddress); #ifdef INTERACTIVE /* Process VFD (display) commands */ if ( using_curses || using_lirc || use_lcdd_menu ) slimproto_add_command_callback(&slimproto, "vfdc", vfd_callback, macaddress); #endif #ifdef EMPEG slimproto_add_command_callback(&slimproto, "grfe", empeg_vfd_callback, macaddress); slimproto_add_command_callback(&slimproto, "grfb", empeg_vfdbrt_callback, macaddress); slimproto_add_command_callback(&slimproto, "aude", empeg_aude_callback, macaddress); #endif slimaudio_set_volume_control(&slimaudio, volume_control); slimaudio_set_output_predelay(&slimaudio, output_predelay, output_predelay_amplitude); if (keepalive_interval >= 0) { slimaudio_set_keepalive_interval(&slimaudio, keepalive_interval); } #ifdef INTERACTIVE init_lcd(); #endif #ifdef EMPEG empeg_init(); if (geteq) empeg_geteq_fromfile(); power_last = empeg_state.power_on; empeg_state.power_on = false; #endif if (slimaudio_open(&slimaudio) < 0) { fprintf(stderr, "Failed to open slimaudio\n"); exit_code = -1; goto exit; } #ifdef SLIMPROTO_DEBUG if (slimaudio_debug) fprintf ( stderr, "Using audio device index: %d\n", slimaudio.output_device_id ); #endif #ifdef INTERACTIVE init_lirc(); setlocale(LC_ALL, ""); initcurses(); #endif #ifdef DAEMONIZE if ( should_daemonize ) { daemonize(logfile); } #endif /* When retry_connection is true, retry connecting to Squeezebox Server ** until we succeed, unless the signal handler tells us to give up. */ do { if (signal_restart_flag) { #ifdef INTERACTIVE exitcurses(); #endif fprintf(stderr,"Retry in %d seconds.\n", retry_interval); Pa_Sleep(1000 * retry_interval); #ifdef INTERACTIVE initcurses(); #endif } #ifdef EMPEG if (discover_server && empeg_state.last_server[0] != '\0') { strcpy(slimserver_address, (char *)empeg_state.last_server); empeg_state.last_server[0] = '\0'; } else #endif if (discover_server && slimproto_discover(slimserver_address, sizeof(slimserver_address), port, &json_port, false) < 0) { fprintf(stderr,"Discover failed.\n"); if (!retry_connection) { exit_code = -1; goto exit; } signal_restart_flag = true; continue; } if (slimproto_connect( &slimproto, slimserver_address, port) < 0) { fprintf(stderr, "Connection to Squeezebox Server %s failed.\n", slimserver_address); if (!retry_connection) { exit_code = -1; goto exit; } signal_restart_flag = true; continue; } signal_restart_flag = false; discover_server = false; #ifdef EMPEG strcpy((char *)empeg_state.last_server, slimserver_address); if (power_last) while (!empeg_state.power_on) { Pa_Sleep(100); slimproto_ir(&slimproto, 1, 1, 0x76898F70); } #endif while (!signal_exit_flag && !signal_restart_flag) { #ifdef EMPEG int rc = empeg_idle(); if (power_bypass) { if (rc == 0 || !empeg_state.power_on) { power_last = false; power_bypass = false; } } else if (rc == -1) { fprintf(stderr, "Power loss detected.\n"); power_last = empeg_state.power_on; slimproto_ir(&slimproto, 1, 1, 0x76898778); while (empeg_state.power_on) Pa_Sleep(250); } else if (rc == -2 && empeg_state.power_on) { fprintf(stderr, "Manual override, aborting power down.\n"); power_bypass = true; } else if (rc == -3) { fprintf(stderr, "Power restored.\n"); if (power_last) slimproto_ir(&slimproto, 1, 1, 0x76898F70); } else if (rc == -4) { fprintf(stderr, "Powering down.\n"); slimproto_goodbye(&slimproto, 0x00); Pa_Sleep(400); slimproto_close(&slimproto); empeg_state.power_on = power_last; empeg_poweroff(); signal_restart_flag = true; } #endif #ifdef INTERACTIVE if (using_curses == 1 || use_lcdd_menu || using_lirc) { FD_ZERO(&read_fds); FD_ZERO(&write_fds); if (using_curses == 1) FD_SET(0, &read_fds); /* watch stdin */ if (use_lcdd_menu) { FD_SET(lcd_fd, &read_fds); maxfd = lcd_fd; } if (using_lirc) { FD_SET(lirc_fd, &read_fds); if (lirc_fd > maxfd) maxfd = lirc_fd; } timeout.tv_sec = 5; if(select(maxfd + 1, &read_fds, NULL, NULL, &timeout) == -1) { #ifndef __WIN32__ if (errno != EINTR) { fprintf(stderr,"Select Error:%d\n", errno); #else WSAerrno = WSAGetLastError(); if ( (WSAerrno != WSAEINTR) && (WSAerrno != WSAENOTSOCK) ) { fprintf(stderr,"Select Error:%d\n", WSAerrno); #endif abort(); } #ifdef __WIN32__ else WaitForSingleObject( GetStdHandle(STD_INPUT_HANDLE), 5000 ); #endif } if (FD_ISSET(0, &read_fds)) { while ((key = getch()) != ERR) { ir = getircode(key); if (ir == (unsigned long) 0x01) { signal_exit_flag = 1; }else{ if (ir != 0) slimproto_ir(&slimproto, 1, 1, ir); } } } if (using_lirc && FD_ISSET(lirc_fd, &read_fds)) { while((key = read_lirc()) != 0 ) { ir = getircode(key); if (ir == 0x01) { signal_exit_flag = 1; } else { if (ir != 0) slimproto_ir(&slimproto, 1, 1, ir); } } } if (use_lcdd_menu && FD_ISSET(lcd_fd, &read_fds)) { while(read_lcd()); } } else { wait_for_restart_signal(); } #else #ifdef EMPEG while ((key = empeg_getkey()) != -1) { ir = empeg_getircode(key); if (ir != 0) slimproto_ir(&slimproto, 1, 1, ir); } #else wait_for_restart_signal(); #endif #endif } #ifdef INTERACTIVE FD_ZERO(&read_fds); FD_ZERO(&write_fds); #endif } while (signal_restart_flag && !signal_exit_flag); exit: slimaudio_close(&slimaudio); slimproto_goodbye(&slimproto, 0x00); /* Wait 200ms for BYE! message send to complete */ Pa_Sleep(200); slimproto_close(&slimproto); #ifdef INTERACTIVE exitcurses(); close_lirc(); #endif #if defined(EMPEG) || defined(INTERACTIVE) close_lcd(); #endif #ifdef SLIMPROTO_DEBUG if (debug_logfile) { fclose (debuglog); } #endif slimproto_destroy(&slimproto); slimaudio_destroy(&slimaudio); return exit_code; }
void SKSE64_Initialize(void) { if(isInit) return; isInit = true; gLog.OpenRelative(CSIDL_MYDOCUMENTS, "\\My Games\\Skyrim Special Edition\\SKSE\\skse64.log"); #ifndef _DEBUG __try { #endif FILETIME now; GetSystemTimeAsFileTime(&now); _MESSAGE("SKSE64 runtime: initialize (version = %d.%d.%d %08X %08X%08X, os = %s)", SKSE_VERSION_INTEGER, SKSE_VERSION_INTEGER_MINOR, SKSE_VERSION_INTEGER_BETA, RUNTIME_VERSION, now.dwHighDateTime, now.dwLowDateTime, GetOSInfoStr().c_str()); _MESSAGE("imagebase = %016I64X", GetModuleHandle(NULL)); _MESSAGE("reloc mgr imagebase = %016I64X", RelocationManager::s_baseAddr); #ifdef _DEBUG SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); WaitForDebugger(); #endif if(!g_branchTrampoline.Create(1024 * 64)) { _ERROR("couldn't create branch trampoline. this is fatal. skipping remainder of init process."); return; } if(!g_localTrampoline.Create(1024 * 64, g_moduleHandle)) { _ERROR("couldn't create codegen buffer. this is fatal. skipping remainder of init process."); return; } // Add Hooks_XXX_Init calls here Hooks_Debug_Init(); Hooks_ObScript_Init(); Hooks_Papyrus_Init(); Hooks_NetImmerse_Init(); Hooks_Threads_Init(); Hooks_Handlers_Init(); g_pluginManager.Init(); // Add Hooks_XXX_Commit calls here in the same order Hooks_Debug_Commit(); Hooks_ObScript_Commit(); Hooks_Papyrus_Commit(); Hooks_UI_Commit(); Hooks_Camera_Commit(); Hooks_NetImmerse_Commit(); Hooks_Threads_Commit(); Hooks_Handlers_Commit(); Hooks_Scaleform_Commit(); Hooks_Gameplay_Commit(); Hooks_Event_Commit(); Hooks_SaveLoad_Commit(); Hooks_Data_Commit(); Init_CoreSerialization_Callbacks(); Hooks_DirectInput_Commit(); FlushInstructionCache(GetCurrentProcess(), NULL, 0); #ifndef _DEBUG } __except(EXCEPTION_EXECUTE_HANDLER) { _ERROR("exception thrown during startup"); } #endif _MESSAGE("init complete"); }
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_CREATE: hListBox1 = CreateWindowEx(WS_EX_CLIENTEDGE , L"LISTBOX", NULL , WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL | LBS_NOTIFY , 10, 10, 250, 480 , hWnd, (HMENU)LB1, hInst, NULL); hListBox2 = CreateWindowEx(WS_EX_CLIENTEDGE , L"LISTBOX", NULL , WS_CHILD | WS_VISIBLE | WS_VSCROLL | ES_AUTOVSCROLL , 270, 10, 250, 480 , hWnd, NULL, hInst, NULL); break; case WM_COMMAND: if (LOWORD(wParam) >= ID_IDLE && LOWORD(wParam) <= ID_ABOVENORMAL) { int index = SendMessage(hListBox1, LB_GETCURSEL, 0, 0); if (index == LB_ERR) break; int pid = SendMessage(hListBox1, LB_GETITEMDATA, index, 0); int priority = 0; switch(LOWORD(wParam)) { case ID_IDLE: priority = IDLE_PRIORITY_CLASS; break; case ID_BELOWNORMAL: priority = BELOW_NORMAL_PRIORITY_CLASS; break; case ID_NORMAL: priority = NORMAL_PRIORITY_CLASS; break; case ID_ABOVENORMAL: priority = ABOVE_NORMAL_PRIORITY_CLASS; case ID_HIGH: priority = HIGH_PRIORITY_CLASS; break; case ID_REALTIME: priority = REALTIME_PRIORITY_CLASS; break; } HANDLE hProcess = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pid); if (!SetPriorityClass(hProcess, priority)) MessageBox(hWnd, L"Failed to set priority", L"", MB_ICONERROR); CloseHandle(hProcess); GetProcessList(); } switch(LOWORD(wParam)) { case LB1: { if (HIWORD(wParam) == NM_RCLICK) { int index = SendMessage(hListBox1, LB_GETCURSEL, 0, 0); } if (HIWORD(wParam) != 0) { int index = SendMessage(hListBox1, LB_GETCURSEL, 0, 0); if (index == LB_ERR) break; int pid = SendMessage(hListBox1, LB_GETITEMDATA, index, 0); SendMessage(hListBox2, LB_RESETCONTENT, 0, 0); GetProcessModulesList(pid); } break; } } break; case WM_CONTEXTMENU: if ((HWND)wParam == hListBox1) { HMENU hMenu = LoadMenu(hInst, MAKEINTRESOURCE(IDR_MENU1)); hMenu = GetSubMenu(hMenu, 0); SetForegroundWindow(hWnd); TrackPopupMenu(hMenu, TPM_TOPALIGN | TPM_LEFTALIGN | TPM_NOANIMATION, LOWORD(lParam), HIWORD(lParam), 0, hWnd, NULL); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); break; } return 0; }
/// Launch the realm server extern int main(int argc, char **argv) { ///- Command line parsing char const* cfg_file = _REALMD_CONFIG; #ifdef WIN32 char const *options = ":c:s:"; #else char const *options = ":c:"; #endif ACE_Get_Opt cmd_opts(argc, argv, options); cmd_opts.long_option("version", 'v'); int option; while ((option = cmd_opts()) != EOF) { switch (option) { case 'c': cfg_file = cmd_opts.opt_arg(); break; case 'v': printf("%s\n", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID)); return 0; #ifdef WIN32 case 's': { const char *mode = cmd_opts.opt_arg(); if (!strcmp(mode, "install")) { if (WinServiceInstall()) sLog.outString("Installing service"); return 1; } else if (!strcmp(mode, "uninstall")) { if (WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; } else if (!strcmp(mode, "run")) WinServiceRun(); else { sLog.outError("Runtime-Error: -%c unsupported argument %s", cmd_opts.opt_opt(), mode); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } break; } #endif case ':': sLog.outError("Runtime-Error: -%c option requires an input argument", cmd_opts.opt_opt()); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; default: sLog.outError("Runtime-Error: bad format of commandline arguments"); usage(argv[0]); Log::WaitBeforeContinueIfNeed(); return 1; } } if (!sConfig.SetSource(cfg_file)) { sLog.outError("Could not find configuration file %s.", cfg_file); Log::WaitBeforeContinueIfNeed(); return 1; } sLog.Initialize(); sLog.outString( "%s [realm-daemon]", _FULLVERSION(REVISION_DATE,REVISION_TIME,REVISION_NR,REVISION_ID) ); sLog.outString( "<Ctrl-C> to stop.\n" ); sLog.outString("Using configuration file %s.", cfg_file); ///- Check the version of the configuration file uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); if (confVersion < _REALMDCONFVERSION) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: Your realmd.conf version indicates your conf file is out of date!"); sLog.outError(" Please check for updates, as your current default values may cause"); sLog.outError(" strange behavior."); sLog.outError("*****************************************************************************"); Log::WaitBeforeContinueIfNeed(); } DETAIL_LOG("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); if (SSLeay() < 0x009080bfL ) { DETAIL_LOG("WARNING: Outdated version of OpenSSL lib. Logins to server may not work!"); DETAIL_LOG("WARNING: Minimal required version [OpenSSL 0.9.8k]"); } DETAIL_LOG("Using ACE: %s", ACE_VERSION); #if defined (ACE_HAS_EVENT_POLL) || defined (ACE_HAS_DEV_POLL) ACE_Reactor::instance(new ACE_Reactor(new ACE_Dev_Poll_Reactor(ACE::max_handles(), 1), 1), true); #else ACE_Reactor::instance(new ACE_Reactor(new ACE_TP_Reactor(), true), true); #endif sLog.outBasic("Max allowed open files is %d", ACE::max_handles()); /// realmd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if(!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if( !pid ) { sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); Log::WaitBeforeContinueIfNeed(); return 1; } sLog.outString( "Daemon PID: %u\n", pid ); } ///- Initialize the database connection if(!StartDB()) { Log::WaitBeforeContinueIfNeed(); return 1; } ///- Get the list of realms for the server sRealmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (sRealmList.size() == 0) { sLog.outError("No valid realms specified."); Log::WaitBeforeContinueIfNeed(); return 1; } // cleanup query // set expired bans to inactive LoginDatabase.BeginTransaction(); LoginDatabase.Execute("UPDATE account_banned SET active = 0 WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.Execute("DELETE FROM ip_banned WHERE unbandate<=UNIX_TIMESTAMP() AND unbandate<>bandate"); LoginDatabase.CommitTransaction(); ///- Launch the listening network socket ACE_Acceptor<AuthSocket, ACE_SOCK_Acceptor> acceptor; uint16 rmport = sConfig.GetIntDefault("RealmServerPort", DEFAULT_REALMSERVER_PORT); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); ACE_INET_Addr bind_addr(rmport, bind_ip.c_str()); if(acceptor.open(bind_addr, ACE_Reactor::instance(), ACE_NONBLOCK) == -1) { sLog.outError("MaNGOS realmd can not bind to %s:%d", bind_ip.c_str(), rmport); Log::WaitBeforeContinueIfNeed(); return 1; } // FG: "bad points" system related uint32 badPointsDropInterval = sConfig.GetIntDefault("BadPoints.DropInterval", HOUR); uint32 badPointsDropAmount = sConfig.GetIntDefault("BadPoints.DropAmount", 1); uint32 badPointsDropWaitTime = sConfig.GetIntDefault("BadPoints.WaitTime", WEEK); IntervalTimer badPointsTimer; badPointsTimer.SetInterval(badPointsDropInterval * IN_MILLISECONDS); ///- Catch termination signals HookSignals(); ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if(Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if(!curAff ) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); } else { if(SetProcessAffinityMask(hProcess,curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if(Prio) { if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) sLog.outString("realmd process priority class set to HIGH"); else sLog.outError("Can't set realmd process priority class."); sLog.outString(); } } #endif //server has started up successfully => enable async DB requests LoginDatabase.AllowAsyncTransactions(); // maximum counter for next ping uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; uint32 last_ping_time = 0; uint32 now = WorldTimer::getMSTime(); uint32 diff; uint32 lasttime = now; uint32 last_ipprops_cleanup = 0; ///- Wait for termination signal while (!stopEvent) { // dont move this outside the loop, the reactor will modify it ACE_Time_Value interval(0, 100000); if (ACE_Reactor::instance()->run_reactor_event_loop(interval) == -1) break; now = WorldTimer::getMSTime(); diff = WorldTimer::getMSTimeDiff(lasttime, now); lasttime = now; badPointsTimer.Update(diff); if( (++loopCounter) == numLoops ) { // FG: protect against network system overloading // if that happens, force realmd close (autorestarter ftw!) if(WorldTimer::getMSTimeDiff(last_ping_time, now) < 10000) { sLog.outError("NETWORK SYSTEM OVERLOAD"); raise(SIGSEGV); // force close abort(); } last_ping_time = now; loopCounter = 0; DETAIL_LOG("Ping MySQL to keep connection alive"); LoginDatabase.Ping(); } // FG: clear flood protect buffer periodically if(WorldTimer::getMSTimeDiff(last_ipprops_cleanup, now) > 30000) // flush stored IPs every 30 secs { last_ipprops_cleanup = now; uint32 flushed = 0, blocked = 0, stored = 0; CleanupIPPropmap(flushed, blocked, stored); sLog.outDetail("IPProp: Flushed %u total, %u of them blocked, now %u stored", flushed, blocked, stored); } // FG: handle "bad points" drop if(badPointsTimer.Passed()) { badPointsTimer.Reset(); if(badPointsDropAmount) { uint64 goodtime = uint64(time(NULL)) - badPointsDropWaitTime; LoginDatabase.Execute("UPDATE account_badpoints SET maxpts = curpts WHERE maxpts < curpts"); LoginDatabase.PExecute("UPDATE account_badpoints SET curpts = 0 WHERE curpts <= %u AND lasttime < "UI64FMTD, badPointsDropAmount, goodtime); LoginDatabase.PExecute("UPDATE account_badpoints SET curpts = curpts - %u WHERE curpts > %u AND lasttime < "UI64FMTD, badPointsDropAmount, badPointsDropAmount, goodtime); } } #ifdef WIN32 if (m_ServiceStatus == 0) stopEvent = true; while (m_ServiceStatus == 2) Sleep(1000); #endif } ///- Wait for the delay thread to exit LoginDatabase.HaltDelayThread(); ///- Remove signal handling before leaving UnhookSignals(); sLog.outString( "Halting process..." ); return 0; }
/// Launch the realm server extern int main(int argc, char **argv) { sLog.SetLogDB(false); ///- Command line parsing to get the configuration file name char const* cfg_file = _CW_REALM_CONFIG; int c=1; while( c < argc ) { if( strcmp(argv[c],"-c") == 0) { if( ++c >= argc ) { sLog.outError("Runtime-Error: -c option requires an input argument"); usage(argv[0]); return 1; } else cfg_file = argv[c]; } #ifdef WIN32 //////////// //Services// //////////// if( strcmp(argv[c],"-s") == 0) { if( ++c >= argc ) { sLog.outError("Runtime-Error: -s option requires an input argument"); usage(argv[0]); return 1; } if( strcmp(argv[c],"install") == 0) { if (WinServiceInstall()) sLog.outString("Installing service"); return 1; } else if( strcmp(argv[c],"uninstall") == 0) { if(WinServiceUninstall()) sLog.outString("Uninstalling service"); return 1; } else { sLog.outError("Runtime-Error: unsupported option %s",argv[c]); usage(argv[0]); return 1; } } if( strcmp(argv[c],"--service") == 0) { WinServiceRun(); } //// #endif ++c; } if (!sConfig.SetSource(cfg_file)) { sLog.outError("Could not find configuration file %s.", cfg_file); return 1; } sLog.Initialize(); sLog.outString( "%s (realm-daemon)", _FULLVERSION ); sLog.outString( "<Ctrl-C> to stop.\n" ); sLog.outString("Using configuration file %s.", cfg_file); ///- Check the version of the configuration file uint32 confVersion = sConfig.GetIntDefault("ConfVersion", 0); if (confVersion < _REALMDCONFVERSION) { sLog.outError("*****************************************************************************"); sLog.outError(" WARNING: Your CWrealm.conf version indicates your conf file is out of date!"); sLog.outError(" Please check for updates, as your current default values may cause"); sLog.outError(" strange behavior."); sLog.outError("*****************************************************************************"); clock_t pause = 3000 + clock(); while (pause > clock()) {} } sLog.outDetail("%s (Library: %s)", OPENSSL_VERSION_TEXT, SSLeay_version(SSLEAY_VERSION)); if (SSLeay() < 0x009080bfL ) { sLog.outError("Outdated version of OpenSSL lib. Logins to server impossible!"); sLog.outError("Minimal required version [OpenSSL 0.9.8k]"); clock_t pause = 5000 + clock(); while (pause > clock()) {} return 1; } /// realmd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if(!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if( !pid ) { sLog.outError( "Cannot create PID file %s.\n", pidfile.c_str() ); return 1; } sLog.outString( "Daemon PID: %u\n", pid ); } ///- Initialize the database connection if(!StartDB()) return 1; ///- Initialize the log database if(sConfig.GetBoolDefault("EnableLogDB", false)) { // everything successful - set var to enable DB logging once startup finished. sLog.SetLogDBLater(true); sLog.SetLogDB(false); // ensure we've set realm to 0 (realmd realmid) sLog.SetRealmID(0); } else { sLog.SetLogDBLater(false); sLog.SetLogDB(false); sLog.SetRealmID(0); } ///- Get the list of realms for the server m_realmList.Initialize(sConfig.GetIntDefault("RealmsStateUpdateDelay", 20)); if (m_realmList.size() == 0) { sLog.outError("No valid realms specified."); return 1; } ///- Launch the listening network socket port_t rmport = sConfig.GetIntDefault( "RealmServerPort", DEFAULT_REALMSERVER_PORT ); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); SocketHandler h; ListenSocket<AuthSocket> authListenSocket(h); if ( authListenSocket.Bind(bind_ip.c_str(),rmport)) { sLog.outError( "CW realm can not bind to %s:%d",bind_ip.c_str(), rmport ); return 1; } h.Add(&authListenSocket); ///- Catch termination signals HookSignals(); ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if(Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if(GetProcessAffinityMask(hProcess,&appAff,&sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if(!curAff ) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for realmd. Accessible processors bitmask (hex): %x",Aff,appAff); } else { if(SetProcessAffinityMask(hProcess,curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); if(Prio) { if(SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS)) sLog.outString("CWRealm process priority class set to HIGH"); else sLog.outError("ERROR: Can't set realmd process priority class."); sLog.outString(); } } #endif // maximum counter for next ping uint32 numLoops = (sConfig.GetIntDefault( "MaxPingTime", 30 ) * (MINUTE * 1000000 / 100000)); uint32 loopCounter = 0; // possibly enable db logging; avoid massive startup spam by doing it here. if (sLog.GetLogDBLater()) { sLog.outString("Enabling database logging..."); sLog.SetLogDBLater(false); // login db needs thread for logging sLog.SetLogDB(true); } else { sLog.SetLogDB(false); sLog.SetLogDBLater(false); } ///- Wait for termination signal while (!stopEvent) { h.Select(0, 100000); if( (++loopCounter) == numLoops ) { loopCounter = 0; sLog.outDetail("Ping MySQL to keep connection alive"); delete loginDatabase.Query("SELECT 1 FROM realmlist LIMIT 1"); } #ifdef WIN32 if (m_ServiceStatus == 0) stopEvent = true; while (m_ServiceStatus == 2) Sleep(1000); #endif } ///- Wait for the delay thread to exit loginDatabase.ThreadEnd(); loginDatabase.HaltDelayThread(); ///- Remove signal handling before leaving UnhookSignals(); sLog.outString( "Halting process..." ); return 0; }
int CPROC PRIORITY( PSENTIENT ps, PTEXT parameters ) { // Just a note : Thread priority does not work // there are MANY MANY threads involved - so only // process priority applies... #if defined( WIN32 ) || defined( _WIN32 ) PTEXT pTemp; HANDLE hToken, hProcess; TOKEN_PRIVILEGES tp; OSVERSIONINFO osvi; DWORD dwPriority = 0xA5A5A5A5; osvi.dwOSVersionInfoSize = sizeof( osvi ); GetVersionEx( &osvi ); if( osvi.dwPlatformId == VER_PLATFORM_WIN32_NT ) { // allow shutdown priviledges.... // wonder if /shutdown will work wihtout this? if( DuplicateHandle( GetCurrentProcess(), GetCurrentProcess() , GetCurrentProcess(), &hProcess, 0 , FALSE, DUPLICATE_SAME_ACCESS ) ) if( OpenProcessToken( hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken ) ) { tp.PrivilegeCount = 1; if( LookupPrivilegeValue( NULL , SE_SHUTDOWN_NAME , &tp.Privileges[0].Luid ) ) { tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; AdjustTokenPrivileges( hToken, FALSE, &tp, 0, NULL, NULL ); } else GetLastError(); } else GetLastError(); else GetLastError(); } if( ps->CurrentMacro ) ps->CurrentMacro->state.flags.bSuccess = TRUE; pTemp = GetParam( ps, ¶meters ); if( pTemp ) { if( TextLike( pTemp, WIDE("idle") ) ) { dwPriority = IDLE_PRIORITY_CLASS; } else if( TextLike( pTemp, WIDE("normal") ) ) { dwPriority = NORMAL_PRIORITY_CLASS; } else if( TextLike( pTemp, WIDE("high") ) ) { dwPriority = HIGH_PRIORITY_CLASS; } else if( TextLike( pTemp, WIDE("realtime") ) ) { dwPriority = REALTIME_PRIORITY_CLASS; } else { if( !ps->CurrentMacro ) { DECLTEXT( msg, WIDE("Invalid process priority (not idle, normal, high, or realtime)") ); EnqueLink( &ps->Command->Output, &msg ); } else { ps->CurrentMacro->state.flags.bSuccess = FALSE; } } } else { if( !ps->CurrentMacro ) { DECLTEXT( msg, WIDE("No process priority specified (idle,normal,high,realtime)") ); EnqueLink( &ps->Command->Output, &msg ); } else { ps->CurrentMacro->state.flags.bSuccess = FALSE; } } if( dwPriority != 0xA5A5A5A5 ) SetPriorityClass( GetCurrentProcess(), dwPriority ); if( !b95 ) { // NT type system we opened these handles CloseHandle( hProcess ); CloseHandle( hToken ); } #endif return 0; }
/// Main function int Master::Run() { BigNumber seed1; seed1.SetRand(16 * 8); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "%s (worldserver-daemon)", _FULLVERSION); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, " "); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, " A World of Warcraft: Cataclysm Core Emulator "); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, " _/_/ _/ _/_/_/ _/_/ _/_/_/ _/_/_/_/ "); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, " _/ _/ _/ _/_/ _/ _/ _/ _/ _/ _/ _/ _/ "); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, " _/_/_/_/ _/_/ _/_/ _/ _/ _/ _/_/_/ _/_/_/ "); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, " _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ _/ "); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, " _/ _/ _/ _/ _/ _/_/_/ _/_/ _/ _/ _/_/_/_/ "); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, " Arkania Community (c) 2013"); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, " <http://arkania.net/>"); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, " "); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "<Ctrl-C> to stop.\n"); /// worldserver PID file creation std::string pidfile = ConfigMgr::GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { TC_LOG_ERROR(LOG_FILTER_WORLDSERVER, "Cannot create PID file %s.\n", pidfile.c_str()); return 1; } TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "Daemon PID: %u\n", pid); } ///- Start the databases if (!_StartDB()) return 1; // set server offline (not connectable) LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = (flag & ~%u) | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, REALM_FLAG_INVALID, realmID); ///- Initialize the World sWorld->SetInitialWorldSettings(); ///- Initialize the signal handlers WorldServerSignalHandler SignalINT, SignalTERM; #ifdef _WIN32 WorldServerSignalHandler SignalBREAK; #endif /* _WIN32 */ ///- Register worldserver's signal handlers ACE_Sig_Handler Handler; Handler.register_handler(SIGINT, &SignalINT); Handler.register_handler(SIGTERM, &SignalTERM); #ifdef _WIN32 Handler.register_handler(SIGBREAK, &SignalBREAK); #endif /* _WIN32 */ ///- Launch WorldRunnable thread ACE_Based::Thread world_thread(new WorldRunnable); world_thread.setPriority(ACE_Based::Highest); ACE_Based::Thread* cliThread = NULL; #ifdef _WIN32 if (ConfigMgr::GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) #else if (ConfigMgr::GetBoolDefault("Console.Enable", true)) #endif { ///- Launch CliRunnable thread cliThread = new ACE_Based::Thread(new CliRunnable); } ACE_Based::Thread rar_thread(new RARunnable); ///- Handle affinity for multiple processors and process priority on Windows #ifdef _WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = ConfigMgr::GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) { TC_LOG_ERROR(LOG_FILTER_WORLDSERVER, "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the worldserver. Accessible processors bitmask (hex): %x", Aff, appAff); } else { if (SetProcessAffinityMask(hProcess, curAff)) TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "Using processors (bitmask, hex): %x", curAff); else TC_LOG_ERROR(LOG_FILTER_WORLDSERVER, "Can't set used processors (hex): %x", curAff); } } } bool Prio = ConfigMgr::GetBoolDefault("ProcessPriority", false); //if (Prio && (m_ServiceStatus == -1) /* need set to default process priority class in service mode*/) if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "worldserver process priority class set to HIGH"); else TC_LOG_ERROR(LOG_FILTER_WORLDSERVER, "Can't set worldserver process priority class."); } } #endif //Start soap serving thread ACE_Based::Thread* soap_thread = NULL; if (ConfigMgr::GetBoolDefault("SOAP.Enabled", false)) { TCSoapRunnable* runnable = new TCSoapRunnable(); runnable->setListenArguments(ConfigMgr::GetStringDefault("SOAP.IP", "127.0.0.1"), uint16(ConfigMgr::GetIntDefault("SOAP.Port", 7878))); soap_thread = new ACE_Based::Thread(runnable); } ///- Start up freeze catcher thread if (uint32 freeze_delay = ConfigMgr::GetIntDefault("MaxCoreStuckTime", 0)) { FreezeDetectorRunnable* fdr = new FreezeDetectorRunnable(); fdr->SetDelayTime(freeze_delay * 1000); ACE_Based::Thread freeze_thread(fdr); freeze_thread.setPriority(ACE_Based::Highest); } ///- Launch the world listener socket uint16 wsport = uint16(sWorld->getIntConfig(CONFIG_PORT_WORLD)); std::string bind_ip = ConfigMgr::GetStringDefault("BindIP", "0.0.0.0"); if (sWorldSocketMgr->StartNetwork(wsport, bind_ip.c_str()) == -1) { TC_LOG_ERROR(LOG_FILTER_WORLDSERVER, "Failed to start network"); World::StopNow(ERROR_EXIT_CODE); // go down and shutdown the server } // set server online (allow connecting now) LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag & ~%u, population = 0 WHERE id = '%u'", REALM_FLAG_INVALID, realmID); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "%s (worldserver-daemon) ready...", _FULLVERSION); // when the main thread closes the singletons get unloaded // since worldrunnable uses them, it will crash if unloaded after master world_thread.wait(); rar_thread.wait(); if (soap_thread) { soap_thread->wait(); soap_thread->destroy(); delete soap_thread; } // set server offline LoginDatabase.DirectPExecute("UPDATE realmlist SET flag = flag | %u WHERE id = '%d'", REALM_FLAG_OFFLINE, realmID); ///- Clean database before leaving ClearOnlineAccounts(); _StopDB(); TC_LOG_INFO(LOG_FILTER_WORLDSERVER, "Halting process..."); if (cliThread) { #ifdef _WIN32 // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API) //_exit(1); // send keyboard input to safely unblock the CLI thread INPUT_RECORD b[5]; HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); b[0].EventType = KEY_EVENT; b[0].Event.KeyEvent.bKeyDown = TRUE; b[0].Event.KeyEvent.uChar.AsciiChar = 'X'; b[0].Event.KeyEvent.wVirtualKeyCode = 'X'; b[0].Event.KeyEvent.wRepeatCount = 1; b[1].EventType = KEY_EVENT; b[1].Event.KeyEvent.bKeyDown = FALSE; b[1].Event.KeyEvent.uChar.AsciiChar = 'X'; b[1].Event.KeyEvent.wVirtualKeyCode = 'X'; b[1].Event.KeyEvent.wRepeatCount = 1; b[2].EventType = KEY_EVENT; b[2].Event.KeyEvent.bKeyDown = TRUE; b[2].Event.KeyEvent.dwControlKeyState = 0; b[2].Event.KeyEvent.uChar.AsciiChar = '\r'; b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; b[2].Event.KeyEvent.wRepeatCount = 1; b[2].Event.KeyEvent.wVirtualScanCode = 0x1c; b[3].EventType = KEY_EVENT; b[3].Event.KeyEvent.bKeyDown = FALSE; b[3].Event.KeyEvent.dwControlKeyState = 0; b[3].Event.KeyEvent.uChar.AsciiChar = '\r'; b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; b[3].Event.KeyEvent.wVirtualScanCode = 0x1c; b[3].Event.KeyEvent.wRepeatCount = 1; DWORD numb; WriteConsoleInput(hStdIn, b, 4, &numb); cliThread->wait(); #else cliThread->destroy(); #endif delete cliThread; } // for some unknown reason, unloading scripts here and not in worldrunnable // fixes a memory leak related to detaching threads from the module //UnloadScriptingModule(); // Exit the process with specified return value return World::GetExitCode(); }
int genkmarkers(int argc, char* argv[]) { // determine my process name _splitpath(argv[0],NULL,NULL,gszProcName,NULL); #else int genkmarkers(int argc, char** argv) { // determine my process name CUtility::splitpath((char *)argv[0],NULL,gszProcName); #endif int iScreenLogLevel; // level of screen diagnostics int iFileLogLevel; // level of file diagnostics char szLogFile[_MAX_PATH]; // write diagnostics to this file int Rslt = 0; // function result code >= 0 represents success, < 0 on failure int NumberOfProcessors; // number of installed CPUs int NumThreads; // number of threads (0 defaults to number of CPUs) int PMode; // processing mode int KMerLen; // this length K-mers int PrefixLen; // inter-cultivar shared prefix length int SuffixLen; // cultivar specific suffix length int MinWithPrefix; // minimum number of cultivars required to have the shared prefix int MinHamming; // must be at least this Hamming away from any other K-mer in other species char szCultivarName[cMaxDatasetSpeciesChrom+1]; // cultivar name char szPartialCultivarsList[(cMaxDatasetSpeciesChrom + 10) * cMaxTargCultivarChroms]; // individual species parsed from this comma/tab/space separated list int NumPartialCultivars; // there are this many pseudo chromosomes for targeted cultivar for which K-mer markers are required char *pszPartialCultivars[cMaxTargCultivarChroms+1]; // pseudo chromosome names which identify targeted cultivar char szSfxPseudoGenome[_MAX_PATH]; // contains assembly + suffix array over all psuedo-chromosomes for all cultivars char szMarkerFile[_MAX_PATH]; // output potential markers to this file char szMarkerReadsFile[_MAX_PATH]; // output reads containing potential markers to this file char szSQLiteDatabase[_MAX_PATH]; // results summaries to this SQLite file char szExperimentName[cMaxDatasetSpeciesChrom+1]; // experiment name char szExperimentDescr[1000]; // describes experiment // command line args struct arg_lit *help = arg_lit0("h","help", "Print this help and exit"); struct arg_lit *version = arg_lit0("v","version,ver", "Print version information and exit"); struct arg_int *FileLogLevel=arg_int0("f", "FileLogLevel", "<int>","Level of diagnostics written to screen and logfile 0=fatal,1=errors,2=info,3=diagnostics,4=debug"); struct arg_file *LogFile = arg_file0("F","log","<file>", "Diagnostics log file"); struct arg_int *pmode = arg_int0("m","mode","<int>", "Processing mode : 0 - default with K-mer extension, 1 - no K-mer extension, 2 - inter-cultivar shared prefix sequences "); struct arg_int *kmerlen = arg_int0("k","kmer","<int>", "Cultivar specific K-mers of this length (default 50, range 25..100)"); struct arg_int *prefixlen = arg_int0("p","prefixlen","<int>", "Cultivar specific K-mers to contain inter-cultivar shared prefix sequences of this length (Mode 2 only"); struct arg_int *minwithprefix = arg_int0("s","minshared","<int>","Inter-cultivar shared prefix sequences must be present in this many cultivars (Mode 2 only, default all)"); struct arg_int *minhamming = arg_int0("K","minhamming","<int>", "Minimum Hamming separation distance in other non-target cultivars (default 2, range 1..5)"); struct arg_str *cultivar = arg_str1("c","cultivar","<str>", "Cultivar name to associate with identified marker K-mers"); struct arg_str *chromnames = arg_str1("C","chromnames","<str>", "Comma/space separated list of pseudo-chrom names specific to cultivar for which markers are required"); struct arg_file *infile = arg_file1("i","in","<file>", "Use this suffix indexed pseudo-chromosomes file"); struct arg_file *outfile = arg_file1("o","markers","<file>", "Output accepted marker K-mer sequences to this multifasta file"); struct arg_file *outreadsfile = arg_file0("O","markerreads","<file>", "Output reads containing accepted marker K-mers to this multifasta file"); struct arg_int *numthreads = arg_int0("T","threads","<int>", "number of processing threads 0..128 (defaults to 0 which sets threads to number of CPU cores)"); struct arg_file *summrslts = arg_file0("q","sumrslts","<file>", "Output results summary to this SQLite3 database file"); struct arg_str *experimentname = arg_str0("w","experimentname","<str>", "experiment name SQLite3 database file"); struct arg_str *experimentdescr = arg_str0("W","experimentdescr","<str>", "experiment description SQLite3 database file"); struct arg_end *end = arg_end(200); void *argtable[] = {help,version,FileLogLevel,LogFile, summrslts,experimentname,experimentdescr, pmode,kmerlen,prefixlen,minwithprefix,minhamming,cultivar,chromnames,infile,outfile,outreadsfile, numthreads, end}; char **pAllArgs; int argerrors; argerrors = CUtility::arg_parsefromfile(argc,(char **)argv,&pAllArgs); if(argerrors >= 0) argerrors = arg_parse(argerrors,pAllArgs,argtable); /* special case: '--help' takes precedence over error reporting */ if (help->count > 0) { printf("\n%s %s %s, Version %s\nOptions ---\n", gszProcName,gpszSubProcess->pszName,gpszSubProcess->pszFullDescr,cpszProgVer); arg_print_syntax(stdout,argtable,"\n"); arg_print_glossary(stdout,argtable," %-25s %s\n"); printf("\nNote: Parameters can be entered into a parameter file, one parameter per line."); printf("\n To invoke this parameter file then precede its name with '@'"); printf("\n e.g. %s %s @myparams.txt\n",gszProcName,gpszSubProcess->pszName); printf("\nPlease report any issues regarding usage of %s at https://github.com/csiro-crop-informatics/biokanga/issues\n\n",gszProcName); return(1); } /* special case: '--version' takes precedence error reporting */ if (version->count > 0) { printf("\n%s %s Version %s\n",gszProcName,gpszSubProcess->pszName,cpszProgVer); return(1); } if (!argerrors) { if(FileLogLevel->count && !LogFile->count) { printf("\nError: FileLogLevel '-f%d' specified but no logfile '-F<logfile>\n'",FileLogLevel->ival[0]); return(1); } iScreenLogLevel = iFileLogLevel = FileLogLevel->count ? FileLogLevel->ival[0] : eDLInfo; if(iFileLogLevel < eDLNone || iFileLogLevel > eDLDebug) { printf("\nError: FileLogLevel '-l%d' specified outside of range %d..%d\n",iFileLogLevel,eDLNone,eDLDebug); return(1); } if(LogFile->count) { strncpy(szLogFile,LogFile->filename[0],_MAX_PATH); szLogFile[_MAX_PATH-1] = '\0'; } else { iFileLogLevel = eDLNone; szLogFile[0] = '\0'; } // now that log parameters have been parsed then initialise diagnostics log system if(!gDiagnostics.Open(szLogFile,(etDiagLevel)iScreenLogLevel,(etDiagLevel)iFileLogLevel,true)) { printf("\nError: Unable to start diagnostics subsystem\n"); if(szLogFile[0] != '\0') printf(" Most likely cause is that logfile '%s' can't be opened/created\n",szLogFile); return(1); } gDiagnostics.DiagOut(eDLInfo,gszProcName,"Subprocess %s Version %s starting",gpszSubProcess->pszName,cpszProgVer); gExperimentID = 0; gProcessID = 0; gProcessingID = 0; szSQLiteDatabase[0] = '\0'; szExperimentName[0] = '\0'; szExperimentDescr[0] = '\0'; if(experimentname->count) { strncpy(szExperimentName,experimentname->sval[0],sizeof(szExperimentName)); szExperimentName[sizeof(szExperimentName)-1] = '\0'; CUtility::TrimQuotedWhitespcExtd(szExperimentName); CUtility::ReduceWhitespace(szExperimentName); } else szExperimentName[0] = '\0'; gExperimentID = 0; gProcessID = 0; gProcessingID = 0; szSQLiteDatabase[0] = '\0'; szExperimentDescr[0] = '\0'; if(summrslts->count) { strncpy(szSQLiteDatabase,summrslts->filename[0],sizeof(szSQLiteDatabase)-1); szSQLiteDatabase[sizeof(szSQLiteDatabase)-1] = '\0'; CUtility::TrimQuotedWhitespcExtd(szSQLiteDatabase); if(strlen(szSQLiteDatabase) < 1) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: After removal of whitespace, no SQLite database specified with '-q<filespec>' option"); return(1); } if(strlen(szExperimentName) < 1) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: After removal of whitespace, no SQLite experiment name specified with '-w<str>' option"); return(1); } if(experimentdescr->count) { strncpy(szExperimentDescr,experimentdescr->sval[0],sizeof(szExperimentDescr)-1); szExperimentDescr[sizeof(szExperimentDescr)-1] = '\0'; CUtility::TrimQuotedWhitespcExtd(szExperimentDescr); } if(strlen(szExperimentDescr) < 1) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: After removal of whitespace, no SQLite experiment description specified with '-W<str>' option"); return(1); } gExperimentID = gSQLiteSummaries.StartExperiment(szSQLiteDatabase,false,true,szExperimentName,szExperimentName,szExperimentDescr); if(gExperimentID < 1) return(1); gProcessID = gSQLiteSummaries.AddProcess((char *)gpszSubProcess->pszName,(char *)gpszSubProcess->pszName,(char *)gpszSubProcess->pszFullDescr); if(gProcessID < 1) return(1); gProcessingID = gSQLiteSummaries.StartProcessing(gExperimentID,gProcessID,(char *)cpszProgVer); if(gProcessingID < 1) return(1); gDiagnostics.DiagOut(eDLInfo,gszProcName,"Initialised SQLite database '%s' for results summary collection",szSQLiteDatabase); gDiagnostics.DiagOut(eDLInfo,gszProcName,"SQLite database experiment identifier for '%s' is %d",szExperimentName,gExperimentID); gDiagnostics.DiagOut(eDLInfo,gszProcName,"SQLite database process identifier for '%s' is %d",(char *)gpszSubProcess->pszName,gProcessID); gDiagnostics.DiagOut(eDLInfo,gszProcName,"SQLite database processing instance identifier is %d",gProcessingID); } else { szSQLiteDatabase[0] = '\0'; szExperimentDescr[0] = '\0'; } // show user current resource limits #ifndef _WIN32 gDiagnostics.DiagOut(eDLInfo, gszProcName, "Resources: %s",CUtility::ReportResourceLimits()); #endif #ifdef _WIN32 SYSTEM_INFO SystemInfo; GetSystemInfo(&SystemInfo); NumberOfProcessors = SystemInfo.dwNumberOfProcessors; #else NumberOfProcessors = sysconf(_SC_NPROCESSORS_CONF); #endif int MaxAllowedThreads = min(cMaxWorkerThreads,NumberOfProcessors); // limit to be at most cMaxWorkerThreads if((NumThreads = numthreads->count ? numthreads->ival[0] : MaxAllowedThreads)==0) NumThreads = MaxAllowedThreads; if(NumThreads < 0 || NumThreads > MaxAllowedThreads) { gDiagnostics.DiagOut(eDLWarn,gszProcName,"Warning: Number of threads '-T%d' specified was outside of range %d..%d",NumThreads,1,MaxAllowedThreads); gDiagnostics.DiagOut(eDLWarn,gszProcName,"Warning: Defaulting number of threads to %d",MaxAllowedThreads); NumThreads = MaxAllowedThreads; } PMode = (etPMode)(pmode->count ? pmode->ival[0] : ePMExtdKMers); if(PMode < ePMExtdKMers || PMode >= ePMplaceholder) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: Processing mode '-m%d' specified outside of range %d..%d\n",PMode,ePMExtdKMers,(int)ePMplaceholder-1); exit(1); } KMerLen = kmerlen->count ? kmerlen->ival[0] : cDfltKMerLen; if(KMerLen < cMinKMerLen || KMerLen > cMaxKMerLen) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: K-mer core length '-k%d' must be in range %d..%d",KMerLen,cMinKMerLen,cMaxKMerLen); return(1); } if(PMode == 2) { PrefixLen = prefixlen->count ? prefixlen->ival[0] : KMerLen/2; if(PrefixLen < cMinKMerLen/2 || PrefixLen > KMerLen-(cMinKMerLen/2)) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: Prefix length '-p%d' must be in range %d..%d",KMerLen,cMinKMerLen/2,KMerLen-(cMinKMerLen/2)); return(1); } SuffixLen = KMerLen - PrefixLen; MinWithPrefix = minwithprefix->count ? minwithprefix->ival[0] : 0; if(MinWithPrefix != 0 && MinWithPrefix < 1) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: Minimum cultivars sharing prefix sequence '-s%d' must be either 0 (all) or at least 1",MinWithPrefix); return(1); } } MinHamming = minhamming->count ? minhamming->ival[0] : cDfltHamming; if(MinHamming < cMinHamming || MinHamming > cMaxHamming) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: Minimum Hamming separation '-K%d' must be in range %d..%d",MinHamming,cMinHamming,cMaxHamming); return(1); } strncpy(szCultivarName,cultivar->sval[0],cMaxDatasetSpeciesChrom); szCultivarName[cMaxDatasetSpeciesChrom]= '\0'; CUtility::TrimQuotedWhitespcExtd(szCultivarName); if(strlen(szCultivarName) < 1) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: Expected cultivar name '-c<name>' is empty"); return(1); } strncpy(szPartialCultivarsList,chromnames->sval[0],sizeof(szPartialCultivarsList)); szPartialCultivarsList[sizeof(szPartialCultivarsList)-1] = '\0'; CUtility::TrimQuotedWhitespcExtd(szPartialCultivarsList); CUtility::ReduceWhitespace(szPartialCultivarsList); char *pChr = szPartialCultivarsList; char *pStartChr; char Chr; int CurSpeciesLen; NumPartialCultivars=0; CurSpeciesLen = 0; pStartChr = pChr; while((Chr = *pChr++) != '\0') { if(Chr == ' ' || Chr == '\t' || Chr == ',') // treat any of these as delimiters { pChr[-1] = '\0'; if(CurSpeciesLen != 0) { pszPartialCultivars[NumPartialCultivars++] = pStartChr; CurSpeciesLen = 0; } pStartChr = pChr; continue; } CurSpeciesLen += 1; } if(CurSpeciesLen) pszPartialCultivars[NumPartialCultivars++] = pStartChr; if(!NumPartialCultivars) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: Expected at least one ('-C<names>') targeted cultivar chromosme name"); return(1); } strcpy(szSfxPseudoGenome,infile->filename[0]); CUtility::TrimQuotedWhitespcExtd(szSfxPseudoGenome); if(strlen(szSfxPseudoGenome) < 1) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: Expected input pseudo-genome suffix array filename '-i<name>' is empty"); return(1); } strcpy(szMarkerFile,outfile->filename[0]); CUtility::TrimQuotedWhitespcExtd(szMarkerFile); if(strlen(szMarkerFile) < 1) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: Expected marker file to generate filename '-o<name>' is empty"); return(1); } if(outreadsfile->count) { strcpy(szMarkerReadsFile,outreadsfile->filename[0]); CUtility::TrimQuotedWhitespcExtd(szMarkerReadsFile); if(strlen(szMarkerReadsFile) < 1) { gDiagnostics.DiagOut(eDLFatal,gszProcName,"Error: Reads containing markers filename '-O<name>' is empty"); return(1); } } else szMarkerReadsFile[0] = '\0'; gDiagnostics.DiagOut(eDLInfo,gszProcName,"Processing parameters:"); const char *pszDescr; switch(PMode) { case ePMExtdKMers: pszDescr = "Extended K-mer markers"; break; case ePMNoExtdKMers: pszDescr = "Non-extended K-mer markers"; break; case ePMPrefixKMers: pszDescr = "K-mers to share prefix sequence with other cultivars"; break; } gDiagnostics.DiagOutMsgOnly(eDLInfo,"Processing mode is : '%s'",pszDescr); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Targeted cultivar name : '%s'",szCultivarName); for(int Idx = 0; Idx < NumPartialCultivars; Idx++) gDiagnostics.DiagOutMsgOnly(eDLInfo,"Targeted cultivar chromosome name (%d) : '%s'", Idx + 1,pszPartialCultivars[Idx]); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Core K-mer length : %d",KMerLen); if(PMode == ePMPrefixKMers) { gDiagnostics.DiagOutMsgOnly(eDLInfo,"Inter-cultivar shared prefix sequence length : %d",PrefixLen); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Cultivar specific suffix sequence length : %d",SuffixLen); if(MinWithPrefix) gDiagnostics.DiagOutMsgOnly(eDLInfo,"Min number cultivars sharing prefix : %d",MinWithPrefix); else gDiagnostics.DiagOutMsgOnly(eDLInfo,"Min number cultivars sharing prefix : 'All'"); } gDiagnostics.DiagOutMsgOnly(eDLInfo,"Minimum Hamming separation : %d",MinHamming); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Input indexed pseudo-genome file: '%s'",szSfxPseudoGenome); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Write marker K-mers to file: '%s'",szMarkerFile); if(szMarkerReadsFile[0] != '\0') gDiagnostics.DiagOutMsgOnly(eDLInfo,"Write marker containing reads to file: '%s'",szMarkerReadsFile); if(szExperimentName[0] != '\0') gDiagnostics.DiagOutMsgOnly(eDLInfo,"This processing reference: %s",szExperimentName); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Number of processing threads: %d",NumThreads); if(gExperimentID > 0) { int ParamID; ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTText,(int)strlen(szLogFile),"log",szLogFile); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTInt32,sizeof(PMode),"mode",&PMode); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTInt32,sizeof(KMerLen),"kmer",&KMerLen); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTInt32,sizeof(PrefixLen),"prefixlen",&PrefixLen); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTInt32,sizeof(SuffixLen),"suffixlen",&SuffixLen); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTInt32,sizeof(MinWithPrefix),"minwithprefix",&MinWithPrefix); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTInt32,sizeof(MinHamming),"minhamming",&MinHamming); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTInt32,sizeof(NumThreads),"threads",&NumThreads); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTInt32,sizeof(NumberOfProcessors),"cpus",&NumberOfProcessors); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTText,(int)strlen(szCultivarName),"cultivar",szCultivarName); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTInt32,sizeof(NumPartialCultivars),"NumPartialCultivars",&NumPartialCultivars); for(int Idx = 0; Idx < NumPartialCultivars; Idx++) ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTText,(int)strlen(pszPartialCultivars[Idx]),"chromnames",pszPartialCultivars[Idx]); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTText,(int)strlen(szSfxPseudoGenome),"in",szSfxPseudoGenome); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTText,(int)strlen(szMarkerFile),"markers",szMarkerFile); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTText,(int)strlen(szMarkerReadsFile),"markerreads",szMarkerReadsFile); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTText,(int)strlen(szSQLiteDatabase),"sumrslts",szSQLiteDatabase); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTText,(int)strlen(szExperimentName),"experimentname",szExperimentName); ParamID = gSQLiteSummaries.AddParameter(gProcessingID,ePTText,(int)strlen(szExperimentDescr),"experimentdescr",szExperimentDescr); } #ifdef _WIN32 SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); #endif gStopWatch.Start(); Rslt = LocMarkers((etPMode)PMode,KMerLen,PrefixLen,SuffixLen,MinWithPrefix,MinHamming,szCultivarName,NumPartialCultivars,pszPartialCultivars,szSfxPseudoGenome,szMarkerFile,szMarkerReadsFile,NumThreads); Rslt = Rslt >=0 ? 0 : 1; if(gExperimentID > 0) { if(gProcessingID) gSQLiteSummaries.EndProcessing(gProcessingID,Rslt); gSQLiteSummaries.EndExperiment(gExperimentID); } gStopWatch.Stop(); gDiagnostics.DiagOut(eDLInfo,gszProcName,"Exit code: %d Total processing time: %s",Rslt,gStopWatch.Read()); return(Rslt); } else { printf("\n%s %s %s, Version %s\n", gszProcName,gpszSubProcess->pszName,gpszSubProcess->pszFullDescr,cpszProgVer); arg_print_errors(stdout,end,gszProcName); arg_print_syntax(stdout,argtable,"\nUse '-h' to view option and parameter usage\n"); return(1); } return 0; }
/// Main function int Master::Run() { /// worldd PID file creation std::string pidfile = sConfig.GetStringDefault("PidFile", ""); if (!pidfile.empty()) { uint32 pid = CreatePIDFile(pidfile); if (!pid) { sLog.outError("Cannot create PID file %s.\n", pidfile.c_str()); Log::WaitBeforeContinueIfNeed(); return 1; } sLog.outString("Daemon PID: %u\n", pid); } ///- Start the databases if (!_StartDB()) { Log::WaitBeforeContinueIfNeed(); return 1; } ///- Initialize the World sWorld.SetInitialWorldSettings(); #ifndef WIN32 detachDaemon(); #endif // server loaded successfully => enable async DB requests // this is done to forbid any async transactions during server startup! CharacterDatabase.AllowAsyncTransactions(); WorldDatabase.AllowAsyncTransactions(); LoginDatabase.AllowAsyncTransactions(); ///- Catch termination signals _HookSignals(); ///- Launch WorldRunnable thread MaNGOS::Thread world_thread(new WorldRunnable); world_thread.setPriority(MaNGOS::Priority_Highest); // set realmbuilds depend on mangosd expected builds, and set server online { std::string builds = AcceptableClientBuildsListStr(); LoginDatabase.escape_string(builds); LoginDatabase.DirectPExecute("UPDATE realmlist SET realmflags = realmflags & ~(%u), population = 0, realmbuilds = '%s' WHERE id = '%u'", REALM_FLAG_OFFLINE, builds.c_str(), realmID); } MaNGOS::Thread* cliThread = nullptr; #ifdef WIN32 if (sConfig.GetBoolDefault("Console.Enable", true) && (m_ServiceStatus == -1)/* need disable console in service mode*/) #else if (sConfig.GetBoolDefault("Console.Enable", true)) #endif { ///- Launch CliRunnable thread cliThread = new MaNGOS::Thread(new CliRunnable); } MaNGOS::Thread* rar_thread = nullptr; if (sConfig.GetBoolDefault("Ra.Enable", false)) { rar_thread = new MaNGOS::Thread(new RARunnable); } ///- Handle affinity for multiple processors and process priority on Windows #ifdef WIN32 { HANDLE hProcess = GetCurrentProcess(); uint32 Aff = sConfig.GetIntDefault("UseProcessors", 0); if (Aff > 0) { ULONG_PTR appAff; ULONG_PTR sysAff; if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) { ULONG_PTR curAff = Aff & appAff; // remove non accessible processors if (!curAff) { sLog.outError("Processors marked in UseProcessors bitmask (hex) %x not accessible for mangosd. Accessible processors bitmask (hex): %x", Aff, appAff); } else { if (SetProcessAffinityMask(hProcess, curAff)) sLog.outString("Using processors (bitmask, hex): %x", curAff); else sLog.outError("Can't set used processors (hex): %x", curAff); } } sLog.outString(); } bool Prio = sConfig.GetBoolDefault("ProcessPriority", false); // if(Prio && (m_ServiceStatus == -1)/* need set to default process priority class in service mode*/) if (Prio) { if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) sLog.outString("mangosd process priority class set to HIGH"); else sLog.outError("Can't set mangosd process priority class."); sLog.outString(); } } #endif ///- Start soap serving thread MaNGOS::Thread* soap_thread = nullptr; if (sConfig.GetBoolDefault("SOAP.Enabled", false)) { MaNGOSsoapRunnable* runnable = new MaNGOSsoapRunnable(); runnable->setListenArguments(sConfig.GetStringDefault("SOAP.IP", "127.0.0.1"), sConfig.GetIntDefault("SOAP.Port", 7878)); soap_thread = new MaNGOS::Thread(runnable); } ///- Start up freeze catcher thread MaNGOS::Thread* freeze_thread = nullptr; if (uint32 freeze_delay = sConfig.GetIntDefault("MaxCoreStuckTime", 0)) { FreezeDetectorRunnable* fdr = new FreezeDetectorRunnable(); fdr->SetDelayTime(freeze_delay * 1000); freeze_thread = new MaNGOS::Thread(fdr); freeze_thread->setPriority(MaNGOS::Priority_Highest); } ///- Launch the world listener socket uint16 wsport = sWorld.getConfig(CONFIG_UINT32_PORT_WORLD); std::string bind_ip = sConfig.GetStringDefault("BindIP", "0.0.0.0"); if (sWorldSocketMgr.StartNetwork(wsport, bind_ip) == -1) { sLog.outError("Failed to start network"); Log::WaitBeforeContinueIfNeed(); World::StopNow(ERROR_EXIT_CODE); // go down and shutdown the server } sWorldSocketMgr.Wait(); ///- Stop freeze protection before shutdown tasks if (freeze_thread) { freeze_thread->destroy(); delete freeze_thread; } ///- Stop soap thread if (soap_thread) { soap_thread->wait(); soap_thread->destroy(); delete soap_thread; } ///- Set server offline in realmlist LoginDatabase.DirectPExecute("UPDATE realmlist SET realmflags = realmflags | %u WHERE id = '%u'", REALM_FLAG_OFFLINE, realmID); ///- Remove signal handling before leaving _UnhookSignals(); // when the main thread closes the singletons get unloaded // since worldrunnable uses them, it will crash if unloaded after master world_thread.wait(); if (rar_thread) { rar_thread->wait(); rar_thread->destroy(); delete rar_thread; } ///- Clean account database before leaving clearOnlineAccounts(); // send all still queued mass mails (before DB connections shutdown) sMassMailMgr.Update(true); ///- Wait for DB delay threads to end CharacterDatabase.HaltDelayThread(); WorldDatabase.HaltDelayThread(); LoginDatabase.HaltDelayThread(); sLog.outString("Halting process..."); if (cliThread) { #ifdef WIN32 // this only way to terminate CLI thread exist at Win32 (alt. way exist only in Windows Vista API) //_exit(1); // send keyboard input to safely unblock the CLI thread INPUT_RECORD b[5]; HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE); b[0].EventType = KEY_EVENT; b[0].Event.KeyEvent.bKeyDown = TRUE; b[0].Event.KeyEvent.uChar.AsciiChar = 'X'; b[0].Event.KeyEvent.wVirtualKeyCode = 'X'; b[0].Event.KeyEvent.wRepeatCount = 1; b[1].EventType = KEY_EVENT; b[1].Event.KeyEvent.bKeyDown = FALSE; b[1].Event.KeyEvent.uChar.AsciiChar = 'X'; b[1].Event.KeyEvent.wVirtualKeyCode = 'X'; b[1].Event.KeyEvent.wRepeatCount = 1; b[2].EventType = KEY_EVENT; b[2].Event.KeyEvent.bKeyDown = TRUE; b[2].Event.KeyEvent.dwControlKeyState = 0; b[2].Event.KeyEvent.uChar.AsciiChar = '\r'; b[2].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; b[2].Event.KeyEvent.wRepeatCount = 1; b[2].Event.KeyEvent.wVirtualScanCode = 0x1c; b[3].EventType = KEY_EVENT; b[3].Event.KeyEvent.bKeyDown = FALSE; b[3].Event.KeyEvent.dwControlKeyState = 0; b[3].Event.KeyEvent.uChar.AsciiChar = '\r'; b[3].Event.KeyEvent.wVirtualKeyCode = VK_RETURN; b[3].Event.KeyEvent.wVirtualScanCode = 0x1c; b[3].Event.KeyEvent.wRepeatCount = 1; DWORD numb; BOOL ret = WriteConsoleInput(hStdIn, b, 4, &numb); cliThread->wait(); #else cliThread->destroy(); #endif delete cliThread; } ///- Exit the process with specified return value return World::GetExitCode(); }
void otserv( #if !defined(WINDOWS) || defined(__CONSOLE__) StringVec args, #endif ServiceManager* services) { srand((uint32_t)OTSYS_TIME()); #if defined(WINDOWS) #if defined(__CONSOLE__) SetConsoleTitle(STATUS_SERVER_NAME); #else GUI::getInstance()->m_connections = false; #endif #endif g_game.setGameState(GAME_STATE_STARTUP); std::cout << STATUS_SERVER_NAME << ", version " << STATUS_SERVER_VERSION << " (" << STATUS_SERVER_CODENAME << ")" << std::endl; std::cout << "Compiled with " << BOOST_COMPILER << " at " << __DATE__ << ", " << __TIME__ << "." << std::endl; std::cout << "A server developed by Gesior." << std::endl; std::stringstream ss; #ifdef __DEBUG__ ss << " GLOBAL"; #endif #ifdef __DEBUG_MOVESYS__ ss << " MOVESYS"; #endif #ifdef __DEBUG_CHAT__ ss << " CHAT"; #endif #ifdef __DEBUG_EXCEPTION_REPORT__ ss << " EXCEPTION-REPORT"; #endif #ifdef __DEBUG_HOUSES__ ss << " HOUSES"; #endif #ifdef __DEBUG_LUASCRIPTS__ ss << " LUA-SCRIPTS"; #endif #ifdef __DEBUG_MAILBOX__ ss << " MAILBOX"; #endif #ifdef __DEBUG_NET__ ss << " NET"; #endif #ifdef __DEBUG_NET_DETAIL__ ss << " NET-DETAIL"; #endif #ifdef __DEBUG_RAID__ ss << " RAIDS"; #endif #ifdef __DEBUG_SCHEDULER__ ss << " SCHEDULER"; #endif #ifdef __DEBUG_SPAWN__ ss << " SPAWNS"; #endif #ifdef __SQL_QUERY_DEBUG__ ss << " SQL-QUERIES"; #endif std::string debug = ss.str(); if(!debug.empty()) { std::cout << ">> Debugging:"; #if defined(WINDOWS) && !defined(__CONSOLE__) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Displaying debugged components"); #endif std::cout << debug << "." << std::endl; } std::cout << ">> Loading config (" << g_config.getString(ConfigManager::CONFIG_FILE) << ")" << std::endl; #if defined(WINDOWS) && !defined(__CONSOLE__) SendMessage(GUI::getInstance()->m_statusBar, WM_SETTEXT, 0, (LPARAM)">> Loading config"); #endif if(!g_config.load()) startupErrorMessage("Unable to load " + g_config.getString(ConfigManager::CONFIG_FILE) + "!"); Logger::getInstance()->open(); IntegerVec cores = vectorAtoi(explodeString(g_config.getString(ConfigManager::CORES_USED), ",")); if(cores[0] != -1) { #ifdef WINDOWS int32_t mask = 0; for(IntegerVec::iterator it = cores.begin(); it != cores.end(); ++it) mask += 1 << (*it); SetProcessAffinityMask(GetCurrentProcess(), mask); } std::stringstream mutexName; mutexName << "forgottenserver_" << g_config.getNumber(ConfigManager::WORLD_ID); CreateMutex(NULL, FALSE, mutexName.str().c_str()); if(GetLastError() == ERROR_ALREADY_EXISTS) startupErrorMessage("Another instance of The Forgotten Server is already running with the same worldId.\nIf you want to run multiple servers, please change the worldId in configuration file."); std::string defaultPriority = asLowerCaseString(g_config.getString(ConfigManager::DEFAULT_PRIORITY)); if(defaultPriority == "realtime") SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); else if(defaultPriority == "high") SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); else if(defaultPriority == "higher") SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS); #else cpu_set_t mask; CPU_ZERO(&mask); for(IntegerVec::iterator it = cores.begin(); it != cores.end(); ++it) CPU_SET((*it), &mask); sched_setaffinity(getpid(), (int32_t)sizeof(mask), &mask); }
void Frameserver::Go(IVDubServerLink *ivdsl, char *name) { int server_index = -1; lpszFsname = name; // prepare the sources... if (!vSrc->setTargetFormat(g_dubOpts.video.mInputFormat)) if (!vSrc->setTargetFormat(nsVDPixmap::kPixFormat_XRGB8888)) if (!vSrc->setTargetFormat(nsVDPixmap::kPixFormat_RGB888)) if (!vSrc->setTargetFormat(nsVDPixmap::kPixFormat_XRGB1555)) if (!vSrc->setTargetFormat(nsVDPixmap::kPixFormat_Pal8)) throw MyError("The decompression codec cannot decompress to an RGB format. This is very unusual. Check that any \"Force YUY2\" options are not enabled in the codec's properties."); IVDStreamSource *pVSS = vSrc->asStream(); FrameSubset videoset(mSubset); const VDFraction frameRateTimeline(g_project->GetTimelineFrameRate()); VDPosition startFrame; VDPosition endFrame; VDConvertSelectionTimesToFrames(*opt, mSubset, frameRateTimeline, startFrame, endFrame); InitVideoStreamValuesStatic(vInfo, vSrc, aSrc, opt, &mSubset, &startFrame, &endFrame); const VDPixmap& px = vSrc->getTargetFormat(); const VDFraction& srcFAR = vSrc->getPixelAspectRatio(); filters.prepareLinearChain(&g_filterChain, px.w, px.h, px.format, vInfo.mFrameRatePreFilter, -1, srcFAR); mpVideoFrameSource = new VDFilterFrameVideoSource; mpVideoFrameSource->Init(vSrc, filters.GetInputLayout()); filters.SetVisualAccelDebugEnabled(false); filters.SetAccelEnabled(VDPreferencesGetFilterAccelEnabled()); filters.SetAsyncThreadCount(VDPreferencesGetFilterThreadCount()); filters.initLinearChain(NULL, 0, &g_filterChain, mpVideoFrameSource, px.w, px.h, px.format, px.palette, vInfo.mFrameRatePreFilter, -1, srcFAR); filters.ReadyFilters(); InitVideoStreamValuesStatic2(vInfo, opt, &filters, frameRateTimeline); InitAudioStreamValuesStatic(aInfo, aSrc, opt); vdfastvector<IVDVideoSource *> vsrcs(1, vSrc); mVideoFrameMap.Init(vsrcs, vInfo.start_src, vInfo.mFrameRateTimeline / vInfo.mFrameRate, &mSubset, vInfo.end_dst, opt->video.mbUseSmartRendering, opt->video.mode == DubVideoOptions::M_NONE, opt->video.mbPreserveEmptyFrames, &filters, false, false); if (opt->audio.fEndAudio) videoset.deleteRange(endFrame, videoset.getTotalFrames()); if (opt->audio.fStartAudio) videoset.deleteRange(0, startFrame); VDDEBUG("Video subset:\n"); videoset.dump(); if (aSrc) AudioTranslateVideoSubset(audioset, videoset, vInfo.mFrameRateTimeline, aSrc->getWaveFormat(), !opt->audio.fEndAudio && (videoset.empty() || videoset.back().end() == pVSS->getEnd()) ? aSrc->getEnd() : 0, NULL); VDDEBUG("Audio subset:\n"); audioset.dump(); if (aSrc) { audioset.offset(aSrc->msToSamples(-opt->audio.offset)); lAudioSamples = VDClampToUint32(audioset.getTotalFrames()); } else lAudioSamples = 0; lVideoSamples = VDClampToUint32(mVideoFrameMap.size()); vSrc->streamBegin(true, false); const VDPixmapLayout& outputLayout = filters.GetOutputLayout(); mFrameSize = VDPixmapCreateLinearLayout(mFrameLayout, nsVDPixmap::kPixFormat_RGB888, outputLayout.w, outputLayout.h, 4); VDPixmapLayoutFlipV(mFrameLayout); if (aSrc) aSrc->streamBegin(true, false); // usurp the window VDUIFrame *pFrame = VDUIFrame::GetFrame(hwnd); mpUIFrame = pFrame; pFrame->Attach(this); guiSetTitle(hwnd, IDS_TITLE_FRAMESERVER); // create dialog box mbExit = false; if (hwndStatus = CreateDialogParam(g_hInst, MAKEINTRESOURCE(IDD_SERVER), hwnd, Frameserver::StatusDlgProc, (LPARAM)this)) { // hide the main window ShowWindow(hwnd, SW_HIDE); // create the frameserver server_index = ivdsl->CreateFrameServer(name, hwnd); if (server_index>=0) { // kick us into high priority SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); // enter window loop { MSG msg; while(!mbExit) { BOOL result = GetMessage(&msg, NULL, 0, 0); if (result == (BOOL)-1) break; if (!result) { PostQuitMessage(msg.wParam); break; } TranslateMessage(&msg); DispatchMessage(&msg); } } // return to normal priority SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS); ivdsl->DestroyFrameServer(server_index); } if (IsWindow(hwndStatus)) DestroyWindow(hwndStatus); // show the main window ShowWindow(hwnd, SW_SHOW); } // unsubclass pFrame->Detach(); if (vSrc) { IVDStreamSource *pVSS = vSrc->asStream(); pVSS->streamEnd(); } if (server_index<0) throw MyError("Couldn't create frameserver"); }
int _tmain(int argc, char* argv[]) { // determine my process name _splitpath(argv[0],NULL,NULL,gszProcName,NULL); #else int main(int argc, const char** argv) { // determine my process name CUtility::splitpath((char *)argv[0],NULL,gszProcName); #endif int iScreenLogLevel; // level of screen diagnostics int iFileLogLevel; // level of file diagnostics char szLogFile[_MAX_PATH]; // write diagnostics to this file int Rslt; bool bSkipFirst; // true if first line contains header and should be skipped int iMinLength; // core elements must be of at least this length int iMaxLength; // and no longer than this length char szInLociFile[_MAX_PATH]; // input element loci from this file char szInSeqFile[_MAX_PATH]; // input bioseq file containing assembly char szRsltsFile[_MAX_PATH]; // output stats to this file // command line args struct arg_lit *help = arg_lit0("hH","help", "print this help and exit"); struct arg_lit *version = arg_lit0("v","version,ver", "print version information and exit"); struct arg_int *FileLogLevel=arg_int0("f", "FileLogLevel", "<int>","Level of diagnostics written to logfile 0=fatal,1=errors,2=info,3=diagnostics,4=debug"); struct arg_int *ScreenLogLevel=arg_int0("S", "ScreenLogLevel", "<int>","Level of diagnostics written to logfile 0=fatal,1=errors,2=info,3=diagnostics,4=debug"); struct arg_file *LogFile = arg_file0("F","log","<file>", "diagnostics log file"); struct arg_file *InLociFile = arg_file1("i","inloci","<file>", "element loci CSV file"); struct arg_file *InSeqFile = arg_file1("I","assembly","<file>", "genome assembly bioseq file"); struct arg_file *RsltsFile = arg_file1("o","output","<file>", "output file"); struct arg_lit *SkipFirst = arg_lit0("x","skipfirst", "skip first line of CSV - header line"); struct arg_int *MinLength = arg_int0("l","minlength","<int>", "minimum element length (default 10)"); struct arg_int *MaxLength = arg_int0("L","maxlength","<int>", "maximum element length (default 1000000000)"); struct arg_end *end = arg_end(20); void *argtable[] = {help,version,FileLogLevel,ScreenLogLevel,LogFile, InLociFile,InSeqFile,RsltsFile,SkipFirst,MinLength,MaxLength, end}; char **pAllArgs; int argerrors; argerrors = CUtility::arg_parsefromfile(argc,(char **)argv,&pAllArgs); if(argerrors >= 0) argerrors = arg_parse(argerrors,pAllArgs,argtable); /* special case: '--help' takes precedence over error reporting */ if (help->count > 0) { printf("\n%s csv2stats, Version %s\nOptions ---\n", gszProcName,cpszProgVer); arg_print_syntax(stdout,argtable,"\n"); arg_print_glossary(stdout,argtable," %-25s %s\n"); printf("\nNote: Parameters can be entered into a parameter file, one parameter per line."); printf("\n To invoke this parameter file then precede its name with '@'"); printf("\n e.g. %s @myparams.txt\n\n",gszProcName); exit(1); } /* special case: '--version' takes precedence error reporting */ if (version->count > 0) { printf("\n%s Version %s\n",gszProcName,cpszProgVer); exit(1); } if (!argerrors) { if(FileLogLevel->count && !LogFile->count) { printf("\nError: FileLogLevel '-f%d' specified but no logfile '-F<logfile>'",FileLogLevel->ival[0]); exit(1); } iScreenLogLevel = iFileLogLevel = FileLogLevel->count ? FileLogLevel->ival[0] : eDLInfo; if(iFileLogLevel < eDLNone || iFileLogLevel > eDLDebug) { printf("\nError: FileLogLevel '-l%d' specified outside of range %d..%d",iFileLogLevel,eDLNone,eDLDebug); exit(1); } if(LogFile->count) { strncpy(szLogFile,LogFile->filename[0],_MAX_PATH); szLogFile[_MAX_PATH-1] = '\0'; } else { iFileLogLevel = eDLNone; szLogFile[0] = '\0'; } bSkipFirst = SkipFirst->count ? true : false; iMinLength = MinLength->count ? MinLength->ival[0] : cDfltMinLengthRange; if(iMinLength < 1 || iMinLength > cMaxLengthRange) { printf("Error: Mininum element length '-l%d' is not in range 1..%d",iMinLength,cMaxLengthRange); exit(1); } iMaxLength = MaxLength->count ? MaxLength->ival[0] : cMaxLengthRange; if(iMaxLength < iMinLength || iMaxLength > cMaxLengthRange) { printf("Error: Maximum element length '-L%d' is not in range %d..%d",iMaxLength,iMinLength,cMaxLengthRange); exit(1); } strncpy(szInLociFile,InLociFile->filename[0],_MAX_PATH); szInLociFile[_MAX_PATH-1] = '\0'; strncpy(szInSeqFile,InSeqFile->filename[0],_MAX_PATH); szInSeqFile[_MAX_PATH-1] = '\0'; strncpy(szRsltsFile,RsltsFile->filename[0],_MAX_PATH); szRsltsFile[_MAX_PATH-1] = '\0'; // now that command parameters have been parsed then initialise diagnostics log system if(!gDiagnostics.Open(szLogFile,(etDiagLevel)iScreenLogLevel,(etDiagLevel)iFileLogLevel,true)) { printf("\nError: Unable to start diagnostics subsystem."); if(szLogFile[0] != '\0') printf(" Most likely cause is that logfile '%s' can't be opened/created",szLogFile); exit(1); } gDiagnostics.DiagOut(eDLInfo,gszProcName,"Version: %s Processing parameters:",cpszProgVer); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Input CSV element loci file: '%s'",szInLociFile); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Input bioseq genome assembly file: '%s'",szInSeqFile); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Output to file: '%s'",szRsltsFile); gDiagnostics.DiagOutMsgOnly(eDLInfo,"First line contains header: %s",bSkipFirst ? "yes" : "no"); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Minimum element length: %d",iMinLength); gDiagnostics.DiagOutMsgOnly(eDLInfo,"Maximum element length: %d",iMaxLength); #ifdef _WIN32 SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS); #endif // processing here... Rslt = Process(bSkipFirst,iMinLength,iMaxLength,szInLociFile,szInSeqFile,szRsltsFile); gStopWatch.Stop(); Rslt = Rslt >=0 ? 0 : 1; gDiagnostics.DiagOut(eDLInfo,gszProcName,"Exit code: %d Total processing time: %s",Rslt,gStopWatch.Read()); exit(Rslt); } else { printf("\n%s csv2stats, Version %s\n",gszProcName,cpszProgVer); arg_print_errors(stdout,end,gszProcName); arg_print_syntax(stdout,argtable,"\nUse '-h' to view option and parameter usage\n"); exit(1); } }
int main( int argc, char * * argv ) { // initialize memory managers MemoryManager::init(); NotePlayHandleManager::init(); // intialize RNG srand( getpid() + time( 0 ) ); disable_denormals(); bool coreOnly = false; bool fullscreen = true; bool exitAfterImport = false; bool allowRoot = false; bool renderLoop = false; bool renderTracks = false; QString fileToLoad, fileToImport, renderOut, profilerOutputFile; // first of two command-line parsing stages for( int i = 1; i < argc; ++i ) { QString arg = argv[i]; if( arg == "--help" || arg == "-h" || arg == "--version" || arg == "-v" || arg == "--render" || arg == "-r" ) { coreOnly = true; } else if( arg == "--rendertracks" ) { coreOnly = true; renderTracks = true; } else if( arg == "--allowroot" ) { allowRoot = true; } else if( arg == "-geometry" ) { // option -geometry is filtered by Qt later, // so we need to check its presence now to // determine, if the application should run in // fullscreen mode (default, no -geometry given). fullscreen = false; } } #ifndef LMMS_BUILD_WIN32 if ( ( getuid() == 0 || geteuid() == 0 ) && !allowRoot ) { printf( "LMMS cannot be run as root.\nUse \"--allowroot\" to override.\n\n" ); return EXIT_FAILURE; } #endif QCoreApplication * app = coreOnly ? new QCoreApplication( argc, argv ) : new QApplication( argc, argv ) ; Mixer::qualitySettings qs( Mixer::qualitySettings::Mode_HighQuality ); ProjectRenderer::OutputSettings os( 44100, false, 160, ProjectRenderer::Depth_16Bit ); ProjectRenderer::ExportFileFormats eff = ProjectRenderer::WaveFile; // second of two command-line parsing stages for( int i = 1; i < argc; ++i ) { QString arg = argv[i]; if( arg == "--version" || arg == "-v" ) { printVersion( argv[0] ); return EXIT_SUCCESS; } else if( arg == "--help" || arg == "-h" ) { printHelp(); return EXIT_SUCCESS; } else if( arg == "--upgrade" || arg == "-u" ) { ++i; if( i == argc ) { printf( "\nNo input file specified.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } DataFile dataFile( QString::fromLocal8Bit( argv[i] ) ); if( argc > i+1 ) // output file specified { dataFile.writeFile( QString::fromLocal8Bit( argv[i+1] ) ); } else // no output file specified; use stdout { QTextStream ts( stdout ); dataFile.write( ts ); fflush( stdout ); } return EXIT_SUCCESS; } else if( arg == "--allowroot" ) { // Ignore, processed earlier #ifdef LMMS_BUILD_WIN32 if( allowRoot ) { printf( "\nOption \"--allowroot\" will be ignored on this platform.\n\n" ); } #endif } else if( arg == "--dump" || arg == "-d" ) { ++i; if( i == argc ) { printf( "\nNo input file specified.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } QFile f( QString::fromLocal8Bit( argv[i] ) ); f.open( QIODevice::ReadOnly ); QString d = qUncompress( f.readAll() ); printf( "%s\n", d.toUtf8().constData() ); return EXIT_SUCCESS; } else if( arg == "--render" || arg == "-r" || arg == "--rendertracks" ) { ++i; if( i == argc ) { printf( "\nNo input file specified.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } fileToLoad = QString::fromLocal8Bit( argv[i] ); renderOut = fileToLoad; } else if( arg == "--loop" || arg == "-l" ) { renderLoop = true; } else if( arg == "--output" || arg == "-o" ) { ++i; if( i == argc ) { printf( "\nNo output file specified.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } renderOut = QString::fromLocal8Bit( argv[i] ); } else if( arg == "--format" || arg == "-f" ) { ++i; if( i == argc ) { printf( "\nNo output format specified.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } const QString ext = QString( argv[i] ); if( ext == "wav" ) { eff = ProjectRenderer::WaveFile; } #ifdef LMMS_HAVE_OGGVORBIS else if( ext == "ogg" ) { eff = ProjectRenderer::OggFile; } #endif else { printf( "\nInvalid output format %s.\n\n" "Try \"%s --help\" for more information.\n\n", argv[i], argv[0] ); return EXIT_FAILURE; } } else if( arg == "--samplerate" || arg == "-s" ) { ++i; if( i == argc ) { printf( "\nNo samplerate specified.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } sample_rate_t sr = QString( argv[i] ).toUInt(); if( sr >= 44100 && sr <= 192000 ) { os.samplerate = sr; } else { printf( "\nInvalid samplerate %s.\n\n" "Try \"%s --help\" for more information.\n\n", argv[i], argv[0] ); return EXIT_FAILURE; } } else if( arg == "--bitrate" || arg == "-b" ) { ++i; if( i == argc ) { printf( "\nNo bitrate specified.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } int br = QString( argv[i] ).toUInt(); if( br >= 64 && br <= 384 ) { os.bitrate = br; } else { printf( "\nInvalid bitrate %s.\n\n" "Try \"%s --help\" for more information.\n\n", argv[i], argv[0] ); return EXIT_FAILURE; } } else if( arg =="--float" || arg == "-a" ) { os.depth = ProjectRenderer::Depth_32Bit; } else if( arg == "--interpolation" || arg == "-i" ) { ++i; if( i == argc ) { printf( "\nNo interpolation method specified.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } const QString ip = QString( argv[i] ); if( ip == "linear" ) { qs.interpolation = Mixer::qualitySettings::Interpolation_Linear; } else if( ip == "sincfastest" ) { qs.interpolation = Mixer::qualitySettings::Interpolation_SincFastest; } else if( ip == "sincmedium" ) { qs.interpolation = Mixer::qualitySettings::Interpolation_SincMedium; } else if( ip == "sincbest" ) { qs.interpolation = Mixer::qualitySettings::Interpolation_SincBest; } else { printf( "\nInvalid interpolation method %s.\n\n" "Try \"%s --help\" for more information.\n\n", argv[i], argv[0] ); return EXIT_FAILURE; } } else if( arg == "--oversampling" || arg == "-x" ) { ++i; if( i == argc ) { printf( "\nNo oversampling specified.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } int o = QString( argv[i] ).toUInt(); switch( o ) { case 1: qs.oversampling = Mixer::qualitySettings::Oversampling_None; break; case 2: qs.oversampling = Mixer::qualitySettings::Oversampling_2x; break; case 4: qs.oversampling = Mixer::qualitySettings::Oversampling_4x; break; case 8: qs.oversampling = Mixer::qualitySettings::Oversampling_8x; break; default: printf( "\nInvalid oversampling %s.\n\n" "Try \"%s --help\" for more information.\n\n", argv[i], argv[0] ); return EXIT_FAILURE; } } else if( arg == "--import" ) { ++i; if( i == argc ) { printf( "\nNo file specified for importing.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } fileToImport = QString::fromLocal8Bit( argv[i] ); // exit after import? (only for debugging) if( QString( argv[i + 1] ) == "-e" ) { exitAfterImport = true; ++i; } } else if( arg == "--profile" || arg == "-p" ) { ++i; if( i == argc ) { printf( "\nNo profile specified.\n\n" "Try \"%s --help\" for more information.\n\n", argv[0] ); return EXIT_FAILURE; } profilerOutputFile = QString::fromLocal8Bit( argv[1] ); } else { if( argv[i][0] == '-' ) { printf( "\nInvalid option %s.\n\n" "Try \"%s --help\" for more information.\n\n", argv[i], argv[0] ); return EXIT_FAILURE; } fileToLoad = QString::fromLocal8Bit( argv[i] ); } } ConfigManager::inst()->loadConfigFile(); // set language QString pos = ConfigManager::inst()->value( "app", "language" ); if( pos.isEmpty() ) { pos = QLocale::system().name().left( 2 ); } #ifdef LMMS_BUILD_WIN32 #undef QT_TRANSLATIONS_DIR #define QT_TRANSLATIONS_DIR ConfigManager::inst()->localeDir() #endif #ifdef QT_TRANSLATIONS_DIR // load translation for Qt-widgets/-dialogs loadTranslation( QString( "qt_" ) + pos, QString( QT_TRANSLATIONS_DIR ) ); #endif // load actual translation for LMMS loadTranslation( pos ); // try to set realtime priority #ifdef LMMS_BUILD_LINUX #ifdef LMMS_HAVE_SCHED_H #ifndef __OpenBSD__ struct sched_param sparam; sparam.sched_priority = ( sched_get_priority_max( SCHED_FIFO ) + sched_get_priority_min( SCHED_FIFO ) ) / 2; if( sched_setscheduler( 0, SCHED_FIFO, &sparam ) == -1 ) { printf( "Notice: could not set realtime priority.\n" ); } #endif #endif #endif #ifdef LMMS_BUILD_WIN32 if( !SetPriorityClass( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) { printf( "Notice: could not set high priority.\n" ); } #endif // if we have an output file for rendering, just render the song // without starting the GUI if( !renderOut.isEmpty() ) { Engine::init( true ); QFileInfo fileInfo( fileToLoad ); if ( !fileInfo.exists() ) { printf("The file %s does not exist!\n", fileToLoad.toStdString().c_str()); exit( 1 ); } printf( "Loading project...\n" ); Engine::getSong()->loadProject( fileToLoad ); printf( "Done\n" ); Engine::getSong()->setExportLoop( renderLoop ); // when rendering multiple tracks, renderOut is a directory // otherwise, it is a file, so we need to append the file extension if ( !renderTracks ) { renderOut = baseName( renderOut ) + ProjectRenderer::getFileExtensionFromFormat(eff); } // create renderer RenderManager * r = new RenderManager( qs, os, eff, renderOut ); QCoreApplication::instance()->connect( r, SIGNAL( finished() ), SLOT( quit() ) ); // timer for progress-updates QTimer * t = new QTimer( r ); r->connect( t, SIGNAL( timeout() ), SLOT( updateConsoleProgress() ) ); t->start( 200 ); if( profilerOutputFile.isEmpty() == false ) { Engine::mixer()->profiler().setOutputFile( profilerOutputFile ); } // start now! if ( renderTracks ) { r->renderTracks(); } else { r->renderProject(); } } else // otherwise, start the GUI { new GuiApplication(); // re-intialize RNG - shared libraries might have srand() or // srandom() calls in their init procedure srand( getpid() + time( 0 ) ); // recover a file? QString recoveryFile = ConfigManager::inst()->recoveryFile(); if( QFileInfo(recoveryFile).exists() && QMessageBox::question( gui->mainWindow(), MainWindow::tr( "Project recovery" ), MainWindow::tr( "It looks like the last session did not end properly. " "Do you want to recover the project of this session?" ), QMessageBox::Yes | QMessageBox::No ) == QMessageBox::Yes ) { fileToLoad = recoveryFile; } // we try to load given file if( !fileToLoad.isEmpty() ) { gui->mainWindow()->show(); if( fullscreen ) { gui->mainWindow()->showMaximized(); } if( fileToLoad == recoveryFile ) { Engine::getSong()->createNewProjectFromTemplate( fileToLoad ); } else { Engine::getSong()->loadProject( fileToLoad ); } } else if( !fileToImport.isEmpty() ) { ImportFilter::import( fileToImport, Engine::getSong() ); if( exitAfterImport ) { return EXIT_SUCCESS; } gui->mainWindow()->show(); if( fullscreen ) { gui->mainWindow()->showMaximized(); } } else { // If enabled, open last project if there is one. Else, create // a new one. if( ConfigManager::inst()-> value( "app", "openlastproject" ).toInt() && !ConfigManager::inst()->recentlyOpenedProjects().isEmpty() ) { QString f = ConfigManager::inst()-> recentlyOpenedProjects().first(); QFileInfo recentFile( f ); if ( recentFile.exists() ) { Engine::getSong()->loadProject( f ); } else { Engine::getSong()->createNewProject(); } } else { Engine::getSong()->createNewProject(); } // [Settel] workaround: showMaximized() doesn't work with // FVWM2 unless the window is already visible -> show() first gui->mainWindow()->show(); if( fullscreen ) { gui->mainWindow()->showMaximized(); } } } const int ret = app->exec(); delete app; // cleanup memory managers MemoryManager::cleanup(); return ret; }
int main(int argc, char *argv[]) { slimproto_t slimproto; slimaudio_t slimaudio; PaDeviceIndex output_device_id = PA_DEFAULT_DEVICE; unsigned int output_predelay = 0; unsigned int output_predelay_amplitude = 0; slimaudio_volume_t volume_control = VOLUME_SOFTWARE; unsigned int retry_interval = RETRY_DEFAULT; char macaddress[6] = { 0, 0, 0, 0, 0, 1 }; int keepalive_interval = -1; bool listdevs = false; #ifdef DAEMONIZE bool should_daemonize = false; char *logfile = NULL; #endif #ifdef INTERACTIVE fd_set read_fds; fd_set write_fds; int key = 0; unsigned long ir = 0; int maxfd = 0; char *home; struct timeval timeout; timeout.tv_usec = 0; #ifdef __WIN32__ int WSAerrno; int ptw32_processInitialize (void); ptw32_processInitialize(); #endif // default lircrc file ($HOME/.lircrc) home = getenv("HOME"); if (home == NULL) home = ""; lircrc = (char *)malloc((strlen(home) + strlen("/.lircrc") + 1) * sizeof(char)); strcpy(lircrc,home); strcat(lircrc,"/.lircrc"); #endif char getopt_options[OPTLEN] = "a:d:Y:e:f:hk:Lm:o:P:p:Rr:Vv:"; static struct option long_options[] = { {"predelay_amplitude", required_argument, 0, 'a'}, {"debug", required_argument, 0, 'd'}, {"debuglog", required_argument, 0, 'Y'}, {"help", no_argument, 0, 'h'}, {"keepalive", required_argument, 0, 'k'}, {"list", no_argument, 0, 'L'}, {"mac", required_argument, 0, 'm'}, {"output", required_argument, 0, 'o'}, {"playerid", required_argument, 0, 'e'}, {"firmware", required_argument, 0, 'f'}, {"port", required_argument, 0, 'P'}, {"predelay", required_argument, 0, 'p'}, {"retry", no_argument, 0, 'R'}, {"intretry", required_argument, 0, 'r'}, {"version", no_argument, 0, 'V'}, {"volume", required_argument, 0, 'v'}, #ifdef PORTAUDIO_DEV {"latency", required_argument, 0, 'y'}, #endif #ifdef DAEMONIZE {"daemonize", required_argument, 0, 'M'}, #endif #ifdef __WIN32__ {"highpriority", no_argument, 0, 'H'}, #ifdef PA_WASAPI {"shared", no_argument, 0, 'S'}, #endif #endif #ifdef INTERACTIVE {"lircrc", required_argument, 0, 'c'}, {"lirc", no_argument, 0, 'i'}, {"lcd", no_argument, 0, 'l'}, {"display", no_argument, 0, 'D'}, {"width", required_argument, 0, 'w'}, #endif {0, 0, 0, 0} }; #ifdef PORTAUDIO_DEV strcat (getopt_options, "y:"); #endif #ifdef DAEMONIZE strcat (getopt_options, "M:"); #endif #ifdef INTERACTIVE strcat (getopt_options, "c:Dilw:"); #endif #ifdef __WIN32__ strcat (getopt_options, "H"); #ifdef PA_WASAPI strcat (getopt_options, "S"); #endif #endif while (true) { const char shortopt = getopt_long_only(argc, argv, getopt_options, long_options, NULL); if (shortopt == (char) -1) { break; } switch (shortopt) { case 'a': output_predelay_amplitude = strtoul(optarg, NULL, 0); break; case 'd': #ifdef SLIMPROTO_DEBUG if (strcmp(optarg, "all") == 0) { slimproto_debug = true; slimaudio_debug = true; slimaudio_buffer_debug = true; slimaudio_buffer_debug_v = true; slimaudio_decoder_debug = true; slimaudio_decoder_debug_r = true; slimaudio_decoder_debug_v = true; slimaudio_http_debug = true; slimaudio_http_debug_v = true; slimaudio_output_debug = true; slimaudio_output_debug_v = true; } else if (strcmp(optarg, "slimproto") == 0) slimproto_debug = true; else if (strcmp(optarg, "slimaudio") == 0) slimaudio_debug = true; else if (strcmp(optarg, "slimaudio_buffer") == 0) slimaudio_buffer_debug = true; else if (strcmp(optarg, "slimaudio_buffer_v") == 0) slimaudio_buffer_debug_v = true; else if (strcmp(optarg, "slimaudio_decoder") == 0) slimaudio_decoder_debug = true; else if (strcmp(optarg, "slimaudio_decoder_r") == 0) slimaudio_decoder_debug_r = true; else if (strcmp(optarg, "slimaudio_decoder_v") == 0) slimaudio_decoder_debug_v = true; else if (strcmp(optarg, "slimaudio_http") == 0) slimaudio_http_debug = true; else if (strcmp(optarg, "slimaudio_http_v") == 0) slimaudio_http_debug_v = true; else if (strcmp(optarg, "slimaudio_output") == 0) slimaudio_output_debug = true; else if (strcmp(optarg, "slimaudio_output_v") == 0) slimaudio_output_debug_v = true; else fprintf(stderr, "%s: Unknown debug option %s\n", argv[0], optarg); #else fprintf(stderr, "%s: Recompile with -DSLIMPROTO_DEBUG to enable debugging.\n", argv[0]); #endif break; case 'Y': #ifdef SLIMPROTO_DEBUG if ( optarg == NULL ) { fprintf(stderr, "%s: Cannot parse debug log filename %s\n", argv[0], optarg); exit(-1); } else { debuglog = freopen( optarg, "a", stderr); if ( debuglog ) debug_logfile = true; else fprintf(stderr, "%s: Redirection of stderr to %s failed.\n", argv[0], optarg); } #endif break; // From server/Slim/Networking/Slimproto.pm from 7.5r28596 // squeezebox(2) // softsqueeze(3) // squeezebox2(4) // transporter(5) // softsqueeze3(6) // receiver(7) // squeezeslave(8) // controller(9) // boom(10) // softboom(11) // squeezeplay(12) // radio(13) // touch(14) case 'e': player_type = strtoul(optarg, NULL, 0); if ( (player_type < 2) || (player_type > 14) ) { player_type = PLAYER_TYPE; fprintf(stderr, "%s: Unknown player type, using (%d)\n", argv[0], player_type); } break; case 'f': firmware = strtoul(optarg, NULL, 0); if ( (firmware < 0) || (firmware > 254) ) { firmware = FIRMWARE_VERSION; fprintf(stderr, "%s: Invalid firmware value, using (%d)\n", argv[0], firmware); } break; case 'h': print_help(); exit(0); case 'k': keepalive_interval = strtoul(optarg, NULL, 0); break; case 'm': if (parse_macaddress(macaddress, optarg) != 0) { fprintf(stderr, "%s: Cannot parse mac address %s\n", argv[0], optarg); exit(-1); } break; #ifdef DAEMONIZE case 'M': if ( optarg == NULL ) { fprintf(stderr, "%s: Cannot parse log filename %s\n", argv[0], optarg); exit(-1); } else { logfile = optarg; } should_daemonize = true; break; #endif #ifdef __WIN32__ case 'H': /* Change Window process priority class to HIGH */ if ( !SetPriorityClass ( GetCurrentProcess(), HIGH_PRIORITY_CLASS ) ) { int dwError = GetLastError(); fprintf(stderr, "%s: Failed to set priority (%d), using default.\n", argv[0], dwError); } break; #ifdef PA_WASAPI case 'S': wasapi_exclusive = false; break; #endif #endif case 'o': output_device_id = strtoul(optarg, NULL, 0); output_change = true; break; case 'p': output_predelay = strtoul(optarg, NULL, 0); break; case 'P': port = strtoul(optarg, NULL, 0); if ( (port < 0) || (port > 65535) ) { port = SLIMPROTOCOL_PORT; fprintf(stderr, "%s: Invalid port value, using (%d)\n", argv[0], port); } break; break; case 'R': retry_connection = true; break; case 'r': retry_connection = true; retry_interval = strtoul(optarg, NULL, 0); if ( retry_interval < 1 ) { fprintf (stderr, "Retry option requires value in seconds.\n"); exit(-1); } break; #ifdef INTERACTIVE case 'c': free(lircrc); lircrc = optarg; break; #ifndef __WIN32__ case 'i': using_lirc = true; break; case 'l': use_lcdd_menu = true; break; #endif case 'D': using_curses = 1; break; case 'w': linelen = strtoul(optarg, NULL, 0); break; #endif case 'L': listdevs = true; break; case 'V': print_version(); exit(0); break; case 'v': if (strcmp(optarg, "sw") == 0) { volume_control = VOLUME_SOFTWARE; } #ifndef PORTAUDIO_DEV else if (strcmp(optarg, "on") == 0 ) { volume_control = VOLUME_DRIVER; } #endif else if (strcmp(optarg, "off") == 0 ) { volume_control = VOLUME_NONE; } break; #ifdef PORTAUDIO_DEV case 'y': modify_latency = true; user_latency = strtoul(optarg, NULL, 0); if ( user_latency > 1000 ) { fprintf (stderr, "Suggested latency invalid, using device default.\n"); modify_latency = false; } break; #endif default: break; } } if (listdevs) { GetAudioDevices(output_device_id, output_change, true); exit(0); } #ifdef DAEMONIZE if ( should_daemonize ) { #ifdef INTERACTIVE if ( using_curses || using_lirc || use_lcdd_menu ) { fprintf(stderr, "Daemonize not supported with lirc or display modes.\n"); exit(-1); } else #endif init_daemonize(); } #endif char *slimserver_address = "127.0.0.1"; if (optind < argc) slimserver_address = argv[optind]; signal(SIGTERM, &exit_handler); install_restart_handler(); #ifdef INTERACTIVE install_toggle_handler(); //SIGUSR2 to toggle IR/LCD on and off #endif if (slimproto_init(&slimproto) < 0) { fprintf(stderr, "Failed to initialize slimproto\n"); exit(-1); } if (slimaudio_init(&slimaudio, &slimproto, output_device_id, output_change) < 0) { fprintf(stderr, "Failed to initialize slimaudio\n"); exit(-1); } slimproto_add_connect_callback(&slimproto, connect_callback, macaddress); #ifdef INTERACTIVE // Process VFD (display) commands if ( using_curses || using_lirc || use_lcdd_menu ) slimproto_add_command_callback(&slimproto, "vfdc", vfd_callback, macaddress); #endif slimaudio_set_volume_control(&slimaudio, volume_control); slimaudio_set_output_predelay(&slimaudio, output_predelay, output_predelay_amplitude); if (keepalive_interval >= 0) { slimaudio_set_keepalive_interval(&slimaudio, keepalive_interval); } #ifdef INTERACTIVE init_lcd(); #endif if (slimaudio_open(&slimaudio) < 0) { fprintf(stderr, "Failed to open slimaudio\n"); #ifdef INTERACTIVE close (lcd_fd); #endif exit(-1); } #ifdef SLIMPROTO_DEBUG if (slimaudio_debug) fprintf ( stderr, "Using audio device index: %d\n", slimaudio.output_device_id ); #endif #ifdef INTERACTIVE init_lirc(); setlocale(LC_ALL, ""); initcurses(); #endif #ifdef DAEMONIZE if ( should_daemonize ) { daemonize(logfile); } #endif // When retry_connection is true, retry connecting to Squeezebox Server // until we succeed, unless the signal handler tells us to give up. do { while (slimproto_connect( &slimproto, slimserver_address, port) < 0) { if (!retry_connection || signal_exit_flag) { if (signal_exit_flag) { // No message when the exit is triggered // by the user. #ifdef INTERACTIVE exitcurses(); close_lirc(); close_lcd(); #endif exit(0); } #ifdef INTERACTIVE exitcurses(); close_lirc(); close_lcd(); #endif fprintf(stderr, "Connection to Squeezebox Server %s failed.\n", slimserver_address); exit(-1); } #ifdef INTERACTIVE exitcurses(); #endif fprintf(stderr,"Retry in %d seconds.\n", retry_interval); Pa_Sleep(1000 * retry_interval); #ifdef INTERACTIVE initcurses(); #endif } signal_restart_flag = false; while (!signal_exit_flag && !signal_restart_flag) { #ifdef INTERACTIVE if (using_curses == 1 || use_lcdd_menu) { FD_ZERO(&read_fds); FD_ZERO(&write_fds); if (using_curses == 1) FD_SET(0, &read_fds); /* watch stdin */ if (use_lcdd_menu) { FD_SET(lcd_fd, &read_fds); maxfd = lcd_fd; } if (using_lirc) { FD_SET(lirc_fd, &read_fds); if (lirc_fd > maxfd) maxfd = lirc_fd; } timeout.tv_sec = 5; if(select(maxfd + 1, &read_fds, NULL, NULL, &timeout) == -1) { #ifndef __WIN32__ if (errno != EINTR) { fprintf(stderr,"Select Error:%d\n", errno); #else WSAerrno = WSAGetLastError(); if ( (WSAerrno != WSAEINTR) && (WSAerrno != WSAENOTSOCK) ) { fprintf(stderr,"Select Error:%d\n", WSAerrno); #endif abort(); } #ifdef __WIN32__ else WaitForSingleObject( GetStdHandle(STD_INPUT_HANDLE), 5000 ); #endif } if (FD_ISSET(0, &read_fds)) { while ((key = getch()) != ERR) { ir = getircode(key); if (ir == (unsigned long) 0x01) { signal_exit_flag = 1; }else{ if (ir != 0) slimproto_ir(&slimproto, 1, 1, ir); } } } if (using_lirc && FD_ISSET(lirc_fd, &read_fds)) { while((key = read_lirc()) != 0 ) { ir = getircode(key); if (ir == 0x01) { signal_exit_flag = 1; } else { if (ir != 0) slimproto_ir(&slimproto, 1, 1, ir); } } } if (use_lcdd_menu && FD_ISSET(lcd_fd, &read_fds)) { while(read_lcd()); } } else { wait_for_restart_signal(); } #else wait_for_restart_signal(); #endif } #ifdef INTERACTIVE FD_ZERO(&read_fds); FD_ZERO(&write_fds); #endif if (signal_restart_flag) { #ifdef INTERACTIVE exitcurses(); #endif fprintf(stderr,"Retry in %d seconds.\n", retry_interval); Pa_Sleep(1000 * retry_interval); #ifdef INTERACTIVE initcurses(); #endif } } while (signal_restart_flag && !signal_exit_flag); #ifdef INTERACTIVE close_lirc(); #endif slimaudio_close(&slimaudio); slimproto_close(&slimproto); #ifdef INTERACTIVE exitcurses(); close_lcd(); #endif #ifdef SLIMPROTO_DEBUG if (debug_logfile) { fclose (debuglog); } #endif slimaudio_destroy(&slimaudio); slimproto_destroy(&slimproto); return 0; }