Ejemplo n.º 1
0
            public void startOnlineRace(string ip, int port, int httpPort, IJavascriptCallback callback = null)
            {
                if (_car == null)
                {
                    throw new Exception("Car is not set");
                }

                if (_track == null)
                {
                    throw new Exception("Track is not set");
                }

                ActionExtension.InvokeInMainThread(async() => {
                    var result = await GameWrapper.StartAsync(new Game.StartProperties {
                        BasicProperties = new Game.BasicProperties {
                            CarId   = _car.Id,
                            TrackId = _track.MainTrackObject.Id,
                            TrackConfigurationId = _track.LayoutId,
                            CarSkinId            = _carSkin?.Id ?? _car.SelectedSkin?.Id ?? ""
                        },
                        ModeProperties = new Game.OnlineProperties {
                            Guid           = SteamIdHelper.Instance.Value,
                            ServerIp       = ip,
                            ServerPort     = port,
                            ServerHttpPort = httpPort,
                            Password       = InternalUtils.GetRaceUPassword(_track.IdWithLayout, ip, port),
                            RequestedCar   = _car.Id
                        }
                    });
                    callback?.ExecuteAsync(result?.IsNotCancelled);
                }).Ignore();
            }
Ejemplo n.º 2
0
        public override string AcApiRequest(string url)
        {
            url = url.SubstringExt(AcApiHandlerFactory.AcSchemeName.Length + 3);
            Logging.Debug(url);

            var index  = url.IndexOf('?');
            var pieces = (index == -1 ? url : url.Substring(0, index)).Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

            switch (pieces[0])
            {
            case "getguid":
                return(SteamIdHelper.Instance.Value);

            case "setsetting":
                switch (pieces.ArrayElementAtOrDefault(1))
                {
                case "race":
                    foreach (var parameter in GetParameters())
                    {
                        var p = parameter.Key.Split('/');
                        if (p.Length != 2)
                        {
                            Logging.Warning($"Invalid key: {parameter.Key}");
                        }
                        else
                        {
                            Logging.Debug($"Parameter: {parameter.Key}={parameter.Value}");
                            _raceConfig[p[0]].Set(p[1], parameter.Value);
                        }
                    }
                    break;

                default:
                    Logging.Warning($"Unknown setting: {pieces.ArrayElementAtOrDefault(1)}");
                    break;
                }
                return(string.Empty);

            case "start":
                ActionExtension.InvokeInMainThread(() => {
                    GameWrapper.StartAsync(new Game.StartProperties {
                        PreparedConfig = _raceConfig
                    });
                });
                return(string.Empty);

            default:
                Logging.Warning($"Unknown request: {pieces[0]} (“{url}”)");
                return(null);
            }

            Dictionary <string, string> GetParameters()
            {
                return((index == -1 ? "" : url.Substring(index + 1))
                       .Split(new[] { '&' }, StringSplitOptions.RemoveEmptyEntries)
                       .Select(x => x.Split(new[] { '=' }, 2)).ToDictionary(
                           x => Uri.UnescapeDataString(x[0]),
                           x => Uri.UnescapeDataString(x.ArrayElementAtOrDefault(1) ?? "")));
            }
        }
Ejemplo n.º 3
0
            public async Task <bool> Go()
            {
                if (Server?.Ip == null || Player == null || CarId == null)
                {
                    return(false);
                }

                try {
                    if (Car == null)
                    {
                        throw new InformativeException(string.Format(ToolsStrings.AcError_CarIsMissing, CarId), AppStrings.Srs_CarIsMissing_Commentary);
                    }

                    var anyTrack = TracksManager.Instance.GetDefault();
                    Logging.Debug(CarSkinId);
                    await GameWrapper.StartAsync(new Game.StartProperties {
                        BasicProperties = new Game.BasicProperties {
                            CarId                = CarId,
                            CarSkinId            = CarSkinId,
                            TrackId              = anyTrack?.Id,
                            TrackConfigurationId = anyTrack?.LayoutId
                        },
                        ModeProperties = new Game.OnlineProperties {
                            ServerName     = Server.DisplayName,
                            ServerIp       = Server.Ip,
                            ServerPort     = Server.Port ?? 9615,
                            ServerHttpPort = Server.PortHttp,
                            Password       = Server.Password,
                            Penalties      = true,
                        },
                        AdditionalPropertieses =
                        {
                            new SrsMark {
                                Name        = Player.DisplayName ?? SrsMark.GetName(),
                                Team        = Player.Team ?? "",
                                Nationality = Player.Nationality ?? ""
                            }
                        }
                    });

                    return(true);
                } catch (Exception e) {
                    NonfatalError.Notify(AppStrings.Common_CannotStartRace, e);
                    return(false);
                }
            }
