using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using ShiftOS.Engine;
using System.Threading;
using static ShiftOS.Objects.ShiftFS.Utils;
using Newtonsoft.Json;
namespace ShiftOS.WinForms.Applications
{
[WinOpen("installer")]
[RequiresUpgrade("installer")]
[MultiplayerOnly]
[DefaultTitle("Installer")]
[Launcher("Installer", true, "al_installer", "Utilities")]
public partial class Installer : UserControl, IShiftOSWindow
{
public Installer()
{
InitializeComponent();
lbtitle.Text = "Select file";
}
public void InitiateInstall(Installation install)
{
pnlselectfile.Hide();
pginstall.Show();
lbprogress.Show();
lbtitle.Text = install.Name;
install.ProgressReported += (p) =>
{
Desktop.InvokeOnWorkerThread(new Action(() =>
{
pginstall.Value = p;
}));
};
install.StatusReported += (s) =>
{
Desktop.InvokeOnWorkerThread(new Action(() =>
{
lbprogress.Text = s;
}));
};
install.InstallCompleted += () =>
{
Desktop.InvokeOnWorkerThread(new Action(() =>
{
lbtitle.Text = "Select file";
pnlselectfile.Show();
}));
isInstalling = false;
InstallCompleted?.Invoke();
};
while (!this.Visible)
{
}
isInstalling = true;
install.Install();
}
public void OnLoad()
{
btnstart.Hide();
pginstall.Hide();
lbprogress.Hide();
}
private bool isInstalling = false;
public void OnSkinLoad()
{
}
public bool OnUnload()
{
return !isInstalling; //Don't close if an install is running.
}
public void OnUpgrade()
{
}
private void pnlselectfile_VisibleChanged(object sender, EventArgs e)
{
if(this.ParentForm != null)
{
this.ParentForm.Height = (pnlselectfile.Visible == true) ? this.ParentForm.Height + pnlselectfile.Height : this.ParentForm.Height - pnlselectfile.Height;
}
}
public event Action InstallCompleted;
private void btnbrowse_Click(object sender, EventArgs e)
{
FileSkimmerBackend.GetFile(new[] { ".stp" }, FileOpenerStyle.Open, (file) =>
{
txtfilepath.Text = file;
btnstart.Show();
});
}
private void btnstart_Click(object sender, EventArgs e)
{
if (FileExists(txtfilepath.Text))
{
var install = new StpInstallation(txtfilepath.Text);
InitiateInstall(install);
}
else
{
Infobox.Show("File not found.", "The file you requested was not found on the system.");
}
}
}
public abstract class Installation
{
///
/// The display name of the installation.
///
public string Name { get; set; }
///
/// Occurs when the installation updates its status.
///
public event Action StatusReported;
///
/// Occurs when the installation updates its progress percentage.
///
public event Action ProgressReported;
///
/// Occurs when the installation completes.
///
public event Action InstallCompleted;
///
/// Start the installation.
///
public void Install()
{
var t = new System.Threading.Thread(() =>
{
ProgressReported?.Invoke(0);
StatusReported?.Invoke("");
Run();
ProgressReported?.Invoke(100);
StatusReported?.Invoke("Installation completed.");
InstallCompleted?.Invoke();
});
t.IsBackground = true;
t.Start();
}
///
/// Sets the install progress percentage.
///
/// The installation percentage.
protected void SetProgress(int value)
{
if (value < 0 || value > 100)
throw new ArgumentOutOfRangeException("value", "A percentage is typically between 0 and 100.... derp...");
ProgressReported?.Invoke(value);
}
///
/// Sets the install status text.
///
/// Text to display as status.
protected void SetStatus(string status)
{
StatusReported?.Invoke(status);
}
///
/// User-defined code to run during install. Once this code is ran, the installation is complete.
///
protected abstract void Run();
}
public class StpInstallation : Installation
{
public StpInstallation(string stpfile) : base()
{
if (!FileExists(stpfile))
throw new System.IO.FileNotFoundException("An attempt to install a ShiftOS setup package failed because the package was not found.", stpfile);
string json = ReadAllText(stpfile);
var contents = JsonConvert.DeserializeObject(json);
this.Name = contents.Name;
Contents = contents;
}
public StpContents Contents { get; set; }
protected override void Run()
{
if (Shiftorium.UpgradeInstalled(Contents.Upgrade))
{
Infobox.Show("Installation failed.", "This package has already been installed.");
return;
}
if (!string.IsNullOrWhiteSpace(Contents.Dependencies))
{
SetStatus("Checking Shiftorium for dependencies...");
string[] dependencies = Contents.Dependencies.Split(';');
for (int i = 0; i < dependencies.Length; i++)
{
if (Shiftorium.UpgradeInstalled(dependencies[i]))
{
double percent = (i / dependencies.Length) * 100;
SetProgress((int)percent);
}
else
{
var upg = Shiftorium.GetDefaults().FirstOrDefault(x => x.Id == dependencies[i]);
Infobox.Show("Missing dependency!", $"You are missing the following Shiftorium Upgrade: {upg.Name}\r\n\r\nThe installation cannot continue.");
return;
}
Thread.Sleep(250);
}
}
SetStatus("Installing...");
SetProgress(0);
for(int i = 0; i < 100; i++)
{
SetProgress(i);
Thread.Sleep(50);
}
Desktop.InvokeOnWorkerThread(() =>
{
Shiftorium.Buy(Contents.Upgrade, 0);
Infobox.Show("Install complete.", "The installation has completed successfully.");
SaveSystem.SaveGame();
});
}
}
public class StpContents : RequiresUpgradeAttribute
{
public StpContents(string name, string author, string dependencies = "") : base(name.ToLower().Replace(" ", "_"))
{
Name = name;
Author = author;
Dependencies = dependencies;
}
public string Name { get; set; }
public string Author { get; set; }
public string Dependencies { get; set; }
}
}