Skip to content

Commit

Permalink
Update for new hearthstone version
Browse files Browse the repository at this point in the history
  • Loading branch information
ardittristan committed Jun 3, 2023
1 parent 526be5b commit 32ba545
Show file tree
Hide file tree
Showing 10 changed files with 135 additions and 106 deletions.
34 changes: 30 additions & 4 deletions ExtractAllTexturesFromHS/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,35 @@

string assetBundleDir = Path.Combine(hsPath, @"Data\Win");

List<string> assetBundles = Directory.EnumerateFiles(assetBundleDir, "*.unity3d").ToList();
string extractDir = Path.Combine(ThisAssembly.Project.ProjectPath, @"obj\hs");

Extractor extractor = new(Path.Combine(ThisAssembly.Project.ProjectPath, @"obj\hs"), "1");
IEnumerable<string> assetBundles = Directory.EnumerateFiles(assetBundleDir, "*.unity3d");

IEnumerable<Task> tasks = assetBundles.Select(bundle => extractor.ExtractAsync(bundle));
await Task.WhenAll(tasks);
Extractor extractor = new(extractDir, "1");

Task[] tasks = assetBundles.Select(bundle => extractor.ExtractAsync(bundle, true)).ToArray();

Task whenAll = Task.WhenAll(tasks);

Console.WriteLine();

while (true)
{
await Task.WhenAny(tasks);

Console.Write("\r{0:D}/{1:D} completed", tasks.Count(t => t.IsCompleted), tasks.Length);

if (whenAll.IsCompleted)
break;
}

string iconBundle =
new DirectoryInfo(
Path.GetDirectoryName(
Directory.GetFiles(extractDir, "class_druid-icon.png", SearchOption.AllDirectories).FirstOrDefault()) ??
"")
.Name;

Console.WriteLine();