Ejemplo n.º 4
0
        private static async Task <ArgumentHandleResult> ProcessRaceConfig(CustomUriRequest custom)
        {
            var config = GetSettings(custom.Params, @"config") ?? throw new Exception(@"Settings are not specified");

            var assists = GetSettings(custom.Params, @"assists");

            if (assists != null && !UserPresetsControl.LoadSerializedPreset(AssistsViewModel.Instance.PresetableKey, assists))
            {
                AssistsViewModel.Instance.ImportFromPresetData(assists);
            }

            await GameWrapper.StartAsync(new Game.StartProperties {
                PreparedConfig = IniFile.Parse(config)
            });

            return(ArgumentHandleResult.Successful);
        }
Ejemplo n.º 5
0
            public void _startOnlineRace(string jsonParams, IJavascriptCallback callback = null)
            {
                var args = JObject.Parse(jsonParams);

                if (_car == null)
                {
                    throw new Exception("Car is not set");
                }

                if (_track == null)
                {
                    throw new Exception("Track is not set");
                }

                var ip   = args.GetStringValueOnly("ip") ?? throw new Exception("“ip” parameter is missing");
                var port = args.GetIntValueOnly("port") ?? throw new Exception("“port” parameter is missing");

                var properties = new Game.StartProperties {
                    BasicProperties = new Game.BasicProperties {
                        CarId   = _car.Id,
                        TrackId = _track.MainTrackObject.Id,
                        TrackConfigurationId = _track.LayoutId,
                        CarSkinId            = _carSkin?.Id ?? _car.SelectedSkin?.Id ?? ""
                    },
                    ModeProperties = new Game.OnlineProperties {
                        Guid           = SteamIdHelper.Instance.Value,
                        ServerIp       = ip,
                        ServerPort     = port,
                        ServerHttpPort = args.GetIntValueOnly("httpPort") ?? throw new Exception("“httpPort” parameter is missing"),
                                               Password               = args.GetStringValueOnly("password") ?? InternalUtils.GetRaceUPassword(_track.IdWithLayout, ip, port),
                                               RequestedCar           = _car.Id,
                                               CspFeaturesList        = args.GetStringValueOnly("cspFeatures"),
                                               CspReplayClipUploadUrl = args.GetStringValueOnly("cspReplayClipUploadUrl"),
                    }
                };

                ActionExtension.InvokeInMainThread(async() => {
                    var result = await GameWrapper.StartAsync(properties);
                    callback?.ExecuteAsync(result?.IsNotCancelled);
                }).Ignore();
            }
Ejemplo n.º 6
0
        private async Task Join(object o)
        {
            var carEntry = SelectedCarEntry;

            if (carEntry == null || Cars == null)
            {
                return;
            }

            var correctId = GetCorrectId(carEntry.Id);

            if (correctId == null)
            {
                Logging.Error("Can’t find correct ID");
                return;
            }

            if (!IsBookedForPlayer && BookingMode && !ReferenceEquals(o, ActualJoin) && !ReferenceEquals(o, ForceJoin))
            {
                if (_factory == null)
                {
                    Logging.Error("Booking: UI factory is missing");
                    return;
                }

                PrepareBookingUi();
                ProcessBookingResponse(await Task.Run(() => KunosApiProvider.TryToBook(Ip, PortHttp, Password, correctId, carEntry.AvailableSkin?.Id,
                                                                                       DriverName.GetOnline(), "")));
                return;
            }

            DisposeHelper.Dispose(ref _ui);
            IsBooked            = false;
            BookingErrorMessage = null;

            var properties = new Game.StartProperties(new Game.BasicProperties {
                CarId                = carEntry.Id,
                CarSkinId            = carEntry.AvailableSkin?.Id,
                TrackId              = Track?.Id,
                TrackConfigurationId = Track?.LayoutId
            }, null, null, null, new Game.OnlineProperties {
                RequestedCar   = correctId,
                ServerIp       = Ip,
                ServerName     = DisplayName,
                ServerPort     = PortRace,
                ServerHttpPort = PortHttp,
                Guid           = SteamIdHelper.Instance.Value,
                Password       = Password
            });

            var now = DateTime.Now;
            await GameWrapper.StartAsync(properties);

            var whatsGoingOn = properties.GetAdditional <WhatsGoingOn>();

            WrongPassword = whatsGoingOn?.Type == WhatsGoingOnType.OnlineWrongPassword;

            if (whatsGoingOn == null)
            {
                LastConnected = now;
                FileBasedOnlineSources.AddRecent(this).Forget();
                UpdateStats();
            }
        }
