Пример #1
0
		public static MemoryDomainProxy[] GetInterfaces()
		{
			try
			{
				Console.WriteLine($" getInterfaces()");

				List<MemoryDomainProxy> interfaces = new List<MemoryDomainProxy>();

				if (Global.Emulator?.ServiceProvider == null || Global.Emulator is NullEmulator)
					return new MemoryDomainProxy[] { };

				ServiceInjector.UpdateServices(Global.Emulator.ServiceProvider, MDRI);

				foreach (MemoryDomain _domain in MDRI.MemoryDomains)
					if(!_domain.Name.Contains("Waterbox")) //Waterbox domains are banned
						interfaces.Add(new MemoryDomainProxy(new VanguardImplementation.BizhawkMemoryDomain(_domain)));


				return interfaces.ToArray();
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();

				return new MemoryDomainProxy[] { };
			}

		}
Пример #2
0
		public static string BIZHAWK_GET_SYSTEMCORENAME(string systemName)
		{
			try
			{
				switch (systemName.ToUpper())
				{
					case "GAMEBOY":

						if (Global.CoreConfig.GB_UseGBHawk)
							return "gbhawk";
						else
							return "gambatte";

					case "GBC":
						if (Global.CoreConfig.GB_UseGBHawk)
							return "gbhawk";
						else
							return "gambatte";

					case "NES":
						return (Global.CoreConfig.NES_InQuickNES ? "quicknes" : "neshawk");

					case "SNES":

						if (MemoryDomains.MemoryInterfaces.ContainsKey("SGB WRAM"))
							return "bsnes_SGB";

						return (Global.CoreConfig.SNES_InSnes9x ? "snes9x" : "bsnes");

					case "GBA":
						return "mgba";

					case "N64":

						N64SyncSettings ss = Global.Config.GetCoreSyncSettings<N64, N64SyncSettings>()
											 ?? new N64SyncSettings();

						return $"{ss.VideoPlugin}/{ss.Rsp}/{ss.Core}/{(ss.DisableExpansionSlot ? "NoExp" : "Exp")}";
					default:
						break;
				}

				return systemName;
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex) == DialogResult.Abort)
					throw new AbortEverythingException();

				return null;
			}
		}
Пример #3
0
		public static Bitmap BIZHAWK_GET_SCREENSHOT()
		{
			try
			{
				return GlobalWin.MainForm.MakeScreenshotImage().ToSysdrawingBitmap();
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();

				return null;
			}
		}
Пример #4
0
		public static void BIZHAWK_OPEN_HEXEDITOR()
		{
			try
			{
				GlobalWin.Tools.Load<HexEditor>();
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();

				return;
			}
		}
Пример #5
0
		public static void MAINFORM_RESIZEEND()
		{
			try
			{
				if (disableRTC) return;

				VanguardCore.SaveBizhawkWindowState();
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();
			}
		}
Пример #6
0
		public static void MAINFORM_FORM_LOAD_END()
		{
			try
			{
				if (disableRTC) return;

				VanguardCore.Start();
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();
			}
		}
Пример #7
0
		public static bool BIZHAWK_ISMAINFORMVISIBLE()
		{
			try
			{
				return GlobalWin.MainForm.Visible;
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();

				return false;
			}
		}
Пример #8
0
		public static void BIZHAWK_LOADROM(string RomFile)
		{
			try
			{
				var lra = new BizHawk.Client.Common.LoadRomArgs { OpenAdvanced = new OpenAdvanced_OpenRom { Path = RomFile } };
				GlobalWin.MainForm.LoadRom(RomFile, lra);
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();

				return;
			}
		}
Пример #9
0
		public static bool BIZHAWK_ISNULLEMULATORCORE()
		{
			try
			{
				//This checks if the currently loaded emulator core is the Null emulator

				return Global.Emulator is NullEmulator;
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex) == DialogResult.Abort)
					throw new AbortEverythingException();

				return false;
			}
		}
Пример #10
0
		public static string BIZHAWK_GET_CURRENTLYOPENEDROM()
		{
			try
			{
				//This returns the filename of the currently opened rom

				return GlobalWin.MainForm.CurrentlyOpenRom;
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();

				return null;
			}
		}
Пример #11
0
		public static string BIZHAWK_GET_CURRENTLYLOADEDSYSTEMNAME()
		{
			try
			{
				//returns the currently loaded core's name

				return Global.Game.System;
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();

				return null;
			}
		}
Пример #12
0
		public static void LOAD_GAME_BEGIN()
		{
			try
			{
				if (disableRTC) return;

				isNormalAdvance = false;

				StepActions.ClearStepBlastUnits();
				RtcClock.ResetCount();
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex) == DialogResult.Abort)
					throw new AbortEverythingException();
			}
		}