Console.WriteLine("Found quest icons in '{0}'", iconBundle);
4 changes: 2 additions & 2 deletions HSReflection/Reflection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ private static List<PlayerQuestState> GetQuestStatesInternal()
{
List<PlayerQuestState> quests = new();

object[]? currentQuestValues = Services.QuestManager["m_questState"]["entries"];
object[]? currentQuestValues = Services.QuestManager["m_questState"]["_entries"];

if (currentQuestValues == null) return quests;

Expand Down Expand Up @@ -164,7 +164,7 @@ private static List<Quest> GetQuestsInternal()

Dictionary<QuestPoolType, DateTime> questPools = new();

foreach (MonoStruct? curEntry in questPoolState["entries"])
foreach (MonoStruct? curEntry in questPoolState["_entries"])
{
MonoObject? questPoolEntry = curEntry?["value"];
double secondsUntilNextGrant = DynamicUtil.TryCast<double>(questPoolEntry?["_SecondsUntilNextGrant"]);
Expand Down
2 changes: 1 addition & 1 deletion HSReflection/Util/Map.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ public static class Map
if (map == null) return null;

if (map["keySlots"] == null)
foreach (dynamic? curEntry in map["entries"])
foreach (dynamic? curEntry in map["_entries"])
{
if (curEntry == null) continue;
if (key == curEntry["key"]) return curEntry["value"];
Expand Down
2 changes: 1 addition & 1 deletion HSReflection/Util/RewardTracksManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal static class RewardTracksManager
{ RewardTrackType.NONE, -1 }
};

private static dynamic[] Entries => Services.RewardTrackManager["m_rewardTrackEntries"]["entries"];
private static dynamic[] Entries => Services.RewardTrackManager["m_rewardTrackEntries"]["_entries"];

public static MonoObject? Global => GetRewardTrack(RewardTrackType.GLOBAL);

Expand Down
10 changes: 8 additions & 2 deletions HSReflection/Util/Services.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,20 @@ internal static class Services
public static MonoObject GameDownloadManager => GetService("Hearthstone.Streaming.GameDownloadManager");
public static MonoObject Network => GetService("Network");
public static MonoObject DownloadableDbfCache => GetService("DownloadableDbfCache");
public static MonoObject SpecialEventManager => GetService("SpecialEventManager");
public static MonoObject EventTimingManager => GetService("EventTimingManager");
public static MonoObject GameMgr => GetService("GameMgr");
public static MonoObject DraftManager => GetService("DraftManager");
public static MonoObject AdventureProgressMgr => GetService("AdventureProgressMgr");
public static MonoObject AchieveManager => GetService("AchieveManager");
public static MonoObject AchievementManager => GetService("Hearthstone.Progression.AchievementManager");
public static MonoObject QuestManager => GetService("Hearthstone.Progression.QuestManager");
public static MonoObject RewardTrackManager => GetService("Hearthstone.Progression.RewardTrackManager");
public static MonoObject SpecialEventManager => GetService("Hearthstone.Progression.SpecialEventManager");
public static MonoObject GenericRewardChestNoticeManager => GetService("GenericRewardChestNoticeManager");
public static MonoObject AccountLicenseMgr => GetService("AccountLicenseMgr");
public static MonoObject FixedRewardsMgr => GetService("FixedRewardsMgr");
public static MonoObject ReturningPlayerMgr => GetService("ReturningPlayerMgr");
public static MonoObject FreeDeckMgr => GetService("FreeDeckMgr");
public static MonoObject DemoMgr => GetService("DemoMgr");
public static MonoObject NetCache => GetService("NetCache");
public static MonoObject GameDbf => GetService("GameDbf");
Expand Down Expand Up @@ -65,10 +67,11 @@ internal static class Services
public static MonoObject Cinematic => GetService("Cinematic");
public static MonoObject WidgetRunner => GetService("Hearthstone.UI.WidgetRunner");
public static MonoObject SpriteAtlasProvider => GetService("Hearthstone.UI.SpriteAtlasProvider");
public static MonoObject IProductDataService => GetService("Hearthstone.Store.IProductDataService");
public static MonoObject HearthstoneCheckout => GetService("HearthstoneCheckout");
public static MonoObject NetworkReachabilityManager => GetService("NetworkReachabilityManager");
public static MonoObject VersionConfigurationService => GetService("Hearthstone.Core.Streaming.VersionConfigurationService");
public static MonoObject DeeplinkService => GetService("Hearthstone.Core.Deeplinking.DeeplinkService");
[Obsolete] public static MonoObject DeeplinkService => throw new NotSupportedException("Hearthstone.Core.Deeplinking.DeeplinkService");
public static MonoObject ILoginService => GetService("Hearthstone.Login.ILoginService");
public static MonoObject PartyManager => GetService("PartyManager");
public static MonoObject PlayerMigrationManager => GetService("PlayerMigrationManager");
Expand All @@ -86,6 +89,9 @@ internal static class Services
public static MonoObject APIGatewayService => GetService("Hearthstone.APIGateway.APIGatewayService");
public static MonoObject BreakingNews => GetService("Hearthstone.BreakingNews.BreakingNews");
public static MonoObject IGameStringsService => GetService("IGameStringsService");
public static MonoObject LuckyDrawManager => GetService("LuckyDrawManager");
public static MonoObject CameraManager => GetService("CameraManager");
public static MonoObject LegendaryHeroRenderToTextureService => GetService("LegendaryHeroRenderToTextureService");
public static MonoObject ActorNames => GetService("ActorNames");
public static MonoObject ITouchScreenService => GetService("ITouchScreenService");
}
4 changes: 1 addition & 3 deletions QuestOverlayPlugin/Plugin.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ namespace QuestOverlayPlugin;
// ReSharper disable once ClassNeverInstantiated.Global
public class Plugin : IPlugin, Updater.IUpdater
{
public const string QUEST_ICONS_LOC = "initial_base_global-69";
public const string DEATH_KNIGHT_ICON_LOC = "initial_base_global-85";
public const string QUEST_ICONS_LOC = "initial_base_global-07ca451d-texture-0";

internal Settings Settings = null!;
private Flyout _settingsFlyout = null!;
Expand Down Expand Up @@ -172,7 +171,6 @@ public void OnLoad()
Core.Game.MetaData.HearthstoneBuild.ToString());

Extractor.ExtractAsync(CreateBundlePath(QUEST_ICONS_LOC));
Extractor.ExtractAsync(CreateBundlePath(DEATH_KNIGHT_ICON_LOC));
}