Ejemplo n.º 7
0
        private static async Task <ArgumentHandleResult> ProcessUriRequestObsolete(string request)
        {
            string key, param;
            NameValueCollection query;

            {
                var splitted = request.Split(new[] { '/' }, 2);
                if (splitted.Length != 2)
                {
                    return(ArgumentHandleResult.FailedShow);
                }

                key   = splitted[0];
                param = splitted[1];

                var index = param.IndexOf('?');
                if (index != -1)
                {
                    query = HttpUtility.ParseQueryString(param.SubstringExt(index + 1));
                    param = param.Substring(0, index);
                }
                else
                {
                    query = null;
                }
            }

            switch (key)
            {
            case "quickdrive":
                var preset = Convert.FromBase64String(param).ToUtf8String();
                if (!await QuickDrive.RunAsync(serializedPreset: preset))
                {
                    NonfatalError.Notify(AppStrings.Common_CannotStartRace, AppStrings.Arguments_CannotStartRace_Commentary);
                    return(ArgumentHandleResult.Failed);
                }
                break;

            case "race":
                var raceIni = Convert.FromBase64String(param).ToUtf8String();
                await GameWrapper.StartAsync(new Game.StartProperties {
                    PreparedConfig = IniFile.Parse(raceIni)
                });

                break;

            case "open":
                var address = Convert.FromBase64String(param).ToUtf8String();
                try {
                    return(await ProcessInputFile(await LoadRemoveFile(address, query?.Get(@"name"))));
                } catch (Exception e) when(e.IsCancelled())
                {
                    return(ArgumentHandleResult.Failed);
                } catch (Exception e) {
                    Logging.Warning(e);
                    return(ArgumentHandleResult.FailedShow);
                }

            case "install":
                return(await ContentInstallationManager.Instance.InstallAsync(param, new ContentInstallationParams(true))
                            ? ArgumentHandleResult.Successful : ArgumentHandleResult.Failed);
            }

            return(ArgumentHandleResult.Successful);
        }
Ejemplo n.º 8
0
        private static async Task <ArgumentHandleResult> ProcessRaceOnline(NameValueCollection p)
        {
            // Required arguments
            var ip       = p.Get(@"ip");
            var port     = FlexibleParser.TryParseInt(p.Get(@"port"));
            var httpPort = FlexibleParser.TryParseInt(p.Get(@"httpPort"));
            var carId    = p.Get(@"car");

            // Optional arguments
            var allowWithoutSteamId = p.GetFlag("allowWithoutSteamId");
            var carSkinId           = p.Get(@"skin");
            var trackId             = p.Get(@"track");
            var name              = p.Get(@"name");
            var nationality       = p.Get(@"nationality");
            var password          = p.Get(@"plainPassword");
            var encryptedPassword = p.Get(@"password");

            if (string.IsNullOrWhiteSpace(ip))
            {
                throw new InformativeException("IP is missing");
            }

            if (!port.HasValue)
            {
                throw new InformativeException("Port is missing or is in invalid format");
            }

            if (!httpPort.HasValue)
            {
                throw new InformativeException("HTTP port is missing or is in invalid format");
            }

            if (string.IsNullOrWhiteSpace(password) && !string.IsNullOrWhiteSpace(encryptedPassword))
            {
                password = OnlineServer.DecryptSharedPassword(ip, httpPort.Value, encryptedPassword);
            }

            if (string.IsNullOrWhiteSpace(carId))
            {
                throw new InformativeException("Car ID is missing");
            }

            var car = CarsManager.Instance.GetById(carId);

            if (car == null)
            {
                throw new InformativeException("Car is missing");
            }

            if (!string.IsNullOrWhiteSpace(carSkinId) && car.GetSkinById(carSkinId) == null)
            {
                throw new InformativeException("Car skin is missing");
            }

            var track = string.IsNullOrWhiteSpace(trackId) ? null : TracksManager.Instance.GetLayoutByKunosId(trackId);

            if (!string.IsNullOrWhiteSpace(trackId) && track == null)
            {
                throw new InformativeException("Track is missing");
            }


            if (!SteamIdHelper.Instance.IsReady && !allowWithoutSteamId)
            {
                throw new InformativeException(ToolsStrings.Common_SteamIdIsMissing);
            }

            await GameWrapper.StartAsync(new Game.StartProperties {
                BasicProperties = new Game.BasicProperties {
                    CarId   = carId,
                    TrackId = track?.MainTrackObject.Id ?? @"imola",
                    TrackConfigurationId = track?.LayoutId,
                    CarSkinId            = carSkinId,
                    DriverName           = name,
                    DriverNationality    = nationality
                },
                ModeProperties = new Game.OnlineProperties {
                    Guid           = SteamIdHelper.Instance.Value,
                    ServerIp       = ip,
                    ServerPort     = port.Value,
                    ServerHttpPort = httpPort.Value,
                    Password       = password,
                    RequestedCar   = carId
                }
            });

            return(ArgumentHandleResult.Successful);
        }