Пример #13
0
		public static void CREATE_VMD_FROM_SELECTED_HEXEDITOR(string domain, List<long> allAddresses, int wordSize)
		{
			int allAddrCount = allAddresses.Count;
			if (wordSize > 1) //fills the gap caused by address spacing
				for (int addrPos = 0; addrPos < allAddrCount; addrPos++)
					for (int addedCount = 1; addedCount < wordSize; addedCount++)
					{
						long newAddr = allAddresses[addrPos] + addedCount;
						allAddresses.Add(newAddr);
					}

			var ordered = allAddresses.OrderBy(it => it).ToArray();
			bool contiguous = true;
			long? lastAddress = null;
			int i = 0;

			foreach (long item in ordered)
			{
				if (lastAddress != null) //not the first one
					if (i != (ordered.Length - 1)) //not the last one
						if (item != lastAddress.Value + 1) //checks expected address
							contiguous = false;

				lastAddress = item;
				i++;
			}

			string ToHexString(long n)
			{
				return $"{n:X}";
			}

			string text;
			if (contiguous)
			{
				text = $"{ToHexString(ordered[0])}-{ToHexString(ordered[ordered.Length - 1])}";
			}
			else
			{
				text = String.Join("\n", ordered.Select(it => ToHexString(it)));
			}

			VanguardCore.CreateVmdText(domain, text);

		}
Пример #14
0
		public static void BIZHAWK_OPEN_HEXEDITOR_ADDRESS(MemoryDomainProxy mdp, long address)
		{
			try
			{
				if (mdp?.MD == null)
					return;
				GlobalWin.Tools.Load<HexEditor>();
				GlobalWin.Tools.HexEditor.SetMemoryDomain(((VanguardImplementation.BizhawkMemoryDomain)(mdp.MD)).MD.ToString());
				GlobalWin.Tools.HexEditor.GoToAddress(address);
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();

				return;
			}
		}
Пример #15
0
		public static void CPU_STEP(bool isRewinding, bool isFastForwarding, bool isBeforeStep = false)
		{
			try
			{
				if (disableRTC || Global.Emulator is NullEmulator)
					return;

				bool runBefore = (bool)(AllSpec.CorruptCoreSpec?[RTCSPEC.STEP_RUNBEFORE.ToString()] ?? false);

				//Return out if it's being called from before the step and we're not on frame 0. If we're on frame 0, then we go as normal
				//If we can't get runbefore, just assume we don't want to run before
				if (isBeforeStep && runBefore == false)
					return;
				if (runBefore)
				{
					AllSpec.CorruptCoreSpec.Update(RTCSPEC.STEP_RUNBEFORE.ToString(), false);
				}

				isNormalAdvance = !(isRewinding || isFastForwarding);

				bool isForward = (!isRewinding && !isFastForwarding);

				// Unique step hooks
				if (isForward)
					STEP_FORWARD();
				else if (isRewinding)
					STEP_REWIND();
				else if (isFastForwarding)
					STEP_FASTFORWARD();

				//Any step hook for corruption
				STEP_CORRUPT(isRewinding, isFastForwarding);
				VanguardCore.RTE_API.ON_STEP(isForward, isRewinding, isFastForwarding);
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();
				MessageBox.Show("Clearing all step blastunits due to an exception within Core_Step().");
				LocalNetCoreRouter.Route(Endpoints.UI, Basic.ErrorDisableAutoCorrupt, false);
				StepActions.ClearStepBlastUnits();
			}
		}
Пример #16
0
		public static string BIZHAWK_GET_FILESYSTEMGAMENAME()
		{
			try
			{
				//This returns the filename of the currently loaded game before extension

				PathEntry pathEntry = Global.Config.PathEntries[Global.Game.System, "Savestates"] ??
				Global.Config.PathEntries[Global.Game.System, "Base"];

				return PathManager.FilesystemSafeName(Global.Game);
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();

				return null;
			}
		}
Пример #17
0
		public static void BIZHAWK_SET_SYSTEMCORE(string systemName, string systemCore)
		{
			try
			{
				switch (systemName.ToUpper())
				{
					case "GAMEBOY":
						Global.CoreConfig.SGB_UseBsnes = false;
						Global.CoreConfig.GB_UseGBHawk = systemCore == "gbhawk";

						break;

					case "NES":
						Global.CoreConfig.NES_InQuickNES = systemCore == "quicknes";
						break;

					case "SNES":

						if (systemCore == "bsnes_SGB")
						{
							Global.CoreConfig.SGB_UseBsnes = true;
						}
						else
							Global.CoreConfig.SNES_InSnes9x = systemCore == "snes9x";

						break;

					case "GBA":
						break;

				}
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();

				return;
			}
		}
