mirror of
https://github.com/openbullet/openbullet.git
synced 2023-10-21 07:33:42 -05:00
Added automatic save and restoration of RunnerManager sessions
This commit is contained in:
@@ -36,6 +36,7 @@ namespace OpenBullet
|
||||
private int snowBuffer = 0;
|
||||
|
||||
public RunnerManager RunnerManagerPage { get; set; }
|
||||
// TODO: Do not create a different View for each RunnerInstance, but instead just replace the vm!
|
||||
public Runner CurrentRunnerPage { get; set; }
|
||||
public ProxyManager ProxyManagerPage { get; set; }
|
||||
public WordlistManager WordlistManagerPage { get; set; }
|
||||
@@ -196,9 +197,15 @@ namespace OpenBullet
|
||||
OB.HitsDB = new HitsDBViewModel();
|
||||
|
||||
// Views
|
||||
RunnerManagerPage = new RunnerManager(OB.OBSettings.General.AutoCreateRunner);
|
||||
if (OB.OBSettings.General.AutoCreateRunner)
|
||||
RunnerManagerPage = new RunnerManager();
|
||||
|
||||
// If we create first runner and there was no session to restore
|
||||
if (OB.OBSettings.General.AutoCreateRunner & !OB.RunnerManager.RestoreSession())
|
||||
{
|
||||
var firstRunner = OB.RunnerManager.Create();
|
||||
CurrentRunnerPage = OB.RunnerManager.RunnersCollection.FirstOrDefault().View;
|
||||
}
|
||||
|
||||
OB.Logger.LogInfo(Components.Main, "Initialized RunnerManager");
|
||||
ProxyManagerPage = new ProxyManager();
|
||||
OB.Logger.LogInfo(Components.Main, "Initialized ProxyManager");
|
||||
@@ -410,6 +417,10 @@ namespace OpenBullet
|
||||
"Confirmation", MessageBoxButton.YesNo, MessageBoxImage.Warning) == MessageBoxResult.No)
|
||||
return false;
|
||||
}
|
||||
|
||||
OB.Logger.LogInfo(Components.Main, "Saving RunnerManager session to the database");
|
||||
OB.RunnerManager.SaveSession();
|
||||
|
||||
OB.Logger.LogInfo(Components.Main, "Quit sequence initiated");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,22 +1,32 @@
|
||||
using OpenBullet.Views.Main.Runner;
|
||||
using OpenBullet.Repositories;
|
||||
using OpenBullet.Views.Main.Runner;
|
||||
using RuriLib.Interfaces;
|
||||
using RuriLib.Models;
|
||||
using RuriLib.Runner;
|
||||
using RuriLib.ViewModels;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
||||
namespace OpenBullet.ViewModels
|
||||
{
|
||||
public class RunnerManagerViewModel : ViewModelBase, IRunnerManager
|
||||
{
|
||||
private LiteDBRepository<RunnerSessionData> _repo;
|
||||
|
||||
public ObservableCollection<RunnerInstance> RunnersCollection { get; set; } = new ObservableCollection<RunnerInstance>();
|
||||
|
||||
public IEnumerable<IRunner> Runners => RunnersCollection.Select(i => i.ViewModel);
|
||||
|
||||
private Random rand = new Random();
|
||||
|
||||
public RunnerManagerViewModel()
|
||||
{
|
||||
_repo = new LiteDBRepository<RunnerSessionData>(OB.dataBaseFile, "runners");
|
||||
}
|
||||
|
||||
public RunnerInstance Get(int id)
|
||||
{
|
||||
return RunnersCollection.Where(r => r.Id == id).First();
|
||||
@@ -25,6 +35,8 @@ namespace OpenBullet.ViewModels
|
||||
public IRunner Create()
|
||||
{
|
||||
var instance = new RunnerInstance(rand.Next());
|
||||
instance.ViewModel.ConfigChanged += OnRunnerSessionChanged;
|
||||
instance.ViewModel.WordlistChanged += OnRunnerSessionChanged;
|
||||
RunnersCollection.Add(instance);
|
||||
return instance.ViewModel;
|
||||
}
|
||||
@@ -43,10 +55,74 @@ namespace OpenBullet.ViewModels
|
||||
{
|
||||
RunnersCollection.Clear();
|
||||
}
|
||||
|
||||
public void OnRunnerSessionChanged(IRunnerMessaging obj)
|
||||
{
|
||||
SaveSession();
|
||||
}
|
||||
|
||||
public void SaveSession()
|
||||
{
|
||||
_repo.RemoveAll();
|
||||
_repo.Add(RunnersCollection
|
||||
.Select(r => r.ViewModel)
|
||||
.Select(r => new RunnerSessionData()
|
||||
{
|
||||
Bots = r.BotsAmount,
|
||||
Config = r.Config != null ? r.ConfigName : "",
|
||||
Wordlist = r.Wordlist != null ? r.Wordlist.Path : "",
|
||||
ProxyMode = r.ProxyMode
|
||||
}
|
||||
));
|
||||
}
|
||||
|
||||
// Returns true if a session was found
|
||||
public bool RestoreSession()
|
||||
{
|
||||
var runners = _repo.Get().ToArray();
|
||||
|
||||
if (runners.Length == 0) return false;
|
||||
|
||||
foreach (var r in runners)
|
||||
{
|
||||
try
|
||||
{
|
||||
var instance = Create();
|
||||
instance.BotsAmount = r.Bots;
|
||||
instance.ProxyMode = r.ProxyMode;
|
||||
|
||||
var configVM = OB.ConfigManager.Configs.FirstOrDefault(c => c.Name == r.Config)
|
||||
?? throw new Exception($"The Config {r.Config} was not found in the ConfigManager");
|
||||
|
||||
instance.SetConfig(configVM.Config, false);
|
||||
|
||||
// Try to get the Wordlist from the Manager
|
||||
var wordlist = OB.WordlistManager.Wordlists.FirstOrDefault(w => w.Path == r.Wordlist);
|
||||
|
||||
// If not found, try to get it from disk
|
||||
if (wordlist == null)
|
||||
{
|
||||
if (!File.Exists(r.Wordlist))
|
||||
throw new Exception($"The Wordlist {r.Wordlist} was not found in the WordlistManager or on Disk");
|
||||
|
||||
wordlist = WordlistManagerViewModel.FileToWordlist(r.Wordlist);
|
||||
}
|
||||
|
||||
instance.SetWordlist(wordlist);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
OB.Logger.LogError(Components.RunnerManager, ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public class RunnerInstance
|
||||
{
|
||||
// TODO: Remove the View from here! It shouldn't be here and nothing should reference this View!
|
||||
public Runner View { get; private set; }
|
||||
public RunnerViewModel ViewModel { get; private set; }
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ namespace OpenBullet.ViewModels
|
||||
{
|
||||
_repo = new LiteDBRepository<Wordlist>(OB.dataBaseFile, "wordlists");
|
||||
WordlistsCollection = new ObservableCollection<Wordlist>();
|
||||
RefreshList();
|
||||
}
|
||||
|
||||
public Wordlist GetWordlistByName(string name)
|
||||
@@ -41,6 +42,20 @@ namespace OpenBullet.ViewModels
|
||||
return WordlistsCollection.Where(x => x.Name == name).First();
|
||||
}
|
||||
|
||||
public static Wordlist FileToWordlist(string path)
|
||||
{
|
||||
// Build the wordlist object
|
||||
var wordlist = new Wordlist(Path.GetFileNameWithoutExtension(path), path, OB.Settings.Environment.WordlistTypes.First().Name, "");
|
||||
|
||||
// Get the first line
|
||||
var first = File.ReadLines(wordlist.Path).First();
|
||||
|
||||
// Set the correct wordlist type
|
||||
wordlist.Type = OB.Settings.Environment.RecognizeWordlistType(first);
|
||||
|
||||
return wordlist;
|
||||
}
|
||||
|
||||
#region CRUD Operations
|
||||
// Create
|
||||
public void Add(Wordlist wordlist)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using OpenBullet.Views.Main.Runner;
|
||||
using OpenBullet.ViewModels;
|
||||
using OpenBullet.Views.Main.Runner;
|
||||
using OpenBullet.Views.UserControls;
|
||||
using RuriLib.Models;
|
||||
using System.ComponentModel;
|
||||
@@ -80,17 +81,8 @@ namespace OpenBullet
|
||||
ofd.ShowDialog();
|
||||
try
|
||||
{
|
||||
// Build the wordlist object
|
||||
var wordlist = new Wordlist(Path.GetFileNameWithoutExtension(ofd.FileName), ofd.FileName, OB.Settings.Environment.WordlistTypes.First().Name, "");
|
||||
|
||||
// Get the first line
|
||||
var first = File.ReadLines(wordlist.Path).First();
|
||||
|
||||
// Set the correct wordlist type
|
||||
wordlist.Type = OB.Settings.Environment.RecognizeWordlistType(first);
|
||||
|
||||
// Add the wordlist to the runner
|
||||
((Runner)Caller).SetWordlist(wordlist);
|
||||
((Runner)Caller).SetWordlist(WordlistManagerViewModel.FileToWordlist(ofd.FileName));
|
||||
|
||||
((MainDialog)Parent).Close();
|
||||
}
|
||||
|
||||
@@ -14,11 +14,6 @@
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock x:Name="helpMessageLabel" Grid.Row="0" Grid.RowSpan="2" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="25" FontWeight="Bold" Foreground="{DynamicResource ForegroundMain}" TextAlignment="Center" >
|
||||
Welcome to Open Bullet!<LineBreak/>
|
||||
Create a Runner to get started.
|
||||
</TextBlock>
|
||||
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||
<Button x:Name="addRunnerButton" Click="addRunnerButton_Click">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
|
||||
@@ -24,24 +24,18 @@ namespace OpenBullet.Views.Main
|
||||
StartRunner?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public RunnerManager(bool createFirst)
|
||||
public RunnerManager()
|
||||
{
|
||||
vm = OB.RunnerManager;
|
||||
DataContext = vm;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
if (createFirst)
|
||||
{
|
||||
addRunnerButton_Click(this, null);
|
||||
}
|
||||
}
|
||||
|
||||
#region Buttons
|
||||
private void addRunnerButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
vm.Create();
|
||||
helpMessageLabel.Visibility = Visibility.Collapsed;
|
||||
}
|
||||
|
||||
private void removeRunnerButton_Click(object sender, RoutedEventArgs e)
|
||||
|
||||
@@ -29,8 +29,6 @@ namespace OpenBullet.Views.Main
|
||||
DataContext = vm;
|
||||
|
||||
InitializeComponent();
|
||||
|
||||
vm.RefreshList();
|
||||
}
|
||||
|
||||
public void AddWordlist(Wordlist wordlist)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
using RuriLib.Runner;
|
||||
using System;
|
||||
|
||||
namespace RuriLib.Models
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains the essential information of a Runner Session.
|
||||
/// </summary>
|
||||
public class RunnerSessionData : Persistable<Guid>
|
||||
{
|
||||
/// <summary>The name of the selected Config.</summary>
|
||||
public string Config { get; set; } = "";
|
||||
|
||||
/// <summary>The name of the selected Wordlist.</summary>
|
||||
public string Wordlist { get; set; } = "";
|
||||
|
||||
/// <summary>The amount of bots selected.</summary>
|
||||
public int Bots { get; set; } = 1;
|
||||
|
||||
/// <summary>The proxy mode selected.</summary>
|
||||
public ProxyMode ProxyMode { get; set; } = ProxyMode.Default;
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,7 @@ namespace RuriLib.Runner
|
||||
/// <summary>
|
||||
/// Main class that handles all the multi-threaded checking of a Wordlist given a Config.
|
||||
/// </summary>
|
||||
// TODO: Split this into partial classes
|
||||
public class RunnerViewModel : ViewModelBase, IRunnerMessaging, IRunner
|
||||
{
|
||||
#region Constructor
|
||||
@@ -349,6 +350,7 @@ namespace RuriLib.Runner
|
||||
Config = config;
|
||||
if (setRecommended) BotsAmount = Clamp(config.Settings.SuggestedBots, 1, 200);
|
||||
OnPropertyChanged("ConfigName");
|
||||
RaiseConfigChanged();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -360,6 +362,7 @@ namespace RuriLib.Runner
|
||||
Wordlist = wordlist;
|
||||
OnPropertyChanged("WordlistName");
|
||||
OnPropertyChanged("WordlistSize");
|
||||
RaiseWordlistChanged();
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -1052,41 +1055,33 @@ namespace RuriLib.Runner
|
||||
#endregion
|
||||
|
||||
#region Events
|
||||
/// <summary>
|
||||
/// Fired when a new message needs to be logged.
|
||||
/// </summary>
|
||||
/// <summary>Fired when a new message needs to be logged.</summary>
|
||||
public event Action<IRunnerMessaging, LogLevel, string, bool, int> MessageArrived;
|
||||
|
||||
/// <summary>
|
||||
/// Fired when the Master Worker status changed.
|
||||
/// </summary>
|
||||
/// <summary>Fired when the Master Worker status changed.</summary>
|
||||
public event Action<IRunnerMessaging> WorkerStatusChanged;
|
||||
|
||||
/// <summary>
|
||||
/// Fired when a Hit was found.
|
||||
/// </summary>
|
||||
/// <summary>Fired when a Hit was found.</summary>
|
||||
public event Action<IRunnerMessaging, Hit> FoundHit;
|
||||
|
||||
/// <summary>
|
||||
/// Fired when proxies need to be reloaded.
|
||||
/// </summary>
|
||||
/// <summary>Fired when proxies need to be reloaded.</summary>
|
||||
public event Action<IRunnerMessaging> ReloadProxies;
|
||||
|
||||
/// <summary>
|
||||
/// Fired when an Action could change the UI and needs to be dispatched to another thread (usually it's handled by the UI thread).
|
||||
/// </summary>
|
||||
/// <summary>/// Fired when an Action could change the UI and needs to be dispatched to another thread (usually it's handled by the UI thread).</summary>
|
||||
public event Action<IRunnerMessaging, Action> DispatchAction;
|
||||
|
||||
/// <summary>
|
||||
/// Fired when the progress record needs to be saved to the Database.
|
||||
/// </summary>
|
||||
/// <summary>Fired when the progress record needs to be saved to the Database.</summary>
|
||||
public event Action<IRunnerMessaging> SaveProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Fired when custom inputs from the user are required.
|
||||
/// </summary>
|
||||
/// <summary>Fired when custom inputs from the user are required.</summary>
|
||||
public event Action<IRunnerMessaging> AskCustomInputs;
|
||||
|
||||
/// <summary>Fired when the currently selected Config changed.</summary>
|
||||
public event Action<IRunnerMessaging> ConfigChanged;
|
||||
|
||||
/// <summary>Fired when the currently selected Wordlist changed.</summary>
|
||||
public event Action<IRunnerMessaging> WordlistChanged;
|
||||
|
||||
private void RaiseMessageArrived(LogLevel level, string message, bool prompt = false, int timeout = 0)
|
||||
{
|
||||
MessageArrived?.Invoke(this, level, message, prompt, timeout);
|
||||
@@ -1122,6 +1117,16 @@ namespace RuriLib.Runner
|
||||
{
|
||||
AskCustomInputs?.Invoke(this);
|
||||
}
|
||||
|
||||
private void RaiseConfigChanged()
|
||||
{
|
||||
ConfigChanged?.Invoke(this);
|
||||
}
|
||||
|
||||
private void RaiseWordlistChanged()
|
||||
{
|
||||
WordlistChanged?.Invoke(this);
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Proxy Management Methods
|
||||
|
||||
@@ -285,6 +285,7 @@
|
||||
<Compile Include="Models\DataPool.cs" />
|
||||
<Compile Include="Models\Persistable.cs" />
|
||||
<Compile Include="Models\ProxyResult.cs" />
|
||||
<Compile Include="Models\RunnerSessionData.cs" />
|
||||
<Compile Include="Models\Stats\ProxyManagerStats.cs" />
|
||||
<Compile Include="Models\ProxyPool.cs" />
|
||||
<Compile Include="Models\RemoteProxySource.cs" />
|
||||
|
||||
Reference in New Issue
Block a user