Ejemplo n.º 9
0
            public async Task <bool> Go()
            {
                if (EventId == null)
                {
                    return(false);
                }

                try {
                    var app = PythonAppsManager.Instance.GetById(RsrMark.AppId);
                    if (app == null)
                    {
                        throw new InformativeException(AppStrings.Rsr_AppIsMissing, AppStrings.Rsr_AppIsMissing_Commentary);
                    }

                    if (!app.Enabled)
                    {
                        app.ToggleCommand.Execute(null);
                        await Task.Delay(500);
                    }

                    if (!app.Enabled)
                    {
                        throw new InformativeException(AppStrings.Rsr_AppIsDisabled, AppStrings.Rsr_AppIsDisabled_Commentary);
                    }

                    var ids = await LoadData();

                    if (ids == null)
                    {
                        throw new InformativeException(AppStrings.Rsr_InvalidParameters, AppStrings.Rsr_InvalidParameters_Commentary);
                    }

                    if (Car == null)
                    {
                        throw new InformativeException(string.Format(ToolsStrings.AcError_CarIsMissing, ids.Item1), AppStrings.Rsr_ContentIsMissing_Commentary);
                    }

                    if (Track == null)
                    {
                        throw new InformativeException(string.Format(ToolsStrings.AcError_TrackIsMissing, ids.Item2), AppStrings.Rsr_ContentIsMissing_Commentary);
                    }

                    await GameWrapper.StartAsync(new Game.StartProperties {
                        BasicProperties = new Game.BasicProperties {
                            CarId   = Car.Id,
                            TrackId = Track.Id,
                            TrackConfigurationId = Track.LayoutId,
                            CarSkinId            = CarSkin?.Id,
                        },
                        AssistsProperties   = Assists.ToGameProperties(),
                        ConditionProperties = new Game.ConditionProperties {
                            AmbientTemperature = 26d,
                            RoadTemperature    = 32d,
                            CloudSpeed         = 1d,
                            SunAngle           = 0,
                            TimeMultipler      = 1d,
                            WeatherName        = WeatherManager.Instance.GetDefault()?.Id
                        },
                        TrackProperties = Game.GetDefaultTrackPropertiesPreset().Properties,
                        ModeProperties  = new Game.HotlapProperties {
                            SessionName       = AppStrings.Rsr_SessionName,
                            Penalties         = true,
                            GhostCar          = GhostCar,
                            GhostCarAdvantage = 0d
                        },
                        AdditionalPropertieses =
                        {
                            new RsrMark()
                        }
                    });

                    return(true);
                } catch (Exception e) {
                    NonfatalError.Notify(AppStrings.Common_CannotStartRace, e);
                    return(false);
                }
            }
Ejemplo n.º 10
0
 protected Task StartAsync(Game.StartProperties properties)
 {
     return(GameWrapper.StartAsync(properties));
 }
