diff --git a/PCK-Studio-Updater/API/GithubParams.cs b/PCK-Studio-Updater/API/GithubParams.cs
new file mode 100644
index 00000000..77aed764
--- /dev/null
+++ b/PCK-Studio-Updater/API/GithubParams.cs
@@ -0,0 +1,22 @@
+using System.Text.RegularExpressions;
+
+namespace PCKStudio_Updater
+{
+ public sealed class GithubParams
+ {
+ public readonly string RepositoryOwnerName;
+ public readonly string RepositoryName;
+ public readonly string TargetExecutableName;
+ public readonly bool UsePreRelease;
+ public readonly Regex VersionMatcher;
+
+ public GithubParams(string repositoryOwnerName, string repositoryName, string targetExecutableName, bool usePreRelease, Regex versionMatcher)
+ {
+ RepositoryOwnerName = repositoryOwnerName;
+ RepositoryName = repositoryName;
+ TargetExecutableName = targetExecutableName;
+ UsePreRelease = usePreRelease;
+ VersionMatcher = versionMatcher;
+ }
+ }
+}
diff --git a/PCK-Studio-Updater/API/GithubUpdateDownloader.cs b/PCK-Studio-Updater/API/GithubUpdateDownloader.cs
new file mode 100644
index 00000000..b89c3897
--- /dev/null
+++ b/PCK-Studio-Updater/API/GithubUpdateDownloader.cs
@@ -0,0 +1,148 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO.Compression;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+using Octokit;
+
+namespace PCKStudio_Updater
+{
+ public sealed class GithubUpdateDownloader : IUpdateDownloader
+ {
+ private static readonly Assembly updaterAssembly = Assembly.GetAssembly(typeof(GithubUpdateDownloader));
+
+ private readonly GithubParams _updateParams;
+ private readonly GitHubClient githubClient;
+ private Release latestFetchedRelease;
+ private Version latestReleaseVersion;
+ private DirectoryInfo downloadDirectory;
+
+
+ public GithubUpdateDownloader(GithubParams updateParams)
+ {
+ _updateParams = updateParams;
+ var githubClientProductHeader = new ProductHeaderValue(updaterAssembly.GetName().Name);
+ githubClient = new GitHubClient(githubClientProductHeader);
+ }
+
+ public bool IsUpdateAvailable(FileVersionInfo fileVersionInfo)
+ {
+ return IsUpdateAvailable(fileVersionInfo.ProductVersion);
+ }
+
+ public bool IsUpdateAvailable(Assembly currentAssembly)
+ {
+ if (!File.Exists(currentAssembly.Location))
+ return false;
+ FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(currentAssembly.Location);
+ return IsUpdateAvailable(fileVersionInfo.ProductVersion);
+ }
+
+ public bool IsUpdateAvailable(Version productVersion)
+ {
+ Debug.WriteLine("Release Product ver.: " + latestReleaseVersion);
+ Debug.WriteLine("Current Product ver.: " + productVersion);
+ return latestReleaseVersion.CompareTo(productVersion) > 0;
+ }
+
+ public bool IsUpdateAvailable(string productVersion)
+ {
+ GetLatestRelease(_updateParams.UsePreRelease);
+ if (Version.TryParse(productVersion, out var currentVersion))
+ {
+ return IsUpdateAvailable(currentVersion);
+ }
+ return false;
+ }
+
+ private void UnpackZip(string zipFilePath)
+ {
+ ZipFile.ExtractToDirectory(zipFilePath, Path.GetDirectoryName(zipFilePath));
+ }
+
+ private static void DownloadAsset(ReleaseAsset asset, Stream destination)
+ {
+ string downloadUrl = asset.BrowserDownloadUrl;
+ var client = new WebClient();
+ using (var serverStream = client.OpenRead(downloadUrl))
+ {
+ serverStream.CopyTo(destination);
+ }
+ }
+
+ private void GetLatestRelease(bool prerelease)
+ {
+ Release release;
+ if (prerelease)
+ {
+ var prereleaseTask = githubClient.Repository.Release.GetAll(_updateParams.RepositoryOwnerName, _updateParams.RepositoryName);
+ prereleaseTask.Wait();
+ var prereleases = prereleaseTask.Result.OrderByDescending(release => release.PublishedAt ?? release.CreatedAt).Where(release => release.Prerelease).ToArray();
+ release = latestFetchedRelease = prereleases[0];
+ }
+ else
+ {
+ var latestReleaseTask = githubClient.Repository.Release.GetLatest(_updateParams.RepositoryOwnerName, _updateParams.RepositoryName);
+ latestReleaseTask.Wait();
+ release = latestFetchedRelease = latestReleaseTask.Result;
+ }
+ var match = _updateParams.VersionMatcher.Match(release.Name);
+ if (match.Success)
+ {
+ string versionString = match.Value;
+ Version.TryParse(versionString, out latestReleaseVersion);
+ }
+ }
+
+ private void EmptyDirectory(DirectoryInfo directory)
+ {
+ string appname = Assembly.GetExecutingAssembly().GetName().Name;
+ foreach (FileInfo file in directory.GetFiles())
+ {
+ if (Path.GetFileNameWithoutExtension(file.Name) != appname && file.Name != "update.zip")
+ file.Delete();
+ }
+ foreach (DirectoryInfo subDirectory in directory.GetDirectories())
+ subDirectory.Delete(true);
+ }
+
+ public void DownloadTo(DirectoryInfo directory)
+ {
+ if (latestFetchedRelease is null)
+ GetLatestRelease(_updateParams.UsePreRelease);
+ if (latestFetchedRelease.Assets?.Count > 0)
+ {
+ var asset = latestFetchedRelease.Assets[0];
+ string zipFilePath = Path.Combine(directory.FullName, "update.zip");
+ using(var zipFileStream = File.OpenWrite(zipFilePath))
+ {
+ DownloadAsset(asset, zipFileStream);
+ }
+ Debug.WriteLine("Download Complete", category: nameof(GithubUpdateDownloader));
+ EmptyDirectory(directory);
+ UnpackZip(zipFilePath);
+ File.Delete(zipFilePath);
+ downloadDirectory = directory;
+ }
+ }
+
+ public void Launch()
+ {
+ if (downloadDirectory is null)
+ {
+ throw new ArgumentNullException("Download directory not set.");
+ }
+
+ var files = downloadDirectory.GetFiles(_updateParams.TargetExecutableName + ".exe", SearchOption.TopDirectoryOnly);
+ if (files is not null && files.Length > 0)
+ {
+ Process.Start(files[0].FullName);
+ }
+ }
+ }
+}
diff --git a/PCK-Studio-Updater/API/IUpdateDownloader.cs b/PCK-Studio-Updater/API/IUpdateDownloader.cs
new file mode 100644
index 00000000..ef422762
--- /dev/null
+++ b/PCK-Studio-Updater/API/IUpdateDownloader.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace PCKStudio_Updater
+{
+ public interface IUpdateDownloader
+ {
+ public bool IsUpdateAvailable(Version currentVersion);
+ public bool IsUpdateAvailable(string currentVersionString);
+
+ public void DownloadTo(DirectoryInfo directory);
+
+ public void Launch();
+ }
+}
diff --git a/PCK-Studio-Updater/PCK-Studio-Updater.csproj b/PCK-Studio-Updater/PCK-Studio-Updater.csproj
new file mode 100644
index 00000000..a47ab997
--- /dev/null
+++ b/PCK-Studio-Updater/PCK-Studio-Updater.csproj
@@ -0,0 +1,105 @@
+
+
+
+
+ Debug
+ AnyCPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}
+ WinExe
+ PCKStudio_Updater
+ PCK-Studio-Updater
+ latest
+ enable
+ v4.8
+ 512
+ true
+ true
+ publish\
+ true
+ Disk
+ false
+ Foreground
+ 7
+ Days
+ false
+ false
+ true
+ 0
+ 1.0.0.%2a
+ false
+ false
+ true
+
+
+ AnyCPU
+ true
+ full
+ false
+ bin\Debug\
+ DEBUG;TRACE
+ prompt
+ 4
+
+
+ AnyCPU
+ pdbonly
+ true
+ bin\Release\
+ TRACE
+ prompt
+ 4
+
+
+ PCKStudio_Updater.Program
+
+
+ ProjectLogo.ico
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 5.7.0
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+ 7.1.0
+
+
+
+
+ False
+ Microsoft .NET Framework 4.8 %28x86 and x64%29
+ true
+
+
+ False
+ .NET Framework 3.5 SP1
+ false
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PCK-Studio-Updater/Program.cs b/PCK-Studio-Updater/Program.cs
new file mode 100644
index 00000000..d150ad4c
--- /dev/null
+++ b/PCK-Studio-Updater/Program.cs
@@ -0,0 +1,58 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using System.Runtime;
+using System.Text;
+using System.Text.RegularExpressions;
+
+namespace PCKStudio_Updater
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ Uri projectUrl = new Uri("https://github.com/PhoenixARC/-PCK-Studio");
+ if (args.Length > 0)
+ {
+ projectUrl = new Uri(args[0]);
+ }
+
+ string executableName = "PCK-Studio";
+ if (args.Length > 1)
+ {
+ executableName = args[1];
+ }
+
+ bool prerelease = false;
+ if (args.Length > 2)
+ {
+ prerelease = args[2].ToLower() == "true" || args[2].ToLower() == "1";
+ }
+
+ var versionMatcher = new Regex("(\\*|\\d+(\\.\\d+){0,3}(\\.\\*)?)");
+ if (args.Length > 3)
+ {
+ versionMatcher = new Regex(args[3]);
+ }
+
+ GithubParams updateParams = new GithubParams(
+ Path.GetDirectoryName(projectUrl.AbsolutePath).Replace("\\", ""),
+ Path.GetFileName(projectUrl.AbsolutePath),
+ executableName,
+ prerelease,
+ versionMatcher
+ );
+
+ IUpdateDownloader updater = new GithubUpdateDownloader(updateParams);
+
+ if (!File.Exists(updateParams.TargetExecutableName + ".exe") || updater.IsUpdateAvailable(FileVersionInfo.GetVersionInfo(updateParams.TargetExecutableName + ".exe").ProductVersion))
+ {
+ updater.DownloadTo(new DirectoryInfo("."));
+ updater.Launch();
+ return;
+ }
+ }
+ }
+}
diff --git a/PCK-Studio-Updater/ProjectLogo.ico b/PCK-Studio-Updater/ProjectLogo.ico
new file mode 100644
index 00000000..85357f6f
Binary files /dev/null and b/PCK-Studio-Updater/ProjectLogo.ico differ
diff --git a/PCK-Studio-Updater/Properties/AssemblyInfo.cs b/PCK-Studio-Updater/Properties/AssemblyInfo.cs
new file mode 100644
index 00000000..8e714011
--- /dev/null
+++ b/PCK-Studio-Updater/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("PckStudio-Updater")]
+[assembly: AssemblyDescription("Updater for PCK-Studio")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("PckStudio-Updater")]
+[assembly: AssemblyCopyright("Copyright © 2023 Miku-666")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("5b223556-15b9-41da-aa0b-5e7f45e743bf")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/PCK-Studio-Updater/Properties/app.manifest b/PCK-Studio-Updater/Properties/app.manifest
new file mode 100644
index 00000000..c02c2d89
--- /dev/null
+++ b/PCK-Studio-Updater/Properties/app.manifest
@@ -0,0 +1,70 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/PCK-Studio/App.config b/PCK-Studio/App.config
index fff538b6..f3cb4efa 100644
--- a/PCK-Studio/App.config
+++ b/PCK-Studio/App.config
@@ -71,6 +71,12 @@
True
+
+ True
+
+
+ False
+
False
diff --git a/PCK-Studio/Classes/Misc/RichPresenceClient.cs b/PCK-Studio/Classes/Misc/RichPresenceClient.cs
index e7bef380..fdbad35f 100644
--- a/PCK-Studio/Classes/Misc/RichPresenceClient.cs
+++ b/PCK-Studio/Classes/Misc/RichPresenceClient.cs
@@ -27,7 +27,7 @@ namespace PckStudio.Classes.Misc
new Button()
{
Label = "Check it out!",
- Url = Program.ProjectUrl,
+ Url = Program.ProjectUrl.AbsoluteUri,
}
};
diff --git a/PCK-Studio/Classes/Networking/Network.cs b/PCK-Studio/Classes/Networking/Network.cs
deleted file mode 100644
index f35575ac..00000000
--- a/PCK-Studio/Classes/Networking/Network.cs
+++ /dev/null
@@ -1,59 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Net;
-using System.Windows.Forms;
-
-namespace PckStudio.Classes.Networking
-{
- [Obsolete]
- class Network
- {
- public static string Version = Application.ProductVersion;
- public static bool IsBeta = true;
- public static bool Portable = false;
- public static bool NeedsUpdate = false;
- public static Uri MainURL = new Uri(Program.BaseAPIUrl);
- public static Uri BackUpURL = new Uri(Program.BackUpAPIUrl);
- static readonly string UpdatePath = "/update/Version";
- static readonly string BetaUpdatePath = "/update/VersionBeta";
-
- public static void CheckUpdate()
- {
- using WebClient wc = new WebClient();
- try
- {
- Update.CheckForUpdate(null); // TODO
-
- Uri versionUri = new Uri(MainURL, IsBeta ? BetaUpdatePath : UpdatePath);
- Console.WriteLine(versionUri);
- string serverVersion = wc.DownloadString(versionUri);
- if (Version != serverVersion)
- {
- if (MessageBox.Show("An update is available! Do you want to update?" +
- $"\nYour Version: {Version}" +
- $"\nAvailable version: {serverVersion}", "Update Available", MessageBoxButtons.YesNo) == DialogResult.Yes)
- {
- Update.UpdateProgram(new UpdateOptions(
- isBeta: IsBeta,
- isPortable: Portable,
- baseUri: new Uri(MainURL, "/Update/Download/setup/PCKStudio-Setup.msi"),
- betaUri: new Uri(MainURL, "/Update/Download/setup/beta/PCKStudioBeta-Setup.msi")
- )
- );
- }
- else
- {
- NeedsUpdate = true;
- }
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex.Message);
- MessageBox.Show("Can't connect to the server!", "Server unavailabe");
- }
- }
-
-
- }
-}
diff --git a/PCK-Studio/Classes/Networking/Update.cs b/PCK-Studio/Classes/Networking/Update.cs
deleted file mode 100644
index 4813ae45..00000000
--- a/PCK-Studio/Classes/Networking/Update.cs
+++ /dev/null
@@ -1,88 +0,0 @@
-using System;
-using System.Diagnostics;
-using System.Threading;
-using System.IO;
-using System.Net;
-using System.Windows.Forms;
-
-namespace PckStudio.Classes.Networking
-{
- [Obsolete]
- public enum UpdateResult
- {
- // Base Failure value
- Failure = -1,
- // Base Success value
- Success,
-
- UpdateAvailable,
-
- UpdateFailure,
- }
-
- [Obsolete]
- class UpdateOptions
- {
- public bool IsBeta { get; set; }
- public bool IsPortable { get; set; }
- public string Domain
- {
- get => _baseDomain?.OriginalString ?? (_betaDomain?.OriginalString ?? throw new NullReferenceException(nameof(_betaDomain)));
- set
- {
- _ = value ?? throw new NullReferenceException(nameof(value));
- _baseDomain = new Uri(value);
- }
- }
-
- private Uri _baseDomain;
- private Uri _betaDomain;
-
- public UpdateOptions(bool isBeta, bool isPortable, Uri baseUri, Uri betaUri)
- {
- IsBeta = isBeta;
- IsPortable = isPortable;
- _baseDomain = baseUri;
- _betaDomain = betaUri;
- }
- }
-
- [Obsolete]
- static class Update
- {
- public static UpdateResult CheckForUpdate(UpdateOptions options)
- {
- // TODO: implement this
- return UpdateResult.Failure;
- }
-
- public static void UpdateProgram(UpdateOptions options)
- {
- string updateURL = options.Domain;
- if (options.IsPortable)
- {
- updateURL = updateURL.Replace(".msi","Portable.msi");
- }
-
- string downloadPath = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) + "\\Temp\\";
- string destinationURL = options.Domain;
- if (TryDownloadFile(downloadPath + Path.GetFileName(destinationURL), destinationURL))
- {
- Process.Start(downloadPath + Path.GetFileName(destinationURL));
- Application.Exit();
- }
- }
-
- static bool TryDownloadFile(string filePath, string url)
- {
- try
- {
- using (WebClient client = new WebClient())
- client.DownloadFile(url, filePath);
- return true;
- }
- catch (Exception ex) { Console.WriteLine(ex.Message); }
- return false;
- }
- }
-}
diff --git a/PCK-Studio/Forms/AppSettingsForm.Designer.cs b/PCK-Studio/Forms/AppSettingsForm.Designer.cs
index d651aef3..977513d6 100644
--- a/PCK-Studio/Forms/AppSettingsForm.Designer.cs
+++ b/PCK-Studio/Forms/AppSettingsForm.Designer.cs
@@ -36,6 +36,7 @@
this.autoLoadPckCheckBox = new MetroFramework.Controls.MetroCheckBox();
this.showPresenceCheckBox = new MetroFramework.Controls.MetroCheckBox();
this.grf_paramKeyComboBoxCheckBox = new MetroFramework.Controls.MetroCheckBox();
+ this.usePrereleaseCheckBox = new MetroFramework.Controls.MetroCheckBox();
this.SuspendLayout();
//
// autoSaveCheckBox
@@ -76,7 +77,6 @@
// autoUpdateCheckBox
//
this.autoUpdateCheckBox.AutoSize = true;
- this.autoUpdateCheckBox.Enabled = false;
this.autoUpdateCheckBox.Location = new System.Drawing.Point(23, 105);
this.autoUpdateCheckBox.Name = "autoUpdateCheckBox";
this.autoUpdateCheckBox.Size = new System.Drawing.Size(90, 15);
@@ -86,6 +86,7 @@
this.autoUpdateCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
this.SettingToolTip.SetToolTip(this.autoUpdateCheckBox, "Whether to automatically check for updates");
this.autoUpdateCheckBox.UseSelectable = true;
+ this.autoUpdateCheckBox.CheckedChanged += new System.EventHandler(this.autoUpdateCheckBox_CheckedChanged);
//
// autoLoadPckCheckBox
//
@@ -129,11 +130,26 @@
this.grf_paramKeyComboBoxCheckBox.UseSelectable = true;
this.grf_paramKeyComboBoxCheckBox.CheckedChanged += new System.EventHandler(this.grf_paramKeyComboBoxCheckBox_CheckedChanged);
//
+ // usePrereleaseCheckBox
+ //
+ this.usePrereleaseCheckBox.AutoSize = true;
+ this.usePrereleaseCheckBox.Location = new System.Drawing.Point(119, 105);
+ this.usePrereleaseCheckBox.Name = "usePrereleaseCheckBox";
+ this.usePrereleaseCheckBox.Size = new System.Drawing.Size(98, 15);
+ this.usePrereleaseCheckBox.Style = MetroFramework.MetroColorStyle.White;
+ this.usePrereleaseCheckBox.TabIndex = 6;
+ this.usePrereleaseCheckBox.Text = "Use Beta Build";
+ this.usePrereleaseCheckBox.Theme = MetroFramework.MetroThemeStyle.Dark;
+ this.SettingToolTip.SetToolTip(this.usePrereleaseCheckBox, "Whether to automatically check for updates");
+ this.usePrereleaseCheckBox.UseSelectable = true;
+ this.usePrereleaseCheckBox.Visible = false;
+ //
// AppSettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(527, 270);
+ this.Controls.Add(this.usePrereleaseCheckBox);
this.Controls.Add(this.grf_paramKeyComboBoxCheckBox);
this.Controls.Add(this.showPresenceCheckBox);
this.Controls.Add(this.autoLoadPckCheckBox);
@@ -164,5 +180,6 @@
private MetroFramework.Controls.MetroCheckBox autoLoadPckCheckBox;
private MetroFramework.Controls.MetroCheckBox showPresenceCheckBox;
private MetroFramework.Controls.MetroCheckBox grf_paramKeyComboBoxCheckBox;
+ private MetroFramework.Controls.MetroCheckBox usePrereleaseCheckBox;
}
}
\ No newline at end of file
diff --git a/PCK-Studio/Forms/AppSettingsForm.cs b/PCK-Studio/Forms/AppSettingsForm.cs
index 71725fb0..b62445a0 100644
--- a/PCK-Studio/Forms/AppSettingsForm.cs
+++ b/PCK-Studio/Forms/AppSettingsForm.cs
@@ -40,11 +40,21 @@ namespace PckStudio.Forms
Settings.Default.ShowRichPresence = showPresenceCheckBox.Checked;
}
+ private void autoUpdateCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ usePrereleaseCheckBox.Visible = Settings.Default.AutoUpdate = autoUpdateCheckBox.Checked;
+ }
+
private void grf_paramKeyComboBoxCheckBox_CheckedChanged(object sender, EventArgs e)
{
Settings.Default.UseComboBoxForGRFParameter = grf_paramKeyComboBoxCheckBox.Checked;
}
+ private void usePrereleaseCheckBox_CheckedChanged(object sender, EventArgs e)
+ {
+ Settings.Default.UsePrerelease = usePrereleaseCheckBox.Checked;
+ }
+
private void LoadCheckboxState(CheckBox checkBox, EventHandler eventHandler, bool state)
{
checkBox.CheckedChanged -= eventHandler;
@@ -58,6 +68,8 @@ namespace PckStudio.Forms
LoadCheckboxState(endianCheckBox, endianCheckBox_CheckedChanged, Settings.Default.UseLittleEndianAsDefault);
LoadCheckboxState(autoLoadPckCheckBox, autoLoadPckCheckBox_CheckedChanged, Settings.Default.LoadSubPcks);
LoadCheckboxState(showPresenceCheckBox, showPresenceCheckBox_CheckedChanged, Settings.Default.ShowRichPresence);
+ LoadCheckboxState(autoUpdateCheckBox, autoUpdateCheckBox_CheckedChanged, Settings.Default.AutoUpdate);
+ LoadCheckboxState(usePrereleaseCheckBox, usePrereleaseCheckBox_CheckedChanged, Settings.Default.UsePrerelease);
LoadCheckboxState(grf_paramKeyComboBoxCheckBox, grf_paramKeyComboBoxCheckBox_CheckedChanged, Settings.Default.UseComboBoxForGRFParameter);
}
diff --git a/PCK-Studio/Forms/Skins-And-Textures/generateModel.resx b/PCK-Studio/Forms/Skins-And-Textures/generateModel.resx
index 6db730f5..f3549bdb 100644
--- a/PCK-Studio/Forms/Skins-And-Textures/generateModel.resx
+++ b/PCK-Studio/Forms/Skins-And-Textures/generateModel.resx
@@ -1442,7 +1442,7 @@
AAEAAAD/////AQAAAAAAAAAMAgAAAElPcGVuVEssIFZlcnNpb249My4zLjMuMCwgQ3VsdHVyZT1uZXV0
cmFsLCBQdWJsaWNLZXlUb2tlbj1iYWQxOTlmZTg0ZWIzZGY0BQEAAAAOT3BlblRLLlZlY3RvcjICAAAA
AVgBWQAACwsCAAAAAAAAAAAAAAAL
-
+
diff --git a/PCK-Studio/MainForm.Designer.cs b/PCK-Studio/MainForm.Designer.cs
index 5a9e5a79..84c5d271 100644
--- a/PCK-Studio/MainForm.Designer.cs
+++ b/PCK-Studio/MainForm.Designer.cs
@@ -33,6 +33,7 @@
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
+ toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.contextMenuPCKEntries = new System.Windows.Forms.ContextMenuStrip(this.components);
this.createToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.folderToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -99,6 +100,7 @@
this.joinDevelopmentDiscordToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.trelloBoardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.helpToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
+ this.checkForUpdatesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.aboutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.videosToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.howToMakeABasicSkinPackToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@@ -147,7 +149,6 @@
this.skinRenderer3DToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
logoPictureBox = new System.Windows.Forms.PictureBox();
toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
- toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
((System.ComponentModel.ISupportInitialize)(logoPictureBox)).BeginInit();
this.contextMenuPCKEntries.SuspendLayout();
this.menuStrip.SuspendLayout();
@@ -640,6 +641,7 @@
// helpToolStripMenuItem
//
this.helpToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.checkForUpdatesToolStripMenuItem,
this.aboutToolStripMenuItem,
toolStripSeparator1,
this.videosToolStripMenuItem,
@@ -650,6 +652,12 @@
this.helpToolStripMenuItem.Name = "helpToolStripMenuItem";
resources.ApplyResources(this.helpToolStripMenuItem, "helpToolStripMenuItem");
//
+ // checkForUpdatesToolStripMenuItem
+ //
+ this.checkForUpdatesToolStripMenuItem.Name = "checkForUpdatesToolStripMenuItem";
+ resources.ApplyResources(this.checkForUpdatesToolStripMenuItem, "checkForUpdatesToolStripMenuItem");
+ this.checkForUpdatesToolStripMenuItem.Click += new System.EventHandler(this.checkForUpdatesToolStripMenuItem_Click);
+ //
// aboutToolStripMenuItem
//
resources.ApplyResources(this.aboutToolStripMenuItem, "aboutToolStripMenuItem");
@@ -1241,6 +1249,7 @@
private System.Windows.Forms.ToolStripMenuItem toPhoenixARCDeveloperToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem forMattNLContributorToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem settingsToolStripMenuItem;
+ private System.Windows.Forms.ToolStripMenuItem checkForUpdatesToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem skinRenderer3DToolStripMenuItem;
}
}
diff --git a/PCK-Studio/MainForm.cs b/PCK-Studio/MainForm.cs
index 14806253..1e974d40 100644
--- a/PCK-Studio/MainForm.cs
+++ b/PCK-Studio/MainForm.cs
@@ -32,10 +32,11 @@ using PckStudio.Extensions;
using PckStudio.Popups;
using PckStudio.Classes.Utils;
using PckStudio.Helper;
+using PCKStudio_Updater;
namespace PckStudio
{
- public partial class MainForm : MetroFramework.Forms.MetroForm
+ public partial class MainForm : MetroFramework.Forms.MetroForm
{
private PckManager PckManager = null;
string saveLocation = string.Empty;
@@ -51,45 +52,45 @@ namespace PckStudio
{
InitializeComponent();
- skinToolStripMenuItem1.Click += (sender, e) => SetFileType(PckFileType.SkinFile);
- capeToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.CapeFile);
- textureToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.TextureFile);
- languagesFileLOCToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.LocalisationFile);
- gameRulesFileGRFToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.GameRulesFile);
- audioPCKFileToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.AudioFile);
- coloursCOLFileToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.ColourTableFile);
- gameRulesHeaderGRHToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.GameRulesHeader);
- skinsPCKToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.SkinDataFile);
- modelsFileBINToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.ModelsFile);
- behavioursFileBINToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.BehavioursFile);
- entityMaterialsFileBINToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.MaterialFile);
+ skinToolStripMenuItem1.Click += (sender, e) => SetFileType(PckFileType.SkinFile);
+ capeToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.CapeFile);
+ textureToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.TextureFile);
+ languagesFileLOCToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.LocalisationFile);
+ gameRulesFileGRFToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.GameRulesFile);
+ audioPCKFileToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.AudioFile);
+ coloursCOLFileToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.ColourTableFile);
+ gameRulesHeaderGRHToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.GameRulesHeader);
+ skinsPCKToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.SkinDataFile);
+ modelsFileBINToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.ModelsFile);
+ behavioursFileBINToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.BehavioursFile);
+ entityMaterialsFileBINToolStripMenuItem.Click += (sender, e) => SetFileType(PckFileType.MaterialFile);
- treeViewMain.TreeViewNodeSorter = new PckNodeSorter();
+ treeViewMain.TreeViewNodeSorter = new PckNodeSorter();
pckOpen.AllowDrop = true;
Text = Application.ProductName;
- labelVersion.Text = $"{Application.ProductName}: {Application.ProductVersion}";
+ labelVersion.Text = $"{Application.ProductName}: {Application.ProductVersion}";
ChangelogRichTextBox.Text = Resources.CHANGELOG;
- pckFileTypeHandler = new Dictionary>(15)
+ pckFileTypeHandler = new Dictionary>(15)
{
- [PckFileType.SkinFile] = HandleSkinFile,
- [PckFileType.CapeFile] = null,
- [PckFileType.TextureFile] = HandleTextureFile,
- [PckFileType.UIDataFile] = _ => throw new NotSupportedException("unused in-game"),
- [PckFileType.InfoFile] = null,
+ [PckFileType.SkinFile] = HandleSkinFile,
+ [PckFileType.CapeFile] = null,
+ [PckFileType.TextureFile] = HandleTextureFile,
+ [PckFileType.UIDataFile] = _ => throw new NotSupportedException("unused in-game"),
+ [PckFileType.InfoFile] = null,
[PckFileType.TexturePackInfoFile] = null,
- [PckFileType.LocalisationFile] = HandleLocalisationFile,
- [PckFileType.GameRulesFile] = HandleGameRuleFile,
- [PckFileType.AudioFile] = HandleAudioFile,
- [PckFileType.ColourTableFile] = HandleColourFile,
- [PckFileType.GameRulesHeader] = HandleGameRuleFile,
- [PckFileType.SkinDataFile] = null,
- [PckFileType.ModelsFile] = HandleModelsFile,
- [PckFileType.BehavioursFile] = HandleBehavioursFile,
- [PckFileType.MaterialFile] = HandleMaterialFile,
+ [PckFileType.LocalisationFile] = HandleLocalisationFile,
+ [PckFileType.GameRulesFile] = HandleGameRuleFile,
+ [PckFileType.AudioFile] = HandleAudioFile,
+ [PckFileType.ColourTableFile] = HandleColourFile,
+ [PckFileType.GameRulesHeader] = HandleGameRuleFile,
+ [PckFileType.SkinDataFile] = null,
+ [PckFileType.ModelsFile] = HandleModelsFile,
+ [PckFileType.BehavioursFile] = HandleBehavioursFile,
+ [PckFileType.MaterialFile] = HandleMaterialFile,
};
}
@@ -98,7 +99,7 @@ namespace PckStudio
checkSaveState();
treeViewMain.Nodes.Clear();
currentPCK = openPck(filepath);
- if (currentPCK == null)
+ if (currentPCK == null)
{
MessageBox.Show(string.Format("Failed to load {0}", Path.GetFileName(filepath)), "Error");
return;
@@ -112,8 +113,8 @@ namespace PckStudio
{
SettingsManager.RegisterPropertyChangedCallback(nameof(Settings.Default.UseLittleEndianAsDefault), state =>
{
- LittleEndianCheckBox.Checked = state;
- });
+ LittleEndianCheckBox.Checked = state;
+ });
SettingsManager.RegisterPropertyChangedCallback(nameof(Settings.Default.LoadSubPcks), () =>
{
if (currentPCK is not null)
@@ -122,32 +123,32 @@ namespace PckStudio
}
});
- imageList.Images.Add(Resources.ZZFolder); // Icon for folders
- imageList.Images.Add(Resources.BINKA_ICON); // Icon for music cue file (audio.pck)
- imageList.Images.Add(Resources.IMAGE_ICON); // Icon for images (unused for now)
- imageList.Images.Add(Resources.LOC_ICON); // Icon for string localization files (languages.loc;localisation.loc)
- imageList.Images.Add(Resources.PCK_ICON); // Icon for generic PCK files (*.pck)
- imageList.Images.Add(Resources.ZUnknown); // Icon for Unknown formats
- imageList.Images.Add(Resources.COL_ICON); // Icon for color palette files (colours.col)
- imageList.Images.Add(Resources.SKINS_ICON); // Icon for Skin.pck archives (skins.pck)
- imageList.Images.Add(Resources.MODELS_ICON); // Icon for Model files (models.bin)
- imageList.Images.Add(Resources.GRF_ICON); // Icon for Game Rule files (*.grf)
- imageList.Images.Add(Resources.GRH_ICON); // Icon for Game Rule Header files (*.grh)
- imageList.Images.Add(Resources.INFO_ICON); // Icon for Info files (0)
- imageList.Images.Add(Resources.SKIN_ICON); // Icon for Skin files (*.png)
- imageList.Images.Add(Resources.CAPE_ICON); // Icon for Cape files (*.png)
- imageList.Images.Add(Resources.TEXTURE_ICON); // Icon for Texture files (*.png;*.tga)
- imageList.Images.Add(Resources.BEHAVIOURS_ICON); // Icon for Behaviour files (behaviours.bin)
- imageList.Images.Add(Resources.ENTITY_MATERIALS_ICON); // Icon for Entity Material files (entityMaterials.bin)
+ imageList.Images.Add(Resources.ZZFolder); // Icon for folders
+ imageList.Images.Add(Resources.BINKA_ICON); // Icon for music cue file (audio.pck)
+ imageList.Images.Add(Resources.IMAGE_ICON); // Icon for images (unused for now)
+ imageList.Images.Add(Resources.LOC_ICON); // Icon for string localization files (languages.loc;localisation.loc)
+ imageList.Images.Add(Resources.PCK_ICON); // Icon for generic PCK files (*.pck)
+ imageList.Images.Add(Resources.ZUnknown); // Icon for Unknown formats
+ imageList.Images.Add(Resources.COL_ICON); // Icon for color palette files (colours.col)
+ imageList.Images.Add(Resources.SKINS_ICON); // Icon for Skin.pck archives (skins.pck)
+ imageList.Images.Add(Resources.MODELS_ICON); // Icon for Model files (models.bin)
+ imageList.Images.Add(Resources.GRF_ICON); // Icon for Game Rule files (*.grf)
+ imageList.Images.Add(Resources.GRH_ICON); // Icon for Game Rule Header files (*.grh)
+ imageList.Images.Add(Resources.INFO_ICON); // Icon for Info files (0)
+ imageList.Images.Add(Resources.SKIN_ICON); // Icon for Skin files (*.png)
+ imageList.Images.Add(Resources.CAPE_ICON); // Icon for Cape files (*.png)
+ imageList.Images.Add(Resources.TEXTURE_ICON); // Icon for Texture files (*.png;*.tga)
+ imageList.Images.Add(Resources.BEHAVIOURS_ICON); // Icon for Behaviour files (behaviours.bin)
+ imageList.Images.Add(Resources.ENTITY_MATERIALS_ICON); // Icon for Entity Material files (entityMaterials.bin)
- isSelectingTab = true;
- tabControl.SelectTab(0);
- isSelectingTab = false;
+ isSelectingTab = true;
+ tabControl.SelectTab(0);
+ isSelectingTab = false;
- UpdateRichPresence();
+ UpdateRichPresence();
}
- private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
+ private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
PckManager?.Close();
checkSaveState();
@@ -222,7 +223,7 @@ namespace PckStudio
isSelectingTab = true;
tabControl.SelectTab(1);
isSelectingTab = false;
- UpdateRichPresence();
+ UpdateRichPresence();
}
private void CloseEditorTab()
@@ -243,35 +244,35 @@ namespace PckStudio
saveToolStripMenuItem1.Enabled = false;
quickChangeToolStripMenuItem.Enabled = false;
closeToolStripMenuItem.Visible = false;
- packSettingsToolStripMenuItem.Visible = false;
- convertToBedrockToolStripMenuItem.Enabled = false;
+ packSettingsToolStripMenuItem.Visible = false;
+ convertToBedrockToolStripMenuItem.Enabled = false;
addCustomPackImageToolStripMenuItem.Enabled = false;
fileEntryCountLabel.Text = string.Empty;
pckFileLabel.Text = string.Empty;
UpdateRichPresence();
}
- private void UpdateRichPresence()
- {
- if (currentPCK is not null &&
- TryGetLocFile(out LOCFile locfile) &&
- locfile.HasLocEntry("IDS_DISPLAY_NAME") &&
- locfile.Languages.Contains("en-EN"))
- {
- RPC.SetPresence($"Editing a Pack: {locfile.GetLocEntry("IDS_DISPLAY_NAME", "en-EN")}");
- return;
- }
- // default
- RPC.SetPresence("An Open Source .PCK File Editor");
- }
+ private void UpdateRichPresence()
+ {
+ if (currentPCK is not null &&
+ TryGetLocFile(out LOCFile locfile) &&
+ locfile.HasLocEntry("IDS_DISPLAY_NAME") &&
+ locfile.Languages.Contains("en-EN"))
+ {
+ RPC.SetPresence($"Editing a Pack: {locfile.GetLocEntry("IDS_DISPLAY_NAME", "en-EN")}");
+ return;
+ }
+ // default
+ RPC.SetPresence("An Open Source .PCK File Editor");
+ }
- ///
- /// wrapper that allows the use of in TreeNode.Nodes.Find(, ...) and TreeNode.Nodes.ContainsKey()
- ///
- ///
- ///
- /// new Created TreeNode
- public static TreeNode CreateNode(string name, object tag = null)
+ ///
+ /// wrapper that allows the use of in TreeNode.Nodes.Find(, ...) and TreeNode.Nodes.ContainsKey()
+ ///
+ ///
+ ///
+ /// new Created TreeNode
+ public static TreeNode CreateNode(string name, object tag = null)
{
TreeNode node = new TreeNode(name);
node.Name = name;
@@ -307,25 +308,25 @@ namespace PckStudio
node.Tag = file;
if (Settings.Default.LoadSubPcks &&
(file.Filetype == PckFileType.SkinDataFile || file.Filetype == PckFileType.TexturePackInfoFile) &&
- file.Size > 0)
+ file.Size > 0)
{
- using (var stream = new MemoryStream(file.Data))
+ using (var stream = new MemoryStream(file.Data))
+ {
+ try
{
- try
- {
- var reader = new PckFileReader(LittleEndianCheckBox.Checked ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian);
- PckFile subPCKfile = reader.FromStream(stream);
- // passes parent path to remove from sub pck filepaths
- BuildPckTreeView(node.Nodes, subPCKfile, file.Filename + "/");
- }
- catch (OverflowException ex)
- {
- MessageBox.Show("Failed to open pck\n" +
- "Try checking the 'Open/Save as Switch/Vita/PS4 pck' checkbox in the upper right corner.",
- "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
- Debug.WriteLine(ex.Message);
- }
+ var reader = new PckFileReader(LittleEndianCheckBox.Checked ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian);
+ PckFile subPCKfile = reader.FromStream(stream);
+ // passes parent path to remove from sub pck filepaths
+ BuildPckTreeView(node.Nodes, subPCKfile, file.Filename + "/");
}
+ catch (OverflowException ex)
+ {
+ MessageBox.Show("Failed to open pck\n" +
+ "Try checking the 'Open/Save as Switch/Vita/PS4 pck' checkbox in the upper right corner.",
+ "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
+ Debug.WriteLine(ex.Message);
+ }
+ }
}
SetNodeIcon(node, file.Filetype);
};
@@ -352,10 +353,10 @@ namespace PckStudio
treeViewMain.Sort();
TreeNode[] selectedNodes;
- if (!string.IsNullOrEmpty(selectedNodeText) &&
+ if (!string.IsNullOrEmpty(selectedNodeText) &&
(selectedNodes = treeViewMain.Nodes.Find(selectedNodeText, true)).Length > 0)
{
- treeViewMain.SelectedNode = selectedNodes[0];
+ treeViewMain.SelectedNode = selectedNodes[0];
}
}
@@ -373,8 +374,8 @@ namespace PckStudio
{
var img = file.GetTexture();
var res = img.Width / 16; // texture count on X axes
- var size = new Size(res, res);
- var viewer = new TextureAtlasEditor(currentPCK, file.Filename, img, size);
+ var size = new Size(res, res);
+ var viewer = new TextureAtlasEditor(currentPCK, file.Filename, img, size);
if (viewer.ShowDialog() == DialogResult.OK)
{
file.SetData(viewer.FinalTexture, ImageFormat.Png);
@@ -437,17 +438,17 @@ namespace PckStudio
}
return;
}
-
+
var img = file.GetTexture();
using var skinViewer = new SkinPreview(img, file.Properties.GetPropertyValue("ANIM", SkinANIM.FromString));
- skinViewer.ShowDialog(this);
- }
+ skinViewer.ShowDialog(this);
+ }
public void HandleModelsFile(PckFileData file)
{
MessageBox.Show("Models.bin support has not been implemented. You can use the Spark Editor for the time being to edit these files.", "Not implemented yet.");
}
-
+
public void HandleBehavioursFile(PckFileData file)
{
using BehaviourEditor edit = new BehaviourEditor(file);
@@ -459,7 +460,7 @@ namespace PckStudio
using MaterialsEditor edit = new MaterialsEditor(file);
wasModified = edit.ShowDialog(this) == DialogResult.OK;
}
-
+
private void selectNode(object sender, TreeViewEventArgs e)
{
ReloadMetaTreeView();
@@ -499,7 +500,7 @@ namespace PckStudio
img = new Bitmap(img);
}
- try
+ try
{
previewPictureBox.Image = img;
labelImageSize.Text = $"{previewPictureBox.Image.Size.Width}x{previewPictureBox.Image.Size.Height}";
@@ -567,7 +568,7 @@ namespace PckStudio
File.WriteAllBytes(extractFilePath, file.Data);
if (file.Properties.Count > 0)
{
- using var fs = File.CreateText($"{extractFilePath}.txt");
+ using var fs = File.CreateText($"{extractFilePath}.txt");
file.Properties.ForEach(property => fs.WriteLine($"{property.Key}: {property.Value}"));
}
// Verification that file extraction path was successful
@@ -682,29 +683,29 @@ namespace PckStudio
/// True if the remove should be canceled, otherwise False
private bool BeforeFileRemove(PckFileData file)
{
- string itemPath = "res/textures/items/";
+ string itemPath = "res/textures/items/";
- // warn the user about deleting compass.png and clock.png
- if (file.Filetype == PckFileType.TextureFile &&
- (file.Filename == itemPath + "compass.png" || file.Filename == itemPath + "clock.png"))
- {
- if (MessageBox.Show("Are you sure want to delete this file? If \"compass.png\" or \"clock.png\" are missing, your game will crash upon loading this pack.", "Warning",
+ // warn the user about deleting compass.png and clock.png
+ if (file.Filetype == PckFileType.TextureFile &&
+ (file.Filename == itemPath + "compass.png" || file.Filename == itemPath + "clock.png"))
+ {
+ if (MessageBox.Show("Are you sure want to delete this file? If \"compass.png\" or \"clock.png\" are missing, your game will crash upon loading this pack.", "Warning",
MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
return true;
- }
+ }
- // remove loc key if its a skin/cape
- if (file.Filetype == PckFileType.SkinFile || file.Filetype == PckFileType.CapeFile)
- {
- if (TryGetLocFile(out LOCFile locFile))
- {
+ // remove loc key if its a skin/cape
+ if (file.Filetype == PckFileType.SkinFile || file.Filetype == PckFileType.CapeFile)
+ {
+ if (TryGetLocFile(out LOCFile locFile))
+ {
locFile.RemoveLocKey(file.Properties.GetPropertyValue("THEMENAMEID"));
locFile.RemoveLocKey(file.Properties.GetPropertyValue("DISPLAYNAMEID"));
- TrySetLocFile(locFile);
- }
- }
+ TrySetLocFile(locFile);
+ }
+ }
return false;
- }
+ }
private void deleteFileToolStripMenuItem_Click(object sender, EventArgs e)
{
@@ -716,7 +717,7 @@ namespace PckStudio
if (node.TryGetTagData(out PckFileData file))
{
- if (!BeforeFileRemove(file) && currentPCK.RemoveFile(file))
+ if (!BeforeFileRemove(file) && currentPCK.RemoveFile(file))
{
node.Remove();
wasModified = true;
@@ -824,7 +825,7 @@ namespace PckStudio
audioPck.AddCategory(PckAudioFile.AudioCategory.EAudioType.Nether);
audioPck.AddCategory(PckAudioFile.AudioCategory.EAudioType.End);
PckFileData pckFileData = new PckFileData("audio.pck", PckFileType.AudioFile);
- pckFileData.SetData(new PckAudioFileWriter(audioPck, isLittle ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian));
+ pckFileData.SetData(new PckAudioFileWriter(audioPck, isLittle ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian));
return pckFileData;
}
@@ -844,7 +845,7 @@ namespace PckStudio
var file = CreateNewAudioFile(LittleEndianCheckBox.Checked);
AudioEditor diag = new AudioEditor(file, LittleEndianCheckBox.Checked);
- if(diag.ShowDialog(this) == DialogResult.OK)
+ if (diag.ShowDialog(this) == DialogResult.OK)
{
currentPCK.AddFile(file);
}
@@ -875,7 +876,7 @@ namespace PckStudio
{
wasModified = true;
AnimationHelper.SaveAnimationToFile(file, animation);
- currentPCK.AddFile(file);
+ currentPCK.AddFile(file);
BuildMainTreeView();
ReloadMetaTreeView();
}
@@ -898,7 +899,7 @@ namespace PckStudio
List GetAllChildNodes(TreeNodeCollection root)
{
List childNodes = new List();
- foreach(TreeNode node in root)
+ foreach (TreeNode node in root)
{
childNodes.Add(node);
if (node.Nodes.Count > 0)
@@ -914,7 +915,7 @@ namespace PckStudio
string parentPath = childPath.Replace('\\', '/');
Debug.WriteLine(parentPath);
string[] s = parentPath.Split('/');
- Debug.WriteLine(s.Length);
+ Debug.WriteLine(s.Length);
foreach (var node in s)
{
TreeNode parent = treeViewMain.Nodes.Find(node, true)[0];
@@ -931,16 +932,16 @@ namespace PckStudio
{
// Support for if a file is edited within a nested PCK File (AKA SubPCK)
- if(!IsSubPCKNode(childPath)) return;
+ if (!IsSubPCKNode(childPath)) return;
TreeNode parent = GetSubPCK(childPath);
- Debug.WriteLine(parent.Name);
+ Debug.WriteLine(parent.Name);
if (parent == null) return;
PckFileData parent_file = parent.Tag as PckFileData;
if (parent_file.Filetype is PckFileType.TexturePackInfoFile || parent_file.Filetype is PckFileType.SkinDataFile)
{
- Debug.WriteLine("Rebuilding " + parent_file.Filename);
+ Debug.WriteLine("Rebuilding " + parent_file.Filename);
PckFile newPCKFile = new PckFile(3, parent_file.Filetype is PckFileType.SkinDataFile);
foreach (TreeNode node in GetAllChildNodes(parent.Nodes))
@@ -964,12 +965,12 @@ namespace PckStudio
{
if (treeViewMain.SelectedNode.TryGetTagData(out PckFileData file))
{
- if (file.Size <= 0)
- {
- Trace.WriteLine($"'{file.Filename}' has no data attached.", category: nameof(treeViewMain_DoubleClick));
- return;
- }
- pckFileTypeHandler[file.Filetype]?.Invoke(file);
+ if (file.Size <= 0)
+ {
+ Trace.WriteLine($"'{file.Filename}' has no data attached.", category: nameof(treeViewMain_DoubleClick));
+ return;
+ }
+ pckFileTypeHandler[file.Filetype]?.Invoke(file);
}
}
@@ -1080,9 +1081,9 @@ namespace PckStudio
if (GetAllChildNodes(treeViewMain.Nodes).Find(n => n.FullPath == diag.NewText) != null)
{
MessageBox.Show(
- this,
+ this,
$"A file with the path \"{diag.NewText}\" already exists. " +
- $"Please try again with a different name.",
+ $"Please try again with a different name.",
"Key already exists");
return;
}
@@ -1119,7 +1120,7 @@ namespace PckStudio
foreach (var property in file.Properties)
{
treeMeta.Nodes.Add(CreateNode(property.Key, property));
- }
+ }
}
}
@@ -1173,7 +1174,7 @@ namespace PckStudio
private PckFile InitializePack(int packId, int packVersion, string packName, bool createSkinsPCK)
{
var pack = new PckFile(3);
-
+
var zeroFile = pack.CreateNewFile("0", PckFileType.InfoFile);
zeroFile.Properties.Add("PACKID", packId.ToString());
zeroFile.Properties.Add("PACKVERSION", packVersion.ToString());
@@ -1186,7 +1187,7 @@ namespace PckStudio
LittleEndianCheckBox.Checked
? OMI.Endianness.LittleEndian
: OMI.Endianness.BigEndian));
-
+
return pack;
}
@@ -1231,9 +1232,9 @@ namespace PckStudio
new KeyValuePair("spawnY", "0"),
new KeyValuePair("spawnZ", "0")
);
-
+
gameRuleFile.SetData(new GameRuleFileWriter(grfFile));
-
+
return pack;
}
@@ -1357,7 +1358,7 @@ namespace PckStudio
FileInfo fileinfo = new FileInfo(filepath);
fileinfo.Directory.Create();
File.WriteAllBytes(filepath, file.Data); // writes data to file
- //attempts to generate reimportable metadata file out of minefiles metadata
+ //attempts to generate reimportable metadata file out of minefiles metadata
string metaData = "";
foreach (var entry in file.Properties)
@@ -1433,7 +1434,7 @@ namespace PckStudio
if (File.Exists(fullfilename + ".txt"))
{
- string[] properties = File.ReadAllText(fullfilename + ".txt").Split(new string[]{ Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
+ string[] properties = File.ReadAllText(fullfilename + ".txt").Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (string property in properties)
{
string[] param = property.Split(':');
@@ -1588,7 +1589,7 @@ namespace PckStudio
private void folderToolStripMenuItem_Click(object sender, EventArgs e)
{
TextPrompt folderNamePrompt = new TextPrompt();
- if(treeViewMain.SelectedNode is not null) folderNamePrompt.contextLabel.Text = $"New folder at the location of \"{treeViewMain.SelectedNode.FullPath}\"";
+ if (treeViewMain.SelectedNode is not null) folderNamePrompt.contextLabel.Text = $"New folder at the location of \"{treeViewMain.SelectedNode.FullPath}\"";
folderNamePrompt.OKButtonText = "Add";
if (folderNamePrompt.ShowDialog() == DialogResult.OK)
{
@@ -1619,9 +1620,9 @@ namespace PckStudio
MessageBox.Show("This feature is currently being reworked.", "Currently unavailable", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
- private void openPckCenterToolStripMenuItem_Click(object sender, EventArgs e)
+ private void openPckCenterToolStripMenuItem_Click(object sender, EventArgs e)
{
- MessageBox.Show("This feature is currently being reworked.", "Currently unavailable", MessageBoxButtons.OK, MessageBoxIcon.Information);
+ MessageBox.Show("This feature is currently being reworked.", "Currently unavailable", MessageBoxButtons.OK, MessageBoxIcon.Information);
#if false
DateTime Begin = DateTime.Now;
//pckCenter open = new pckCenter();
@@ -1703,14 +1704,14 @@ namespace PckStudio
if (currentPCK is not null &&
wasModified &&
MessageBox.Show("Save PCK?", "Unsaved PCK", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
+ {
+ if (isTemplateFile || string.IsNullOrEmpty(saveLocation))
{
- if (isTemplateFile || string.IsNullOrEmpty(saveLocation))
- {
- SaveTemplate();
- return;
- }
- Save(saveLocation);
+ SaveTemplate();
+ return;
}
+ Save(saveLocation);
+ }
}
private void OpenPck_DragEnter(object sender, DragEventArgs e)
@@ -1892,15 +1893,15 @@ namespace PckStudio
{
string mippedPath = $"{textureDirectory}/{textureName}MipMapLevel{i}{textureExtension}";
Debug.WriteLine(mippedPath);
- if (currentPCK.HasFile(mippedPath, PckFileType.TextureFile))
+ if (currentPCK.HasFile(mippedPath, PckFileType.TextureFile))
currentPCK.RemoveFile(currentPCK.GetFile(mippedPath, PckFileType.TextureFile));
PckFileData MipMappedFile = new PckFileData(mippedPath, PckFileType.TextureFile);
Image originalTexture = Image.FromStream(new MemoryStream(file.Data));
- int NewWidth = Math.Max(originalTexture.Width / (int)Math.Pow(2,i - 1), 1);
+ int NewWidth = Math.Max(originalTexture.Width / (int)Math.Pow(2, i - 1), 1);
int NewHeight = Math.Max(originalTexture.Height / (int)Math.Pow(2, i - 1), 1);
-
+
Rectangle tileArea = new Rectangle(0, 0, NewWidth, NewHeight);
Image mippedTexture = new Bitmap(NewWidth, NewHeight);
using (Graphics gfx = Graphics.FromImage(mippedTexture))
@@ -1910,7 +1911,7 @@ namespace PckStudio
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(originalTexture, tileArea);
}
-
+
MipMappedFile.SetData(mippedTexture, ImageFormat.Png);
currentPCK.InsertFile(currentPCK.IndexOfFile(file) + i - 1, MipMappedFile);
@@ -1985,9 +1986,9 @@ namespace PckStudio
if (treeViewMain.SelectedNode.TryGetTagData(out PckFileData file) &&
file.Filetype == PckFileType.SkinFile)
{
- foreach(var p in file.Properties.FindAll(s => s.Key == "BOX" || s.Key == "OFFSET"))
+ foreach (var p in file.Properties.FindAll(s => s.Key == "BOX" || s.Key == "OFFSET"))
{
- file.Properties[file.Properties.IndexOf(p)] = new KeyValuePair(p.Key, p.Value.Replace(',','.'));
+ file.Properties[file.Properties.IndexOf(p)] = new KeyValuePair(p.Key, p.Value.Replace(',', '.'));
}
ReloadMetaTreeView();
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
@@ -2007,9 +2008,9 @@ namespace PckStudio
if (currentPCK is not null)
{
- DialogResult prompt = MessageBox.Show(this,
- "Would you like to use the current PackID? You can enter any PackID if not.",
- "",
+ DialogResult prompt = MessageBox.Show(this,
+ "Would you like to use the current PackID? You can enter any PackID if not.",
+ "",
MessageBoxButtons.YesNoCancel);
switch (prompt)
@@ -2018,9 +2019,9 @@ namespace PckStudio
if (!currentPCK.TryGetFile("0", PckFileType.InfoFile, out PckFileData file) ||
string.IsNullOrEmpty(file.Properties.GetPropertyValue("PACKID")))
{
- MessageBox.Show(this,
+ MessageBox.Show(this,
"No PackID is present in this PCK. " +
- "To avoid this error, ensure that the PCK has a proper PackID property on the \"0\" Info file before trying again.",
+ "To avoid this error, ensure that the PCK has a proper PackID property on the \"0\" Info file before trying again.",
"Operation Aborted", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
@@ -2191,21 +2192,21 @@ namespace PckStudio
if (!PckManager.Visible)
{
PckManager.Show();
- PckManager.BringToFront();
- }
+ PckManager.BringToFront();
+ }
if (PckManager.Focus())
PckManager.BringToFront();
}
private void wavBinkaToolStripMenuItem_Click(object sender, EventArgs e)
{
- using OpenFileDialog fileDialog = new OpenFileDialog
- {
- Multiselect = true,
- Filter = "WAV files (*.wav)|*.wav",
- Title = "Please choose WAV files to convert to BINKA"
- };
- if (fileDialog.ShowDialog() == DialogResult.OK)
+ using OpenFileDialog fileDialog = new OpenFileDialog
+ {
+ Multiselect = true,
+ Filter = "WAV files (*.wav)|*.wav",
+ Title = "Please choose WAV files to convert to BINKA"
+ };
+ if (fileDialog.ShowDialog() == DialogResult.OK)
{
BinkaConverter.ToBinka(fileDialog.FileNames, new DirectoryInfo(Path.GetDirectoryName(fileDialog.FileName)));
}
@@ -2213,32 +2214,32 @@ namespace PckStudio
private void binkaWavToolStripMenuItem_Click(object sender, EventArgs e)
{
- using OpenFileDialog fileDialog = new OpenFileDialog
- {
- Multiselect = true,
- Filter = "BINKA files (*.binka)|*.binka",
- Title = "Please choose BINKA files to convert to WAV"
- };
- if (fileDialog.ShowDialog() == DialogResult.OK)
+ using OpenFileDialog fileDialog = new OpenFileDialog
+ {
+ Multiselect = true,
+ Filter = "BINKA files (*.binka)|*.binka",
+ Title = "Please choose BINKA files to convert to WAV"
+ };
+ if (fileDialog.ShowDialog() == DialogResult.OK)
{
BinkaConverter.ToWav(fileDialog.FileNames, new DirectoryInfo(Path.GetDirectoryName(fileDialog.FileName)));
}
}
- private void fullBoxSupportToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
- {
+ private void fullBoxSupportToolStripMenuItem_CheckedChanged(object sender, EventArgs e)
+ {
currentPCK.SetVersion(fullBoxSupportToolStripMenuItem.Checked);
- }
+ }
- private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
- {
+ private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
+ {
var appSettings = new AppSettingsForm();
appSettings.ShowDialog(this);
- }
+ }
private void addBOXEntryToolStripMenuItem1_Click(object sender, EventArgs e)
{
- if(treeViewMain.SelectedNode is TreeNode t && t.Tag is PckFileData file)
+ if (treeViewMain.SelectedNode is TreeNode t && t.Tag is PckFileData file)
{
using BoxEditor diag = new BoxEditor(SkinBOX.Empty, IsSubPCKNode(treeViewMain.SelectedNode.FullPath));
if (diag.ShowDialog(this) == DialogResult.OK)
@@ -2268,10 +2269,20 @@ namespace PckStudio
}
}
- private void skinRenderer3DToolStripMenuItem_Click(object sender, EventArgs e)
- {
+ private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e)
+ {
+ if (Program.Updater.IsUpdateAvailable(Application.ProductVersion))
+ {
+ Program.UpdateToLatest("Would you like to download it?", MessageBoxButtons.YesNo, MessageBoxIcon.Question, DialogResult.Yes);
+ return;
+ }
+ MessageBox.Show("Already up to date.", "No update available");
+ }
+
+ private void skinRenderer3DToolStripMenuItem_Click(object sender, EventArgs e)
+ {
var gl = new TestGL();
gl.Show();
- }
- }
+ }
+ }
}
\ No newline at end of file
diff --git a/PCK-Studio/MainForm.resx b/PCK-Studio/MainForm.resx
index 39cd9c44..10818175 100644
--- a/PCK-Studio/MainForm.resx
+++ b/PCK-Studio/MainForm.resx
@@ -815,6 +815,9 @@
177, 6
+
+ 177, 6
+
False
@@ -1570,6 +1573,12 @@
More
+
+ 180, 22
+
+
+ Check for updates
+
iVBORw0KGgoAAAANSUhEUgAAAtAAAALQCAYAAAC5V0ecAAAABGdBTUEAALGPC/xhBQAAazFJREFUeF7t
@@ -6810,6 +6819,12 @@
System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+ checkForUpdatesToolStripMenuItem
+
+
+ System.Windows.Forms.ToolStripMenuItem, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
aboutToolStripMenuItem
diff --git a/PCK-Studio/PckStudio.csproj b/PCK-Studio/PckStudio.csproj
index 2fd819fc..d5dcc65c 100644
--- a/PCK-Studio/PckStudio.csproj
+++ b/PCK-Studio/PckStudio.csproj
@@ -4,6 +4,7 @@
preview
true
+ NDEBUG
publish\
true
Disk
@@ -40,7 +41,7 @@
full
false
bin\Debug\
- DEBUG;TRACE
+ $(DefineConstants);DEBUG;TRACE
prompt
4
true
@@ -50,7 +51,7 @@
none
true
bin\Release\
- TRACE
+ $(DefineConstants);TRACE
prompt
4
true
@@ -60,7 +61,7 @@
pdbonly
false
bin\Beta\
- BETA;TRACE
+ $(DefineConstants);BETA;TRACE
prompt
4
true
@@ -228,9 +229,7 @@
-
-
UserControl
@@ -571,6 +570,7 @@
generateModel.cs
+ Designer
SkinPreview.cs
@@ -734,6 +734,10 @@
+
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}
+ PCK-Studio-Updater
+
{693AEBC1-293D-4DF0-BCAE-26A1099FE7BB}
OMI Filetype Library
diff --git a/PCK-Studio/Program.cs b/PCK-Studio/Program.cs
index 644b6c70..38fe6f56 100644
--- a/PCK-Studio/Program.cs
+++ b/PCK-Studio/Program.cs
@@ -1,21 +1,36 @@
using System;
using System.Diagnostics;
using System.IO;
+using System.Text.RegularExpressions;
using System.Windows.Forms;
using PckStudio.Classes.Misc;
using PckStudio.Internal;
+using PckStudio.Properties;
+using PCKStudio_Updater;
+
namespace PckStudio
{
static class Program
{
- public static readonly string ProjectUrl = "https://github.com/PhoenixARC/-PCK-Studio";
- public static readonly string BaseAPIUrl = "http://api.pckstudio.xyz/api/pck";
- public static readonly string BackUpAPIUrl = "https://raw.githubusercontent.com/PhoenixARC/pckstudio.tk/main/studio/PCK/api/";
- public static readonly string AppData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Application.ProductName);
- public static readonly string AppDataCache = Path.Combine(AppData, "cache");
+ internal static readonly Uri ProjectUrl = new Uri("https://github.com/PhoenixARC/-PCK-Studio");
+ internal static readonly string BaseAPIUrl = "http://api.pckstudio.xyz/api/pck";
+ internal static readonly string BackUpAPIUrl = "https://raw.githubusercontent.com/PhoenixARC/pckstudio.tk/main/studio/PCK/api/";
- public static MainForm MainInstance { get; private set; }
+ internal static readonly string AppData = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), Application.ProductName);
+ internal static readonly string AppDataCache = Path.Combine(AppData, "cache");
+
+ private static readonly GithubParams UpdateParams = new GithubParams(
+ Path.GetDirectoryName(ProjectUrl.AbsolutePath).Replace("\\", ""),
+ Path.GetFileName(ProjectUrl.AbsolutePath),
+ Application.ProductName,
+ Settings.Default.UsePrerelease,
+ new Regex("(\\*|\\d+(\\.\\d+){0,3}(\\.\\*)?)")
+ );
+ internal static readonly IUpdateDownloader Updater = new GithubUpdateDownloader(UpdateParams);
+
+
+ internal static MainForm MainInstance { get; private set; }
///
/// The main entry point for the application.
@@ -23,6 +38,11 @@ namespace PckStudio
[STAThread]
static void Main(string[] args)
{
+ if (Settings.Default.AutoUpdate)
+ {
+ UpdateToLatest("Click Ok to continue.", MessageBoxButtons.OK, MessageBoxIcon.Exclamation, DialogResult.OK);
+ }
+
ApplicationScope.Initialize();
Trace.TraceInformation("Startup");
RPC.Initialize();
@@ -32,5 +52,21 @@ namespace PckStudio
Application.ApplicationExit += (sender, e) => { RPC.Deinitialize(); };
Application.Run(MainInstance);
}
+
+ [Conditional("NDEBUG")]
+ internal static void UpdateToLatest(string message, MessageBoxButtons buttons, MessageBoxIcon icon, DialogResult dialogResult)
+ {
+ bool updateAvailable = Updater.IsUpdateAvailable(Application.ProductVersion);
+ if (updateAvailable && MessageBox.Show(
+ "New update available.\n" +
+ message,
+ "Update Available",
+ buttons, icon, MessageBoxDefaultButton.Button1) == dialogResult)
+ {
+ Updater.DownloadTo(new DirectoryInfo(Application.StartupPath));
+ Updater.Launch();
+ Application.Exit();
+ }
+ }
}
-}
+}
\ No newline at end of file
diff --git a/PCK-Studio/Properties/AssemblyInfo.cs b/PCK-Studio/Properties/AssemblyInfo.cs
index 27386512..9e7ee662 100644
--- a/PCK-Studio/Properties/AssemblyInfo.cs
+++ b/PCK-Studio/Properties/AssemblyInfo.cs
@@ -32,6 +32,6 @@ using System.Security.Permissions;
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("7.0")]
-[assembly: AssemblyFileVersion("7.0")]
+[assembly: AssemblyVersion("7.0.0.0")]
+[assembly: AssemblyFileVersion("7.0.0.0")]
[assembly: NeutralResourcesLanguage("")]
diff --git a/PCK-Studio/Properties/Settings.Designer.cs b/PCK-Studio/Properties/Settings.Designer.cs
index e6d87129..95fa109d 100644
--- a/PCK-Studio/Properties/Settings.Designer.cs
+++ b/PCK-Studio/Properties/Settings.Designer.cs
@@ -80,6 +80,30 @@ namespace PckStudio.Properties {
}
}
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("True")]
+ public bool UsePrerelease {
+ get {
+ return ((bool)(this["UsePrerelease"]));
+ }
+ set {
+ this["UsePrerelease"] = value;
+ }
+ }
+
+ [global::System.Configuration.UserScopedSettingAttribute()]
+ [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+ [global::System.Configuration.DefaultSettingValueAttribute("False")]
+ public bool AutoUpdate {
+ get {
+ return ((bool)(this["AutoUpdate"]));
+ }
+ set {
+ this["AutoUpdate"] = value;
+ }
+ }
+
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
diff --git a/PCK-Studio/Properties/Settings.settings b/PCK-Studio/Properties/Settings.settings
index 8724beec..2e32328f 100644
--- a/PCK-Studio/Properties/Settings.settings
+++ b/PCK-Studio/Properties/Settings.settings
@@ -17,6 +17,12 @@
True
+
+ True
+
+
+ False
+
False
diff --git a/PCK_Studio.sln b/PCK_Studio.sln
index 8062268c..772bd2c5 100644
--- a/PCK_Studio.sln
+++ b/PCK_Studio.sln
@@ -11,6 +11,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OMI Filetype Library", "Ven
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpMss32", "Vendor\SharpMss32\SharpMss32\SharpMss32.csproj", "{E8D0B671-3AB1-48B6-A767-58DF67BD5D11}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PCK-Studio-Updater", "PCK-Studio-Updater\PCK-Studio-Updater.csproj", "{5B223556-15B9-41DA-AA0B-5E7F45E743BF}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Beta|Any CPU = Beta|Any CPU
@@ -78,6 +80,24 @@ Global
{E8D0B671-3AB1-48B6-A767-58DF67BD5D11}.Release|x64.Build.0 = Release|Any CPU
{E8D0B671-3AB1-48B6-A767-58DF67BD5D11}.Release|x86.ActiveCfg = Release|Any CPU
{E8D0B671-3AB1-48B6-A767-58DF67BD5D11}.Release|x86.Build.0 = Release|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Beta|Any CPU.ActiveCfg = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Beta|Any CPU.Build.0 = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Beta|x64.ActiveCfg = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Beta|x64.Build.0 = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Beta|x86.ActiveCfg = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Beta|x86.Build.0 = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Debug|x64.Build.0 = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Debug|x86.Build.0 = Debug|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Release|x64.ActiveCfg = Release|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Release|x64.Build.0 = Release|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Release|x86.ActiveCfg = Release|Any CPU
+ {5B223556-15B9-41DA-AA0B-5E7F45E743BF}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE