private bool Cleanup() { if (_cleanupState == CleanupState.Initiated) { // Backup last saved game if it may be skipped due to time difference rule and then remove oldest backups until MaxBackups number is guaranteed _cleanupState = CleanupState.Running; JobType job = JobType.Cleanup; // If there is a backup in the pipeline stop it's timer, we will ensure anyways to backup the last savegame, which in this case will be this one _backupTimer.Stop(); // Check if we backuped the last savegame to ensure always backup the last savegame of a playsession if (_backupSavegame != null && !HasLastSavegameBackup(_backupSavegame)) { // Do a backup depending on settings and time frame if (Properties.Settings.Default.IgnoreMinTimeDiffOnClose || !BackupRecentlyPerformed(_backupSavegame)) { Debug.WriteLine("cleanup with backup"); job |= JobType.Backup; } } // let's roll backgroundWorkerTnS.RunWorkerAsync(new Work(job, _backupSavegame)); return(true); } return(false); }
private void OnTrayMenuExit(object sender, EventArgs e) { // User initiated close via context menu, aks for confirmation if (AskUserForCloseConfirmation()) { _cleanupState = CleanupState.Initiated; this.Close(); } }
private void processTnS_Exited(object sender, EventArgs e) { // Timber and Stone was closed, so we close also Debug.WriteLine("processTnS_Exited " + _cleanupState.ToString()); if (_cleanupState != CleanupState.Running) { _cleanupState = CleanupState.Initiated; } this.Close(); }
private void buttonCancel_Click(object sender, EventArgs e) { // User initiated close via cancle button, aks for confirmation if (AskUserForCloseConfirmation()) { if (_cleanupState != CleanupState.Running) { _cleanupState = CleanupState.Initiated; } this.Close(); } }
private void backgroundWorkerTnS_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { Work work = e.Result as Work; if (work == null) { labelStatus.Text = "Monotoring Timber and Stone..."; _backupState = BackupState.Idle; _cleanupState = CleanupState.None; } else if ((work.Job & JobType.Cleanup) == JobType.Cleanup) { labelStatus.Text = "Closing..."; _cleanupState = CleanupState.Finished; this.Close(); } else // if (work.Job == JobType.Backup) { _backupState = BackupState.Idle; } }
public void ProcessState() { switch (State) { case CleanupState.Start: //Cleanup State should only start every 20 seconds if (DateTime.Now.Subtract(_lastCleanupAction).TotalSeconds < 20) break; State = CleanupState.CheckModalWindows; break; case CleanupState.CheckModalWindows: // // go through *every* window // foreach (var window in Cache.Instance.Windows) { // Telecom messages are generally mission info messages: close them if (window.Name == "telecom") { Logging.Log("Cleanup: Closing telecom message..."); Logging.Log("Cleanup: Content of telecom window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); window.Close(); } // Modal windows must be closed // But lets only close known modal windows if (window.Name == "modal") { bool close = false; bool restart = false; bool gotobasenow = false; bool sayyes = false; //bool sayno = false; if (!string.IsNullOrEmpty(window.Html)) { // Server going down /unscheduled/ potentially very soon! // CCP does not reboot in the middle of the day because the server is behaving // dock now to avoid problems gotobasenow |= window.Html.Contains("for a short unscheduled reboot"); // Server going down close |= window.Html.Contains("Please make sure your characters are out of harm"); close |= window.Html.Contains("the servers are down for 30 minutes each day for maintenance and updates"); if (window.Html.Contains("The socket was closed")) { Logging.Log("Cleanup: This window indicates we are disconnected: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); //Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.CmdLogOff); //this causes the questor window to not re-appear Cache.Instance.CloseQuestorCMDLogoff = false; Cache.Instance.CloseQuestorCMDExitGame = true; Cache.Instance.ReasonToStopQuestor = "The socket was closed"; Cache.Instance.SessionState = "Quitting"; break; } // In space "shit" close |= window.Html.Contains("Item cannot be moved back to a loot container."); close |= window.Html.Contains("you do not have the cargo space"); close |= window.Html.Contains("cargo units would be required to complete this operation."); close |= window.Html.Contains("You are too far away from the acceleration gate to activate it!"); close |= window.Html.Contains("maximum distance is 2500 meters"); // Stupid warning, lets see if we can find it close |= window.Html.Contains("Do you wish to proceed with this dangerous action?"); // Yes we know the mission isnt complete, Questor will just redo the mission close |= window.Html.Contains("Please check your mission journal for further information."); close |= window.Html.Contains("weapons in that group are already full"); close |= window.Html.Contains("You have to be at the drop off location to deliver the items in person"); // Lag :/ close |= window.Html.Contains("This gate is locked!"); close |= window.Html.Contains("The Zbikoki's Hacker Card"); close |= window.Html.Contains(" units free."); close |= window.Html.Contains("already full"); // // restart the client if these are encountered // restart |= window.Html.Contains("Local cache is corrupt"); restart |= window.Html.Contains("Local session information is corrupt"); restart |= window.Html.Contains("The connection to the server was closed"); //CONNECTION LOST restart |= window.Html.Contains("server was closed"); //CONNECTION LOST restart |= window.Html.Contains("The socket was closed"); //CONNECTION LOST restart |= window.Html.Contains("The connection was closed"); //CONNECTION LOST restart |= window.Html.Contains("Connection to server lost"); //INFORMATION restart |= window.Html.Contains("The user connection has been usurped on the proxy"); //CONNECTION LOST restart |= window.Html.Contains("The transport has not yet been connected, or authentication was not successful"); //CONNECTION LOST // // Modal Dialogs the need "yes" pressed // sayyes |= window.Html.Contains("objectives requiring a total capacity"); sayyes |= window.Html.Contains("your ship only has space for"); // // Modal Dialogs the need "no" pressed // //sayno |= window.Html.Contains("Do you wish to proceed with this dangerous action } if (sayyes) { Logging.Log("Cleanup: Found a window that needs 'yes' chosen..."); Logging.Log("Cleanup: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); window.AnswerModal("Yes"); continue; } if (close) { Logging.Log("Cleanup: Closing modal window..."); Logging.Log("Cleanup: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); window.Close(); continue; } if (restart) { Logging.Log("Cleanup: Restarting eve..."); Logging.Log("Cleanup: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); Cache.Instance.CloseQuestorCMDLogoff = false; Cache.Instance.CloseQuestorCMDExitGame = true; Cache.Instance.ReasonToStopQuestor = "A message from ccp indicated we were disconnected"; Cache.Instance.SessionState = "Quitting"; window.Close(); continue; } if (gotobasenow) { Logging.Log("Cleanup: Evidentially the cluster is dieing... and CCP is restarting the server"); Logging.Log("Cleanup: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); Cache.Instance.GotoBaseNow = true; Settings.Instance.AutoStart = false; // // do not close eve, let the shutdown of the server do that // //Cache.Instance.CloseQuestorCMDLogoff = false; //Cache.Instance.CloseQuestorCMDExitGame = true; //Cache.Instance.ReasonToStopQuestor = "A message from ccp indicated we were disonnected"; //Cache.Instance.SessionState = "Quitting"; window.Close(); continue; } } } State = CleanupState.Done; break; case CleanupState.Done: _lastCleanupAction = DateTime.Now; State = CleanupState.Start; break; default: // Next state State = CleanupState.Start; break; } }
private void FormMain_Load(object sender, EventArgs e) { // Load settings _backupDelayInSeconds = Properties.Settings.Default.BackupDelayInSeconds; _maxNumberOfBackups = Properties.Settings.Default.MaxNumberOfBackups; _minTimeDiffInSeconds = Properties.Settings.Default.MinTimeDiffInSeconds; // validate settings if (_backupDelayInSeconds < 1) { MessageBox.Show("Error: Settings invalid!" + Environment.NewLine + Environment.NewLine + "BackupDelayInSeconds must be greater than 1.", "Safeguard"); Application.Exit(); } if (_minTimeDiffInSeconds < 1) { MessageBox.Show("Error: Settings invalid!" + Environment.NewLine + Environment.NewLine + "MinTimeDiffInSeconds must be greater than 1 and greater than BackupDelayInSeconds.", "Safeguard"); Application.Exit(); } if (_maxNumberOfBackups < 1) { MessageBox.Show("Error: Settings invalid!" + Environment.NewLine + Environment.NewLine + "MaxNumberOfBackups must be greater than 1.", "Safeguard"); Application.Exit(); } // check environment try { _baseFolder = Directory.GetCurrentDirectory(); //_baseFolder = Application.StartupPath; _appPath = Path.Combine(_baseFolder, _appName); _savesPath = Path.Combine(_baseFolder, @"saves\saves.sav"); _saveFolder = Path.Combine(_baseFolder, @"saves"); _backupFolder = Path.Combine(_baseFolder, @"Safeguard"); } catch (Exception) { MessageBox.Show("Error: Failed to obtain startup directory info!", "Safeguard"); Application.Exit(); } if (!File.Exists(_appPath)) { MessageBox.Show("Error: 'Timber and Stone' not found!" + Environment.NewLine + "Safeguard.exe has to be in the same directory as 'Timber and Stone.exe'.", "Safeguard"); Application.Exit(); } if (!Directory.Exists(_saveFolder)) { MessageBox.Show("Error: 'Timber and Stone' savegame directory 'saves' not found!", "Safeguard"); Application.Exit(); } if (!File.Exists(_savesPath)) { MessageBox.Show("Error: 'Timber and Stone' savegame master file 'saves\\saves.sav' not found!", "Safeguard"); Application.Exit(); } try { Directory.CreateDirectory(_backupFolder); } catch (Exception ex) { MessageBox.Show("Error: Could not create or access directory " + _backupFolder + Environment.NewLine + Environment.NewLine + "Exception was: " + ex.Message, "Safeguard"); Application.Exit(); } // Prepare process info processTnS.StartInfo.FileName = _appPath; processTnS.StartInfo.WorkingDirectory = _baseFolder; // Start process try { processTnS.EnableRaisingEvents = true; processTnS.Start(); } catch (Exception ex) { MessageBox.Show("Error: Failed to start 'Timber and Stone'!" + Environment.NewLine + Environment.NewLine + "Exception was: " + ex.Message, "Safeguard"); Application.Exit(); } // Monitor savegame changes try { fileSystemWatcherTnS.Path = _saveFolder; fileSystemWatcherTnS.EnableRaisingEvents = true; } catch (Exception ex) { MessageBox.Show("Error: Failed to register savegame change monitoring!" + Environment.NewLine + Environment.NewLine + "Exception was: " + ex.Message, "Safeguard"); Application.Exit(); } // Since we have now started the process and are monotoring it, remember to check for necessary cleanup afterwards _cleanupState = CleanupState.None; // Create backup list _lastBackups = new Dictionary <string, string>(); // Create timer _backupTimer = new System.Windows.Forms.Timer(); _backupTimer.Interval = _backupDelayInSeconds * 1000; _backupTimer.Tick += new EventHandler(OnTimerTick); // Create a simple tray menu with only one item _trayMenu = new ContextMenu(); _trayMenu.MenuItems.Add("Close", OnTrayMenuExit); // Create a tray icon _trayIcon = new NotifyIcon(); _trayIcon.Text = "Safeguard (Timber and Stone)"; _trayIcon.Icon = Safeguard.Properties.Resources.app; // Add menu to tray icon and show it _trayIcon.ContextMenu = _trayMenu; _trayIcon.Visible = true; }
public void ProcessState() { switch (State) { case CleanupState.Start: //Cleanup State should only start every 20 seconds if (DateTime.Now.Subtract(_lastCleanupAction).TotalSeconds < 20) { break; } State = CleanupState.CheckModalWindows; break; case CleanupState.CheckModalWindows: // // go through *every* window // foreach (var window in Cache.Instance.Windows) { // Telecom messages are generally mission info messages: close them if (window.Name == "telecom") { Logging.Log("Cleanup: Closing telecom message..."); Logging.Log("Cleanup: Content of telecom window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); window.Close(); } // Modal windows must be closed // But lets only close known modal windows if (window.Name == "modal") { bool close = false; bool restart = false; bool gotobasenow = false; bool sayyes = false; //bool sayno = false; if (!string.IsNullOrEmpty(window.Html)) { // Server going down /unscheduled/ potentially very soon! // CCP does not reboot in the middle of the day because the server is behaving // dock now to avoid problems gotobasenow |= window.Html.Contains("for a short unscheduled reboot"); // Server going down close |= window.Html.Contains("Please make sure your characters are out of harm"); close |= window.Html.Contains("the servers are down for 30 minutes each day for maintenance and updates"); if (window.Html.Contains("The socket was closed")) { Logging.Log("Cleanup: This window indicates we are disconnected: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); //Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.CmdLogOff); //this causes the questor window to not re-appear Cache.Instance.CloseQuestorCMDLogoff = false; Cache.Instance.CloseQuestorCMDExitGame = true; Cache.Instance.ReasonToStopQuestor = "The socket was closed"; Cache.Instance.SessionState = "Quitting"; break; } // In space "shit" close |= window.Html.Contains("Item cannot be moved back to a loot container."); close |= window.Html.Contains("you do not have the cargo space"); close |= window.Html.Contains("cargo units would be required to complete this operation."); close |= window.Html.Contains("You are too far away from the acceleration gate to activate it!"); close |= window.Html.Contains("maximum distance is 2500 meters"); // Stupid warning, lets see if we can find it close |= window.Html.Contains("Do you wish to proceed with this dangerous action?"); // Yes we know the mission isnt complete, Questor will just redo the mission close |= window.Html.Contains("Please check your mission journal for further information."); close |= window.Html.Contains("weapons in that group are already full"); close |= window.Html.Contains("You have to be at the drop off location to deliver the items in person"); // Lag :/ close |= window.Html.Contains("This gate is locked!"); close |= window.Html.Contains("The Zbikoki's Hacker Card"); close |= window.Html.Contains(" units free."); close |= window.Html.Contains("already full"); // // restart the client if these are encountered // restart |= window.Html.Contains("Local cache is corrupt"); restart |= window.Html.Contains("Local session information is corrupt"); restart |= window.Html.Contains("The connection to the server was closed"); //CONNECTION LOST restart |= window.Html.Contains("server was closed"); //CONNECTION LOST restart |= window.Html.Contains("The socket was closed"); //CONNECTION LOST restart |= window.Html.Contains("The connection was closed"); //CONNECTION LOST restart |= window.Html.Contains("Connection to server lost"); //INFORMATION restart |= window.Html.Contains("The user connection has been usurped on the proxy"); //CONNECTION LOST restart |= window.Html.Contains("The transport has not yet been connected, or authentication was not successful"); //CONNECTION LOST // // Modal Dialogs the need "yes" pressed // sayyes |= window.Html.Contains("objectives requiring a total capacity"); sayyes |= window.Html.Contains("your ship only has space for"); // // Modal Dialogs the need "no" pressed // //sayno |= window.Html.Contains("Do you wish to proceed with this dangerous action } if (sayyes) { Logging.Log("Cleanup: Found a window that needs 'yes' chosen..."); Logging.Log("Cleanup: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); window.AnswerModal("Yes"); continue; } if (close) { Logging.Log("Cleanup: Closing modal window..."); Logging.Log("Cleanup: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); window.Close(); continue; } if (restart) { Logging.Log("Cleanup: Restarting eve..."); Logging.Log("Cleanup: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); Cache.Instance.CloseQuestorCMDLogoff = false; Cache.Instance.CloseQuestorCMDExitGame = true; Cache.Instance.ReasonToStopQuestor = "A message from ccp indicated we were disconnected"; Cache.Instance.SessionState = "Quitting"; window.Close(); continue; } if (gotobasenow) { Logging.Log("Cleanup: Evidentially the cluster is dieing... and CCP is restarting the server"); Logging.Log("Cleanup: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]"); Cache.Instance.GotoBaseNow = true; Settings.Instance.AutoStart = false; // // do not close eve, let the shutdown of the server do that // //Cache.Instance.CloseQuestorCMDLogoff = false; //Cache.Instance.CloseQuestorCMDExitGame = true; //Cache.Instance.ReasonToStopQuestor = "A message from ccp indicated we were disonnected"; //Cache.Instance.SessionState = "Quitting"; window.Close(); continue; } } } State = CleanupState.Done; break; case CleanupState.Done: _lastCleanupAction = DateTime.Now; State = CleanupState.Start; break; default: // Next state State = CleanupState.Start; break; } }