Merge branch main into '3dSkinRenderer'

This commit is contained in:
miku-666
2024-08-15 17:08:13 +02:00
8 changed files with 229 additions and 363 deletions

View File

@@ -1,17 +1,19 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Diagnostics;
using System.Collections.Generic;
using OMI.Formats.Languages;
using OMI.Formats.Pck;
using OMI.Workers;
using PckStudio.Interfaces;
using PckStudio.Internal.Deserializer;
using PckStudio.Internal.Serializer;
using PckStudio.Internal.Skin;
using System.Linq;
using System.Diagnostics;
namespace PckStudio.Extensions
{
@@ -176,26 +178,22 @@ namespace PckStudio.Extensions
return asset.Filename.Remove(asset.Filename.Length - (MipMap.Length + 1) - ext.Length) + ext;
}
internal static void DeserializePropertiesFromString(this PckAsset asset, string serializedData)
internal static void DeserializeProperties(this PckAsset asset, IEnumerable<string> serializedData)
{
string[] lines = serializedData.Split(new string[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries);
foreach (string line in lines)
IEnumerable<KeyValuePair<string, string>> lines = serializedData
.Select(line => line.Split([' '], 2))
.Where (keyValue => keyValue.Length == 2)
.Select(keyValue => new KeyValuePair<string, string>(keyValue[0].Replace(":", ""), keyValue[1]));
foreach (KeyValuePair<string, string> kv in lines)
{
int idx = line.IndexOf(' ');
if (idx == -1 || line.Length - 1 == idx)
continue;
asset.AddProperty(line.Substring(0, idx).Replace(":", string.Empty), line.Substring(idx + 1));
asset.AddProperty(kv);
}
}
internal static string SerializePropertiesToString(this PckAsset asset)
internal static IEnumerable<string> SerializeProperties(this PckAsset asset, string seperater = ":")
{
StringBuilder builder = new StringBuilder(asset.PropertyCount * 20);
foreach (KeyValuePair<string, string> property in asset.GetProperties())
{
builder.AppendLine(property.Key + ": " + property.Value);
}
return builder.ToString();
IReadOnlyList<KeyValuePair<string, string>> properties = asset.GetProperties();
return properties.Select(property => property.Key + seperater + property.Value);
}
}
}

View File

