JD2022-TU1/main/tools/apps/ResourceViewer/Utils.cs

332 lines
12 KiB
C#

using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System;
using System.Runtime.InteropServices;
using System.Windows.Media.Imaging;
using System.Drawing;
using JD.Core;
using JD.Core.Drawing;
using JD.Core.ProjectManaging;
namespace ResourceViewer
{
/// <summary>
/// class offering dedicated services for the tool
/// </summary>
public class Utils
{
/// <summary>
/// configuration file extension
/// </summary>
public const string TFIExtension = ".tfi";
public const string TGAExtension = ".tga";
private readonly List<string> _ipAdressList = new List<string>();
private static Utils _instance = null;
private static readonly Object _thisLock = new Object();
private readonly CultureInfo _culture = new CultureInfo("en-US");
/// <summary>
/// Get instance of PA4manager object
/// </summary>
public static Utils Instance
{
get
{
if (_instance == null)
{
lock (_thisLock)
{
if (_instance == null)
{
_instance = new Utils();
}
}
}
return (_instance);
}
}
public string DefaultIPAdress
{
get
{
return "127.0.0.1";
}
}
public string SelectedIPAdress
{
get;
set;
}
public IEnumerable<string> IPAdressList
{
get
{
return _ipAdressList;
}
}
public string ConfigFilePath
{
get;
set;
}
public string UserConfigFilePath
{
get;
set;
}
private Utils()
{
}
/// <summary>
/// Add ending separator character if needed
/// </summary>
/// <param name="src"></param>
/// <returns></returns>
public string FormatDirectoryName(string src)
{
if (src.Length >= 1)
{
string normalized = src.Normalize();
if (normalized.EndsWith("\\") == false && normalized.EndsWith("/") == false)
normalized += "\\";
return normalized;
}
return string.Empty;
}
/// <summary>
/// Replace slash in string helpers
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public string PathToP4Path(string path)
{
return path.Replace(@"\", "/");
}
/// <summary>
/// Function to check if string S1 contains string S2.
/// Comparison is case insensitive
/// </summary>
/// <param name="s1">string to test key string in</param>
/// <param name="s2">key string</param>
/// <returns>true if S1 contains S2, else false </returns>
public bool ContainsNoCase(string s1, string s2)
{
return _culture.CompareInfo.IndexOf(s1, s2, CompareOptions.IgnoreCase) >= 0;
}
/// <summary>
/// Check that a name match a key
/// </summary>
/// <param name="name">the name to test</param>
/// <param name="regexPattern">the key to match</param>
/// <param name="explicitCapture">explicit capture needed</param>
/// <returns>MAtch colelction result</returns>
public MatchCollection MatchNameWithKey(string name, string regexPattern, bool explicitCapture)
{
if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(regexPattern))
{
return null;
}
RegexOptions options = explicitCapture ? RegexOptions.ExplicitCapture : RegexOptions.None;
return Regex.Matches(name, regexPattern, RegexOptions.IgnoreCase | options);
}
/// <summary>
/// Log a match result from regex
/// </summary>
/// <param name="results">The match collection resulting from Regex.Match</param>
public void LogRegexMatches(MatchCollection results)
{
if (results != null)
{
foreach (Match match in results)
{
Console.WriteLine(@"The match: {0}", match.Value);
int groupCtr = 0;
foreach (Group group in match.Groups)
{
Console.WriteLine(@" Group {0}: {1}", groupCtr, @group.Value);
groupCtr++;
int captureCtr = 0;
foreach (Capture capture in @group.Captures)
{
Console.WriteLine(@" Capture {0}: {1}", captureCtr, capture.Value);
captureCtr++;
}
}
}
}
}
[DllImport("gdi32.dll", EntryPoint = "DeleteObject")]
public static extern IntPtr DeleteObject(IntPtr hDc);
/// <summary>
/// Static GDI function to create a C# Bitmapsource compatble object
/// </summary>
/// <param name="gdiBitmap">bitmap object</param>
/// <returns>Bitmapsource created from GDI bitmap object</returns>
public static BitmapSource GetBitmapSource(Bitmap gdiBitmap)
{
IntPtr hBitmap = gdiBitmap.GetHbitmap();
BitmapSource bitmapSource = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(hBitmap,
IntPtr.Zero,
System.Windows.Int32Rect.Empty,
BitmapSizeOptions.FromEmptyOptions());
DeleteObject(hBitmap);
return bitmapSource;
}
/// <summary>
/// Create a compatible DC bitmap from a TGA or a JPEG file
/// </summary>
/// <param name="fullFilepath">full file path</param>
/// <param name="imageSize">image size, retrieve from file header analysis</param>
/// <returns>the bitmap source if succeed, null else</returns>
public BitmapSource CreateTextureBitmapSourceFromFile(string fullFilepath, ref System.Windows.Size imageSize)
{
if (string.IsNullOrEmpty(fullFilepath) == false)
{
string extension = System.IO.Path.GetExtension(fullFilepath);
try
{
if (string.Compare(extension, TGAExtension, StringComparison.OrdinalIgnoreCase) == 0)
{
var bitmap = TargaImage.LoadTargaImage(fullFilepath);
imageSize.Width = bitmap.Width;
imageSize.Height = bitmap.Height;
return Utils.GetBitmapSource(bitmap);
}
else
{
var textureImage = new BitmapImage();
textureImage.BeginInit();
textureImage.UriSource = new Uri(fullFilepath);
textureImage.EndInit();
imageSize.Width = textureImage.PixelWidth;
imageSize.Height = textureImage.PixelHeight;
return textureImage;
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
return null;
}
/// <summary>
/// Retrieve the correct bitmpa to display according to ressource type
/// </summary>
/// <param name="selectedResource">selected resource</param>
/// <param name="rootedFilePath">file path for resource</param>
/// <param name="imageSize">retrieve image size for texture</param>
/// <param name="multiselection">a multi selection is active</param>
/// <returns>the bitmap source if succeed, null else</returns>
public BitmapSource GetSelectedResourceBitmapSource(ResourceInfo selectedResource, string rootedFilePath, ref System.Windows.Size imageSize, bool multiselection = false)
{
BitmapSource bitmapSource = null;
if (selectedResource.IsTexture)
{
if (File.Exists(rootedFilePath))
{
bitmapSource = multiselection == false
? CreateTextureBitmapSourceFromFile(rootedFilePath, ref imageSize)
: GetBitmapSource(Properties.Resources.Icons_256x256_MultiTexture);
}
}
else
{
if (selectedResource.IsSound)
{
bitmapSource = GetBitmapSource(Properties.Resources.Icons_256x256_Wave);
}
else
{
if (selectedResource.IsAnim)
{
bitmapSource = GetBitmapSource(Properties.Resources.Icons_256x256_Animation);
}
else
{
if (selectedResource.IsMove)
{
bitmapSource = GetBitmapSource(Properties.Resources.Icons_256x256_MSMType);
}
else
{
bitmapSource = GetBitmapSource(Properties.Resources.Icons_256x256_NoTexture);
}
}
}
}
return bitmapSource;
}
/// <summary>
/// Opens explorer with a specified directory to open
/// </summary>
/// <param name="pathToOpen">the directory path to select in the explorer</param>
public void OpenExplorer(string pathToOpen)
{
Process.Start("explorer.exe", "/select,\"" + pathToOpen.Replace("/", @"\") + "\"");
}
/// <summary>
///
/// </summary>
/// <param name="pathToOpen"></param>
public void OpenAssociatedApplication(string pathToOpen)
{
}
/// <summary>
/// Ask plugin to recook a texture file from its resourceInfo
/// </summary>
/// <param name="resource">resourceInfo instance containing texture</param>
public void CookTexture(ResourceViewerPlugin plugin, ResourceInfo resource)
{
if (resource == null)
throw new ArgumentNullException();
if (resource.IsTexture == false)
throw new ArgumentException("Resource is not a texture");
string resFilePath = Utils.Instance.PathToP4Path(DataPath.GetAbsolutePath(resource.PathName));
if (File.Exists(resFilePath) == false)
throw new FileNotFoundException();
string tempFilePath = DataPath.GetAbsolutePath("ConfigTemporary") + Utils.TFIExtension;
using (var writer = new TextureConfigFileWriter(tempFilePath))
{
writer.Save(resource.TextureConfigurations.Values, TextureConfigFileWriter.ModifyUpdate.KeepModified);
}
string shortFilePath = Utils.Instance.PathToP4Path(resource.PathName);
if (plugin.CookTexture(plugin.Platform, shortFilePath) == true)
{
PlatformId target;
if (Enum.TryParse(plugin.Platform, true, out target))
{
resource.TextureConfigurations[target].MarkAsCooked();
}
plugin.RequestReloadResource(shortFilePath);
}
}
}
}