Пример #18
0
        public static void StartClient()
        {
            try
            {
                ConsoleEx.WriteLine("Starting Vanguard Client");
                Thread.Sleep(500);                 //When starting in Multiple Startup Project, the first try will be uncessful since
                //the server takes a bit more time to start then the client.

                var spec = new NetCoreReceiver();
                spec.Attached         = VanguardCore.attached;
                spec.MessageReceived += OnMessageReceived;

                connector = new RTCV.Vanguard.VanguardConnector(spec);
            }
            catch (Exception ex)
            {
                if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
                {
                    throw new RTCV.NetCore.AbortEverythingException();
                }
            }
        }
Пример #19
0
		public static bool RefreshDomains(bool updateSpecs = true)
		{
			try
			{
				//Compare the old to the new. If the name and sizes are all the same, don't push that there were changes.
				//We need to compare like this because the domains can change from syncsettings.
				//We only check name and size as those are the only things that can change on the fly
				var oldInterfaces = VanguardCore.MemoryInterfacees;
				var newInterfaces = GetInterfaces();
				bool domainsChanged = oldInterfaces.Length != newInterfaces.Length;

				//Bruteforce it since domains can change inconsistently
				for (int i = 0; i < oldInterfaces.Length; i++)
				{
					if (domainsChanged)
						break;
					if (oldInterfaces[i].Name != newInterfaces[i].Name)
						domainsChanged = true;
					if (oldInterfaces[i].Size != newInterfaces[i].Size)
						domainsChanged = true;
				}

				//We gotta push this no matter what since it's new underlying objects
				if (updateSpecs)
				{
					AllSpec.VanguardSpec.Update(VSPEC.MEMORYDOMAINS_INTERFACES, newInterfaces);
					LocalNetCoreRouter.Route(Endpoints.CorruptCore, Remote.EventDomainsUpdated, domainsChanged, true);
				}
				return domainsChanged;
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex) == DialogResult.Abort)
					throw new AbortEverythingException();

				return false;
			}
		}
Пример #20
0
		public static void MAIN_BIZHAWK(string[] args)
		{
			//MessageBox.Show("ATTACH DEBUGGER NOW");

			if (!System.Environment.Is64BitOperatingSystem)
			{
				MessageBox.Show("32-bit operating system detected. Bizhawk requires 64-bit to run. Program will shut down");
				Application.Exit();
			}

			try
			{
				VanguardCore.args = args;

				disableRTC = VanguardCore.args.Contains("-DISABLERTC");

				//VanguardCore.attached = true;
				VanguardCore.attached = VanguardCore.args.Contains("-ATTACHED");

				//BizHawk.Client.EmuHawk.LogConsole.ReleaseConsole();
				RTCV.Common.Logging.StartLogging(VanguardCore.logPath);
				if (args.Contains("-CONSOLE"))
				{
					Common.ConsoleHelper.ShowConsole();
				}
				else
				{
					Common.ConsoleHelper.HideConsole();
				}
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex, true) == DialogResult.Abort)
					throw new AbortEverythingException();
			}
		}
Пример #21
0
		public static void CLOSE_GAME(bool loadDefault = false)
		{
			try
			{
				if (disableRTC) return;

				if (CLOSE_GAME_loop_flag)
					return;

				CLOSE_GAME_loop_flag = true;

				//RTC_Core.AutoCorrupt = false;

				StepActions.ClearStepBlastUnits();

				MemoryDomains.Clear();

				VanguardCore.OpenRomFilename = null;

				if (loadDefault)
					VanguardCore.LoadDefaultRom();

				//RTC_RPC.SendToKillSwitch("UNFREEZE");

				CLOSE_GAME_loop_flag = false;

				RtcCore.InvokeGameClosed();
				VanguardCore.RTE_API.GAME_CLOSED();

			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex) == DialogResult.Abort)
					throw new AbortEverythingException();
			}
		}