Ejemplo n.º 11
0
        private static async Task MainAsync(Options options)
        {
            var sunAngle = MathUtils.Random(-70d, 70d);
            var seconds  = Game.ConditionProperties.GetSeconds(sunAngle);
            var weather  = WeatherManager.Instance.GetById(options.WeatherId);
            var track    = options.TrackId.Split('/');

            switch (options.Starter)
            {
            case Starter.Official:
                SettingsHolder.Drive.SelectedStarterType = SettingsHolder.Drive.StarterTypes.GetById("Official");
                break;

            case Starter.Tricky:
                SettingsHolder.Drive.SelectedStarterType = SettingsHolder.Drive.StarterTypes.GetById("Tricky");
                break;

            case Starter.UiModule:
                SettingsHolder.Drive.SelectedStarterType = SettingsHolder.Drive.StarterTypes.GetById("UI Module");
                break;

            case Starter.Sse:
                PluginsManager.Initialize(options.PluginsDir);
                SettingsHolder.Drive.SelectedStarterType = SettingsHolder.Drive.StarterTypes.GetById("SSE");
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var result = await GameWrapper.StartAsync(new Game.StartProperties(new Game.BasicProperties {
                CarId                = options.CarId,
                CarSkinId            = options.CarSkinId,
                TrackId              = track[0],
                TrackConfigurationId = track.ElementAtOrDefault(1),
                DriverName           = options.DriverName
            }, GetAssistsProperties(options.Assist), new Game.ConditionProperties {
                AmbientTemperature = options.AmbientTemperature,
                CloudSpeed         = 2d,
                SunAngle           = sunAngle,
                RoadTemperature    = Game.ConditionProperties.GetRoadTemperature(seconds, options.AmbientTemperature, weather.TemperatureCoefficient),
                TimeMultipler      = 1d,
                WeatherName        = weather.Id
            }, Game.DefaultTrackPropertiesPresets.First().Properties, GetModeProperties(options)));

            if (result == null)
            {
                Console.WriteLine("Race cancelled");
                return;
            }

            switch (options.Mode)
            {
            case Mode.Practice:
                return;

            case Mode.HotLap:
                var bestLap = result.GetExtraByType <Game.ResultExtraBestLap>()?.Time;
                if (bestLap.HasValue)
                {
                    Console.WriteLine(bestLap);
                }
                else
                {
                    Console.WriteLine("Time has not been set");
                }
                return;

            case Mode.Race:
                var position = result.Sessions.LastOrDefault(x => x.BestLaps.Any())?.CarPerTakenPlace?.IndexOf(0);
                if (position.HasValue)
                {
                    Console.WriteLine(position);
                }
                else
                {
                    Console.WriteLine("Position has not been taken");
                }
                return;

            case Mode.Drift:
                var points = result.GetExtraByType <Game.ResultExtraDrift>()?.Points;
                if (points.HasValue)
                {
                    Console.WriteLine(points);
                }
                else
                {
                    Console.WriteLine("Score has not been set");
                }
                return;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
Ejemplo n.º 12
0
        void IGameUi.OnResult(Game.Result result, ReplayHelper replayHelper)
        {
            if (result != null && result.NumberOfSessions == 1 && result.Sessions.Length == 1 &&
                result.Sessions[0].Type == Game.SessionType.Practice && SettingsHolder.Drive.SkipPracticeResults ||
                _properties?.ReplayProperties != null || _properties?.BenchmarkProperties != null)
            {
                Close();
                return;
            }

            /* save replay button * /
             * Func<string> buttonText = () => replayHelper?.IsReplayRenamed == true ?
             *      AppStrings.RaceResult_UnsaveReplay : AppStrings.RaceResult_SaveReplay;
             *
             * var saveReplayButton = CreateExtraDialogButton(buttonText(), () => {
             *  if (replayHelper == null) {
             *      Logging.Warning("ReplayHelper=<NULL>");
             *      return;
             *  }
             *
             *  replayHelper.IsReplayRenamed = !replayHelper.IsReplayRenamed;
             * });
             *
             * if (replayHelper == null) {
             *  saveReplayButton.IsEnabled = false;
             * } else {
             *  replayHelper.PropertyChanged += (sender, args) => {
             *      if (args.PropertyName == nameof(ReplayHelper.IsReplayRenamed)) {
             *          saveReplayButton.Content = buttonText();
             *      }
             *  };
             * }
             *
             * /* save replay alt button */
            ButtonWithComboBox saveReplayButton;

            if (replayHelper != null)
            {
                Func <string> buttonText = () => replayHelper.IsRenamed ?
                                           AppStrings.RaceResult_UnsaveReplay : AppStrings.RaceResult_SaveReplay;
                Func <string> saveAsText = () => string.Format(replayHelper.IsRenamed ? "Saved as “{0}”" : "Save as “{0}”",
                                                               replayHelper.Name);

                saveReplayButton = new ButtonWithComboBox {
                    Margin    = new Thickness(4, 0, 0, 0),
                    MinHeight = 21,
                    MinWidth  = 65,
                    Content   = ToolsStrings.Shared_Replay,
                    Command   = new AsyncCommand(replayHelper.Play),
                    MenuItems =
                    {
                        new MenuItem {
                            Header = saveAsText(), Command = new DelegateCommand(() =>{
                                var newName = Prompt.Show("Save replay as:", "Replay Name", replayHelper.Name, "?", required: true);
                                if (!string.IsNullOrWhiteSpace(newName))
                                {
                                    replayHelper.Name = newName;
                                }

                                replayHelper.IsRenamed = true;
                            })
                        },
                        new MenuItem {
                            Header = buttonText(), Command = new DelegateCommand(replayHelper.Rename)
                        },
                        new Separator(),
                        new MenuItem {
                            Header  = "Share Replay",
                            Command = new AsyncCommand(() =>{
                                var car = _properties?.BasicProperties?.CarId == null ? null :
                                          CarsManager.Instance.GetById(_properties.BasicProperties.CarId);
                                var track = _properties?.BasicProperties?.TrackId == null ? null :
                                            TracksManager.Instance.GetById(_properties.BasicProperties.TrackId);
                                return(SelectedReplayPage.ShareReplay(replayHelper.Name, replayHelper.Filename, car, track));
                            })
                        },
                    }
                };

                replayHelper.PropertyChanged += (sender, args) => {
                    if (args.PropertyName == nameof(ReplayHelper.IsRenamed))
                    {
                        ((MenuItem)saveReplayButton.MenuItems[0]).Header = saveAsText();
                        ((MenuItem)saveReplayButton.MenuItems[1]).Header = buttonText();
                    }
                };
            }
            else
            {
                saveReplayButton = null;
            }

            var tryAgainButton = CreateExtraDialogButton(AppStrings.RaceResult_TryAgain, () => {
                CloseWithResult(MessageBoxResult.None);
                GameWrapper.StartAsync(_properties).Forget();
            });

            Button fixButton = null;

            if (result == null || !result.IsNotCancelled)
            {
                Model.CurrentState = ViewModel.State.Cancelled;

                var whatsGoingOn = _properties?.GetAdditional <WhatsGoingOn>();
                fixButton          = this.CreateFixItButton(whatsGoingOn?.Solution);
                Model.ErrorMessage = whatsGoingOn?.GetDescription();
            }
            else
            {
                try {
                    Model.CurrentState = ViewModel.State.Finished;
                    Model.FinishedData = GetFinishedData(_properties, result);
                } catch (Exception e) {
                    Logging.Warning(e);

                    Model.CurrentState = ViewModel.State.Error;
                    Model.ErrorMessage = AppStrings.RaceResult_ResultProcessingError;
                    Buttons            = new[] { CloseButton };
                    return;
                }
            }

            Buttons = new[] {
                fixButton,
                fixButton == null ? saveReplayButton : null,
                fixButton == null ? tryAgainButton : null,
                CloseButton
            };
        }
Ejemplo n.º 13
0
        private async Task <ArgumentHandleResult> ProcessUriRequestObsolete(string request)
        {
            string key, param;
            NameValueCollection query;

            {
                var splitted = request.Split(new[] { '/' }, 2);
                if (splitted.Length != 2)
                {
                    return(ArgumentHandleResult.FailedShow);
                }

                key   = splitted[0];
                param = splitted[1];

                var index = param.IndexOf('?');
                if (index != -1)
                {
                    query = HttpUtility.ParseQueryString(param.SubstringExt(index + 1));
                    param = param.Substring(0, index);
                }
                else
                {
                    query = null;
                }
            }

            switch (key)
            {
            case "quickdrive":
                var preset = Convert.FromBase64String(param).ToUtf8String();
                if (!QuickDrive.RunSerializedPreset(preset))
                {
                    NonfatalError.Notify(AppStrings.Common_CannotStartRace, AppStrings.Arguments_CannotStartRace_Commentary);
                    return(ArgumentHandleResult.Failed);
                }
                break;

            case "race":
                var raceIni = Convert.FromBase64String(param).ToUtf8String();
                await GameWrapper.StartAsync(new Game.StartProperties {
                    PreparedConfig = IniFile.Parse(raceIni)
                });

                break;

            case "open":
            case "install":
                var address = Convert.FromBase64String(param).ToUtf8String();
                var path    = await LoadRemoveFile(address, query?.Get(@"name"));

                if (string.IsNullOrWhiteSpace(path))
                {
                    return(ArgumentHandleResult.FailedShow);
                }

                try {
                    if (!FileUtils.Exists(path))
                    {
                        return(ArgumentHandleResult.FailedShow);
                    }
                } catch (Exception) {
                    return(ArgumentHandleResult.FailedShow);
                }

                return(await ProcessInputFile(path));
            }

            return(ArgumentHandleResult.Successful);
        }