public async Task <LaunchResult> LaunchAsync(LaunchSetting setting) { var result = await Task.Factory.StartNew(() => { return(Launch(setting)); }); return(result); }
private async Task LaunchGameFromWindow() { try { string userName = playerNameTextBox.Text; #region 检查有效数据 if (authTypeCombobox.SelectedItem == null) { await this.ShowMessageAsync(App.GetResourceString("String.Message.EmptyAuthType"), App.GetResourceString("String.Message.EmptyAuthType2")); return; } if (string.IsNullOrWhiteSpace(userName)) { await this.ShowMessageAsync(App.GetResourceString("String.Message.EmptyUsername"), App.GetResourceString("String.Message.EmptyUsername2")); return; } if (launchVersionCombobox.SelectedItem == null) { await this.ShowMessageAsync(App.GetResourceString("String.Message.EmptyLaunchVersion"), App.GetResourceString("String.Message.EmptyLaunchVersion2")); return; } if (App.handler.Java == null) { await this.ShowMessageAsync(App.GetResourceString("String.Message.NoJava"), App.GetResourceString("String.Message.NoJava2")); return; } #endregion LaunchSetting launchSetting = new LaunchSetting() { Version = (Core.Modules.Version)launchVersionCombobox.SelectedItem }; this.loadingGrid.Visibility = Visibility.Visible; this.loadingRing.IsActive = true; #region 验证 AuthTypeItem auth = (AuthTypeItem)authTypeCombobox.SelectedItem; //设置CLIENT TOKEN if (string.IsNullOrWhiteSpace(App.config.MainConfig.User.ClientToken)) { App.config.MainConfig.User.ClientToken = Guid.NewGuid().ToString("N"); } else { Requester.ClientToken = App.config.MainConfig.User.ClientToken; } #region NewData string autoVerifyingMsg = null; string autoVerifyingMsg2 = null; string autoVerificationFailedMsg = null; string autoVerificationFailedMsg2 = null; string loginMsg = null; string loginMsg2 = null; LoginDialogSettings loginDialogSettings = new LoginDialogSettings() { NegativeButtonText = App.GetResourceString("String.Base.Cancel"), AffirmativeButtonText = App.GetResourceString("String.Base.Login"), RememberCheckBoxText = App.GetResourceString("String.Base.ShouldRememberLogin"), UsernameWatermark = App.GetResourceString("String.Base.Username"), InitialUsername = userName, RememberCheckBoxVisibility = Visibility, EnablePasswordPreview = true, PasswordWatermark = App.GetResourceString("String.Base.Password"), NegativeButtonVisibility = Visibility.Visible }; string verifyingMsg = null, verifyingMsg2 = null, verifyingFailedMsg = null, verifyingFailedMsg2 = null; #endregion switch (auth.Type) { #region 离线验证 case Config.AuthenticationType.OFFLINE: var loginResult = Core.Auth.OfflineAuthenticator.DoAuthenticate(userName); launchSetting.AuthenticateAccessToken = loginResult.Item1; launchSetting.AuthenticateUUID = loginResult.Item2; break; #endregion #region Mojang验证 case Config.AuthenticationType.MOJANG: Requester.AuthURL = "https://authserver.mojang.com"; autoVerifyingMsg = App.GetResourceString("String.Mainwindow.Auth.Mojang.AutoVerifying"); autoVerifyingMsg2 = App.GetResourceString("String.Mainwindow.Auth.Mojang.AutoVerifying2"); autoVerificationFailedMsg = App.GetResourceString("String.Mainwindow.Auth.Mojang.AutoVerificationFailed"); autoVerificationFailedMsg2 = App.GetResourceString("String.Mainwindow.Auth.Mojang.AutoVerificationFailed2"); loginMsg = App.GetResourceString("String.Mainwindow.Auth.Mojang.Login"); loginMsg2 = App.GetResourceString("String.Mainwindow.Auth.Mojang.Login2"); verifyingMsg = App.GetResourceString("String.Mainwindow.Auth.Mojang.Verifying"); verifyingMsg2 = App.GetResourceString("String.Mainwindow.Auth.Mojang.Verifying2"); verifyingFailedMsg = App.GetResourceString("String.Mainwindow.Auth.Mojang.VerificationFailed"); verifyingFailedMsg2 = App.GetResourceString("String.Mainwindow.Auth.Mojang.VerificationFailed2"); break; #endregion #region 统一通行证验证 case Config.AuthenticationType.NIDE8: if (App.nide8Handler == null) { await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.Auth.Nide8.NoID"), App.GetResourceString("String.Mainwindow.Auth.Nide8.NoID2")); return; } Requester.AuthURL = string.Format("{0}authserver", App.nide8Handler.BaseURL); autoVerifyingMsg = App.GetResourceString("String.Mainwindow.Auth.Nide8.AutoVerifying"); autoVerifyingMsg2 = App.GetResourceString("String.Mainwindow.Auth.Nide8.AutoVerifying2"); autoVerificationFailedMsg = App.GetResourceString("String.Mainwindow.Auth.Nide8.AutoVerificationFailed"); autoVerificationFailedMsg2 = App.GetResourceString("String.Mainwindow.Auth.Nide8.AutoVerificationFailed2"); loginMsg = App.GetResourceString("String.Mainwindow.Auth.Nide8.Login"); loginMsg2 = App.GetResourceString("String.Mainwindow.Auth.Nide8.Login2"); verifyingMsg = App.GetResourceString("String.Mainwindow.Auth.Nide8.Verifying"); verifyingMsg2 = App.GetResourceString("String.Mainwindow.Auth.Nide8.Verifying2"); verifyingFailedMsg = App.GetResourceString("String.Mainwindow.Auth.Nide8.VerificationFailed"); verifyingFailedMsg2 = App.GetResourceString("String.Mainwindow.Auth.Nide8.VerificationFailed2"); loginDialogSettings.NegativeButtonVisibility = Visibility.Visible; var nide8ChooseResult = await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.Auth.Nide8.Login2"), App.GetResourceString("String.Base.Choose"), MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, new MetroDialogSettings() { AffirmativeButtonText = App.GetResourceString("String.Base.Login"), NegativeButtonText = App.GetResourceString("String.Base.Cancel"), FirstAuxiliaryButtonText = App.GetResourceString("String.Base.Register"), DefaultButtonFocus = MessageDialogResult.Affirmative }); if (nide8ChooseResult == MessageDialogResult.Negative) { return; } if (nide8ChooseResult == MessageDialogResult.FirstAuxiliary) { System.Diagnostics.Process.Start(string.Format("https://login2.nide8.com:233/{0}/register", App.nide8Handler.ServerID)); return; } break; #endregion #region 自定义验证 case Config.AuthenticationType.CUSTOM_SERVER: string customAuthServer = App.config.MainConfig.User.AuthServer; if (string.IsNullOrWhiteSpace(customAuthServer)) { await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.Auth.Custom.NoAdrress"), App.GetResourceString("String.Mainwindow.Auth.Custom.NoAdrress2")); return; } else { Requester.AuthURL = customAuthServer; } autoVerifyingMsg = App.GetResourceString("String.Mainwindow.Auth.Custom.AutoVerifying"); autoVerifyingMsg2 = App.GetResourceString("String.Mainwindow.Auth.Custom.AutoVerifying2"); autoVerificationFailedMsg = App.GetResourceString("String.Mainwindow.Auth.Custom.AutoVerificationFailed"); autoVerificationFailedMsg2 = App.GetResourceString("String.Mainwindow.Auth.Custom.AutoVerificationFailed2"); loginMsg = App.GetResourceString("String.Mainwindow.Auth.Custom.Login"); loginMsg2 = App.GetResourceString("String.Mainwindow.Auth.Custom.Login2"); verifyingMsg = App.GetResourceString("String.Mainwindow.Auth.Custom.Verifying"); verifyingMsg2 = App.GetResourceString("String.Mainwindow.Auth.Custom.Verifying2"); verifyingFailedMsg = App.GetResourceString("String.Mainwindow.Auth.Custom.VerificationFailed"); verifyingFailedMsg2 = App.GetResourceString("String.Mainwindow.Auth.Custom.VerificationFailed2"); break; #endregion default: var defaultLoginResult = Core.Auth.OfflineAuthenticator.DoAuthenticate(userName); launchSetting.AuthenticateAccessToken = defaultLoginResult.Item1; launchSetting.AuthenticateUUID = defaultLoginResult.Item2; break; } if (auth.Type != Config.AuthenticationType.OFFLINE) { try { #region 如果记住登陆(有登陆记录) if ((!string.IsNullOrWhiteSpace(App.config.MainConfig.User.AccessToken)) && (App.config.MainConfig.User.AuthenticationUUID != null)) { var loader = await this.ShowProgressAsync(autoVerifyingMsg, autoVerifyingMsg2); loader.SetIndeterminate(); Validate validate = new Validate(App.config.MainConfig.User.AccessToken); var validateResult = await validate.PerformRequestAsync(); if (validateResult.IsSuccess) { launchSetting.AuthenticateAccessToken = App.config.MainConfig.User.AccessToken; launchSetting.AuthenticateUUID = App.config.MainConfig.User.AuthenticationUUID; await loader.CloseAsync(); } else { Refresh refresher = new Refresh(App.config.MainConfig.User.AccessToken); var refreshResult = await refresher.PerformRequestAsync(); await loader.CloseAsync(); if (refreshResult.IsSuccess) { App.config.MainConfig.User.AccessToken = refreshResult.AccessToken; launchSetting.AuthenticateUUID = App.config.MainConfig.User.AuthenticationUUID; launchSetting.AuthenticateAccessToken = refreshResult.AccessToken; } else { App.config.MainConfig.User.AccessToken = string.Empty; App.config.Save(); await this.ShowMessageAsync(autoVerificationFailedMsg, autoVerificationFailedMsg2); return; } } } #endregion #region 从零登陆 else { var loginMsgResult = await this.ShowLoginAsync(loginMsg, loginMsg2, loginDialogSettings); if (loginMsgResult == null) { return; } var loader = await this.ShowProgressAsync(verifyingMsg, verifyingMsg2); loader.SetIndeterminate(); userName = loginMsgResult.Username; Authenticate authenticate = new Authenticate(new Credentials() { Username = loginMsgResult.Username, Password = loginMsgResult.Password }); var aloginResult = await authenticate.PerformRequestAsync(); await loader.CloseAsync(); if (aloginResult.IsSuccess) { if (loginMsgResult.ShouldRemember) { App.config.MainConfig.User.AccessToken = aloginResult.AccessToken; } App.config.MainConfig.User.AuthenticationUserData = aloginResult.User; App.config.MainConfig.User.AuthenticationUUID = aloginResult.SelectedProfile; launchSetting.AuthenticateAccessToken = aloginResult.AccessToken; launchSetting.AuthenticateUUID = aloginResult.SelectedProfile; launchSetting.AuthenticationUserData = aloginResult.User; } else { await this.ShowMessageAsync(verifyingFailedMsg, verifyingFailedMsg2 + aloginResult.Error.ErrorMessage); return; } } #endregion } catch (Exception ex) { await this.ShowMessageAsync(verifyingFailedMsg, verifyingFailedMsg2 + ex.Message); return; } } App.config.MainConfig.User.AuthenticationType = auth.Type; #endregion #region 检查游戏完整 List <DownloadTask> losts = new List <DownloadTask>(); App.logHandler.AppendInfo("检查丢失的依赖库文件中..."); var lostDepend = await GetLost.GetLostDependDownloadTaskAsync( App.config.MainConfig.Download.DownloadSource, App.handler, launchSetting.Version); if (auth.Type == Config.AuthenticationType.NIDE8) { string nideJarPath = App.handler.GetNide8JarPath(); if (!File.Exists(nideJarPath)) { lostDepend.Add(new DownloadTask("统一通行证核心", "https://login2.nide8.com:233/index/jar", nideJarPath)); } } if (App.config.MainConfig.Environment.DownloadLostDepend && lostDepend.Count != 0) { MessageDialogResult downDependResult = await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.NeedDownloadDepend"), App.GetResourceString("String.Mainwindow.NeedDownloadDepend2"), MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, new MetroDialogSettings() { AffirmativeButtonText = App.GetResourceString("String.Base.Download"), NegativeButtonText = App.GetResourceString("String.Base.Cancel"), FirstAuxiliaryButtonText = App.GetResourceString("String.Base.Unremember"), DefaultButtonFocus = MessageDialogResult.Affirmative }); switch (downDependResult) { case MessageDialogResult.Affirmative: losts.AddRange(lostDepend); break; case MessageDialogResult.FirstAuxiliary: App.config.MainConfig.Environment.DownloadLostDepend = false; break; default: break; } } App.logHandler.AppendInfo("检查丢失的资源文件中..."); if (App.config.MainConfig.Environment.DownloadLostAssets && (await GetLost.IsLostAssetsAsync(App.config.MainConfig.Download.DownloadSource, App.handler, launchSetting.Version))) { MessageDialogResult downDependResult = await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.NeedDownloadAssets"), App.GetResourceString("String.Mainwindow.NeedDownloadAssets2"), MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, new MetroDialogSettings() { AffirmativeButtonText = App.GetResourceString("String.Base.Download"), NegativeButtonText = App.GetResourceString("String.Base.Cancel"), FirstAuxiliaryButtonText = App.GetResourceString("String.Base.Unremember"), DefaultButtonFocus = MessageDialogResult.Affirmative }); switch (downDependResult) { case MessageDialogResult.Affirmative: var lostAssets = await GetLost.GetLostAssetsDownloadTaskAsync( App.config.MainConfig.Download.DownloadSource, App.handler, launchSetting.Version); losts.AddRange(lostAssets); break; case MessageDialogResult.FirstAuxiliary: App.config.MainConfig.Environment.DownloadLostAssets = false; break; default: break; } } if (losts.Count != 0) { App.downloader.SetDownloadTasks(losts); App.downloader.StartDownload(); await new Windows.DownloadWindow().ShowWhenDownloading(); } #endregion #region 根据配置文件设置 launchSetting.AdvencedGameArguments += App.config.MainConfig.Environment.AdvencedGameArguments; launchSetting.AdvencedJvmArguments += App.config.MainConfig.Environment.AdvencedJvmArguments; launchSetting.GCArgument += App.config.MainConfig.Environment.GCArgument; launchSetting.GCEnabled = App.config.MainConfig.Environment.GCEnabled; launchSetting.GCType = App.config.MainConfig.Environment.GCType; launchSetting.JavaAgent += App.config.MainConfig.Environment.JavaAgent; if (auth.Type == Config.AuthenticationType.NIDE8) { launchSetting.JavaAgent += string.Format(" \"{0}\"={1}", App.handler.GetNide8JarPath(), App.config.MainConfig.User.Nide8ServerID); } //直连服务器设置 if ((auth.Type == Config.AuthenticationType.NIDE8) && App.config.MainConfig.User.AllUsingNide8) { var nide8ReturnResult = await App.nide8Handler.GetInfoAsync(); if (App.config.MainConfig.User.AllUsingNide8 && !string.IsNullOrWhiteSpace(nide8ReturnResult.Meta.ServerIP)) { Server server = new Server(); string[] serverIp = nide8ReturnResult.Meta.ServerIP.Split(':'); if (serverIp.Length == 2) { server.Address = serverIp[0]; server.Port = ushort.Parse(serverIp[1]); } else { server.Address = nide8ReturnResult.Meta.ServerIP; server.Port = 25565; } launchSetting.LaunchToServer = server; } } else if (App.config.MainConfig.Server.LaunchToServer) { launchSetting.LaunchToServer = new Server() { Address = App.config.MainConfig.Server.Address, Port = App.config.MainConfig.Server.Port }; } //自动内存设置 if (App.config.MainConfig.Environment.AutoMemory) { var m = SystemTools.GetBestMemory(App.handler.Java); App.config.MainConfig.Environment.MaxMemory = m; launchSetting.MaxMemory = m; } else { launchSetting.MaxMemory = App.config.MainConfig.Environment.MaxMemory; } launchSetting.VersionType = App.config.MainConfig.Customize.VersionInfo; launchSetting.WindowSize = App.config.MainConfig.Environment.WindowSize; #endregion #region 配置文件处理 App.config.MainConfig.User.UserName = userName; App.config.Save(); #endregion #region 启动 App.logHandler.OnLog += (a, b) => { this.Invoke(() => { launchInfoBlock.Text = b.Message; }); }; var result = await App.handler.LaunchAsync(launchSetting); App.logHandler.OnLog -= (a, b) => { this.Invoke(() => { launchInfoBlock.Text = b.Message; }); }; //程序猿是找不到女朋友的了 :) if (!result.IsSuccess) { await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.LaunchError") + result.LaunchException.Title, result.LaunchException.Message); App.logHandler.AppendError(result.LaunchException); } else { try { await Task.Factory.StartNew(() => { result.Process.WaitForInputIdle(); }); } catch (Exception ex) { await this.ShowMessageAsync("启动后等待游戏窗口响应异常", "这可能是由于游戏进程发生意外(闪退)导致的。具体原因:" + ex.Message); return; } if (App.config.MainConfig.Environment.ExitAfterLaunch) { Application.Current.Shutdown(); } this.WindowState = WindowState.Minimized; Refresh(); //自定义处理 if (!string.IsNullOrWhiteSpace(App.config.MainConfig.Customize.GameWindowTitle)) { GameHelper.SetGameTitle(result, App.config.MainConfig.Customize.GameWindowTitle); } if (App.config.MainConfig.Customize.CustomBackGroundMusic) { mediaElement.Volume = 0.5; await Task.Factory.StartNew(() => { try { for (int i = 0; i < 50; i++) { this.Dispatcher.Invoke(new Action(() => { this.mediaElement.Volume -= 0.01; })); Thread.Sleep(50); } this.Dispatcher.Invoke(new Action(() => { this.mediaElement.Stop(); })); } catch (Exception) {} }); } } #endregion } catch (Exception ex) { App.logHandler.AppendFatal(ex); } finally { this.loadingGrid.Visibility = Visibility.Hidden; this.loadingRing.IsActive = false; } }
public string Parse(LaunchSetting setting, string replace) { Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); #region JVM头参数部分 StringBuilder jvmHead = new StringBuilder(); #region 处理JavaAgent if (!string.IsNullOrWhiteSpace(setting.JavaAgent)) { jvmHead.Append("-javaagent:"); if (!App.Handler.VersionIsolation) { jvmHead.Append(setting.JavaAgent.Replace(replace + "\\", "").Trim()); } else { jvmHead.Append(setting.JavaAgent.Replace(replace + "\\", "..\\..\\").Trim()); } jvmHead.Append(' '); } #endregion #region 处理JVM启动头参数 if (setting.GCEnabled) { switch (setting.GCType) { case Modules.GCType.G1GC: jvmHead.Append("-XX:+UseG1GC"); break; case Modules.GCType.SerialGC: jvmHead.Append("-XX:+UseSerialGC"); break; case Modules.GCType.ParallelGC: jvmHead.Append("-XX:+UseParallelGC"); break; case Modules.GCType.CMSGC: jvmHead.Append("-XX:+UseConcMarkSweepGC"); break; default: break; } jvmHead.Append(' '); } if (!string.IsNullOrWhiteSpace(setting.GCArgument)) { jvmHead.Append(setting.GCArgument).Append(' '); } if (setting.MinMemory != 0) { jvmHead.Append(string.Format("-Xms{0}m ", setting.MinMemory)); } if (setting.MaxMemory != 0) { jvmHead.Append(string.Format("-Xmx{0}m ", setting.MaxMemory)); } if (!string.IsNullOrWhiteSpace(setting.AdvencedJvmArguments)) { jvmHead.Append(setting.AdvencedJvmArguments).Append(' '); } #endregion #region 处理游戏JVM参数 Dictionary <string, string> jvmArgDic = new Dictionary <string, string>() { { "${natives_directory}", string.Format("\"{0}{1}\"", handler.GetGameVersionRootDir(setting.Version), @"\$natives") }, { "${launcher_name}", "NsisoLauncher5" }, { "${launcher_version}", Assembly.GetExecutingAssembly().GetName().Version.ToString() }, { "${classpath}", GetClassPaths(setting.Version.Libraries, setting.Version) }, }; jvmHead.Append(ReplaceByDic(setting.Version.JvmArguments, jvmArgDic)?.Trim()); jvmHead.Append(' '); jvmHead.Append("-Dfml.ignoreInvalidMinecraftCertificates=true -Dfml.ignorePatchDiscrepancies=true "); #endregion #endregion #region 处理游戏参数 string assetsPath = string.Format("\"{0}\\assets\"", handler.GameRootPath); string legacy = setting.AuthenticateResult.SelectedProfileUUID.Legacy ? "Legacy" : "Mojang"; string gameDir = string.Format("\"{0}\"", handler.GetGameVersionRootDir(setting.Version)); Dictionary <string, string> gameArgDic = new Dictionary <string, string>() { { "${auth_player_name}", string.Format("\"{0}\"", setting.AuthenticateResult.SelectedProfileUUID.PlayerName) }, { "${auth_session}", setting.AuthenticateResult.AccessToken }, { "${version_name}", string.Format("\"{0}\"", setting.Version.ID) }, { "${game_directory}", gameDir }, { "${game_assets}", assetsPath }, { "${assets_root}", assetsPath }, { "${assets_index_name}", setting.Version.Assets }, { "${auth_uuid}", setting.AuthenticateResult.SelectedProfileUUID.Value }, { "${auth_access_token}", setting.AuthenticateResult.AccessToken }, { "${user_properties}", ToList(setting.AuthenticateResult.UserData?.Properties) }, { "${user_type}", legacy }, { "${version_type}", string.IsNullOrWhiteSpace(setting.VersionType) ? PathManager.LauncherName : setting.VersionType } }; StringBuilder otherGamearg = new StringBuilder(); if (setting.WindowSize != null) { if (setting.WindowSize.FullScreen) { otherGamearg.Append(" --fullscreen"); } else { if (setting.WindowSize.Width > 0) { otherGamearg.AppendFormat(" --width {0}", setting.WindowSize.Width); } if (setting.WindowSize.Height > 0) { otherGamearg.AppendFormat(" --height {0}", setting.WindowSize.Height); } } } if (setting.LaunchToServer != null) { ServerInfo server = new ServerInfo(setting.LaunchToServer); SendDebugLog("正在获取服务器信息(SRV)"); server.StartGetServerInfo(); if (server.State == ServerInfo.StateType.GOOD) { SendDebugLog("服务器信息返回正常"); otherGamearg.AppendFormat(" --server {0}", server.ServerAddress); otherGamearg.AppendFormat(" --port {0}", server.ServerPort); } else { SendDebugLog("服务器未正常响应,尝试使用原始地址"); if (!string.IsNullOrWhiteSpace(setting.LaunchToServer.Address)) { otherGamearg.AppendFormat(" --server {0}", setting.LaunchToServer.Address); } if (setting.LaunchToServer.Port > 0) { otherGamearg.AppendFormat(" --port {0}", setting.LaunchToServer.Port); } } } if (!string.IsNullOrWhiteSpace(setting.AdvencedGameArguments)) { otherGamearg.Append(' ' + setting.AdvencedGameArguments); } string gameArg = (ReplaceByDic(setting.Version.MinecraftArguments, gameArgDic) + otherGamearg.ToString())?.Trim(); #endregion stopwatch.Stop(); string allArg = jvmHead.ToString() + setting.Version.MainClass + ' ' + gameArg; SendDebugLog(string.Format("完成启动参数转换,用时:{0}ms", stopwatch.ElapsedMilliseconds)); SendDebugLog(string.Format("启动参数:{0}", allArg)); return(allArg.Trim()); }
private async Task LaunchGameFromArgs(Controls.LaunchEventArgs args) { try { #region 检查有效数据 if (args.LaunchVersion == null) { await this.ShowMessageAsync(App.GetResourceString("String.Message.EmptyLaunchVersion"), App.GetResourceString("String.Message.EmptyLaunchVersion2")); return; } if (args.UserNode == null) { await this.ShowMessageAsync(App.GetResourceString("String.Message.EmptyUsername"), App.GetResourceString("String.Message.EmptyUsername2")); return; } if (args.AuthNode == null) { await this.ShowMessageAsync(App.GetResourceString("String.Message.EmptyAuthType"), App.GetResourceString("String.Message.EmptyAuthType2")); return; } if (App.handler.Java == null) { await this.ShowMessageAsync(App.GetResourceString("String.Message.NoJava"), App.GetResourceString("String.Message.NoJava2")); return; } #endregion #region 保存启动数据 App.config.MainConfig.History.LastLaunchVersion = args.LaunchVersion.ID; #endregion LaunchSetting launchSetting = new LaunchSetting() { Version = args.LaunchVersion }; this.loadingGrid.Visibility = Visibility.Visible; this.loadingRing.IsActive = true; #region 验证 #region 设置ClientToken if (string.IsNullOrWhiteSpace(App.config.MainConfig.User.ClientToken)) { App.config.MainConfig.User.ClientToken = Guid.NewGuid().ToString("N"); } else { Requester.ClientToken = App.config.MainConfig.User.ClientToken; } #endregion #region 多语言支持变量 LoginDialogSettings loginDialogSettings = new LoginDialogSettings() { NegativeButtonText = App.GetResourceString("String.Base.Cancel"), AffirmativeButtonText = App.GetResourceString("String.Base.Login"), RememberCheckBoxText = App.GetResourceString("String.Base.ShouldRememberLogin"), UsernameWatermark = App.GetResourceString("String.Base.Username"), InitialUsername = args.UserNode.UserName, RememberCheckBoxVisibility = Visibility, EnablePasswordPreview = true, PasswordWatermark = App.GetResourceString("String.Base.Password"), NegativeButtonVisibility = Visibility.Visible }; #endregion //主验证器接口 IAuthenticator authenticator = null; bool shouldRemember = false; //bool isSameAuthType = (authNode.AuthenticationType == auth); bool isRemember = (!string.IsNullOrWhiteSpace(args.UserNode.AccessToken)) && (args.UserNode.SelectProfileUUID != null); //bool isSameName = userName == App.config.MainConfig.User.UserName; switch (args.AuthNode.AuthType) { #region 离线验证 case AuthenticationType.OFFLINE: if (args.IsNewUser) { authenticator = new OfflineAuthenticator(args.UserNode.UserName); } else { authenticator = new OfflineAuthenticator(args.UserNode.UserName, args.UserNode.UserData, args.UserNode.SelectProfileUUID); } break; #endregion #region MOJANG验证 case AuthenticationType.MOJANG: if (isRemember) { var mYggTokenAuthenticator = new YggdrasilTokenAuthenticator(args.UserNode.AccessToken, args.UserNode.GetSelectProfileUUID(), args.UserNode.UserData); mYggTokenAuthenticator.ProxyAuthServerAddress = "https://authserver.mojang.com"; authenticator = mYggTokenAuthenticator; } else { var mojangLoginDResult = await this.ShowLoginAsync(App.GetResourceString("String.Mainwindow.Auth.Mojang.Login"), App.GetResourceString("String.Mainwindow.Auth.Mojang.Login2"), loginDialogSettings); if (IsValidateLoginData(mojangLoginDResult)) { var mYggAuthenticator = new YggdrasilAuthenticator(new Credentials() { Username = mojangLoginDResult.Username, Password = mojangLoginDResult.Password }); mYggAuthenticator.ProxyAuthServerAddress = "https://authserver.mojang.com"; authenticator = mYggAuthenticator; shouldRemember = mojangLoginDResult.ShouldRemember; } else { await this.ShowMessageAsync("您输入的账号或密码为空", "请检查您是否正确填写登录信息"); return; } } break; #endregion #region NIDE8验证 case AuthenticationType.NIDE8: string nide8ID = args.AuthNode.Property["nide8ID"]; if (string.IsNullOrWhiteSpace(nide8ID)) { await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.Auth.Nide8.NoID"), App.GetResourceString("String.Mainwindow.Auth.Nide8.NoID2")); return; } var nide8ChooseResult = await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.Auth.Nide8.Login2"), App.GetResourceString("String.Base.Choose"), MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, new MetroDialogSettings() { AffirmativeButtonText = App.GetResourceString("String.Base.Login"), NegativeButtonText = App.GetResourceString("String.Base.Cancel"), FirstAuxiliaryButtonText = App.GetResourceString("String.Base.Register"), DefaultButtonFocus = MessageDialogResult.Affirmative }); switch (nide8ChooseResult) { case MessageDialogResult.Canceled: return; case MessageDialogResult.Negative: return; case MessageDialogResult.FirstAuxiliary: System.Diagnostics.Process.Start(string.Format("https://login2.nide8.com:233/{0}/register", nide8ID)); return; case MessageDialogResult.Affirmative: if (isRemember) { var nYggTokenCator = new Nide8TokenAuthenticator(nide8ID, args.UserNode.AccessToken, args.UserNode.GetSelectProfileUUID(), args.UserNode.UserData); authenticator = nYggTokenCator; } else { var nide8LoginDResult = await this.ShowLoginAsync(App.GetResourceString("String.Mainwindow.Auth.Nide8.Login"), App.GetResourceString("String.Mainwindow.Auth.Nide8.Login2"), loginDialogSettings); if (IsValidateLoginData(nide8LoginDResult)) { var nYggCator = new Nide8Authenticator( nide8ID, new Credentials() { Username = nide8LoginDResult.Username, Password = nide8LoginDResult.Password }); authenticator = nYggCator; shouldRemember = nide8LoginDResult.ShouldRemember; } else { await this.ShowMessageAsync("您输入的账号或密码为空", "请检查您是否正确填写登录信息"); return; } } break; default: break; } break; #endregion #region AUTHLIB验证 case AuthenticationType.AUTHLIB_INJECTOR: string aiRootAddr = args.AuthNode.Property["authserver"]; if (string.IsNullOrWhiteSpace(aiRootAddr)) { await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.Auth.Custom.NoAdrress"), App.GetResourceString("String.Mainwindow.Auth.Custom.NoAdrress2")); return; } else { if (isRemember) { var cYggTokenCator = new AuthlibInjectorTokenAuthenticator(aiRootAddr, args.UserNode.AccessToken, args.UserNode.GetSelectProfileUUID(), args.UserNode.UserData); authenticator = cYggTokenCator; } else { var customLoginDResult = await this.ShowLoginAsync(App.GetResourceString("String.Mainwindow.Auth.Custom.Login"), App.GetResourceString("String.Mainwindow.Auth.Custom.Login2"), loginDialogSettings); if (IsValidateLoginData(customLoginDResult)) { var cYggAuthenticator = new AuthlibInjectorAuthenticator( aiRootAddr, new Credentials() { Username = customLoginDResult.Username, Password = customLoginDResult.Password }); authenticator = cYggAuthenticator; shouldRemember = customLoginDResult.ShouldRemember; } else { await this.ShowMessageAsync("您输入的账号或密码为空", "请检查您是否正确填写登录信息"); return; } } } break; #endregion #region 自定义验证 case AuthenticationType.CUSTOM_SERVER: string customAuthServer = args.AuthNode.Property["authserver"]; if (string.IsNullOrWhiteSpace(customAuthServer)) { await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.Auth.Custom.NoAdrress"), App.GetResourceString("String.Mainwindow.Auth.Custom.NoAdrress2")); return; } else { if (isRemember) { var cYggTokenCator = new YggdrasilTokenAuthenticator(args.UserNode.AccessToken, args.UserNode.GetSelectProfileUUID(), args.UserNode.UserData); cYggTokenCator.ProxyAuthServerAddress = customAuthServer; } else { var customLoginDResult = await this.ShowLoginAsync(App.GetResourceString("String.Mainwindow.Auth.Custom.Login"), App.GetResourceString("String.Mainwindow.Auth.Custom.Login2"), loginDialogSettings); if (IsValidateLoginData(customLoginDResult)) { var cYggAuthenticator = new YggdrasilAuthenticator(new Credentials() { Username = customLoginDResult.Username, Password = customLoginDResult.Password }); cYggAuthenticator.ProxyAuthServerAddress = customAuthServer; authenticator = cYggAuthenticator; shouldRemember = customLoginDResult.ShouldRemember; } else { await this.ShowMessageAsync("您输入的账号或密码为空", "请检查您是否正确填写登录信息"); return; } } } break; #endregion #region 意外情况 default: if (args.IsNewUser) { authenticator = new OfflineAuthenticator(args.UserNode.UserName); } else { authenticator = new OfflineAuthenticator(args.UserNode.UserName, args.UserNode.UserData, args.UserNode.SelectProfileUUID); } break; #endregion } //如果验证方式不是离线验证 if (args.AuthNode.AuthType != AuthenticationType.OFFLINE) { string currentLoginType = string.Format("正在进行{0}中...", args.AuthNode.Name); string loginMsg = "这需要联网进行操作,可能需要一分钟的时间"; var loader = await this.ShowProgressAsync(currentLoginType, loginMsg, true); loader.SetIndeterminate(); var authResult = await authenticator.DoAuthenticateAsync(); await loader.CloseAsync(); switch (authResult.State) { case AuthState.SUCCESS: args.UserNode.SelectProfileUUID = authResult.SelectedProfileUUID.Value; args.UserNode.UserData = authResult.UserData; if (authResult.Profiles != null) { args.UserNode.Profiles.Clear(); authResult.Profiles.ForEach(x => args.UserNode.Profiles.Add(x.Value, x)); } if (shouldRemember) { args.UserNode.AccessToken = authResult.AccessToken; } launchSetting.AuthenticateResult = authResult; break; case AuthState.REQ_LOGIN: args.UserNode.ClearAuthCache(); await this.ShowMessageAsync("验证失败:您的登录信息已过期", string.Format("请您重新进行登录。具体信息:{0}", authResult.Error.ErrorMessage)); return; case AuthState.ERR_INVALID_CRDL: await this.ShowMessageAsync("验证失败:您的登录账号或密码错误", string.Format("请您确认您输入的账号密码正确。具体信息:{0}", authResult.Error.ErrorMessage)); return; case AuthState.ERR_NOTFOUND: if (args.AuthNode.AuthType == AuthenticationType.CUSTOM_SERVER || args.AuthNode.AuthType == AuthenticationType.AUTHLIB_INJECTOR) { await this.ShowMessageAsync("验证失败:代理验证服务器地址有误或账号未找到", string.Format("请确认您的Authlib-Injector验证服务器(Authlib-Injector验证)或自定义验证服务器(自定义验证)地址正确或确认账号和游戏角色存在。具体信息:{0}", authResult.Error.ErrorMessage)); } else { await this.ShowMessageAsync("验证失败:您的账号未找到", string.Format("请确认您的账号和游戏角色存在。具体信息:{0}", authResult.Error.ErrorMessage)); } return; case AuthState.ERR_OTHER: await this.ShowMessageAsync("验证失败:其他错误", string.Format("具体信息:{0}", authResult.Error.ErrorMessage)); return; case AuthState.ERR_INSIDE: await this.ShowMessageAsync("验证失败:启动器内部错误", string.Format("建议您联系启动器开发者进行解决。具体信息:{0}", authResult.Error.ErrorMessage)); return; default: await this.ShowMessageAsync("验证失败:未知错误", "建议您联系启动器开发者进行解决。"); return; } } else { var authResult = await authenticator.DoAuthenticateAsync(); launchSetting.AuthenticateResult = authResult; args.UserNode.UserData = authResult.UserData; args.UserNode.SelectProfileUUID = authResult.SelectedProfileUUID.Value; } App.config.MainConfig.History.SelectedUserNodeID = args.UserNode.UserData.Uuid; if (!App.config.MainConfig.User.UserDatabase.ContainsKey(args.UserNode.UserData.Uuid)) { App.config.MainConfig.User.UserDatabase.Add(args.UserNode.UserData.Uuid, args.UserNode); } #endregion #region 检查游戏完整 List <DownloadTask> losts = new List <DownloadTask>(); App.logHandler.AppendInfo("检查丢失的依赖库文件中..."); var lostDepend = await FileHelper.GetLostDependDownloadTaskAsync( App.config.MainConfig.Download.DownloadSource, App.handler, launchSetting.Version); if (args.AuthNode.AuthType == AuthenticationType.NIDE8) { string nideJarPath = App.handler.GetNide8JarPath(); if (!File.Exists(nideJarPath)) { lostDepend.Add(new DownloadTask("统一通行证核心", "https://login2.nide8.com:233/index/jar", nideJarPath)); } } else if (args.AuthNode.AuthType == AuthenticationType.AUTHLIB_INJECTOR) { string aiJarPath = App.handler.GetAIJarPath(); if (!File.Exists(aiJarPath)) { lostDepend.Add(await MineRealmsLauncherCore.Net.Tools.GetDownloadUrl.GetAICoreDownloadTask(App.config.MainConfig.Download.DownloadSource, aiJarPath)); } } if (App.config.MainConfig.Environment.DownloadLostDepend && lostDepend.Count != 0) { MessageDialogResult downDependResult = await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.NeedDownloadDepend"), App.GetResourceString("String.Mainwindow.NeedDownloadDepend2"), MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, new MetroDialogSettings() { AffirmativeButtonText = App.GetResourceString("String.Base.Download"), NegativeButtonText = App.GetResourceString("String.Base.Cancel"), FirstAuxiliaryButtonText = App.GetResourceString("String.Base.Unremember"), DefaultButtonFocus = MessageDialogResult.Affirmative }); switch (downDependResult) { case MessageDialogResult.Affirmative: losts.AddRange(lostDepend); break; case MessageDialogResult.FirstAuxiliary: App.config.MainConfig.Environment.DownloadLostDepend = false; break; default: break; } } App.logHandler.AppendInfo("检查丢失的资源文件中..."); if (App.config.MainConfig.Environment.DownloadLostAssets && (await FileHelper.IsLostAssetsAsync(App.config.MainConfig.Download.DownloadSource, App.handler, launchSetting.Version))) { MessageDialogResult downDependResult = await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.NeedDownloadAssets"), App.GetResourceString("String.Mainwindow.NeedDownloadAssets2"), MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, new MetroDialogSettings() { AffirmativeButtonText = App.GetResourceString("String.Base.Download"), NegativeButtonText = App.GetResourceString("String.Base.Cancel"), FirstAuxiliaryButtonText = App.GetResourceString("String.Base.Unremember"), DefaultButtonFocus = MessageDialogResult.Affirmative }); switch (downDependResult) { case MessageDialogResult.Affirmative: var lostAssets = await FileHelper.GetLostAssetsDownloadTaskAsync( App.config.MainConfig.Download.DownloadSource, App.handler, launchSetting.Version); losts.AddRange(lostAssets); break; case MessageDialogResult.FirstAuxiliary: App.config.MainConfig.Environment.DownloadLostAssets = false; break; default: break; } } if (losts.Count != 0) { if (!App.downloader.IsBusy) { App.downloader.SetDownloadTasks(losts); App.downloader.StartDownload(); var downloadResult = await new DownloadWindow().ShowWhenDownloading(); if (downloadResult?.ErrorList?.Count != 0) { await this.ShowMessageAsync(string.Format("有{0}个文件下载补全失败", downloadResult.ErrorList.Count), "这可能是因为本地网络问题或下载源问题,您可以尝试检查网络环境或在设置中切换首选下载源,启动器将继续尝试启动"); } } else { await this.ShowMessageAsync("无法下载补全:当前有正在下载中的任务", "请等待其下载完毕或取消下载,启动器将尝试继续启动"); } } #endregion #region 根据配置文件设置 launchSetting.AdvencedGameArguments += App.config.MainConfig.Environment.AdvencedGameArguments; launchSetting.AdvencedJvmArguments += App.config.MainConfig.Environment.AdvencedJvmArguments; launchSetting.GCArgument += App.config.MainConfig.Environment.GCArgument; launchSetting.GCEnabled = App.config.MainConfig.Environment.GCEnabled; launchSetting.GCType = App.config.MainConfig.Environment.GCType; launchSetting.JavaAgent += App.config.MainConfig.Environment.JavaAgent; if (args.AuthNode.AuthType == AuthenticationType.NIDE8) { launchSetting.JavaAgent += string.Format(" \"{0}\"={1}", App.handler.GetNide8JarPath(), args.AuthNode.Property["nide8ID"]); } else if (args.AuthNode.AuthType == AuthenticationType.AUTHLIB_INJECTOR) { launchSetting.JavaAgent += string.Format(" \"{0}\"={1}", App.handler.GetAIJarPath(), args.AuthNode.Property["authserver"]); } //直连服务器设置 var lockAuthNode = App.config.MainConfig.User.GetLockAuthNode(); if (App.config.MainConfig.User.Nide8ServerDependence && (lockAuthNode != null) && (lockAuthNode.AuthType == AuthenticationType.NIDE8)) { var nide8ReturnResult = await(new MineRealmsLauncherCore.Net.Nide8API.APIHandler(lockAuthNode.Property["nide8ID"])).GetInfoAsync(); if (!string.IsNullOrWhiteSpace(nide8ReturnResult.Meta.ServerIP)) { MineRealmsLauncherCore.Modules.Server server = new MineRealmsLauncherCore.Modules.Server(); string[] serverIp = nide8ReturnResult.Meta.ServerIP.Split(':'); if (serverIp.Length == 2) { server.Address = serverIp[0]; server.Port = ushort.Parse(serverIp[1]); } else { server.Address = nide8ReturnResult.Meta.ServerIP; server.Port = 25565; } launchSetting.LaunchToServer = server; } } else if (App.config.MainConfig.Server.LaunchToServer) { launchSetting.LaunchToServer = new MineRealmsLauncherCore.Modules.Server() { Address = App.config.MainConfig.Server.Address, Port = App.config.MainConfig.Server.Port }; } //自动内存设置 if (App.config.MainConfig.Environment.AutoMemory) { var m = SystemTools.GetBestMemory(App.handler.Java); App.config.MainConfig.Environment.MaxMemory = m; launchSetting.MaxMemory = m; } else { launchSetting.MaxMemory = App.config.MainConfig.Environment.MaxMemory; } launchSetting.VersionType = App.config.MainConfig.Customize.VersionInfo; launchSetting.WindowSize = App.config.MainConfig.Environment.WindowSize; #endregion #region 配置文件处理 App.config.Save(); #endregion #region 启动 App.logHandler.OnLog += (a, b) => { this.Invoke(() => { launchInfoBlock.Text = b.Message; }); }; var result = await App.handler.LaunchAsync(launchSetting); App.logHandler.OnLog -= (a, b) => { this.Invoke(() => { launchInfoBlock.Text = b.Message; }); }; //程序猿是找不到女朋友的了 :) if (!result.IsSuccess) { await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.LaunchError") + result.LaunchException.Title, result.LaunchException.Message); App.logHandler.AppendError(result.LaunchException); } else { cancelLaunchButton.Click += (x, y) => { CancelLaunching(result); }; #region 等待游戏响应 try { await Task.Factory.StartNew(() => { result.Process.WaitForInputIdle(); }); } catch (Exception ex) { await this.ShowMessageAsync("启动后等待游戏窗口响应异常", "这可能是由于游戏进程发生意外(闪退)导致的。具体原因:" + ex.Message); return; } #endregion cancelLaunchButton.Click -= (x, y) => { CancelLaunching(result); }; #region 数据反馈 //API使用次数计数器+1 await App.MineRealmsAPIHandler.RefreshUsingTimesCounter(); #endregion if (App.config.MainConfig.Environment.ExitAfterLaunch) { Application.Current.Shutdown(); } this.WindowState = WindowState.Minimized; mainPanel.Refresh(); //自定义处理 if (!string.IsNullOrWhiteSpace(App.config.MainConfig.Customize.GameWindowTitle)) { GameHelper.SetGameTitle(result, App.config.MainConfig.Customize.GameWindowTitle); } if (App.config.MainConfig.Customize.CustomBackGroundMusic) { mediaElement.Volume = 0.5; await Task.Factory.StartNew(() => { try { for (int i = 0; i < 50; i++) { this.Dispatcher.Invoke(new Action(() => { this.mediaElement.Volume -= 0.01; })); Thread.Sleep(50); } this.Dispatcher.Invoke(new Action(() => { this.mediaElement.Stop(); })); } catch (Exception) { } }); } } #endregion } catch (Exception ex) { App.logHandler.AppendFatal(ex); } finally { this.loadingGrid.Visibility = Visibility.Hidden; this.loadingRing.IsActive = false; } }
private LaunchResult Launch(LaunchSetting setting) { try { IsBusyLaunching = true; lock (launchLocker) { if (Java == null) { return(new LaunchResult(new NullJavaException())); } if (setting.AuthenticateResult == null) { return(new LaunchResult(new ArgumentException("启动所需必要的验证参数为空"))); } if (setting.Version == null) { return(new LaunchResult(new ArgumentException("启动所需必要的版本参数为空"))); } if (setting.MaxMemory == 0) { setting.MaxMemory = SystemTools.GetBestMemory(this.Java); } Stopwatch sw = new Stopwatch(); sw.Start(); if (setting.LaunchType == LaunchType.SAFE) { setting.AdvencedGameArguments = null; setting.AdvencedJvmArguments = null; setting.GCArgument = null; setting.JavaAgent = null; } string arg = argumentsParser.Parse(setting); if (setting.LaunchType == LaunchType.CREATE_SHORT) { File.WriteAllText(Environment.CurrentDirectory + "\\LaunchMinecraft.bat", string.Format("\"{0}\" {1}", Java.Path, arg)); return(new LaunchResult() { IsSuccess = true, LaunchArguments = arg }); } #region 处理库文件 foreach (var item in setting.Version.Natives) { string nativePath = GetNativePath(item); if (File.Exists(nativePath)) { AppendLaunchInfoLog(string.Format("检查并解压不存在的库文件:{0}", nativePath)); Unzip.UnZipNativeFile(nativePath, GetGameVersionRootDir(setting.Version) + @"\$natives", item.Exclude, setting.LaunchType != LaunchType.SAFE); } else { return(new LaunchResult(new NativeNotFoundException(item, nativePath))); } } #endregion AppendLaunchInfoLog(string.Format("开始启动游戏进程,使用JAVA路径:{0}", this.Java.Path)); ProcessStartInfo startInfo = new ProcessStartInfo(Java.Path, arg) { RedirectStandardError = true, RedirectStandardOutput = true, UseShellExecute = false, WorkingDirectory = GetGameVersionRootDir(setting.Version) }; var process = Process.Start(startInfo); sw.Stop(); long launchUsingMsTime = sw.ElapsedMilliseconds; AppendLaunchInfoLog(string.Format("成功启动游戏进程,总共用时:{0}ms", launchUsingMsTime)); Task.Factory.StartNew(() => { process.WaitForExit(); AppendLaunchInfoLog("游戏进程退出,代码:" + process.ExitCode); GameExit?.Invoke(this, new GameExitArg() { Process = process, Version = setting.Version, ExitCode = process.ExitCode, Duration = (process.StartTime - process.ExitTime) }); }); process.OutputDataReceived += Process_OutputDataReceived; process.ErrorDataReceived += Process_ErrorDataReceived; process.BeginErrorReadLine(); process.BeginOutputReadLine(); return(new LaunchResult() { Process = process, IsSuccess = true, LaunchArguments = arg, LaunchUsingMs = launchUsingMsTime }); } } catch (LaunchException.LaunchException ex) { return(new LaunchResult(ex)); } catch (Exception ex) { return(new LaunchResult(ex)); } finally { IsBusyLaunching = false; } }
private async Task LaunchGameFromWindow() { try { string userName = playerNameTextBox.Text; #region 检查有效数据 if (authTypeCombobox.SelectedItem == null) { await this.ShowMessageAsync(App.GetResourceString("String.Message.EmptyAuthType"), App.GetResourceString("String.Message.EmptyAuthType2")); return; } if (string.IsNullOrWhiteSpace(userName)) { await this.ShowMessageAsync(App.GetResourceString("String.Message.EmptyUsername"), App.GetResourceString("String.Message.EmptyUsername2")); return; } if (launchVersionCombobox.SelectedItem == null) { await this.ShowMessageAsync(App.GetResourceString("String.Message.EmptyLaunchVersion"), App.GetResourceString("String.Message.EmptyLaunchVersion2")); return; } if (App.handler.Java == null) { await this.ShowMessageAsync(App.GetResourceString("String.Message.NoJava"), App.GetResourceString("String.Message.NoJava2")); return; } #endregion NsisoLauncherCore.Modules.Version launchVersion = (NsisoLauncherCore.Modules.Version)launchVersionCombobox.SelectedItem; AuthTypeItem auth = (AuthTypeItem)authTypeCombobox.SelectedItem; #region 保存启动数据 App.config.MainConfig.History.LastLaunchVersion = launchVersion.ID; App.config.MainConfig.User.UserName = userName; #endregion LaunchSetting launchSetting = new LaunchSetting() { Version = (NsisoLauncherCore.Modules.Version)launchVersionCombobox.SelectedItem }; this.loadingGrid.Visibility = Visibility.Visible; this.loadingRing.IsActive = true; #region 验证 #region 设置ClientToken if (string.IsNullOrWhiteSpace(App.config.MainConfig.User.ClientToken)) { App.config.MainConfig.User.ClientToken = Guid.NewGuid().ToString("N"); } else { Requester.ClientToken = App.config.MainConfig.User.ClientToken; } #endregion #region 多语言支持变量(old) //string autoVerifyingMsg = null; //string autoVerifyingMsg2 = null; //string autoVerificationFailedMsg = null; //string autoVerificationFailedMsg2 = null; //string loginMsg = null; //string loginMsg2 = null; LoginDialogSettings loginDialogSettings = new LoginDialogSettings() { NegativeButtonText = App.GetResourceString("String.Base.Cancel"), AffirmativeButtonText = App.GetResourceString("String.Base.Login"), RememberCheckBoxText = App.GetResourceString("String.Base.ShouldRememberLogin"), UsernameWatermark = App.GetResourceString("String.Base.Username"), InitialUsername = userName, RememberCheckBoxVisibility = Visibility, EnablePasswordPreview = true, PasswordWatermark = App.GetResourceString("String.Base.Password"), NegativeButtonVisibility = Visibility.Visible }; //string verifyingMsg = null, verifyingMsg2 = null, verifyingFailedMsg = null, verifyingFailedMsg2 = null; #endregion //主验证器接口 IAuthenticator authenticator = null; bool shouldRemember = false; bool isSameAuthType = App.config.MainConfig.User.AuthenticationType == auth.Type; bool isRemember = (!string.IsNullOrWhiteSpace(App.config.MainConfig.User.AccessToken)) && (App.config.MainConfig.User.AuthenticationUUID != null); switch (auth.Type) { #region 离线验证 case Config.AuthenticationType.OFFLINE: authenticator = new OfflineAuthenticator(userName); break; #endregion #region Mojang验证 case Config.AuthenticationType.MOJANG: if (isSameAuthType && isRemember) { var mYggTokenAuthenticator = new YggdrasilTokenAuthenticator(App.config.MainConfig.User.AccessToken, App.config.MainConfig.User.AuthenticationUUID, App.config.MainConfig.User.AuthenticationUserData); mYggTokenAuthenticator.ProxyAuthServerAddress = "https://authserver.mojang.com"; authenticator = mYggTokenAuthenticator; } else { var mojangLoginDResult = await this.ShowLoginAsync(App.GetResourceString("String.Mainwindow.Auth.Mojang.Login"), App.GetResourceString("String.Mainwindow.Auth.Mojang.Login2"), loginDialogSettings); if (IsValidateLoginData(mojangLoginDResult)) { var mYggAuthenticator = new YggdrasilAuthenticator(new Credentials() { Username = mojangLoginDResult.Username, Password = mojangLoginDResult.Password }); mYggAuthenticator.ProxyAuthServerAddress = "https://authserver.mojang.com"; authenticator = mYggAuthenticator; shouldRemember = mojangLoginDResult.ShouldRemember; } else { await this.ShowMessageAsync("您输入的账号或密码为空", "请检查您是否正确填写登陆信息"); return; } } break; #endregion #region 统一通行证验证 case Config.AuthenticationType.NIDE8: if (App.nide8Handler == null) { await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.Auth.Nide8.NoID"), App.GetResourceString("String.Mainwindow.Auth.Nide8.NoID2")); return; } var nide8ChooseResult = await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.Auth.Nide8.Login2"), App.GetResourceString("String.Base.Choose"), MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, new MetroDialogSettings() { AffirmativeButtonText = App.GetResourceString("String.Base.Login"), NegativeButtonText = App.GetResourceString("String.Base.Cancel"), FirstAuxiliaryButtonText = App.GetResourceString("String.Base.Register"), DefaultButtonFocus = MessageDialogResult.Affirmative }); switch (nide8ChooseResult) { case MessageDialogResult.Canceled: return; case MessageDialogResult.Negative: return; case MessageDialogResult.FirstAuxiliary: System.Diagnostics.Process.Start(string.Format("https://login2.nide8.com:233/{0}/register", App.nide8Handler.ServerID)); return; case MessageDialogResult.SecondAuxiliary: if (isSameAuthType && isRemember) { var nYggTokenCator = new Nide8TokenAuthenticator(App.config.MainConfig.User.AccessToken, App.config.MainConfig.User.AuthenticationUUID, App.config.MainConfig.User.AuthenticationUserData); nYggTokenCator.ProxyAuthServerAddress = string.Format("{0}authserver", App.nide8Handler.BaseURL); authenticator = nYggTokenCator; } else { var nide8LoginDResult = await this.ShowLoginAsync(App.GetResourceString("String.Mainwindow.Auth.Nide8.Login"), App.GetResourceString("String.Mainwindow.Auth.Nide8.Login2"), loginDialogSettings); if (IsValidateLoginData(nide8LoginDResult)) { var nYggCator = new Nide8Authenticator(new Credentials() { Username = nide8LoginDResult.Username, Password = nide8LoginDResult.Password }); nYggCator.ProxyAuthServerAddress = string.Format("{0}authserver", App.nide8Handler.BaseURL); authenticator = nYggCator; shouldRemember = nide8LoginDResult.ShouldRemember; } else { await this.ShowMessageAsync("您输入的账号或密码为空", "请检查您是否正确填写登陆信息"); return; } } break; default: break; } break; #endregion #region 自定义验证 case Config.AuthenticationType.CUSTOM_SERVER: string customAuthServer = App.config.MainConfig.User.AuthServer; if (string.IsNullOrWhiteSpace(customAuthServer)) { await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.Auth.Custom.NoAdrress"), App.GetResourceString("String.Mainwindow.Auth.Custom.NoAdrress2")); return; } else { if (shouldRemember && isSameAuthType) { var cYggTokenCator = new YggdrasilTokenAuthenticator(App.config.MainConfig.User.AccessToken, App.config.MainConfig.User.AuthenticationUUID, App.config.MainConfig.User.AuthenticationUserData); cYggTokenCator.ProxyAuthServerAddress = customAuthServer; } else { var customLoginDResult = await this.ShowLoginAsync(App.GetResourceString("String.Mainwindow.Auth.Custom.Login"), App.GetResourceString("String.Mainwindow.Auth.Custom.Login2"), loginDialogSettings); if (IsValidateLoginData(customLoginDResult)) { var cYggAuthenticator = new YggdrasilAuthenticator(new Credentials() { Username = customLoginDResult.Username, Password = customLoginDResult.Password }); cYggAuthenticator.ProxyAuthServerAddress = customAuthServer; authenticator = cYggAuthenticator; shouldRemember = customLoginDResult.ShouldRemember; } else { await this.ShowMessageAsync("您输入的账号或密码为空", "请检查您是否正确填写登陆信息"); return; } } } break; #endregion default: authenticator = new OfflineAuthenticator(userName); break; } #region Old //if (auth.Type != Config.AuthenticationType.OFFLINE) //{ // try // { // #region 如果记住登陆(有登陆记录) // if ((!string.IsNullOrWhiteSpace(App.config.MainConfig.User.AccessToken)) && (App.config.MainConfig.User.AuthenticationUUID != null)) // { // authenticator = new YggdrasilTokenAuthenticator(App.config.MainConfig.User.AccessToken, // App.config.MainConfig.User.AuthenticationUUID, // App.config.MainConfig.User.AuthenticationUserData); // //var loader = await this.ShowProgressAsync(autoVerifyingMsg, autoVerifyingMsg2); // //loader.SetIndeterminate(); // //Validate validate = new Validate(App.config.MainConfig.User.AccessToken); // //var validateResult = await validate.PerformRequestAsync(); // //if (validateResult.IsSuccess) // //{ // // launchSetting.AuthenticateAccessToken = App.config.MainConfig.User.AccessToken; // // launchSetting.AuthenticateUUID = App.config.MainConfig.User.AuthenticationUUID; // // await loader.CloseAsync(); // //} // //else // //{ // // Refresh refresher = new Refresh(App.config.MainConfig.User.AccessToken); // // var refreshResult = await refresher.PerformRequestAsync(); // // await loader.CloseAsync(); // // if (refreshResult.IsSuccess) // // { // // App.config.MainConfig.User.AccessToken = refreshResult.AccessToken; // // launchSetting.AuthenticateUUID = App.config.MainConfig.User.AuthenticationUUID; // // launchSetting.AuthenticateAccessToken = refreshResult.AccessToken; // // } // // else // // { // // App.config.MainConfig.User.AccessToken = string.Empty; // // App.config.Save(); // // await this.ShowMessageAsync(autoVerificationFailedMsg, autoVerificationFailedMsg2); // // return; // // } // //} // } // #endregion // #region 从零登陆 // else // { // var loginMsgResult = await this.ShowLoginAsync(loginMsg, loginMsg2, loginDialogSettings); // if (loginMsgResult == null) // { // return; // } // var loader = await this.ShowProgressAsync(verifyingMsg, verifyingMsg2); // loader.SetIndeterminate(); // userName = loginMsgResult.Username; // Authenticate authenticate = new Authenticate(new Credentials() { Username = loginMsgResult.Username, Password = loginMsgResult.Password }); // var aloginResult = await authenticate.PerformRequestAsync(); // await loader.CloseAsync(); // if (aloginResult.IsSuccess) // { // if (loginMsgResult.ShouldRemember) // { // App.config.MainConfig.User.AccessToken = aloginResult.AccessToken; // } // App.config.MainConfig.User.AuthenticationUserData = aloginResult.User; // App.config.MainConfig.User.AuthenticationUUID = aloginResult.SelectedProfile; // launchSetting.AuthenticateAccessToken = aloginResult.AccessToken; // launchSetting.AuthenticateUUID = aloginResult.SelectedProfile; // launchSetting.AuthenticationUserData = aloginResult.User; // } // else // { // await this.ShowMessageAsync(verifyingFailedMsg, verifyingFailedMsg2 + aloginResult.Error.ErrorMessage); // return; // } // } // #endregion // } // catch (Exception ex) // { // await this.ShowMessageAsync(verifyingFailedMsg, verifyingFailedMsg2 + ex.Message); // return; // } //} #endregion if (auth.Type != Config.AuthenticationType.OFFLINE) { string currentLoginType = string.Format("正在进行{0}中...", auth.Name); string loginMsg = "这需要联网进行操作,可能需要一分钟的时间"; var loader = await this.ShowProgressAsync(currentLoginType, loginMsg); loader.SetIndeterminate(); var authResult = await authenticator.DoAuthenticateAsync(); await loader.CloseAsync(); switch (authResult.State) { case AuthState.SUCCESS: if (shouldRemember) { App.config.MainConfig.User.AccessToken = authResult.AccessToken; App.config.MainConfig.User.AuthenticationUUID = authResult.UUID; App.config.MainConfig.User.AuthenticationUserData = authResult.UserData; } launchSetting.AuthenticateResult = authResult; break; case AuthState.REQ_LOGIN: await this.ShowMessageAsync("验证失败:您的登陆信息已过期", string.Format("请您重新进行登陆。具体信息:{0}", authResult.Error.ErrorMessage)); return; case AuthState.ERR_INVALID_CRDL: await this.ShowMessageAsync("验证失败:您的登陆账号或密码错误", string.Format("请您确认您输入的账号密码正确。具体信息:{0}", authResult.Error.ErrorMessage)); return; case AuthState.ERR_NOTFOUND: await this.ShowMessageAsync("验证失败:您的账号未找到", string.Format("请确认您的账号和游戏角色存在。具体信息:{0}", authResult.Error.ErrorMessage)); return; case AuthState.ERR_OTHER: await this.ShowMessageAsync("验证失败:其他错误", string.Format("具体信息:{0}", authResult.Error.ErrorMessage)); return; case AuthState.ERR_INSIDE: await this.ShowMessageAsync("验证失败:启动器内部错误", string.Format("建议您联系启动器开发者进行解决。具体信息:{0}", authResult.Error.ErrorMessage)); return; default: await this.ShowMessageAsync("验证失败:未知错误", "建议您联系启动器开发者进行解决。"); return; } } else { launchSetting.AuthenticateResult = await authenticator.DoAuthenticateAsync(); } App.config.MainConfig.User.AuthenticationType = auth.Type; #endregion #region 检查游戏完整 List <DownloadTask> losts = new List <DownloadTask>(); App.logHandler.AppendInfo("检查丢失的依赖库文件中..."); var lostDepend = await FileHelper.GetLostDependDownloadTaskAsync( App.config.MainConfig.Download.DownloadSource, App.handler, launchSetting.Version); if (auth.Type == Config.AuthenticationType.NIDE8) { string nideJarPath = App.handler.GetNide8JarPath(); if (!File.Exists(nideJarPath)) { lostDepend.Add(new DownloadTask("统一通行证核心", "https://login2.nide8.com:233/index/jar", nideJarPath)); } } if (App.config.MainConfig.Environment.DownloadLostDepend && lostDepend.Count != 0) { MessageDialogResult downDependResult = await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.NeedDownloadDepend"), App.GetResourceString("String.Mainwindow.NeedDownloadDepend2"), MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, new MetroDialogSettings() { AffirmativeButtonText = App.GetResourceString("String.Base.Download"), NegativeButtonText = App.GetResourceString("String.Base.Cancel"), FirstAuxiliaryButtonText = App.GetResourceString("String.Base.Unremember"), DefaultButtonFocus = MessageDialogResult.Affirmative }); switch (downDependResult) { case MessageDialogResult.Affirmative: losts.AddRange(lostDepend); break; case MessageDialogResult.FirstAuxiliary: App.config.MainConfig.Environment.DownloadLostDepend = false; break; default: break; } } App.logHandler.AppendInfo("检查丢失的资源文件中..."); if (App.config.MainConfig.Environment.DownloadLostAssets && (await FileHelper.IsLostAssetsAsync(App.config.MainConfig.Download.DownloadSource, App.handler, launchSetting.Version))) { MessageDialogResult downDependResult = await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.NeedDownloadAssets"), App.GetResourceString("String.Mainwindow.NeedDownloadAssets2"), MessageDialogStyle.AffirmativeAndNegativeAndSingleAuxiliary, new MetroDialogSettings() { AffirmativeButtonText = App.GetResourceString("String.Base.Download"), NegativeButtonText = App.GetResourceString("String.Base.Cancel"), FirstAuxiliaryButtonText = App.GetResourceString("String.Base.Unremember"), DefaultButtonFocus = MessageDialogResult.Affirmative }); switch (downDependResult) { case MessageDialogResult.Affirmative: var lostAssets = await FileHelper.GetLostAssetsDownloadTaskAsync( App.config.MainConfig.Download.DownloadSource, App.handler, launchSetting.Version); losts.AddRange(lostAssets); break; case MessageDialogResult.FirstAuxiliary: App.config.MainConfig.Environment.DownloadLostAssets = false; break; default: break; } } if (losts.Count != 0) { App.downloader.SetDownloadTasks(losts); App.downloader.StartDownload(); await new Windows.DownloadWindow().ShowWhenDownloading(); } #endregion #region 根据配置文件设置 launchSetting.AdvencedGameArguments += App.config.MainConfig.Environment.AdvencedGameArguments; launchSetting.AdvencedJvmArguments += App.config.MainConfig.Environment.AdvencedJvmArguments; launchSetting.GCArgument += App.config.MainConfig.Environment.GCArgument; launchSetting.GCEnabled = App.config.MainConfig.Environment.GCEnabled; launchSetting.GCType = App.config.MainConfig.Environment.GCType; launchSetting.JavaAgent += App.config.MainConfig.Environment.JavaAgent; if (auth.Type == Config.AuthenticationType.NIDE8) { launchSetting.JavaAgent += string.Format(" \"{0}\"={1}", App.handler.GetNide8JarPath(), App.config.MainConfig.User.Nide8ServerID); } //直连服务器设置 if ((auth.Type == Config.AuthenticationType.NIDE8) && App.config.MainConfig.User.AllUsingNide8) { var nide8ReturnResult = await App.nide8Handler.GetInfoAsync(); if (App.config.MainConfig.User.AllUsingNide8 && !string.IsNullOrWhiteSpace(nide8ReturnResult.Meta.ServerIP)) { Server server = new Server(); string[] serverIp = nide8ReturnResult.Meta.ServerIP.Split(':'); if (serverIp.Length == 2) { server.Address = serverIp[0]; server.Port = ushort.Parse(serverIp[1]); } else { server.Address = nide8ReturnResult.Meta.ServerIP; server.Port = 25565; } launchSetting.LaunchToServer = server; } } else if (App.config.MainConfig.Server.LaunchToServer) { launchSetting.LaunchToServer = new Server() { Address = App.config.MainConfig.Server.Address, Port = App.config.MainConfig.Server.Port }; } //自动内存设置 if (App.config.MainConfig.Environment.AutoMemory) { var m = SystemTools.GetBestMemory(App.handler.Java); App.config.MainConfig.Environment.MaxMemory = m; launchSetting.MaxMemory = m; } else { launchSetting.MaxMemory = App.config.MainConfig.Environment.MaxMemory; } launchSetting.VersionType = App.config.MainConfig.Customize.VersionInfo; launchSetting.WindowSize = App.config.MainConfig.Environment.WindowSize; #endregion #region 配置文件处理 App.config.Save(); #endregion #region 启动 App.logHandler.OnLog += (a, b) => { this.Invoke(() => { launchInfoBlock.Text = b.Message; }); }; var result = await App.handler.LaunchAsync(launchSetting); App.logHandler.OnLog -= (a, b) => { this.Invoke(() => { launchInfoBlock.Text = b.Message; }); }; //程序猿是找不到女朋友的了 :) if (!result.IsSuccess) { await this.ShowMessageAsync(App.GetResourceString("String.Mainwindow.LaunchError") + result.LaunchException.Title, result.LaunchException.Message); App.logHandler.AppendError(result.LaunchException); } else { try { await Task.Factory.StartNew(() => { result.Process.WaitForInputIdle(); }); } catch (Exception ex) { await this.ShowMessageAsync("启动后等待游戏窗口响应异常", "这可能是由于游戏进程发生意外(闪退)导致的。具体原因:" + ex.Message); return; } if (App.config.MainConfig.Environment.ExitAfterLaunch) { Application.Current.Shutdown(); } this.WindowState = WindowState.Minimized; Refresh(); //自定义处理 if (!string.IsNullOrWhiteSpace(App.config.MainConfig.Customize.GameWindowTitle)) { GameHelper.SetGameTitle(result, App.config.MainConfig.Customize.GameWindowTitle); } if (App.config.MainConfig.Customize.CustomBackGroundMusic) { mediaElement.Volume = 0.5; await Task.Factory.StartNew(() => { try { for (int i = 0; i < 50; i++) { this.Dispatcher.Invoke(new Action(() => { this.mediaElement.Volume -= 0.01; })); Thread.Sleep(50); } this.Dispatcher.Invoke(new Action(() => { this.mediaElement.Stop(); })); } catch (Exception) { } }); } } #endregion } catch (Exception ex) { App.logHandler.AppendFatal(ex); } finally { this.loadingGrid.Visibility = Visibility.Hidden; this.loadingRing.IsActive = false; } }
private LaunchResult Launch(LaunchSetting setting) { try { if (setting.AuthenticateAccessToken == null || setting.AuthenticateUUID == null) { return(new LaunchResult(new ArgumentException("启动所需必要的验证参数为空"))); } if (setting.Version == null) { return(new LaunchResult(new ArgumentException("启动所需必要的版本参数为空"))); } if (setting.MaxMemory == 0) { setting.MaxMemory = SystemTools.GetBestMemory(this.Java); } Stopwatch sw = new Stopwatch(); sw.Start(); string arg = argumentsParser.Parse(setting); #region 处理库文件 foreach (var item in setting.Version.Natives) { string nativePath = GetNativePath(item); if (File.Exists(nativePath)) { App.logHandler.AppendDebug(string.Format("检查并解压不存在的库文件:{0}", nativePath)); Unzip.UnZipFile(nativePath, GetGameVersionRootDir(setting.Version) + @"\$natives", item.Exclude); } else { return(new LaunchResult(new NativeNotFoundException(item, nativePath))); } } #endregion ProcessStartInfo startInfo = new ProcessStartInfo(Java.Path, arg) { RedirectStandardError = true, RedirectStandardOutput = true, UseShellExecute = false, WorkingDirectory = GetGameVersionRootDir(setting.Version) }; var process = Process.Start(startInfo); sw.Stop(); App.logHandler.AppendInfo(string.Format("成功启动游戏进程,总共用时:{0}ms", sw.ElapsedMilliseconds)); Task.Factory.StartNew(() => { process.WaitForExit(); App.logHandler.AppendInfo("游戏进程退出,代码:" + process.ExitCode); GameExit?.Invoke(this, process.ExitCode); }); process.OutputDataReceived += Process_OutputDataReceived; process.ErrorDataReceived += Process_ErrorDataReceived; process.BeginErrorReadLine(); process.BeginOutputReadLine(); #region 配置文件 App.config.MainConfig.History.LastLaunchUsingMs = sw.ElapsedMilliseconds; App.config.MainConfig.History.LastLaunchTime = DateTime.Now; App.config.MainConfig.History.LastLaunchVersion = setting.Version.ID; App.config.Save(); #endregion return(new LaunchResult() { Process = process, IsSuccess = true, LaunchArguments = arg }); } catch (LaunchException.LaunchException ex) { return(new LaunchResult(ex)); } catch (Exception ex) { return(new LaunchResult(ex)); } }