Novetus_src/Novetus/NovetusLauncher/Classes/Launcher/AddonLoader.cs

140 lines
5.1 KiB
C#

#region Usings
using Ionic.Zip;
using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
#endregion
#region Addon Loader
public class AddonLoader
{
private readonly OpenFileDialog openFileDialog1;
private string installOutcome = "";
private int fileListDisplay = 0;
private RichTextBox consoleBox;
private CancellationTokenSource tokenSource;
private int pastPercentage = 0;
public AddonLoader(RichTextBox box)
{
Application.ApplicationExit += new EventHandler(OnApplicationExit);
consoleBox = box;
openFileDialog1 = new OpenFileDialog()
{
FileName = "Select an addon .zip file",
Filter = "Compressed zip files (*.zip)|*.zip",
Title = "Open addon .zip"
};
}
public void setInstallOutcome(string text)
{
installOutcome = text;
}
public string getInstallOutcome()
{
return installOutcome;
}
public void setFileListDisplay(int number)
{
fileListDisplay = number;
}
public async Task LoadAddon()
{
if (openFileDialog1.ShowDialog() == DialogResult.OK)
{
MessageBox.Show("Your addon is loading. You will recieve a notification when it is installed. Please keep the launcher open. You can see the installation progress in the Console.", "Novetus - Addon Loading");
try
{
int filecount = 0;
StringBuilder filelistbuilder = new StringBuilder();
StringBuilder filelistcutdown = new StringBuilder();
using (Stream str = openFileDialog1.OpenFile())
{
using (var zipFile = ZipFile.Read(str))
{
zipFile.ExtractProgress += ExtractProgress;
ZipEntry[] entries = zipFile.Entries.ToArray();
foreach (ZipEntry entry in entries)
{
filelistbuilder.Append(!entry.IsDirectory ? (entry.FileName + " (" + entry.UncompressedSize + " KB)" + Environment.NewLine) : "");
if (filecount < fileListDisplay)
{
filelistcutdown.Append(!entry.IsDirectory ? (entry.FileName + " (" + entry.UncompressedSize + " KB)" + Environment.NewLine) : "");
}
if (!entry.IsDirectory)
{
filecount++;
}
}
tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;
await Task.Factory.StartNew(() => zipFile.ExtractAll(GlobalPaths.BasePath, ExtractExistingFileAction.OverwriteSilently), token);
zipFile.Dispose();
}
}
string filelist = filelistbuilder.ToString();
if (filecount > fileListDisplay)
{
installOutcome = "Addon " + openFileDialog1.SafeFileName + " installed! " + filecount + " files copied!" + Environment.NewLine + "Files added/modified:" + Environment.NewLine + Environment.NewLine + filelistcutdown + Environment.NewLine + "and " + (filecount - fileListDisplay) + " more files!";
}
else
{
installOutcome = "Addon " + openFileDialog1.SafeFileName + " installed! " + filecount + " files copied!" + Environment.NewLine + "Files added/modified:" + Environment.NewLine + Environment.NewLine + filelist;
}
}
catch (Exception ex)
{
GlobalFuncs.LogExceptions(ex);
installOutcome = "Error when installing addon: " + ex.Message;
}
}
}
//https://stackoverflow.com/questions/38948801/dotnetzip-display-progress-of-extraction
void ExtractProgress(object sender, ExtractProgressEventArgs e)
{
if (e.EventType == ZipProgressEventType.Extracting_EntryBytesWritten)
{
double percentage = Math.Round(e.BytesTransferred / (0.01 * e.TotalBytesToTransfer), 2);
int intPercent = Convert.ToInt32(percentage);
if (intPercent % 25 == 0 && pastPercentage != intPercent)
{
GlobalFuncs.ConsolePrint("AddonLoader - Extracting: "
+ e.CurrentEntry.FileName + ". Progress: "
+ e.BytesTransferred + "/" + e.TotalBytesToTransfer
+ " (" + intPercent + "%)", 3, consoleBox, true);
pastPercentage = intPercent;
}
}
else if (e.EventType == ZipProgressEventType.Extracting_BeforeExtractEntry)
{
GlobalFuncs.ConsolePrint("AddonLoader - Extracting: " + e.CurrentEntry.FileName, 3, consoleBox);
}
}
public void OnApplicationExit(object sender, EventArgs e)
{
tokenSource.Cancel();
}
}
#endregion