Пример #22
0
		public static void LOAD_GAME_DONE()
		{
			try
			{
				if (disableRTC) return;

				if (AllSpec.UISpec == null)
				{
					CLOSE_GAME();
					GlobalWin.MainForm.CloseRom();
					MessageBox.Show("It appears you haven't connected to StandaloneRTC. Please make sure that the RTC is running and not just Bizhawk.\nIf you have an antivirus, it might be blocking the RTC from launching.\n\nIf you keep getting this message, poke the RTC devs for help (Discord is in the launcher).", "RTC Not Connected");
					return;
				}

				//Glitch Harvester warning for archives

				string uppercaseFilename = GlobalWin.MainForm.CurrentlyOpenRom.ToUpper();
				if (uppercaseFilename.Contains(".ZIP") || uppercaseFilename.Contains(".7Z"))
				{
					MessageBox.Show($"The selected file {Path.GetFileName(uppercaseFilename.Split('|')[0])} is an archive.\nThe RTC does not support archived rom files. Please extract the file then try again.");
					CLOSE_GAME(true);
					return;
				}

				//Load Game vars into RTC_Core
				PathEntry pathEntry = Global.Config.PathEntries[Global.Game.System, "Savestates"] ??
				Global.Config.PathEntries[Global.Game.System, "Base"];



				//prepare memory domains in advance on bizhawk side
				bool domainsChanged = RefreshDomains(false);

				PartialSpec gameDone = new PartialSpec("VanguardSpec");
				gameDone[VSPEC.SYSTEM] = BIZHAWK_GET_CURRENTLYLOADEDSYSTEMNAME().ToUpper();
				gameDone[VSPEC.GAMENAME] = BIZHAWK_GET_FILESYSTEMGAMENAME();
				gameDone[VSPEC.SYSTEMPREFIX] = BIZHAWK_GET_SAVESTATEPREFIX();
				gameDone[VSPEC.SYSTEMCORE] = BIZHAWK_GET_SYSTEMCORENAME(Global.Game.System);
				gameDone[VSPEC.SYNCSETTINGS] = BIZHAWK_GETSET_SYNCSETTINGS;
				gameDone[VSPEC.OPENROMFILENAME] = GlobalWin.MainForm.CurrentlyOpenRom;
				gameDone[VSPEC.MEMORYDOMAINS_BLACKLISTEDDOMAINS] = VanguardCore.GetBlacklistedDomains(BIZHAWK_GET_CURRENTLYLOADEDSYSTEMNAME().ToUpper());
				gameDone[VSPEC.MEMORYDOMAINS_INTERFACES] = GetInterfaces();
				gameDone[VSPEC.CORE_DISKBASED] = isCurrentCoreDiskBased();
				AllSpec.VanguardSpec.Update(gameDone);

				//This is local. If the domains changed it propgates over netcore
				LocalNetCoreRouter.Route(Endpoints.CorruptCore, Remote.EventDomainsUpdated, domainsChanged, true);

				if (VanguardCore.GameName != lastGameName)
				{
					LocalNetCoreRouter.Route(Endpoints.UI, Basic.ResetGameProtectionIfRunning, true);
				}
				lastGameName = VanguardCore.GameName;

				RtcCore.InvokeLoadGameDone();
				VanguardCore.RTE_API.LOAD_GAME();
			}
			catch (Exception ex)
			{
				if (VanguardCore.ShowErrorDialog(ex) == DialogResult.Abort)
					throw new AbortEverythingException();
			}
		}
