332 lines
12 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|
|
}
|