// ugly workaround because Windows does weird things and ENOTIME int real_main(int argc, char *argv[]); int main(int argc, char *argv[]) { return real_main(argc, argv); } #include #include #include #include #include #include #include #include #ifdef CHIAKI_ENABLE_CLI #include #endif #include #include #include #include #include #include #include #include #include #include #include Q_DECLARE_METATYPE(ChiakiLogLevel) #ifdef CHIAKI_ENABLE_CLI struct CLICommand { int (*cmd)(ChiakiLog *log, int argc, char *argv[]); }; static const QMap cli_commands = { { "discover", { chiaki_cli_cmd_discover } }, { "wakeup", { chiaki_cli_cmd_wakeup } } }; #endif int RunStream(QApplication &app, const StreamSessionConnectInfo &connect_info); int RunMain(QApplication &app, Settings *settings); int real_main(int argc, char *argv[]) { qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); qRegisterMetaType(); QApplication::setOrganizationName("Chiaki"); QApplication::setApplicationName("Chiaki"); ChiakiErrorCode err = chiaki_lib_init(); if(err != CHIAKI_ERR_SUCCESS) { fprintf(stderr, "Chiaki lib init failed: %s\n", chiaki_error_string(err)); return 1; } QApplication::setAttribute(Qt::AA_ShareOpenGLContexts); QSurfaceFormat::setDefaultFormat(AVOpenGLWidget::CreateSurfaceFormat()); QApplication app(argc, argv); QApplication::setWindowIcon(QIcon(":/icons/chiaki.svg")); QApplication::setAttribute(Qt::AA_UseHighDpiPixmaps); Settings settings; QCommandLineParser parser; parser.setOptionsAfterPositionalArgumentsMode(QCommandLineParser::ParseAsPositionalArguments); parser.addHelpOption(); QStringList cmds; cmds.append("stream"); cmds.append("list"); #ifdef CHIAKI_ENABLE_CLI cmds.append(cli_commands.keys()); #endif parser.addPositionalArgument("command", cmds.join(", ")); parser.addPositionalArgument("nickname", "Needed for stream command to get credentials for connecting. " "Use 'list' to get the nickname."); parser.addPositionalArgument("host", "Address to connect to (when using the stream command)"); QCommandLineOption regist_key_option("registkey", "", "registkey"); parser.addOption(regist_key_option); QCommandLineOption morning_option("morning", "", "morning"); parser.addOption(morning_option); QCommandLineOption fullscreen_option("fullscreen", "Start window in fullscreen (only for use with stream command)"); parser.addOption(fullscreen_option); parser.process(app); QStringList args = parser.positionalArguments(); if(args.length() == 0) return RunMain(app, &settings); if(args[0] == "list") { for(const auto &host : settings.GetRegisteredHosts()) printf("Host: %s \n", host.GetServerNickname().toLocal8Bit().constData()); return 0; } if(args[0] == "stream") { if(args.length() < 2) parser.showHelp(1); //QString host = args[sizeof(args) -1]; //the ip is always the last param for stream QString host = args[args.size()-1]; QByteArray morning; QByteArray regist_key; ChiakiTarget target = CHIAKI_TARGET_PS4_10; if(parser.value(regist_key_option).isEmpty() && parser.value(morning_option).isEmpty()) { if(args.length() < 3) parser.showHelp(1); bool found = false; for(const auto &temphost : settings.GetRegisteredHosts()) { if(temphost.GetServerNickname() == args[1]) { found = true; morning = temphost.GetRPKey(); regist_key = temphost.GetRPRegistKey(); target = temphost.GetTarget(); break; } } if(!found) { printf("No configuration found for '%s'\n", args[1].toLocal8Bit().constData()); return 1; } } else { // TODO: explicit option for target regist_key = parser.value(regist_key_option).toUtf8(); if(regist_key.length() > sizeof(ChiakiConnectInfo::regist_key)) { printf("Given regist key is too long (expected size <=%llu, got %d)\n", (unsigned long long)sizeof(ChiakiConnectInfo::regist_key), regist_key.length()); return 1; } regist_key += QByteArray(sizeof(ChiakiConnectInfo::regist_key) - regist_key.length(), 0); morning = QByteArray::fromBase64(parser.value(morning_option).toUtf8()); if(morning.length() != sizeof(ChiakiConnectInfo::morning)) { printf("Given morning has invalid size (expected %llu, got %d)\n", (unsigned long long)sizeof(ChiakiConnectInfo::morning), morning.length()); printf("Given morning has invalid size (expected %llu)", (unsigned long long)sizeof(ChiakiConnectInfo::morning)); return 1; } } StreamSessionConnectInfo connect_info(&settings, target, host, regist_key, morning, parser.isSet(fullscreen_option)); return RunStream(app, connect_info); } #ifdef CHIAKI_ENABLE_CLI else if(cli_commands.contains(args[0])) { ChiakiLog log; // TODO: add verbose arg chiaki_log_init(&log, CHIAKI_LOG_ALL & ~CHIAKI_LOG_VERBOSE, chiaki_log_cb_print, nullptr); const auto &cmd = cli_commands[args[0]]; int sub_argc = args.count(); QVector sub_argv_b(sub_argc); QVector sub_argv(sub_argc); for(size_t i=0; i