Пример #23
0
        private static void OnMessageReceived(object sender, NetCoreEventArgs e)
        {
            try
            {
                // This is where you implement interaction.
                // Warning: Any error thrown in here will be caught by NetCore and handled by being displayed in the console.

                var message         = e.message;
                var simpleMessage   = message as NetCoreSimpleMessage;
                var advancedMessage = message as NetCoreAdvancedMessage;

                ConsoleEx.WriteLine(message.Type);
                switch (message.Type)                 //Handle received messages here
                {
                case RTCV.NetCore.Commands.Remote.AllSpecSent:
                {
                    if (VanguardCore.FirstConnect)
                    {
                        SyncObjectSingleton.FormExecute(() =>
                            {
                                VanguardCore.LoadDefaultAndShowBizhawkForm();
                            });
                        VanguardCore.FirstConnect = false;
                    }
                }
                break;

                case RTCV.NetCore.Commands.Basic.SaveSavestate:
                    SyncObjectSingleton.FormExecute(() =>
                    {
                        e.setReturnValue(VanguardCore.SaveSavestate_NET(advancedMessage.objectValue as string));
                    });
                    break;

                case RTCV.NetCore.Commands.Basic.LoadSavestate:
                {
                    var cmd      = advancedMessage.objectValue as object[];
                    var path     = cmd[0] as string;
                    var location = (StashKeySavestateLocation)cmd[1];
                    SyncObjectSingleton.FormExecute(() =>
                        {
                            e.setReturnValue(VanguardCore.LoadSavestate_NET(path, location));
                        });
                    break;
                }

                case RTCV.NetCore.Commands.Remote.LoadROM:
                {
                    var fileName = advancedMessage.objectValue as String;
                    SyncObjectSingleton.FormExecute(() =>
                        {
                            VanguardCore.LoadRom_NET(fileName);
                        });
                }
                break;

                case RTCV.NetCore.Commands.Remote.CloseGame:
                {
                    SyncObjectSingleton.FormExecute(() =>
                        {
                            Hooks.CLOSE_GAME(true);
                        });
                }
                break;

                case RTCV.NetCore.Commands.Remote.DomainGetDomains:
                    SyncObjectSingleton.FormExecute(() =>
                    {
                        e.setReturnValue(Hooks.GetInterfaces());
                    });
                    break;

                case RTCV.NetCore.Commands.Remote.KeySetSyncSettings:
                    SyncObjectSingleton.FormExecute(() =>
                    {
                        Hooks.BIZHAWK_GETSET_SYNCSETTINGS = (string)advancedMessage.objectValue;
                    });
                    break;

                case RTCV.NetCore.Commands.Remote.KeySetSystemCore:
                {
                    var cmd        = advancedMessage.objectValue as object[];
                    var systemName = (string)cmd[0];
                    var systemCore = (string)cmd[1];
                    SyncObjectSingleton.FormExecute(() =>
                        {
                            Hooks.BIZHAWK_SET_SYSTEMCORE(systemName, systemCore);
                        });
                }
                break;

                case RTCV.NetCore.Commands.Remote.OpenHexEditor:
                    SyncObjectSingleton.FormExecute(() => Hooks.BIZHAWK_OPEN_HEXEDITOR());
                    break;

                case RTCV.NetCore.Commands.Emulator.GetRealtimeAPI:
                    e.setReturnValue(VanguardCore.RTE_API);
                    break;

                case RTCV.NetCore.Commands.Emulator.GetScreenshot:
                    e.setReturnValue(Hooks.BIZHAWK_GET_SCREENSHOT());
                    break;

                case RTCV.NetCore.Commands.Emulator.OpenHexEditorAddress:
                {
                    var    temp    = advancedMessage.objectValue as object[];
                    string domain  = (string)temp[0];
                    long   address = (long)temp[1];

                    MemoryDomainProxy mdp = MemoryDomains.GetProxy(domain, address);
                    long realAddress      = MemoryDomains.GetRealAddress(domain, address);

                    SyncObjectSingleton.FormExecute(() =>
                        {
                            Hooks.BIZHAWK_OPEN_HEXEDITOR_ADDRESS(mdp, realAddress);
                        });

                    break;
                }

                case RTCV.NetCore.Commands.Remote.EventEmuMainFormClose:
                    SyncObjectSingleton.FormExecute(() =>
                    {
                        Hooks.BIZHAWK_MAINFORM_CLOSE();
                    });
                    break;

                case RTCV.NetCore.Commands.Remote.RenderStart:
                    SyncObjectSingleton.FormExecute(() =>
                    {
                        BizhawkRender.StartRender_NET();
                    });
                    break;

                case RTCV.NetCore.Commands.Remote.RenderStop:
                    SyncObjectSingleton.FormExecute(() =>
                    {
                        BizhawkRender.StopRender_NET();
                    });
                    break;

                case RTCV.NetCore.Commands.Remote.EventEmuStarted:
                    //if (RTC_StockpileManager.BackupedState == null)
                    //S.GET<RTC_Core_Form>().AutoCorrupt = false;


                    //Todo
                    //RTC_NetcoreImplementation.SendCommandToBizhawk(new RTC_Command("REMOTE_PUSHVMDS) { objectValue = MemoryDomains.VmdPool.Values.Select(it => (it as VirtualMemoryDomain).Proto).ToArray() }, true, true);

                    //Thread.Sleep(100);

                    //		if (RTC_StockpileManager.BackupedState != null)
                    //			S.GET<RTC_MemoryDomains_Form>().RefreshDomainsAndKeepSelected(RTC_StockpileManager.BackupedState.SelectedDomains.ToArray());

                    //		if (S.GET<RTC_Core_Form>().cbUseGameProtection.Checked)
                    //			RTC_GameProtection.Start();

                    break;

                case RTCV.NetCore.Commands.Remote.IsNormalAdvance:
                    e.setReturnValue(Hooks.isNormalAdvance);
                    break;

                case RTCV.NetCore.Commands.Remote.EventCloseEmulator:
                    Environment.Exit(-1);
                    break;
                }
            }
            catch (Exception ex)
            {
                VanguardCore.ShowErrorDialog(ex, true);
            }
        }