private void UpdateQuestWindow(Mode mode) => UpdateQuestWindow();
Expand Down
11 changes: 3 additions & 8 deletions QuestOverlayPlugin/Util/Icon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,14 +142,9 @@ private static string IconNameFilter(string name)
}
}

private ImageSource BrokenIcon => new BitmapImage(GetImageUri("testt.png"));
private ImageSource BrokenIcon => new BitmapImage(GetImageUri("3Class_Background-icon.png"));

private Uri GetImageUri(string fileName) =>
fileName switch
{
"class_deathknight-icon.png" => new Uri(
Path.Combine(Plugin.Instance.Extractor.OutputPath, Plugin.DEATH_KNIGHT_ICON_LOC, fileName),
UriKind.Absolute),
_ => new Uri(Path.Combine(Plugin.Instance.Extractor.OutputPath, AssetBundle, fileName), UriKind.Absolute)
};
new(Path.Combine(Plugin.Instance.Extractor.OutputPath, AssetBundle, fileName),
UriKind.Absolute);
}
171 changes: 87 additions & 84 deletions TextureExtractor/Extractor.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using AssetsTools.NET;
using AssetsTools.NET.Extra;
using AssetsTools.NET.Texture;
Expand All @@ -11,94 +9,99 @@ namespace TextureExtractor;