@@ -1,15 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace PckStudio.Forms.Additional_Popups
{
public partial class MultiTextPrompt : MetroFramework.Forms.MetroForm
{
public string[] TextOutput => DialogResult == DialogResult.OK ? PromptTextBox.Lines : Array.Empty<string>();
public MultiTextPrompt(string[] list = null)
public IEnumerable<string> TextOutput => DialogResult == DialogResult.OK ? PromptTextBox.Lines : Array.Empty<string>();
public MultiTextPrompt(IEnumerable<string> textLines)
{
InitializeComponent();
PromptTextBox.Lines = list;
PromptTextBox.Lines = textLines.ToArray();
}
public MultiTextPrompt()
: this(Enumerable.Empty<string>())
{
}
private void okBtn_Click(object sender, EventArgs e)

View File

@@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace PckStudio.Internal.Json
{
internal class UpdateInformation
{
[JsonProperty("version")]
public string Version { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("changelog")]
public string Changelog { get; set; }
[JsonProperty("mandatory")]
public bool Mandatory { get; set; }
}
}

View File

@@ -0,0 +1,62 @@
using System;
using System.IO;
using System.Windows.Forms;
using AutoUpdaterDotNET;
using Newtonsoft.Json;
using PckStudio.Internal.Json;
using PckStudio.Properties;
namespace PckStudio.Internal
{
internal static class Updater
{
private static Uri _appCast;
internal static void Initialize(Uri appCast)
{
_appCast = appCast;
//AutoUpdater.ClearAppDirectory = true;
#if DEBUG
AutoUpdater.ReportErrors = true;
#endif
AutoUpdater.DownloadPath = Application.StartupPath;
AutoUpdater.ExecutablePath = "./PCK-Studio.exe";
AutoUpdater.TopMost = true;
string jsonPath = Path.Combine(Environment.CurrentDirectory, "updates.json");
AutoUpdater.PersistenceProvider = new JsonFilePersistenceProvider(jsonPath);
AutoUpdater.ParseUpdateInfoEvent += AutoUpdaterOnParseUpdateInfoEvent;
AutoUpdater.Icon = Resources.ProjectLogo.ToBitmap();
if (Settings.Default.AutoUpdate)
{
UpdateToLatest();
}
}
internal static void SetOwner(Form owner) => AutoUpdater.SetOwner(owner);
internal static void UpdateToLatest()
{
#if NDEBUG
string url = $"{_appCast}/main/Version.json";
AutoUpdater.Start(url);
#endif
}
private static void AutoUpdaterOnParseUpdateInfoEvent(ParseUpdateInfoEventArgs args)
{
UpdateInformation json = JsonConvert.DeserializeObject<UpdateInformation>(args.RemoteData);
args.UpdateInfo = new UpdateInfoEventArgs
{
CurrentVersion = json.Version,
DownloadURL = json.Url,
ChangelogURL = json.Changelog,
Mandatory = new Mandatory()
{
Value = json.Mandatory,
}
};
}
}
}

View File

@@ -264,16 +264,14 @@ namespace PckStudio
private void openToolStripMenuItem_Click(object sender, EventArgs e)
{
using (var ofd = new OpenFileDialog())
{
ofd.CheckFileExists = true;
ofd.Filter = "PCK (Minecraft Console Package)|*.pck";
if (ofd.ShowDialog(this) == DialogResult.OK)
{
LoadPckFromFile(ofd.FileName);
}
}
}
using var ofd = new OpenFileDialog();
ofd.CheckFileExists = true;
ofd.Filter = "PCK (Minecraft Console Package)|*.pck";
if (ofd.ShowDialog(this) == DialogResult.OK)
{
LoadPckFromFile(ofd.FileName);
}
}
private PckFile OpenPck(string filePath)
{
@@ -759,7 +757,7 @@ namespace PckStudio
File.WriteAllBytes(outFilePath, asset.Data);
if (asset.PropertyCount > 0)
{
File.WriteAllText($"{outFilePath}.txt", asset.SerializePropertiesToString());
File.WriteAllLines($"{outFilePath}.txt", asset.SerializeProperties());
}
}
@@ -785,27 +783,10 @@ namespace PckStudio
string selectedFolder = node.FullPath;
if (IsSubPCKNode(node.FullPath))
{
GetAllChildNodes(node.Nodes).ForEach(fileNode =>
{
if (fileNode.TryGetTagData(out PckAsset asset))
{
extractFolderFile(outPath, asset);
}
}
);
}
else
{
foreach (PckAsset asset in currentPCK.GetAssets())
{
if (asset.Filename.StartsWith(selectedFolder))
{
extractFolderFile(outPath, asset);
}
}
}
foreach (PckAsset asset in currentPCK.GetAssets().Where(asset => asset.Filename.StartsWith(selectedFolder)))
{
extractFolderFile(outPath, asset);
}
}
private void extractToolStripMenuItem_Click(object sender, EventArgs e)
@@ -898,7 +879,6 @@ namespace PckStudio
string newFileExt = Path.GetExtension(ofd.FileName);
asset.SetData(File.ReadAllBytes(ofd.FileName));
asset.Filename = asset.Filename.Replace(fileExt, newFileExt);
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
wasModified = true;
BuildMainTreeView();
}
@@ -964,7 +944,6 @@ namespace PckStudio
node.Remove();
wasModified = true;
}
RebuildSubPCK(path);
}
private void renameFileToolStripMenuItem_Click(object sender, EventArgs e)
@@ -1003,7 +982,6 @@ namespace PckStudio
}
}
wasModified = true;
RebuildSubPCK(path);
BuildMainTreeView();
}
}
@@ -1124,120 +1102,6 @@ namespace PckStudio
}
}
[Obsolete()]
bool IsSubPCKNode(string nodePath, string extention = ".pck")
{
// written by miku, implemented and modified by MattNL
if (nodePath.EndsWith(extention))
return false;
string[] subpaths = nodePath.Split('/');
bool isSubFile = subpaths.Any(s => Path.GetExtension(s).Equals(extention));
Debug.WriteLineIf(isSubFile, $"{nodePath} is a Sub-PCK File", category: nameof(IsSubPCKNode));
return isSubFile;
}
List<TreeNode> GetAllChildNodes(TreeNodeCollection root)
{
List<TreeNode> childNodes = new List<TreeNode>();
foreach (TreeNode node in root)
{
childNodes.Add(node);
if (node.Nodes.Count > 0)
{
childNodes.AddRange(GetAllChildNodes(node.Nodes));
}
}
return childNodes;
}
[Obsolete()]
TreeNode GetSubPCK(string childPath)
{
string parentPath = childPath.Replace('\\', '/');
Debug.WriteLine(parentPath);
string[] s = parentPath.Split('/');
Debug.WriteLine(s.Length);
foreach (string node in s)
{
TreeNode parent = treeViewMain.Nodes.Find(node, true)[0];
if (parent.TryGetTagData(out PckAsset asset) &&
(asset.Type is PckAssetType.TexturePackInfoFile ||
asset.Type is PckAssetType.SkinDataFile))
return parent;
}
return null;
}
[Obsolete()]
void RebuildSubPCK(string childPath)
{
// Support for if a file is edited within a nested PCK File (AKA SubPCK)
if (!IsSubPCKNode(childPath))
return;
TreeNode parent = GetSubPCK(childPath);
Debug.WriteLine(parent.Name);
if (parent == null)
return;
PckAsset parentAsset = parent.Tag as PckAsset;
PckFile parentAssetPck =
new PckFileReader(
LittleEndianCheckBox.Checked ?
OMI.Endianness.LittleEndian :
OMI.Endianness.BigEndian
).FromStream(new MemoryStream(parentAsset.Data));
if (parentAsset.Type is PckAssetType.TexturePackInfoFile || parentAsset.Type is PckAssetType.SkinDataFile)
{
Debug.WriteLine("Rebuilding " + parentAsset.Filename);
PckFile newPCKFile = new PckFile(3, parentAsset.Type is PckAssetType.SkinDataFile);
bool hasSkinsFolder = false;
// add original pck files to prevent data loss
foreach (PckAsset asset in parentAssetPck.GetAssets())
{
PckAsset newAsset = newPCKFile.CreateNewAsset(asset.Filename, asset.Type);
// check for skins folder so files are placed consistently in final pck
if (asset.Filename.StartsWith("Skins/") && parentAsset.Type is PckAssetType.SkinDataFile)
hasSkinsFolder = true;
foreach (KeyValuePair<string, string> prop in asset.GetProperties())
newAsset.AddProperty(prop);
newAsset.SetData(asset.Data);
}
foreach (TreeNode node in GetAllChildNodes(parent.Nodes))
{
if (node.Tag is PckAsset nodeAsset)
{
PckAsset newAsset = newPCKFile.CreateNewAsset(
(hasSkinsFolder ? "Skins/" : String.Empty)
+ nodeAsset.Filename.Replace(parentAsset.Filename + "/", String.Empty), nodeAsset.Type);
foreach (KeyValuePair<string, string> prop in nodeAsset.GetProperties())
newAsset.AddProperty(prop);
newAsset.SetData(nodeAsset.Data);
}
}
parentAsset.SetData(new PckFileWriter(newPCKFile, LittleEndianCheckBox.Checked ? OMI.Endianness.LittleEndian : OMI.Endianness.BigEndian));
parent.Tag = parentAsset;
// erase hidden sub-pck nodes to prevent duplication
parent.Nodes.Clear();
BuildMainTreeView();
MessageBox.Show(this, $"Files added successfully to {parentAsset.Filename}");
}
}
private void treeViewMain_DoubleClick(object sender, EventArgs e)
{
if (treeViewMain.SelectedNode.TryGetTagData(out PckAsset asset))
@@ -1276,7 +1140,6 @@ namespace PckStudio
if (diag.ShowDialog(this) == DialogResult.OK)
{
asset.SetProperty(asset.GetPropertyIndex(property), new KeyValuePair<string, string>("ANIM", diag.ResultAnim.ToString()));
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
ReloadMetaTreeView();
wasModified = true;
}
@@ -1293,11 +1156,10 @@ namespace PckStudio
case "BOX" when asset.Type == PckAssetType.SkinFile:
try
{
using BoxEditor diag = new BoxEditor(property.Value, IsSubPCKNode(treeViewMain.SelectedNode.FullPath));
using BoxEditor diag = new BoxEditor(property.Value, false);
if (diag.ShowDialog(this) == DialogResult.OK)
{
asset.SetProperty(asset.GetPropertyIndex(property), new KeyValuePair<string, string>("BOX", diag.Result.ToString()));
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
ReloadMetaTreeView();
wasModified = true;
}
@@ -1321,7 +1183,6 @@ namespace PckStudio
if (addProperty.ShowDialog(this) == DialogResult.OK)
{
asset.SetProperty(asset.GetPropertyIndex(property), addProperty.Property);
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
ReloadMetaTreeView();
wasModified = true;
}
@@ -1358,7 +1219,7 @@ namespace PckStudio
newNode.ImageIndex = node.ImageIndex;
newNode.SelectedImageIndex = node.SelectedImageIndex;
if (GetAllChildNodes(treeViewMain.Nodes).Find(n => n.FullPath == diag.NewText) != null)
if (GetAllChildNodes(treeViewMain.Nodes).FirstOrDefault(n => n.FullPath == diag.NewText) is not null)
{
MessageBox.Show(
this,
@@ -1368,17 +1229,10 @@ namespace PckStudio
return;
}
// adds generated file node
if (node.Parent == null)
treeViewMain.Nodes.Insert(node.Index + 1, newNode);
// adds generated file node to selected folder
else
node.Parent.Nodes.Insert(node.Index + 1, newNode);
TreeNodeCollection nodeCollection = node.Parent?.Nodes ?? treeViewMain.Nodes;
nodeCollection.Insert(node.Index + 1, newNode);
if (!IsSubPCKNode(node.FullPath))
currentPCK.InsertAsset(node.Index + 1, newFile);
else
RebuildSubPCK(node.FullPath);
currentPCK.InsertAsset(node.Index + 1, newFile);
BuildMainTreeView();
wasModified = true;
}
@@ -1392,7 +1246,6 @@ namespace PckStudio
asset.RemoveProperty(property))
{
treeMeta.SelectedNode.Remove();
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
wasModified = true;
}
}
@@ -1419,7 +1272,6 @@ namespace PckStudio
if (addProperty.ShowDialog(this) == DialogResult.OK)
{
asset.AddProperty(addProperty.Property);
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
ReloadMetaTreeView();
wasModified = true;
}
@@ -1536,7 +1388,7 @@ namespace PckStudio
}
else
{
List<PckAsset> pckFiles = GetEndingNodes(draggedNode.Nodes).Where(t => t.IsTagOfType<PckAsset>()).Select(t => t.Tag as PckAsset).ToList();
IEnumerable<PckAsset> pckFiles = GetAllChildNodes(draggedNode.Nodes).Where(t => t.IsTagOfType<PckAsset>()).Select(t => t.Tag as PckAsset);
string oldPath = draggedNode.FullPath;
string newPath = Path.Combine(isTargetPckFile ? Path.GetDirectoryName(targetNode.FullPath) : targetNode.FullPath, draggedNode.Text).Replace('\\', '/');
foreach (PckAsset pckFile in pckFiles)
@@ -1548,20 +1400,17 @@ namespace PckStudio
}
}
private IEnumerable<TreeNode> GetEndingNodes(TreeNodeCollection collection)
IEnumerable<TreeNode> GetAllChildNodes(TreeNodeCollection root)
{
List<TreeNode> trailingNodes = new List<TreeNode>(collection.Count);
foreach (TreeNode node in collection)
{
if (node.Nodes.Count > 0)
{
trailingNodes.AddRange(GetEndingNodes(node.Nodes));
continue;
}
trailingNodes.Add(node);
}
return trailingNodes;
}
List<TreeNode> childNodes = new List<TreeNode>(root.Count);
foreach (TreeNode childNode in root)
{
childNodes.Add(childNode);
childNodes.AddRange(GetAllChildNodes(childNode.Nodes));
}
return childNodes;
}
private void ImportFiles(string[] files)
{
@@ -1574,14 +1423,14 @@ namespace PckStudio
if (currentPCK.Contains(addFile.Filepath, addFile.Filetype))
{
MessageBox.Show(this, $"'{addFile.Filepath}' of type {addFile.Filetype} already exists.", "Import failed", MessageBoxButtons.OK, MessageBoxIcon.Warning);
MessageBox.Show(this, $"'{addFile.Filepath}' of type {addFile.Filetype} already exists.\nSkiping file.", "File already exists", MessageBoxButtons.OK, MessageBoxIcon.Warning, MessageBoxDefaultButton.Button1);
continue;
}
PckAsset importedAsset = currentPCK.CreateNewAsset(addFile.Filepath, addFile.Filetype, () => File.ReadAllBytes(filepath));
string propertyFile = filepath + ".txt";
if (File.Exists(propertyFile))
{
importedAsset.DeserializePropertiesFromString(File.ReadAllText(propertyFile));
importedAsset.DeserializeProperties(File.ReadAllLines(propertyFile));
}
addedCount++;
@@ -1743,16 +1592,19 @@ namespace PckStudio
e.CancelEdit = true;
}
[Obsolete("Move this")]
public string GetDataPath()
{
return Path.Combine(Path.GetDirectoryName(saveLocation), "Data");
}
[Obsolete("Move this")]
public bool HasDataFolder()
{
return Directory.Exists(GetDataPath());
}
[Obsolete("Move this")]
public bool CreateDataFolder()
{
if (!HasDataFolder())
@@ -1771,49 +1623,7 @@ namespace PckStudio
if (e.KeyData == Keys.Delete)
deleteEntryToolStripMenuItem_Click(sender, e);
}
private void importExtractedSkinsFolder(object sender, EventArgs e)
{
using FolderBrowserDialog contents = new FolderBrowserDialog();
if (contents.ShowDialog(this) == DialogResult.OK && Directory.Exists(contents.SelectedPath))
{
string filepath = treeViewMain.SelectedNode?.FullPath ?? "";
if (treeViewMain.SelectedNode is not null && treeViewMain.SelectedNode.IsTagOfType<PckAsset>())
filepath = treeViewMain.SelectedNode.Parent?.FullPath ?? "";
foreach (var fullfilename in Directory.GetFiles(contents.SelectedPath, "dlc*.png"))
{
string filename = Path.GetFileName(fullfilename);
// only accept skin or cape named files
if (!filename.StartsWith("dlcskin") && !filename.StartsWith("dlccape"))
continue;
// sets file type based on wether its a cape or skin
PckAssetType pckfiletype = filename.StartsWith("dlccape", StringComparison.OrdinalIgnoreCase)
? PckAssetType.CapeFile
: PckAssetType.SkinFile;
string pckfilepath = Path.Combine(filepath, filename);
if (currentPCK.Contains(pckfilepath, pckfiletype))
{
Trace.TraceInformation("[{0}] {1} already exists.", nameof(importExtractedSkinsFolder), pckfilepath);
continue;
}
PckAsset newAsset = currentPCK.CreateNewAsset(pckfilepath, pckfiletype);
byte[] filedata = File.ReadAllBytes(fullfilename);
newAsset.SetData(filedata);
if (File.Exists(fullfilename + ".txt"))
{
string propertiesFileContent = File.ReadAllText(fullfilename + ".txt");
newAsset.DeserializePropertiesFromString(propertiesFileContent);
}
}
BuildMainTreeView();
wasModified = true;
}
}
private bool TryGetLocFile(out LOCFile locFile)
{
if (!currentPCK.TryGetAsset("localisation.loc", PckAssetType.LocalisationFile, out PckAsset locAsset) &&
@@ -1856,6 +1666,47 @@ namespace PckStudio
return false;
}
private void importExtractedSkinsFolder(object sender, EventArgs e)
{
OpenFolderDialog contents = new OpenFolderDialog();
if (contents.ShowDialog(Handle) == true && Directory.Exists(contents.ResultPath))
{
string filepath = treeViewMain.SelectedNode?.FullPath ?? "";
if (treeViewMain.SelectedNode is not null && treeViewMain.SelectedNode.IsTagOfType<PckAsset>())
filepath = treeViewMain.SelectedNode.Parent?.FullPath ?? "";
foreach (var fullfilename in Directory.GetFiles(contents.ResultPath, "dlc*.png"))
{
string filename = Path.GetFileName(fullfilename);
// only accept skin or cape named files
if (!filename.StartsWith("dlcskin") && !filename.StartsWith("dlccape"))
continue;
// sets file type based on wether its a cape or skin
PckAssetType pckfiletype = filename.StartsWith("dlccape", StringComparison.OrdinalIgnoreCase)
? PckAssetType.CapeFile
: PckAssetType.SkinFile;
string pckfilepath = Path.Combine(filepath, filename);
if (currentPCK.Contains(pckfilepath, pckfiletype))
{
Trace.TraceInformation("[{0}] {1} already exists.", nameof(importExtractedSkinsFolder), pckfilepath);
continue;
}
PckAsset newAsset = currentPCK.CreateNewAsset(pckfilepath, pckfiletype);
byte[] filedata = File.ReadAllBytes(fullfilename);
newAsset.SetData(filedata);
if (File.Exists(fullfilename + ".txt"))
{
string[] propertiesFileContent = File.ReadAllLines(fullfilename + ".txt");
newAsset.DeserializeProperties(propertiesFileContent);
}
}
BuildMainTreeView();
wasModified = true;
}
}
[Obsolete("Refactor or remove this")]
private void importSkinToolStripMenuItem_Click(object sender, EventArgs e)
@@ -1881,13 +1732,14 @@ namespace PckStudio
string propertyFile = contents.FileName + ".txt";
if (File.Exists(propertyFile))
{
string txtProperties = File.ReadAllText(propertyFile);
importSkinAsset.DeserializePropertiesFromString(txtProperties);
// Because extracting/exporting an assest doesn't export
// the actual loc value we just get an undefined loc key
// - Miku
importSkinAsset.RemoveProperty("DISPLAYNAMEID");
string[] txtProperties = File.ReadAllLines(propertyFile);
importSkinAsset.DeserializeProperties(txtProperties);
// Because extracting/exporting an assest doesn't export
// the actual loc value we just get an undefined loc key.
// That's why why remove them after deserializing.
// - Miku
importSkinAsset.RemoveProperty("DISPLAYNAMEID");
importSkinAsset.RemoveProperty("THEMENAMEID");
BuildMainTreeView();
wasModified = true;
@@ -2015,13 +1867,9 @@ namespace PckStudio
{
pckOpen.Image = Resources.pckDrop;
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop) ?? Array.Empty<string>();
foreach (string file in files)
{
string ext = Path.GetExtension(file);
if (ext.Equals(".pck", StringComparison.CurrentCultureIgnoreCase))
e.Effect = DragDropEffects.Copy;
return;
}
e.Effect = files.Any(file => Path.GetExtension(file).Equals(".pck", StringComparison.CurrentCultureIgnoreCase))
? DragDropEffects.Copy
: DragDropEffects.None;
}
private void OpenPck_DragDrop(object sender, DragEventArgs e)
@@ -2067,23 +1915,23 @@ namespace PckStudio
break;
case PckAssetType.TexturePackInfoFile:
goto default;
node.ImageIndex = 4;
node.SelectedImageIndex = 4;
break;
//node.ImageIndex = 4;
//node.SelectedImageIndex = 4;
//break;
case PckAssetType.ColourTableFile:
node.ImageIndex = 6;
node.SelectedImageIndex = 6;
break;
case PckAssetType.ModelsFile:
goto default;
node.ImageIndex = 8;
node.SelectedImageIndex = 8;
break;
//node.ImageIndex = 8;
//node.SelectedImageIndex = 8;
//break;
case PckAssetType.SkinDataFile:
goto default;
node.ImageIndex = 7;
node.SelectedImageIndex = 7;
break;
//node.ImageIndex = 7;
//node.SelectedImageIndex = 7;
//break;
case PckAssetType.GameRulesFile:
node.ImageIndex = 9;
node.SelectedImageIndex = 9;
@@ -2130,11 +1978,9 @@ namespace PckStudio
Debug.WriteLine($"Setting {asset.Type} to {type}");
asset.Type = type;
SetNodeIcon(treeViewMain.SelectedNode, type);
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
}
}
[Obsolete()]
private void addTextureToolStripMenuItem_Click(object sender, EventArgs e)
{
using OpenFileDialog fileDialog = new OpenFileDialog();
@@ -2260,23 +2106,14 @@ namespace PckStudio
{
if (treeViewMain.SelectedNode.TryGetTagData(out PckAsset asset))
{
using (var input = new MultiTextPrompt())
{
if (input.ShowDialog(this) == DialogResult.OK)
{
foreach (string line in input.TextOutput)
{
int idx = line.IndexOf(' ');
if (idx == -1 || line.Length - 1 == idx)
continue;
asset.AddProperty(line.Substring(0, idx), line.Substring(idx + 1));
}
ReloadMetaTreeView();
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
wasModified = true;
}
}
}
using var input = new MultiTextPrompt();
if (input.ShowDialog(this) == DialogResult.OK)
{
asset.DeserializeProperties(input.TextOutput);
ReloadMetaTreeView();
wasModified = true;
}
}
}
private void correctSkinDecimalsToolStripMenuItem_Click(object sender, EventArgs e)
@@ -2290,7 +2127,6 @@ namespace PckStudio
asset.SetProperty(asset.GetPropertyIndex(p), new KeyValuePair<string, string>(p.Key, p.Value.Replace(',', '.')));
}
ReloadMetaTreeView();
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
wasModified = true;
}
}
@@ -2313,21 +2149,14 @@ namespace PckStudio
{
if (treeViewMain.SelectedNode.TryGetTagData(out PckAsset asset))
{
string[] props = asset.GetProperties().Select(p => p.Key + " " + p.Value).ToArray();
IEnumerable<string> props = asset.SerializeProperties(seperater:" ");
using (var input = new MultiTextPrompt(props))
{
if (input.ShowDialog(this) == DialogResult.OK)
{
asset.ClearProperties();
foreach (string line in input.TextOutput)
{
int idx = line.IndexOf(' ');
if (idx == -1 || line.Length - 1 == idx)
continue;
asset.AddProperty(line.Substring(0, idx).Replace(":", string.Empty), line.Substring(idx + 1));
}
asset.DeserializeProperties(input.TextOutput);
ReloadMetaTreeView();
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
wasModified = true;
}
}
@@ -2354,8 +2183,6 @@ namespace PckStudio
}
PckAsset asset = currentPCK.CreateNewAsset(diag.Filepath, diag.Filetype, () => File.ReadAllBytes(ofd.FileName));
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
BuildMainTreeView();
wasModified = true;
}
@@ -2451,11 +2278,10 @@ namespace PckStudio
{
if (treeViewMain.SelectedNode is TreeNode t && t.Tag is PckAsset asset)
{
using BoxEditor diag = new BoxEditor(SkinBOX.Empty, IsSubPCKNode(treeViewMain.SelectedNode.FullPath));
using BoxEditor diag = new BoxEditor(SkinBOX.Empty, false);
if (diag.ShowDialog(this) == DialogResult.OK)
{
asset.AddProperty("BOX", diag.Result);
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
ReloadMetaTreeView();
wasModified = true;
}
@@ -2471,7 +2297,6 @@ namespace PckStudio
if (diag.ShowDialog(this) == DialogResult.OK)
{
asset.AddProperty("ANIM", diag.ResultAnim);
RebuildSubPCK(treeViewMain.SelectedNode.FullPath);
ReloadMetaTreeView();
wasModified = true;
}
@@ -2481,7 +2306,7 @@ namespace PckStudio
private void checkForUpdatesToolStripMenuItem_Click(object sender, EventArgs e)
{
Program.UpdateToLatest();
Updater.UpdateToLatest();
}
private void exitToolStripMenuItem_Click(object sender, EventArgs e)
@@ -2522,6 +2347,7 @@ namespace PckStudio
}
private void littleEndianToolStripMenuItem_Click(object sender, EventArgs e) => SetPckEndianness(OMI.Endianness.LittleEndian);
private void bigEndianToolStripMenuItem_Click(object sender, EventArgs e) => SetPckEndianness(OMI.Endianness.BigEndian);
private void SetModelVersion(int version)

View File

@@ -45,6 +45,8 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<NoWarn>CS0618</NoWarn>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
@@ -175,6 +177,7 @@
<Compile Include="Internal\ModelPartSpecifics.cs" />
<Compile Include="Internal\Json\JsonModelMetaData.cs" />
<Compile Include="Internal\NamedTexture.cs" />
<Compile Include="Internal\Json\UpdateInformation.cs" />
<Compile Include="Internal\Serializer\AnimationSerializer.cs" />
<Compile Include="Internal\Deserializer\AnimationDeserializer.cs" />
<Compile Include="Interfaces\IPckAssetDeserializer.cs" />
@@ -192,6 +195,7 @@
<Compile Include="Internal\Serializer\ImageSerializer.cs" />
<Compile Include="Internal\Skin\SkinAnimFlag.cs" />
<Compile Include="Internal\Skin\SkinAnimMask.cs" />
<Compile Include="Internal\Updater.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>

View File

@@ -31,74 +31,18 @@ namespace PckStudio
[STAThread]
static void Main(string[] args)
{
AutoUpdater.SetOwner(MainInstance);
//AutoUpdater.ClearAppDirectory = true;
#if DEBUG
AutoUpdater.ReportErrors = true;
#endif
AutoUpdater.DownloadPath = Application.StartupPath;
AutoUpdater.ExecutablePath = "./PCK-Studio.exe";
AutoUpdater.TopMost = true;
string jsonPath = Path.Combine(Environment.CurrentDirectory, "updates.json");
AutoUpdater.PersistenceProvider = new JsonFilePersistenceProvider(jsonPath);
AutoUpdater.ParseUpdateInfoEvent += AutoUpdaterOnParseUpdateInfoEvent;
AutoUpdater.Icon = Resources.ProjectLogo.ToBitmap();
if (Settings.Default.AutoUpdate)
{
UpdateToLatest();
}
Updater.Initialize(RawProjectUrl);
ApplicationScope.Initialize();
Trace.TraceInformation("Startup");
RPC.Initialize();
MainInstance = new MainForm();
Updater.SetOwner(MainInstance);
if (args.Length > 0 && File.Exists(args[0]) && args[0].EndsWith(".pck"))
MainInstance.InitPckFromFile(args[0]);
Application.ApplicationExit += (sender, e) => { RPC.Deinitialize(); };
MainInstance.FocusMe();
Application.Run(MainInstance);
}
internal static void UpdateToLatest()
{
#if NDEBUG
string url = $"{RawProjectUrl}/main/Version.json";
AutoUpdater.Start(url);
#endif
}
class UpdateInfo
{
[JsonProperty("version")]
public string Version { get; set; }
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("changelog")]
public string Changelog { get; set; }
[JsonProperty("mandatory")]
public bool Mandatory { get; set; }
}
private static void AutoUpdaterOnParseUpdateInfoEvent(ParseUpdateInfoEventArgs args)
{
UpdateInfo json = JsonConvert.DeserializeObject<UpdateInfo>(args.RemoteData);
args.UpdateInfo = new UpdateInfoEventArgs
{
CurrentVersion = json.Version,
DownloadURL = json.Url,
ChangelogURL = json.Changelog,
Mandatory = new Mandatory()
{
Value = json.Mandatory,
}
};
}
}
}

2
Vendor/OMI-Lib vendored