public class Extractor
{
public class FileDoesNotExitException : Exception
{
public override string Message => "File does not exist";
}

public readonly string OutputPath;
public readonly string HearthstoneBuild;

public Extractor(string outputPath, string hearthstoneBuild)
{
OutputPath = outputPath;
HearthstoneBuild = hearthstoneBuild;

PortableSettingsProvider.SettingsFileName = "settings.config";
PortableSettingsProviderBase.SettingsDirectory = outputPath;
PortableSettingsProviderBase.AllRoaming = true;
PortableSettingsProvider.ApplyProvider(Properties.Settings.Default);
}

public async Task ExtractAsync(string bundlePath, bool force = false)
{
Task t = new(() => Extract(bundlePath, force));
t.Start();
await Task.WhenAll(t);
}

public void Extract(string bundlePath, bool force = false)
{
if (!Validate(bundlePath, force)) return;

string bundleName = Path.GetFileNameWithoutExtension(bundlePath);

AssetsManager manager = new();

BundleFileInstance bundleInst = manager.LoadBundleFile(bundlePath);
AssetsFileInstance assetsFileInst = manager.LoadAssetsFileFromBundle(bundleInst, 0);

PrepareExportDirectory(bundleName);

foreach (AssetFileInfo assetFile in assetsFileInst.file.GetAssetsOfType(AssetClassID.Texture2D))
{
AssetTypeValueField baseField =
manager.GetBaseField(assetsFileInst, assetFile);
TextureFile textureField = TextureFile.ReadTextureFile(baseField);

string name = textureField.m_Name;

byte[] texDat = textureField.GetTextureData(assetsFileInst);
Bitmap canvas = new(textureField.m_Width, textureField.m_Height, textureField.m_Width * 4,
PixelFormat.Format32bppArgb,
Marshal.UnsafeAddrOfPinnedArrayElement(texDat, 0));
canvas.RotateFlip(RotateFlipType.RotateNoneFlipY);
canvas.Save(Path.Combine(OutputPath, bundleName, name + ".png"));
}

manager.UnloadAll(true);

Properties.Settings.Default.VersionStore[bundleName] = HearthstoneBuild;
Properties.Settings.Default.Save();
}

private bool Validate(string bundlePath, bool forced)
{
if (!File.Exists(bundlePath))
throw new FileDoesNotExitException();

bool hasUpdated = HasUpdated(Path.GetFileNameWithoutExtension(bundlePath), HearthstoneBuild);
public class FileDoesNotExitException : Exception
{
public override string Message => "File does not exist";
}

public readonly string OutputPath;
public readonly string HearthstoneBuild;

public Extractor(string outputPath, string hearthstoneBuild)
{
OutputPath = outputPath;
HearthstoneBuild = hearthstoneBuild;

PortableSettingsProvider.SettingsFileName = "settings.config";
PortableSettingsProviderBase.SettingsDirectory = outputPath;
PortableSettingsProviderBase.AllRoaming = true;
PortableSettingsProvider.ApplyProvider(Properties.Settings.Default);
}

public async Task ExtractAsync(string bundlePath, bool force = false)
{
Task t = new(() => Extract(bundlePath, force));
t.Start();
await Task.WhenAll(t);
}

public void Extract(string bundlePath, bool force = false)
{
if (!Validate(bundlePath, force)) return;

string bundleName = Path.GetFileNameWithoutExtension(bundlePath);

AssetsManager manager = new();

BundleFileInstance bundleInst = manager.LoadBundleFile(bundlePath);
AssetsFileInstance assetsFileInst = manager.LoadAssetsFileFromBundle(bundleInst, 0);

PrepareExportDirectory(bundleName);

foreach (AssetFileInfo assetFile in assetsFileInst.file.GetAssetsOfType(AssetClassID.Texture2D))
{
AssetTypeValueField baseField =
manager.GetBaseField(assetsFileInst, assetFile);
TextureFile textureField = TextureFile.ReadTextureFile(baseField);

string name = textureField.m_Name;

byte[] texDat = textureField.GetTextureData(assetsFileInst);
unsafe
{
fixed (byte* p = texDat)
{
Bitmap canvas = new(textureField.m_Width, textureField.m_Height, textureField.m_Width * 4,
PixelFormat.Format32bppArgb, (IntPtr)p);
canvas.RotateFlip(RotateFlipType.RotateNoneFlipY);
canvas.Save(Path.Combine(OutputPath, bundleName, name + ".png"));
}
}
}

manager.UnloadAll(true);

Properties.Settings.Default.VersionStore[bundleName] = HearthstoneBuild;
Properties.Settings.Default.Save();
}

private bool Validate(string bundlePath, bool forced)
{
if (!File.Exists(bundlePath))
throw new FileDoesNotExitException();

bool hasUpdated = HasUpdated(Path.GetFileNameWithoutExtension(bundlePath), HearthstoneBuild);

#if DEBUG
System.Diagnostics.Debug.WriteLine("Validate: " + !(forced || hasUpdated));
return true;
System.Diagnostics.Debug.WriteLine("Validate: " + !(forced || hasUpdated));
return true;
#else
return !(forced || hasUpdated);
#endif
}
}

private static bool HasUpdated(string fileToExport, string hearthstoneBuild)
{
return string.Equals(Properties.Settings.Default.VersionStore[fileToExport], hearthstoneBuild);
}
private static bool HasUpdated(string fileToExport, string hearthstoneBuild)
{
return string.Equals(Properties.Settings.Default.VersionStore[fileToExport], hearthstoneBuild);
}

private void PrepareExportDirectory(string bundleName)
{
string path = Path.Combine(OutputPath, bundleName);
private void PrepareExportDirectory(string bundleName)
{
string path = Path.Combine(OutputPath, bundleName);

if (Directory.Exists(path))
Directory.Delete(path, true);
if (Directory.Exists(path))
Directory.Delete(path, true);

Directory.CreateDirectory(path);
}
Directory.CreateDirectory(path);
}
}
1 change: 1 addition & 0 deletions TextureExtractor/TextureExtractor.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<TargetFramework>net472</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>

<ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion Version.props
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<Project>
<PropertyGroup>
<Version>1.5.6</Version>
<Version>1.5.7</Version>
</PropertyGroup>
</Project>

0 comments on commit 32ba545

Please sign in to comment.