mirror of
https://github.com/Jacobwasbeast/LegacyWeaveLoader.git
synced 2026-07-02 17:14:18 +00:00
Rebrand LegacyForge to Weave Loader
Rename across entire codebase: - LegacyForge -> WeaveLoader (identifiers, namespaces, classes, DLLs) - LegacyForgeRuntime -> WeaveLoaderRuntime (C++ project) - LegacyForge.API/Core/Launcher -> WeaveLoader.API/Core/Launcher (C# projects) - [LegacyForge] -> [WeaveLoader] (log prefixes) - legacyforge -> weaveloader (config files, log files, backup suffixes) - Display name "Weave Loader" in README, CONTRIBUTING, LICENSE
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
# Contributing to LegacyForge
|
||||
# Contributing to Weave Loader
|
||||
|
||||
Thank you for your interest in contributing to LegacyForge!
|
||||
Thank you for your interest in contributing to Weave Loader!
|
||||
|
||||
## Project Structure
|
||||
|
||||
- **LegacyForge.Launcher/** -- C# console app that launches the game and injects the runtime DLL
|
||||
- **LegacyForgeRuntime/** -- C++ DLL injected into the game process (hooks, .NET hosting, native exports)
|
||||
- **LegacyForge.Core/** -- C# assembly loaded inside the game process (mod discovery, lifecycle management)
|
||||
- **LegacyForge.API/** -- C# class library that mod authors reference (IMod, Registry, Events)
|
||||
- **WeaveLoader.Launcher/** -- C# console app that launches the game and injects the runtime DLL
|
||||
- **WeaveLoaderRuntime/** -- C++ DLL injected into the game process (hooks, .NET hosting, native exports)
|
||||
- **WeaveLoader.Core/** -- C# assembly loaded inside the game process (mod discovery, lifecycle management)
|
||||
- **WeaveLoader.API/** -- C# class library that mod authors reference (IMod, Registry, Events)
|
||||
- **ExampleMod/** -- Sample mod demonstrating the API
|
||||
|
||||
## Building
|
||||
@@ -21,7 +21,7 @@ Thank you for your interest in contributing to LegacyForge!
|
||||
### C++ Runtime
|
||||
|
||||
```bash
|
||||
cd LegacyForgeRuntime
|
||||
cd WeaveLoaderRuntime
|
||||
cmake -B build -A x64
|
||||
cmake --build build --config Release
|
||||
```
|
||||
@@ -29,7 +29,7 @@ cmake --build build --config Release
|
||||
### C# Projects
|
||||
|
||||
```bash
|
||||
dotnet build LegacyForge.sln -c Release
|
||||
dotnet build Weave Loader.sln -c Release
|
||||
```
|
||||
|
||||
## Guidelines
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
using LegacyForge.API;
|
||||
using LegacyForge.API.Block;
|
||||
using LegacyForge.API.Item;
|
||||
using LegacyForge.API.Events;
|
||||
using WeaveLoader.API;
|
||||
using WeaveLoader.API.Block;
|
||||
using WeaveLoader.API.Item;
|
||||
using WeaveLoader.API.Events;
|
||||
|
||||
namespace ExampleMod;
|
||||
|
||||
[Mod("examplemod", Name = "Example Mod", Version = "1.0.0", Author = "LegacyForge",
|
||||
Description = "A sample mod demonstrating the LegacyForge API")]
|
||||
[Mod("examplemod", Name = "Example Mod", Version = "1.0.0", Author = "WeaveLoader",
|
||||
Description = "A sample mod demonstrating the WeaveLoader API")]
|
||||
public class ExampleMod : IMod
|
||||
{
|
||||
public static RegisteredBlock? RubyOre;
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>ExampleMod</RootNamespace>
|
||||
<AssemblyName>ExampleMod</AssemblyName>
|
||||
<Description>Example mod for LegacyForge demonstrating the mod API</Description>
|
||||
<Description>Example mod for WeaveLoader demonstrating the mod API</Description>
|
||||
<Version>1.0.0</Version>
|
||||
<OutputPath>..\build\mods\ExampleMod</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
@@ -14,8 +14,8 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Private=false: do not copy LegacyForge.API into ExampleMod. API lives in mods/LegacyForge.API/ -->
|
||||
<ProjectReference Include="..\LegacyForge.API\LegacyForge.API.csproj">
|
||||
<!-- Private=false: do not copy WeaveLoader.API into ExampleMod. API lives in mods/WeaveLoader.API/ -->
|
||||
<ProjectReference Include="..\WeaveLoader.API\WeaveLoader.API.csproj">
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 LegacyForge Contributors
|
||||
Copyright (c) 2026 Weave Loader Contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("LegacyForge.Core")]
|
||||
@@ -1,14 +0,0 @@
|
||||
using LegacyForge.API;
|
||||
|
||||
namespace LegacyForge.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Built-in mod representing the LegacyForge API. Counts in the mod list and appears
|
||||
/// when mods/LegacyForge.API/ exists. Does not run lifecycle hooks.
|
||||
/// </summary>
|
||||
[Mod("legacyforge.api", Name = "LegacyForge API", Version = "1.0.0", Author = "LegacyForge",
|
||||
Description = "Mod API and shared types")]
|
||||
internal sealed class LegacyForgeApiMod : IMod
|
||||
{
|
||||
public void OnInitialize() { }
|
||||
}
|
||||
40
README.md
40
README.md
@@ -1,24 +1,24 @@
|
||||
# LegacyForge
|
||||
# Weave Loader
|
||||
|
||||
An SKSE-style mod loader for Minecraft Legacy Edition. LegacyForge injects into the game process at runtime, hooks key engine functions, and hosts the .NET runtime to load C# mods. **Zero game source modifications required.**
|
||||
An SKSE-style mod loader for Minecraft Legacy Edition. Weave Loader injects into the game process at runtime, hooks key engine functions, and hosts the .NET runtime to load C# mods. **Zero game source modifications required.**
|
||||
|
||||
## How It Works
|
||||
|
||||
1. **LegacyForge.exe** launches the game in a suspended state and injects `LegacyForgeRuntime.dll`
|
||||
1. **Weave Loader.exe** launches the game in a suspended state and injects `WeaveLoaderRuntime.dll`
|
||||
2. The runtime DLL uses PDB debug symbols to locate game functions (`MinecraftWorld_RunStaticCtors`, `Minecraft::tick`, etc.)
|
||||
3. MinHook detours those functions to insert mod lifecycle callbacks
|
||||
4. The .NET CoreCLR runtime is hosted inside the game process via hostfxr
|
||||
5. `LegacyForge.Core` discovers and loads C# mod assemblies from the `mods/` folder
|
||||
6. Mods use the `LegacyForge.API` to register blocks, items, entities, and subscribe to game events using Fabric-style namespaced string IDs
|
||||
5. `WeaveLoader.Core` discovers and loads C# mod assemblies from the `mods/` folder
|
||||
6. Mods use the `WeaveLoader.API` to register blocks, items, entities, and subscribe to game events using Fabric-style namespaced string IDs
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
ModLoader/
|
||||
├── LegacyForge.Launcher/ C# launcher (the exe users run)
|
||||
├── LegacyForgeRuntime/ C++ DLL (injected into game process)
|
||||
├── LegacyForge.Core/ C# mod management (loaded inside game)
|
||||
├── LegacyForge.API/ C# mod API (what mod authors reference)
|
||||
├── WeaveLoader.Launcher/ C# launcher (the exe users run)
|
||||
├── WeaveLoaderRuntime/ C++ DLL (injected into game process)
|
||||
├── WeaveLoader.Core/ C# mod management (loaded inside game)
|
||||
├── WeaveLoader.API/ C# mod API (what mod authors reference)
|
||||
└── ExampleMod/ Sample mod for reference
|
||||
```
|
||||
|
||||
@@ -36,7 +36,7 @@ ModLoader/
|
||||
**C++ Runtime DLL:**
|
||||
|
||||
```bash
|
||||
cd LegacyForgeRuntime
|
||||
cd WeaveLoaderRuntime
|
||||
cmake -B build -A x64
|
||||
cmake --build build --config Release
|
||||
```
|
||||
@@ -44,27 +44,27 @@ cmake --build build --config Release
|
||||
**C# Projects:**
|
||||
|
||||
```bash
|
||||
dotnet build LegacyForge.sln
|
||||
dotnet build Weave Loader.sln
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
1. Build LegacyForge (see above)
|
||||
1. Build Weave Loader (see above)
|
||||
2. Copy the output files to a folder:
|
||||
- `LegacyForge.exe`
|
||||
- `LegacyForgeRuntime.dll`
|
||||
- `LegacyForge.Core.dll`
|
||||
- `LegacyForge.API.dll`
|
||||
- `Weave Loader.exe`
|
||||
- `WeaveLoaderRuntime.dll`
|
||||
- `WeaveLoader.Core.dll`
|
||||
- `WeaveLoader.API.dll`
|
||||
3. Create a `mods/` folder and drop mod DLLs in it
|
||||
4. Run `LegacyForge.exe` -- it will ask for the game exe path on first launch
|
||||
4. Run `Weave Loader.exe` -- it will ask for the game exe path on first launch
|
||||
5. The game starts with mods loaded
|
||||
|
||||
## Writing a Mod
|
||||
|
||||
Create a new .NET 8 class library and reference `LegacyForge.API`:
|
||||
Create a new .NET 8 class library and reference `WeaveLoader.API`:
|
||||
|
||||
```csharp
|
||||
using LegacyForge.API;
|
||||
using WeaveLoader.API;
|
||||
|
||||
[Mod("mymod", Name = "My Mod", Version = "1.0.0", Author = "You")]
|
||||
public class MyMod : IMod
|
||||
@@ -82,7 +82,7 @@ public class MyMod : IMod
|
||||
}
|
||||
```
|
||||
|
||||
Build it, copy the DLL to `mods/`, and launch via LegacyForge.
|
||||
Build it, copy the DLL to `mods/`, and launch via Weave Loader.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
3
WeaveLoader.API/AssemblyInfo.cs
Normal file
3
WeaveLoader.API/AssemblyInfo.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("WeaveLoader.Core")]
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API.Assets;
|
||||
namespace WeaveLoader.API.Assets;
|
||||
|
||||
/// <summary>
|
||||
/// Asset registration for mods. Use for language strings and (future) texture paths.
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API.Block;
|
||||
namespace WeaveLoader.API.Block;
|
||||
|
||||
public enum MaterialType
|
||||
{
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API.Block;
|
||||
namespace WeaveLoader.API.Block;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a block that has been registered with the game engine.
|
||||
@@ -19,7 +19,7 @@ public class RegisteredBlock
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Block registration via the LegacyForge registry.
|
||||
/// Block registration via the WeaveLoader registry.
|
||||
/// Accessed through <see cref="Registry.Block"/>.
|
||||
/// </summary>
|
||||
public static class BlockRegistry
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API;
|
||||
namespace WeaveLoader.API;
|
||||
|
||||
/// <summary>
|
||||
/// Creative inventory tabs matching the game's internal group indices.
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API.Entity;
|
||||
namespace WeaveLoader.API.Entity;
|
||||
|
||||
/// <summary>
|
||||
/// Fluent builder for defining entity properties.
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API.Entity;
|
||||
namespace WeaveLoader.API.Entity;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an entity type that has been registered with the game engine.
|
||||
@@ -16,7 +16,7 @@ public class RegisteredEntity
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Entity registration via the LegacyForge registry.
|
||||
/// Entity registration via the WeaveLoader registry.
|
||||
/// Accessed through <see cref="Registry.Entity"/>.
|
||||
/// </summary>
|
||||
public static class EntityRegistry
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API.Events;
|
||||
namespace WeaveLoader.API.Events;
|
||||
|
||||
public class TickEventArgs : EventArgs { }
|
||||
|
||||
@@ -42,7 +42,7 @@ public class PlayerJoinEventArgs : EventArgs
|
||||
|
||||
/// <summary>
|
||||
/// Global game event subscriptions. Subscribe to these in your mod's OnInitialize().
|
||||
/// Events are fired from the game's main thread via hooks in LegacyForgeRuntime.
|
||||
/// Events are fired from the game's main thread via hooks in WeaveLoaderRuntime.
|
||||
/// </summary>
|
||||
public static class GameEvents
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace LegacyForge.API;
|
||||
namespace WeaveLoader.API;
|
||||
|
||||
/// <summary>
|
||||
/// The main interface all LegacyForge mods must implement.
|
||||
/// The main interface all WeaveLoader mods must implement.
|
||||
/// Default interface methods allow mods to only override what they need.
|
||||
/// </summary>
|
||||
public interface IMod
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API;
|
||||
namespace WeaveLoader.API;
|
||||
|
||||
/// <summary>
|
||||
/// A namespaced identifier in the form "namespace:path" (e.g. "minecraft:stone", "mymod:ruby_ore").
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API.Item;
|
||||
namespace WeaveLoader.API.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Fluent builder for defining item properties.
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API.Item;
|
||||
namespace WeaveLoader.API.Item;
|
||||
|
||||
/// <summary>
|
||||
/// Represents an item that has been registered with the game engine.
|
||||
@@ -19,7 +19,7 @@ public class RegisteredItem
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Item registration via the LegacyForge registry.
|
||||
/// Item registration via the WeaveLoader registry.
|
||||
/// Accessed through <see cref="Registry.Item"/>.
|
||||
/// </summary>
|
||||
public static class ItemRegistry
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace LegacyForge.API;
|
||||
namespace WeaveLoader.API;
|
||||
|
||||
public enum LogLevel
|
||||
{
|
||||
@@ -17,7 +17,7 @@ public static class Logger
|
||||
|
||||
/// <summary>
|
||||
/// Set the log handler that routes messages to the native runtime.
|
||||
/// Called by LegacyForge.Core during initialization.
|
||||
/// Called by WeaveLoader.Core during initialization.
|
||||
/// </summary>
|
||||
public static void SetLogHandler(Action<string, LogLevel> handler) => LogHandler = handler;
|
||||
|
||||
@@ -31,6 +31,6 @@ public static class Logger
|
||||
if (LogHandler != null)
|
||||
LogHandler(message, level);
|
||||
else
|
||||
Console.WriteLine($"[LegacyForge/{level}] {message}");
|
||||
Console.WriteLine($"[WeaveLoader/{level}] {message}");
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace LegacyForge.API;
|
||||
namespace WeaveLoader.API;
|
||||
|
||||
/// <summary>
|
||||
/// Marks a class as a LegacyForge mod and provides metadata.
|
||||
/// Marks a class as a WeaveLoader mod and provides metadata.
|
||||
/// The class must also implement <see cref="IMod"/>.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
|
||||
@@ -1,14 +1,14 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LegacyForge.API;
|
||||
namespace WeaveLoader.API;
|
||||
|
||||
/// <summary>
|
||||
/// Internal P/Invoke bindings to LegacyForgeRuntime.dll native exports.
|
||||
/// Internal P/Invoke bindings to WeaveLoaderRuntime.dll native exports.
|
||||
/// Mod authors should use the Registry and Logger classes instead of calling these directly.
|
||||
/// </summary>
|
||||
internal static class NativeInterop
|
||||
{
|
||||
private const string RuntimeDll = "LegacyForgeRuntime";
|
||||
private const string RuntimeDll = "WeaveLoaderRuntime";
|
||||
|
||||
[DllImport(RuntimeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
|
||||
internal static extern int native_register_block(
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace LegacyForge.API.Recipe;
|
||||
namespace WeaveLoader.API.Recipe;
|
||||
|
||||
/// <summary>
|
||||
/// Recipe registration via the LegacyForge registry.
|
||||
/// Recipe registration via the WeaveLoader registry.
|
||||
/// Accessed through <see cref="Registry.Recipe"/>.
|
||||
/// </summary>
|
||||
public static class RecipeRegistry
|
||||
@@ -1,13 +1,13 @@
|
||||
using LegacyForge.API.Block;
|
||||
using LegacyForge.API.Item;
|
||||
using LegacyForge.API.Entity;
|
||||
using LegacyForge.API.Recipe;
|
||||
using LegacyForge.API.Assets;
|
||||
using WeaveLoader.API.Block;
|
||||
using WeaveLoader.API.Item;
|
||||
using WeaveLoader.API.Entity;
|
||||
using WeaveLoader.API.Recipe;
|
||||
using WeaveLoader.API.Assets;
|
||||
|
||||
namespace LegacyForge.API;
|
||||
namespace WeaveLoader.API;
|
||||
|
||||
/// <summary>
|
||||
/// Central access point for all LegacyForge registries.
|
||||
/// Central access point for all WeaveLoader registries.
|
||||
/// Use Registry.Block, Registry.Item, Registry.Entity, Registry.Recipe, or Registry.Assets.
|
||||
/// </summary>
|
||||
public static class Registry
|
||||
@@ -4,11 +4,11 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>LegacyForge.API</RootNamespace>
|
||||
<AssemblyName>LegacyForge.API</AssemblyName>
|
||||
<Description>Mod API for LegacyForge - Minecraft Legacy Edition mod loader</Description>
|
||||
<RootNamespace>WeaveLoader.API</RootNamespace>
|
||||
<AssemblyName>WeaveLoader.API</AssemblyName>
|
||||
<Description>Mod API for WeaveLoader - Minecraft Legacy Edition mod loader</Description>
|
||||
<Version>1.0.0</Version>
|
||||
<OutputPath>..\build\mods\LegacyForge.API</OutputPath>
|
||||
<OutputPath>..\build\mods\WeaveLoader.API</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||
</PropertyGroup>
|
||||
@@ -1,8 +1,8 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.Loader;
|
||||
using LegacyForge.API;
|
||||
using WeaveLoader.API;
|
||||
|
||||
namespace LegacyForge.Core;
|
||||
namespace WeaveLoader.Core;
|
||||
|
||||
internal static class ModDiscovery
|
||||
{
|
||||
@@ -21,18 +21,18 @@ internal static class ModDiscovery
|
||||
return mods;
|
||||
}
|
||||
|
||||
// Count LegacyForge.API as a mod when its folder exists (mods/LegacyForge.API/)
|
||||
var apiFolder = Path.Combine(modsPath, "LegacyForge.API");
|
||||
// Count WeaveLoader.API as a mod when its folder exists (mods/WeaveLoader.API/)
|
||||
var apiFolder = Path.Combine(modsPath, "WeaveLoader.API");
|
||||
if (Directory.Exists(apiFolder))
|
||||
{
|
||||
var apiMod = new LegacyForgeApiMod();
|
||||
var attr = typeof(LegacyForgeApiMod).GetCustomAttribute<ModAttribute>()!;
|
||||
var apiMod = new WeaveLoaderApiMod();
|
||||
var attr = typeof(WeaveLoaderApiMod).GetCustomAttribute<ModAttribute>()!;
|
||||
mods.Add(new DiscoveredMod(apiMod, attr, typeof(ModDiscovery).Assembly));
|
||||
Logger.Info($"Discovered mod: {attr.Name} v{attr.Version} by {attr.Author} (mods/LegacyForge.API/)");
|
||||
Logger.Info($"Discovered mod: {attr.Name} v{attr.Version} by {attr.Author} (mods/WeaveLoader.API/)");
|
||||
}
|
||||
|
||||
// Scan each mod folder: mods/ExampleMod/, mods/SomeMod/, etc.
|
||||
// Each subfolder may contain one or more mod DLLs (we skip LegacyForge.API.dll)
|
||||
// Each subfolder may contain one or more mod DLLs (we skip WeaveLoader.API.dll)
|
||||
var modFolders = Directory.GetDirectories(modsPath);
|
||||
foreach (var folder in modFolders)
|
||||
{
|
||||
@@ -44,7 +44,7 @@ internal static class ModDiscovery
|
||||
string fileName = Path.GetFileName(dllPath);
|
||||
|
||||
// Skip the API assembly -- it's in its own folder and counted above
|
||||
if (fileName.Equals("LegacyForge.API.dll", StringComparison.OrdinalIgnoreCase))
|
||||
if (fileName.Equals("WeaveLoader.API.dll", StringComparison.OrdinalIgnoreCase))
|
||||
continue;
|
||||
|
||||
try
|
||||
@@ -69,8 +69,8 @@ internal static class ModDiscovery
|
||||
var fileName = Path.GetFileName(dllPath);
|
||||
var fullPath = Path.GetFullPath(dllPath);
|
||||
|
||||
// Load into the SAME ALC that LegacyForge.Core lives in (the hostfxr component context).
|
||||
// This ensures LegacyForge.API types (IMod, ModAttribute, etc.) have the same identity.
|
||||
// Load into the SAME ALC that WeaveLoader.Core lives in (the hostfxr component context).
|
||||
// This ensures WeaveLoader.API types (IMod, ModAttribute, etc.) have the same identity.
|
||||
var coreContext = AssemblyLoadContext.GetLoadContext(typeof(ModDiscovery).Assembly)
|
||||
?? AssemblyLoadContext.Default;
|
||||
var assembly = coreContext.LoadFromAssemblyPath(fullPath);
|
||||
@@ -1,6 +1,6 @@
|
||||
using LegacyForge.API;
|
||||
using WeaveLoader.API;
|
||||
|
||||
namespace LegacyForge.Core;
|
||||
namespace WeaveLoader.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Manages the lifecycle of all loaded mods.
|
||||
@@ -4,9 +4,9 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>LegacyForge.Core</RootNamespace>
|
||||
<AssemblyName>LegacyForge.Core</AssemblyName>
|
||||
<Description>LegacyForge core runtime - mod discovery and lifecycle management</Description>
|
||||
<RootNamespace>WeaveLoader.Core</RootNamespace>
|
||||
<AssemblyName>WeaveLoader.Core</AssemblyName>
|
||||
<Description>WeaveLoader core runtime - mod discovery and lifecycle management</Description>
|
||||
<Version>1.0.0</Version>
|
||||
<OutputPath>..\build</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
@@ -14,7 +14,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\LegacyForge.API\LegacyForge.API.csproj" />
|
||||
<ProjectReference Include="..\WeaveLoader.API\WeaveLoader.API.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
14
WeaveLoader.Core/WeaveLoaderApiMod.cs
Normal file
14
WeaveLoader.Core/WeaveLoaderApiMod.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using WeaveLoader.API;
|
||||
|
||||
namespace WeaveLoader.Core;
|
||||
|
||||
/// <summary>
|
||||
/// Built-in mod representing the WeaveLoader API. Counts in the mod list and appears
|
||||
/// when mods/WeaveLoader.API/ exists. Does not run lifecycle hooks.
|
||||
/// </summary>
|
||||
[Mod("weaveloader.api", Name = "WeaveLoader API", Version = "1.0.0", Author = "WeaveLoader",
|
||||
Description = "Mod API and shared types")]
|
||||
internal sealed class WeaveLoaderApiMod : IMod
|
||||
{
|
||||
public void OnInitialize() { }
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
using System.Runtime.InteropServices;
|
||||
using LegacyForge.API;
|
||||
using WeaveLoader.API;
|
||||
|
||||
namespace LegacyForge.Core;
|
||||
namespace WeaveLoader.Core;
|
||||
|
||||
public static class LegacyForgeCore
|
||||
public static class WeaveLoaderCore
|
||||
{
|
||||
private static ModManager? _modManager;
|
||||
private static bool _initialized;
|
||||
@@ -15,7 +15,7 @@ public static class LegacyForgeCore
|
||||
|
||||
Logger.SetLogHandler((message, level) =>
|
||||
{
|
||||
string formatted = $"[LegacyForge/{level}] {message}";
|
||||
string formatted = $"[WeaveLoader/{level}] {message}";
|
||||
try
|
||||
{
|
||||
NativeInterop.native_log(formatted, (int)level);
|
||||
@@ -26,7 +26,7 @@ public static class LegacyForgeCore
|
||||
}
|
||||
});
|
||||
|
||||
Logger.Info("LegacyForge Core initialized");
|
||||
Logger.Info("WeaveLoader Core initialized");
|
||||
_modManager = new ModManager();
|
||||
return 0;
|
||||
}
|
||||
@@ -89,7 +89,7 @@ public static class LegacyForgeCore
|
||||
public static int Shutdown(IntPtr args, int sizeBytes)
|
||||
{
|
||||
_modManager?.Shutdown();
|
||||
Logger.Info("LegacyForge shut down.");
|
||||
Logger.Info("WeaveLoader shut down.");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Text.Json;
|
||||
|
||||
namespace LegacyForge.Launcher;
|
||||
namespace WeaveLoader.Launcher;
|
||||
|
||||
public class Config
|
||||
{
|
||||
@@ -1,6 +1,6 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LegacyForge.Launcher;
|
||||
namespace WeaveLoader.Launcher;
|
||||
|
||||
/// <summary>
|
||||
/// Thin wrapper around the Win32 GetOpenFileName API.
|
||||
@@ -3,11 +3,11 @@ using System.Diagnostics;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace LegacyForge.Launcher;
|
||||
namespace WeaveLoader.Launcher;
|
||||
|
||||
/// <summary>
|
||||
/// Handles launching the game process in a suspended state and injecting
|
||||
/// the LegacyForgeRuntime DLL via CreateRemoteThread + LoadLibraryW.
|
||||
/// the WeaveLoaderRuntime DLL via CreateRemoteThread + LoadLibraryW.
|
||||
/// </summary>
|
||||
public static class Injector
|
||||
{
|
||||
@@ -1,23 +1,23 @@
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
namespace LegacyForge.Launcher;
|
||||
namespace WeaveLoader.Launcher;
|
||||
|
||||
class Program
|
||||
{
|
||||
private const string RuntimeDllName = "LegacyForgeRuntime.dll";
|
||||
private const string RuntimeDllName = "WeaveLoaderRuntime.dll";
|
||||
|
||||
[STAThread]
|
||||
static int Main(string[] args)
|
||||
{
|
||||
Console.WriteLine("╔══════════════════════════════════╗");
|
||||
Console.WriteLine("║ LegacyForge v1.0 ║");
|
||||
Console.WriteLine("║ WeaveLoader v1.0 ║");
|
||||
Console.WriteLine("║ Mod Loader for MC Legacy Edition║");
|
||||
Console.WriteLine("╚══════════════════════════════════╝");
|
||||
Console.WriteLine();
|
||||
|
||||
// All paths relative to where the exe lives, not the working directory
|
||||
string baseDir = AppContext.BaseDirectory;
|
||||
string configFile = Path.Combine(baseDir, "legacyforge.json");
|
||||
string configFile = Path.Combine(baseDir, "weaveloader.json");
|
||||
string runtimeDll = Path.Combine(baseDir, RuntimeDllName);
|
||||
string modsDir = Path.Combine(baseDir, "mods");
|
||||
|
||||
@@ -55,11 +55,11 @@ class Program
|
||||
Console.Error.WriteLine($"Expected at: {runtimeDll}");
|
||||
Console.Error.WriteLine();
|
||||
Console.Error.WriteLine("The C++ runtime DLL must be built separately with CMake:");
|
||||
Console.Error.WriteLine(" cd LegacyForgeRuntime");
|
||||
Console.Error.WriteLine(" cd WeaveLoaderRuntime");
|
||||
Console.Error.WriteLine(" cmake -B build -A x64");
|
||||
Console.Error.WriteLine(" cmake --build build --config Release");
|
||||
Console.Error.WriteLine();
|
||||
Console.Error.WriteLine("Then copy LegacyForgeRuntime.dll to the same folder as LegacyForge.exe.");
|
||||
Console.Error.WriteLine("Then copy WeaveLoaderRuntime.dll to the same folder as WeaveLoader.exe.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class Program
|
||||
Console.WriteLine($"[OK] {RuntimeDllName} injected and loaded in target process.");
|
||||
|
||||
Injector.ResumeProcess(process);
|
||||
Console.WriteLine("[OK] Game resumed. LegacyForge is active.");
|
||||
Console.WriteLine("[OK] Game resumed. WeaveLoader is active.");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("Press any key to exit the launcher (game will keep running).");
|
||||
Console.ReadKey(true);
|
||||
@@ -5,9 +5,9 @@
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>LegacyForge.Launcher</RootNamespace>
|
||||
<AssemblyName>LegacyForge</AssemblyName>
|
||||
<Description>LegacyForge launcher - injects the mod loader runtime into Minecraft Legacy Edition</Description>
|
||||
<RootNamespace>WeaveLoader.Launcher</RootNamespace>
|
||||
<AssemblyName>WeaveLoader</AssemblyName>
|
||||
<Description>WeaveLoader launcher - injects the mod loader runtime into Minecraft Legacy Edition</Description>
|
||||
<Version>1.0.0</Version>
|
||||
<OutputPath>..\build</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
@@ -16,17 +16,17 @@
|
||||
|
||||
<!-- Build the C++ runtime DLL via CMake before the launcher -->
|
||||
<Target Name="BuildNativeRuntime" BeforeTargets="Build">
|
||||
<Message Importance="high" Text="[LegacyForge] Configuring C++ runtime with CMake..." />
|
||||
<Exec Command="cmake -B "$(MSBuildThisFileDirectory)..\LegacyForgeRuntime\build" -S "$(MSBuildThisFileDirectory)..\LegacyForgeRuntime" -A x64"
|
||||
WorkingDirectory="$(MSBuildThisFileDirectory)..\LegacyForgeRuntime" />
|
||||
<Message Importance="high" Text="[LegacyForge] Building C++ runtime..." />
|
||||
<Exec Command="cmake --build "$(MSBuildThisFileDirectory)..\LegacyForgeRuntime\build" --config $(Configuration)"
|
||||
WorkingDirectory="$(MSBuildThisFileDirectory)..\LegacyForgeRuntime" />
|
||||
<Message Importance="high" Text="[WeaveLoader] Configuring C++ runtime with CMake..." />
|
||||
<Exec Command="cmake -B "$(MSBuildThisFileDirectory)..\WeaveLoaderRuntime\build" -S "$(MSBuildThisFileDirectory)..\WeaveLoaderRuntime" -A x64"
|
||||
WorkingDirectory="$(MSBuildThisFileDirectory)..\WeaveLoaderRuntime" />
|
||||
<Message Importance="high" Text="[WeaveLoader] Building C++ runtime..." />
|
||||
<Exec Command="cmake --build "$(MSBuildThisFileDirectory)..\WeaveLoaderRuntime\build" --config $(Configuration)"
|
||||
WorkingDirectory="$(MSBuildThisFileDirectory)..\WeaveLoaderRuntime" />
|
||||
</Target>
|
||||
|
||||
<!-- Copy the runtimeconfig.json to the build output -->
|
||||
<Target Name="CopyRuntimeConfig" AfterTargets="Build">
|
||||
<Copy SourceFiles="$(MSBuildThisFileDirectory)..\LegacyForge.Core\LegacyForge.Core.runtimeconfig.json"
|
||||
<Copy SourceFiles="$(MSBuildThisFileDirectory)..\WeaveLoader.Core\WeaveLoader.Core.runtimeconfig.json"
|
||||
DestinationFolder="$(OutputPath)"
|
||||
SkipUnchangedFiles="true" />
|
||||
</Target>
|
||||
@@ -3,11 +3,11 @@ Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31903.59
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LegacyForge.Launcher", "LegacyForge.Launcher\LegacyForge.Launcher.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WeaveLoader.Launcher", "WeaveLoader.Launcher\WeaveLoader.Launcher.csproj", "{A1B2C3D4-E5F6-7890-ABCD-EF1234567890}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LegacyForge.API", "LegacyForge.API\LegacyForge.API.csproj", "{B2C3D4E5-F6A7-8901-BCDE-F12345678901}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WeaveLoader.API", "WeaveLoader.API\WeaveLoader.API.csproj", "{B2C3D4E5-F6A7-8901-BCDE-F12345678901}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LegacyForge.Core", "LegacyForge.Core\LegacyForge.Core.csproj", "{C3D4E5F6-A7B8-9012-CDEF-123456789012}"
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WeaveLoader.Core", "WeaveLoader.Core\WeaveLoader.Core.csproj", "{C3D4E5F6-A7B8-9012-CDEF-123456789012}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ExampleMod", "ExampleMod\ExampleMod.csproj", "{D4E5F6A7-B8C9-0123-DEF0-234567890123}"
|
||||
EndProject
|
||||
@@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.24)
|
||||
cmake_policy(SET CMP0091 NEW)
|
||||
project(LegacyForgeRuntime LANGUAGES CXX)
|
||||
project(WeaveLoaderRuntime LANGUAGES CXX)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
@@ -76,7 +76,7 @@ else()
|
||||
endif()
|
||||
|
||||
# ── Runtime DLL target ─────────────────────────────────────────────────
|
||||
add_library(LegacyForgeRuntime SHARED
|
||||
add_library(WeaveLoaderRuntime SHARED
|
||||
src/dllmain.cpp
|
||||
src/LogUtil.cpp
|
||||
src/CrashHandler.cpp
|
||||
@@ -94,35 +94,35 @@ add_library(LegacyForgeRuntime SHARED
|
||||
src/ModAtlas.cpp
|
||||
)
|
||||
|
||||
target_include_directories(LegacyForgeRuntime PRIVATE
|
||||
target_include_directories(WeaveLoaderRuntime PRIVATE
|
||||
"${NETHOST_INCLUDE_DIR}"
|
||||
"${STB_DIR}"
|
||||
)
|
||||
|
||||
target_link_libraries(LegacyForgeRuntime PRIVATE
|
||||
target_link_libraries(WeaveLoaderRuntime PRIVATE
|
||||
minhook
|
||||
raw_pdb
|
||||
)
|
||||
|
||||
if(EXISTS "${NETHOST_LIB}")
|
||||
target_link_libraries(LegacyForgeRuntime PRIVATE "${NETHOST_LIB}")
|
||||
target_link_libraries(WeaveLoaderRuntime PRIVATE "${NETHOST_LIB}")
|
||||
if(NETHOST_STATIC)
|
||||
target_compile_definitions(LegacyForgeRuntime PRIVATE NETHOST_USE_AS_STATIC)
|
||||
target_compile_definitions(WeaveLoaderRuntime PRIVATE NETHOST_USE_AS_STATIC)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "nethost lib not found. You may need to set NETHOST_DIR.")
|
||||
endif()
|
||||
|
||||
target_compile_definitions(LegacyForgeRuntime PRIVATE
|
||||
target_compile_definitions(WeaveLoaderRuntime PRIVATE
|
||||
WIN32_LEAN_AND_MEAN
|
||||
_CRT_SECURE_NO_WARNINGS
|
||||
)
|
||||
|
||||
if(MSVC)
|
||||
target_compile_options(LegacyForgeRuntime PRIVATE /W3 /MP)
|
||||
target_compile_options(WeaveLoaderRuntime PRIVATE /W3 /MP)
|
||||
endif()
|
||||
|
||||
set_target_properties(LegacyForgeRuntime PROPERTIES
|
||||
set_target_properties(WeaveLoaderRuntime PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../build"
|
||||
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../build"
|
||||
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../build"
|
||||
@@ -186,7 +186,7 @@ static LONG WINAPI VectoredHandler(EXCEPTION_POINTERS* ep)
|
||||
st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||
|
||||
LogUtil::LogCrash("========================================");
|
||||
LogUtil::LogCrash(" LegacyForge Crash Report");
|
||||
LogUtil::LogCrash(" WeaveLoader Crash Report");
|
||||
LogUtil::LogCrash(" %s", timeBuf);
|
||||
LogUtil::LogCrash("========================================");
|
||||
LogUtil::LogCrash("");
|
||||
@@ -263,7 +263,7 @@ static LONG WINAPI VectoredHandler(EXCEPTION_POINTERS* ep)
|
||||
LogUtil::LogCrash("========================================");
|
||||
LogUtil::LogCrash("");
|
||||
|
||||
LogUtil::Log("[LegacyForge] CRASH DETECTED - see logs/crash.log for details");
|
||||
LogUtil::Log("[WeaveLoader] CRASH DETECTED - see logs/crash.log for details");
|
||||
|
||||
InterlockedExchange(&s_handling, 0);
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
@@ -281,7 +281,7 @@ void Install(HMODULE runtimeModule)
|
||||
void SetGameBase(uintptr_t base)
|
||||
{
|
||||
s_gameBase = base;
|
||||
LogUtil::Log("[LegacyForge] Crash handler: game base set to 0x%016llX", (DWORD64)base);
|
||||
LogUtil::Log("[WeaveLoader] Crash handler: game base set to 0x%016llX", (DWORD64)base);
|
||||
}
|
||||
|
||||
} // namespace CrashHandler
|
||||
@@ -49,7 +49,7 @@ typedef void (__fastcall *VectorPushBackMove_fn)(void* vectorThis, void* sharedP
|
||||
void AddPending(int itemId, int count, int auxValue, int groupIndex)
|
||||
{
|
||||
s_pendingItems.push_back({ itemId, count, auxValue, groupIndex });
|
||||
LogUtil::Log("[LegacyForge] Queued creative item: id=%d group=%d", itemId, groupIndex);
|
||||
LogUtil::Log("[WeaveLoader] Queued creative item: id=%d group=%d", itemId, groupIndex);
|
||||
}
|
||||
|
||||
bool ResolveSymbols(SymbolResolver& resolver)
|
||||
@@ -70,22 +70,22 @@ bool ResolveSymbols(SymbolResolver& resolver)
|
||||
pSpecs = resolver.Resolve(
|
||||
"?specs@IUIScene_CreativeMenu@@1PEAPEAUTabSpec@1@EA");
|
||||
|
||||
if (pCategoryGroups) LogUtil::Log("[LegacyForge] categoryGroups @ %p", pCategoryGroups);
|
||||
else LogUtil::Log("[LegacyForge] MISSING: categoryGroups");
|
||||
if (pCategoryGroups) LogUtil::Log("[WeaveLoader] categoryGroups @ %p", pCategoryGroups);
|
||||
else LogUtil::Log("[WeaveLoader] MISSING: categoryGroups");
|
||||
|
||||
if (pItemInstanceCtor) LogUtil::Log("[LegacyForge] ItemInstance ctor @ %p", pItemInstanceCtor);
|
||||
else LogUtil::Log("[LegacyForge] MISSING: ItemInstance(int,int,int)");
|
||||
if (pItemInstanceCtor) LogUtil::Log("[WeaveLoader] ItemInstance ctor @ %p", pItemInstanceCtor);
|
||||
else LogUtil::Log("[WeaveLoader] MISSING: ItemInstance(int,int,int)");
|
||||
|
||||
if (pSharedPtrCtor) LogUtil::Log("[LegacyForge] shared_ptr<II> ctor @ %p", pSharedPtrCtor);
|
||||
else LogUtil::Log("[LegacyForge] MISSING: shared_ptr<ItemInstance>(ItemInstance*)");
|
||||
if (pSharedPtrCtor) LogUtil::Log("[WeaveLoader] shared_ptr<II> ctor @ %p", pSharedPtrCtor);
|
||||
else LogUtil::Log("[WeaveLoader] MISSING: shared_ptr<ItemInstance>(ItemInstance*)");
|
||||
|
||||
if (pVectorPushBack) LogUtil::Log("[LegacyForge] vector::push_back @ %p", pVectorPushBack);
|
||||
else LogUtil::Log("[LegacyForge] MISSING: vector<shared_ptr<II>>::push_back");
|
||||
if (pVectorPushBack) LogUtil::Log("[WeaveLoader] vector::push_back @ %p", pVectorPushBack);
|
||||
else LogUtil::Log("[WeaveLoader] MISSING: vector<shared_ptr<II>>::push_back");
|
||||
|
||||
if (pSpecs) LogUtil::Log("[LegacyForge] specs @ %p", pSpecs);
|
||||
if (pSpecs) LogUtil::Log("[WeaveLoader] specs @ %p", pSpecs);
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] MISSING: specs (page counts won't be updated)");
|
||||
LogUtil::Log("[WeaveLoader] MISSING: specs (page counts won't be updated)");
|
||||
PdbParser::DumpMatching("specs@IUIScene_CreativeMenu");
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ void UpdateTabPageCounts()
|
||||
{
|
||||
if (!pSpecs || !pCategoryGroups)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Cannot update tab page counts: specs=%p categoryGroups=%p",
|
||||
LogUtil::Log("[WeaveLoader] Cannot update tab page counts: specs=%p categoryGroups=%p",
|
||||
pSpecs, pCategoryGroups);
|
||||
return;
|
||||
}
|
||||
@@ -112,7 +112,7 @@ void UpdateTabPageCounts()
|
||||
void** specsArray = *reinterpret_cast<void***>(pSpecs);
|
||||
if (!specsArray)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] specs pointer is null, TabSpec array not yet allocated");
|
||||
LogUtil::Log("[WeaveLoader] specs pointer is null, TabSpec array not yet allocated");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ void UpdateTabPageCounts()
|
||||
|
||||
if (totalItems != oldItems)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Tab %d: staticItems %u -> %u, pages %u -> %u",
|
||||
LogUtil::Log("[WeaveLoader] Tab %d: staticItems %u -> %u, pages %u -> %u",
|
||||
tabIdx, oldItems, totalItems, oldPages, static_cast<unsigned int>(newPages));
|
||||
}
|
||||
}
|
||||
@@ -158,13 +158,13 @@ void InjectItems()
|
||||
{
|
||||
if (!pCategoryGroups || !pItemInstanceCtor || !pSharedPtrCtor || !pVectorPushBack)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Cannot inject creative items: missing symbols");
|
||||
LogUtil::Log("[WeaveLoader] Cannot inject creative items: missing symbols");
|
||||
return;
|
||||
}
|
||||
|
||||
if (s_pendingItems.empty())
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] No creative items to inject");
|
||||
LogUtil::Log("[WeaveLoader] No creative items to inject");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -180,7 +180,7 @@ void InjectItems()
|
||||
{
|
||||
if (item.groupIndex < 0 || item.groupIndex >= CREATIVE_GROUP_COUNT)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Skipping creative item id=%d: invalid group %d",
|
||||
LogUtil::Log("[WeaveLoader] Skipping creative item id=%d: invalid group %d",
|
||||
item.itemId, item.groupIndex);
|
||||
continue;
|
||||
}
|
||||
@@ -191,7 +191,7 @@ void InjectItems()
|
||||
|
||||
// Verify ItemInstance vtable was set (first 8 bytes should be non-null)
|
||||
void* vtable = *reinterpret_cast<void**>(rawItem);
|
||||
LogUtil::Log("[LegacyForge] ItemInstance(%d,%d,%d) @ %p, vtable=%p",
|
||||
LogUtil::Log("[WeaveLoader] ItemInstance(%d,%d,%d) @ %p, vtable=%p",
|
||||
item.itemId, item.count, item.auxValue, rawItem, vtable);
|
||||
|
||||
char spBuf[16];
|
||||
@@ -201,7 +201,7 @@ void InjectItems()
|
||||
// Log shared_ptr contents (ptr + control block)
|
||||
void* spPtr = *reinterpret_cast<void**>(spBuf);
|
||||
void* spCtrl = *reinterpret_cast<void**>(spBuf + 8);
|
||||
LogUtil::Log("[LegacyForge] shared_ptr: ptr=%p ctrl=%p", spPtr, spCtrl);
|
||||
LogUtil::Log("[WeaveLoader] shared_ptr: ptr=%p ctrl=%p", spPtr, spCtrl);
|
||||
|
||||
char* vec = groups + item.groupIndex * SIZEOF_MSVC_VECTOR;
|
||||
size_t sizeBefore = ReadVectorSize(vec);
|
||||
@@ -209,12 +209,12 @@ void InjectItems()
|
||||
pushFn(vec, spBuf);
|
||||
|
||||
size_t sizeAfter = ReadVectorSize(vec);
|
||||
LogUtil::Log("[LegacyForge] Injected item id=%d into creative group %d "
|
||||
LogUtil::Log("[WeaveLoader] Injected item id=%d into creative group %d "
|
||||
"(vector @ %p, size: %zu -> %zu)",
|
||||
item.itemId, item.groupIndex, vec, sizeBefore, sizeAfter);
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] Injected %zu items into creative inventory", s_pendingItems.size());
|
||||
LogUtil::Log("[WeaveLoader] Injected %zu items into creative inventory", s_pendingItems.size());
|
||||
s_pendingItems.clear();
|
||||
}
|
||||
|
||||
@@ -31,14 +31,14 @@ static bool LoadHostfxr()
|
||||
int rc = get_hostfxr_path(buffer, &buffer_size, nullptr);
|
||||
if (rc != 0)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] get_hostfxr_path failed: 0x%x", rc);
|
||||
LogUtil::Log("[WeaveLoader] get_hostfxr_path failed: 0x%x", rc);
|
||||
return false;
|
||||
}
|
||||
|
||||
HMODULE lib = LoadLibraryW(buffer);
|
||||
if (!lib)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to load hostfxr");
|
||||
LogUtil::Log("[WeaveLoader] Failed to load hostfxr");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ static load_assembly_and_get_function_pointer_fn GetDotNetLoadAssembly(const wch
|
||||
int rc = init_fptr(configPath, nullptr, &cxt);
|
||||
if (rc != 0 || cxt == nullptr)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] hostfxr_initialize failed: 0x%x", rc);
|
||||
LogUtil::Log("[WeaveLoader] hostfxr_initialize failed: 0x%x", rc);
|
||||
if (cxt) close_fptr(cxt);
|
||||
return nullptr;
|
||||
}
|
||||
@@ -67,7 +67,7 @@ static load_assembly_and_get_function_pointer_fn GetDotNetLoadAssembly(const wch
|
||||
rc = get_delegate_fptr(cxt, hdt_load_assembly_and_get_function_pointer, &load_fn);
|
||||
if (rc != 0 || load_fn == nullptr)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] hostfxr_get_runtime_delegate failed: 0x%x", rc);
|
||||
LogUtil::Log("[WeaveLoader] hostfxr_get_runtime_delegate failed: 0x%x", rc);
|
||||
}
|
||||
|
||||
close_fptr(cxt);
|
||||
@@ -82,7 +82,7 @@ static bool ResolveManagedMethod(
|
||||
{
|
||||
int rc = load_fn(
|
||||
assemblyPath,
|
||||
L"LegacyForge.Core.LegacyForgeCore, LegacyForge.Core",
|
||||
L"WeaveLoader.Core.WeaveLoaderCore, WeaveLoader.Core",
|
||||
methodName,
|
||||
nullptr,
|
||||
nullptr,
|
||||
@@ -95,7 +95,7 @@ bool DotNetHost::Initialize()
|
||||
{
|
||||
if (!LoadHostfxr())
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to load hostfxr library");
|
||||
LogUtil::Log("[WeaveLoader] Failed to load hostfxr library");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -123,13 +123,13 @@ bool DotNetHost::Initialize()
|
||||
else
|
||||
selfDir = L".\\";
|
||||
|
||||
std::wstring configPath = selfDir + L"LegacyForge.Core.runtimeconfig.json";
|
||||
std::wstring assemblyPath = selfDir + L"LegacyForge.Core.dll";
|
||||
std::wstring configPath = selfDir + L"WeaveLoader.Core.runtimeconfig.json";
|
||||
std::wstring assemblyPath = selfDir + L"WeaveLoader.Core.dll";
|
||||
|
||||
auto load_fn = GetDotNetLoadAssembly(configPath.c_str());
|
||||
if (!load_fn)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to get load_assembly_and_get_function_pointer");
|
||||
LogUtil::Log("[WeaveLoader] Failed to get load_assembly_and_get_function_pointer");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -144,11 +144,11 @@ bool DotNetHost::Initialize()
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to resolve one or more managed entry points");
|
||||
LogUtil::Log("[WeaveLoader] Failed to resolve one or more managed entry points");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] All managed entry points resolved");
|
||||
LogUtil::Log("[WeaveLoader] All managed entry points resolved");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#include <cstdint>
|
||||
|
||||
/// Hosts the .NET CoreCLR runtime inside the game process using the hostfxr API.
|
||||
/// Loads LegacyForge.Core.dll and resolves managed entry point methods.
|
||||
/// Loads WeaveLoader.Core.dll and resolves managed entry point methods.
|
||||
namespace DotNetHost
|
||||
{
|
||||
bool Initialize();
|
||||
@@ -27,12 +27,12 @@ namespace GameHooks
|
||||
|
||||
void __fastcall Hooked_LoadUVs(void* thisPtr)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hooked_LoadUVs: ENTER (textureMap=%p)", thisPtr);
|
||||
LogUtil::Log("[WeaveLoader] Hooked_LoadUVs: ENTER (textureMap=%p)", thisPtr);
|
||||
if (Original_LoadUVs)
|
||||
Original_LoadUVs(thisPtr);
|
||||
LogUtil::Log("[LegacyForge] Hooked_LoadUVs: original returned, creating mod icons");
|
||||
LogUtil::Log("[WeaveLoader] Hooked_LoadUVs: original returned, creating mod icons");
|
||||
ModAtlas::CreateModIcons(thisPtr);
|
||||
LogUtil::Log("[LegacyForge] Hooked_LoadUVs: DONE");
|
||||
LogUtil::Log("[WeaveLoader] Hooked_LoadUVs: DONE");
|
||||
}
|
||||
|
||||
static int s_registerIconCallCount = 0;
|
||||
@@ -43,14 +43,14 @@ namespace GameHooks
|
||||
void* modIcon = ModAtlas::LookupModIcon(name);
|
||||
if (modIcon)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] registerIcon #%d: '%ls' -> MOD ICON %p",
|
||||
LogUtil::Log("[WeaveLoader] registerIcon #%d: '%ls' -> MOD ICON %p",
|
||||
s_registerIconCallCount, name.c_str(), modIcon);
|
||||
return modIcon;
|
||||
}
|
||||
void* result = Original_RegisterIcon ? Original_RegisterIcon(thisPtr, name) : nullptr;
|
||||
if (s_registerIconCallCount <= 30 || !result)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] registerIcon #%d: '%ls' -> vanilla %p",
|
||||
LogUtil::Log("[WeaveLoader] registerIcon #%d: '%ls' -> vanilla %p",
|
||||
s_registerIconCallCount, name.c_str(), result);
|
||||
}
|
||||
return result;
|
||||
@@ -66,13 +66,13 @@ namespace GameHooks
|
||||
if (!terrainPath.empty() && path->find(L"terrain.png") != std::wstring::npos)
|
||||
{
|
||||
std::wstring ourPath(terrainPath.begin(), terrainPath.end());
|
||||
LogUtil::Log("[LegacyForge] getResourceAsStream: redirecting terrain.png to merged atlas");
|
||||
LogUtil::Log("[WeaveLoader] getResourceAsStream: redirecting terrain.png to merged atlas");
|
||||
return Original_GetResourceAsStream(&ourPath);
|
||||
}
|
||||
if (!itemsPath.empty() && path->find(L"items.png") != std::wstring::npos)
|
||||
{
|
||||
std::wstring ourPath(itemsPath.begin(), itemsPath.end());
|
||||
LogUtil::Log("[LegacyForge] getResourceAsStream: redirecting items.png to merged atlas");
|
||||
LogUtil::Log("[WeaveLoader] getResourceAsStream: redirecting items.png to merged atlas");
|
||||
return Original_GetResourceAsStream(&ourPath);
|
||||
}
|
||||
}
|
||||
@@ -85,7 +85,7 @@ namespace GameHooks
|
||||
if (ModStrings::IsModId(id))
|
||||
{
|
||||
const wchar_t* modStr = ModStrings::Get(id);
|
||||
LogUtil::Log("[LegacyForge] GetString(id=%d) -> mod '%ls'", id,
|
||||
LogUtil::Log("[WeaveLoader] GetString(id=%d) -> mod '%ls'", id,
|
||||
(modStr && modStr[0]) ? modStr : L"<null/empty>");
|
||||
if (modStr && modStr[0])
|
||||
return modStr;
|
||||
@@ -95,7 +95,7 @@ namespace GameHooks
|
||||
{
|
||||
s_loggedGetString = true;
|
||||
const wchar_t* r = Original_GetString ? Original_GetString(id) : L"";
|
||||
LogUtil::Log("[LegacyForge] GetString(id=%d) -> vanilla '%ls' (first call sample)", id, r ? r : L"<null>");
|
||||
LogUtil::Log("[WeaveLoader] GetString(id=%d) -> vanilla '%ls' (first call sample)", id, r ? r : L"<null>");
|
||||
return r;
|
||||
}
|
||||
return Original_GetString ? Original_GetString(id) : L"";
|
||||
@@ -104,12 +104,12 @@ namespace GameHooks
|
||||
|
||||
void Hooked_RunStaticCtors()
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hook: RunStaticCtors -- calling PreInit");
|
||||
LogUtil::Log("[WeaveLoader] Hook: RunStaticCtors -- calling PreInit");
|
||||
DotNetHost::CallPreInit();
|
||||
|
||||
Original_RunStaticCtors();
|
||||
|
||||
LogUtil::Log("[LegacyForge] Hook: RunStaticCtors complete -- calling Init");
|
||||
LogUtil::Log("[WeaveLoader] Hook: RunStaticCtors complete -- calling Init");
|
||||
DotNetHost::CallInit();
|
||||
|
||||
// Inject mod strings directly into the game's StringTable vector.
|
||||
@@ -167,13 +167,13 @@ namespace GameHooks
|
||||
// fully populated. Copy it to our mod icons so getSourceHeight() works.
|
||||
ModAtlas::FixupModIcons();
|
||||
|
||||
LogUtil::Log("[LegacyForge] Hook: Minecraft::init complete -- calling PostInit");
|
||||
LogUtil::Log("[WeaveLoader] Hook: Minecraft::init complete -- calling PostInit");
|
||||
DotNetHost::CallPostInit();
|
||||
}
|
||||
|
||||
void __fastcall Hooked_ExitGame(void* thisPtr)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hook: ExitGame -- calling Shutdown");
|
||||
LogUtil::Log("[WeaveLoader] Hook: ExitGame -- calling Shutdown");
|
||||
DotNetHost::CallShutdown();
|
||||
|
||||
Original_ExitGame(thisPtr);
|
||||
@@ -183,15 +183,15 @@ namespace GameHooks
|
||||
{
|
||||
// Inject mod items BEFORE vanilla staticCtor so they are included in the
|
||||
// TabSpec page-count calculation that happens at the end of staticCtor.
|
||||
LogUtil::Log("[LegacyForge] Hook: CreativeStaticCtor -- injecting modded items first");
|
||||
LogUtil::Log("[WeaveLoader] Hook: CreativeStaticCtor -- injecting modded items first");
|
||||
CreativeInventory::InjectItems();
|
||||
|
||||
LogUtil::Log("[LegacyForge] Hook: CreativeStaticCtor -- building vanilla creative lists");
|
||||
LogUtil::Log("[WeaveLoader] Hook: CreativeStaticCtor -- building vanilla creative lists");
|
||||
Original_CreativeStaticCtor();
|
||||
|
||||
// Safety: recalculate TabSpec page counts in case the injection-before
|
||||
// approach didn't fully account for all items (e.g. different binary).
|
||||
LogUtil::Log("[LegacyForge] Hook: CreativeStaticCtor -- updating tab page counts");
|
||||
LogUtil::Log("[WeaveLoader] Hook: CreativeStaticCtor -- updating tab page counts");
|
||||
CreativeInventory::UpdateTabPageCounts();
|
||||
}
|
||||
|
||||
@@ -68,7 +68,7 @@ namespace GameObjectFactory
|
||||
|
||||
bool ResolveSymbols(SymbolResolver& resolver)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] GameObjectFactory: resolving symbols...");
|
||||
LogUtil::Log("[WeaveLoader] GameObjectFactory: resolving symbols...");
|
||||
|
||||
// Tile constructor — protected (IEAA not QEAA)
|
||||
fnTileCtor = (TileCtor_fn)resolver.Resolve("??0Tile@@IEAA@HPEAVMaterial@@_N@Z");
|
||||
@@ -104,23 +104,23 @@ bool ResolveSymbols(SymbolResolver& resolver)
|
||||
{
|
||||
// mov eax, [rcx+disp8] — 8B 41 XX
|
||||
s_itemDescIdOffset = static_cast<int>(code[2]);
|
||||
LogUtil::Log("[LegacyForge] Item descriptionId offset = 0x%X (from getDescriptionId disp8)", s_itemDescIdOffset);
|
||||
LogUtil::Log("[WeaveLoader] Item descriptionId offset = 0x%X (from getDescriptionId disp8)", s_itemDescIdOffset);
|
||||
}
|
||||
else if (code[0] == 0x8B && code[1] == 0x81)
|
||||
{
|
||||
// mov eax, [rcx+disp32] — 8B 81 XX XX XX XX
|
||||
s_itemDescIdOffset = *reinterpret_cast<const int*>(code + 2);
|
||||
LogUtil::Log("[LegacyForge] Item descriptionId offset = 0x%X (from getDescriptionId disp32)", s_itemDescIdOffset);
|
||||
LogUtil::Log("[WeaveLoader] Item descriptionId offset = 0x%X (from getDescriptionId disp32)", s_itemDescIdOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Item::getDescriptionId has unexpected opcode pattern: %02X %02X %02X",
|
||||
LogUtil::Log("[WeaveLoader] Item::getDescriptionId has unexpected opcode pattern: %02X %02X %02X",
|
||||
code[0], code[1], code[2]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] MISSING: Item::getDescriptionId — cannot set item display names");
|
||||
LogUtil::Log("[WeaveLoader] MISSING: Item::getDescriptionId — cannot set item display names");
|
||||
}
|
||||
|
||||
// Resolve Material* static pointer ADDRESSES (values are NULL until staticCtor runs)
|
||||
@@ -160,8 +160,8 @@ bool ResolveSymbols(SymbolResolver& resolver)
|
||||
resolveSound(9, "?SOUND_SNOW@Tile@@2PEAVSoundType@1@EA");
|
||||
|
||||
auto logSym = [](const char* name, void* ptr) {
|
||||
if (ptr) LogUtil::Log("[LegacyForge] GOF %-20s @ %p", name, ptr);
|
||||
else LogUtil::Log("[LegacyForge] GOF MISSING: %s", name);
|
||||
if (ptr) LogUtil::Log("[WeaveLoader] GOF %-20s @ %p", name, ptr);
|
||||
else LogUtil::Log("[WeaveLoader] GOF MISSING: %s", name);
|
||||
};
|
||||
|
||||
logSym("Tile::Tile", (void*)fnTileCtor);
|
||||
@@ -190,9 +190,9 @@ bool ResolveSymbols(SymbolResolver& resolver)
|
||||
s_resolved = fnTileCtor && fnTileItemCtor && fnItemCtor;
|
||||
|
||||
if (s_resolved)
|
||||
LogUtil::Log("[LegacyForge] GameObjectFactory: core symbols resolved OK");
|
||||
LogUtil::Log("[WeaveLoader] GameObjectFactory: core symbols resolved OK");
|
||||
else
|
||||
LogUtil::Log("[LegacyForge] GameObjectFactory: MISSING core symbols -- block/item creation disabled");
|
||||
LogUtil::Log("[WeaveLoader] GameObjectFactory: MISSING core symbols -- block/item creation disabled");
|
||||
|
||||
return s_resolved;
|
||||
}
|
||||
@@ -202,7 +202,7 @@ bool CreateTile(int tileId, int materialType, float hardness, float resistance,
|
||||
{
|
||||
if (!s_resolved || !fnTileCtor)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] CreateTile: symbols not resolved");
|
||||
LogUtil::Log("[WeaveLoader] CreateTile: symbols not resolved");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -213,7 +213,7 @@ bool CreateTile(int tileId, int materialType, float hardness, float resistance,
|
||||
|
||||
if (!mat)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] CreateTile: no material pointer for type %d", materialType);
|
||||
LogUtil::Log("[WeaveLoader] CreateTile: no material pointer for type %d", materialType);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -242,7 +242,7 @@ bool CreateTile(int tileId, int materialType, float hardness, float resistance,
|
||||
fnTileSetDescriptionId(tile, static_cast<unsigned int>(descriptionId));
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] Created Tile id=%d (material=%d, icon=%ls, descId=%d)", tileId, materialType,
|
||||
LogUtil::Log("[WeaveLoader] Created Tile id=%d (material=%d, icon=%ls, descId=%d)", tileId, materialType,
|
||||
iconName ? iconName : L"<none>", descriptionId);
|
||||
|
||||
// Create the corresponding TileItem so the block can appear in inventory.
|
||||
@@ -252,7 +252,7 @@ bool CreateTile(int tileId, int materialType, float hardness, float resistance,
|
||||
void* tileItem = ::operator new(TILEITEM_ALLOC_SIZE);
|
||||
memset(tileItem, 0, TILEITEM_ALLOC_SIZE);
|
||||
fnTileItemCtor(tileItem, tileId - 256);
|
||||
LogUtil::Log("[LegacyForge] Created TileItem for tile %d", tileId);
|
||||
LogUtil::Log("[WeaveLoader] Created TileItem for tile %d", tileId);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -262,7 +262,7 @@ bool CreateItem(int itemId, int maxStackSize, const wchar_t* iconName, int descr
|
||||
{
|
||||
if (!s_resolved || !fnItemCtor)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] CreateItem: symbols not resolved");
|
||||
LogUtil::Log("[WeaveLoader] CreateItem: symbols not resolved");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ bool CreateItem(int itemId, int maxStackSize, const wchar_t* iconName, int descr
|
||||
static_cast<unsigned int>(descriptionId);
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] Created Item id=%d (ctorParam=%d, icon=%ls, descId=%d)",
|
||||
LogUtil::Log("[WeaveLoader] Created Item id=%d (ctorParam=%d, icon=%ls, descId=%d)",
|
||||
itemId, ctorParam, iconName ? iconName : L"<none>", descriptionId);
|
||||
|
||||
return true;
|
||||
@@ -13,7 +13,7 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
{
|
||||
if (MH_Initialize() != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] MH_Initialize failed");
|
||||
LogUtil::Log("[WeaveLoader] MH_Initialize failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -23,10 +23,10 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_RunStaticCtors),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_RunStaticCtors)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to hook RunStaticCtors");
|
||||
LogUtil::Log("[WeaveLoader] Failed to hook RunStaticCtors");
|
||||
return false;
|
||||
}
|
||||
LogUtil::Log("[LegacyForge] Hooked RunStaticCtors");
|
||||
LogUtil::Log("[WeaveLoader] Hooked RunStaticCtors");
|
||||
}
|
||||
|
||||
if (symbols.pMinecraftTick)
|
||||
@@ -35,10 +35,10 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_MinecraftTick),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_MinecraftTick)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to hook Minecraft::tick");
|
||||
LogUtil::Log("[WeaveLoader] Failed to hook Minecraft::tick");
|
||||
return false;
|
||||
}
|
||||
LogUtil::Log("[LegacyForge] Hooked Minecraft::tick");
|
||||
LogUtil::Log("[WeaveLoader] Hooked Minecraft::tick");
|
||||
}
|
||||
|
||||
if (symbols.pMinecraftInit)
|
||||
@@ -47,10 +47,10 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_MinecraftInit),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_MinecraftInit)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to hook Minecraft::init");
|
||||
LogUtil::Log("[WeaveLoader] Failed to hook Minecraft::init");
|
||||
return false;
|
||||
}
|
||||
LogUtil::Log("[LegacyForge] Hooked Minecraft::init");
|
||||
LogUtil::Log("[WeaveLoader] Hooked Minecraft::init");
|
||||
}
|
||||
|
||||
if (symbols.pExitGame)
|
||||
@@ -59,11 +59,11 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_ExitGame),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_ExitGame)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: Failed to hook ExitGame (shutdown hook unavailable)");
|
||||
LogUtil::Log("[WeaveLoader] Warning: Failed to hook ExitGame (shutdown hook unavailable)");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hooked ExitGame");
|
||||
LogUtil::Log("[WeaveLoader] Hooked ExitGame");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,11 +76,11 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_LoadUVs),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_LoadUVs)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: Failed to hook PreStitchedTextureMap::loadUVs (mod textures may not appear)");
|
||||
LogUtil::Log("[WeaveLoader] Warning: Failed to hook PreStitchedTextureMap::loadUVs (mod textures may not appear)");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hooked PreStitchedTextureMap::loadUVs (mod texture injection)");
|
||||
LogUtil::Log("[WeaveLoader] Hooked PreStitchedTextureMap::loadUVs (mod texture injection)");
|
||||
}
|
||||
|
||||
if (symbols.pRegisterIcon)
|
||||
@@ -89,11 +89,11 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_RegisterIcon),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_RegisterIcon)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: Failed to hook PreStitchedTextureMap::registerIcon");
|
||||
LogUtil::Log("[WeaveLoader] Warning: Failed to hook PreStitchedTextureMap::registerIcon");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hooked PreStitchedTextureMap::registerIcon (mod icon lookup)");
|
||||
LogUtil::Log("[WeaveLoader] Hooked PreStitchedTextureMap::registerIcon (mod icon lookup)");
|
||||
// Pass the trampoline to ModAtlas so it can look up vanilla icons
|
||||
// for copying internal state (field_0x48 source image pointer).
|
||||
ModAtlas::SetRegisterIconFn(GameHooks::Original_RegisterIcon);
|
||||
@@ -102,7 +102,7 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
}
|
||||
else if (symbols.pLoadUVs)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Mod texture injection unavailable: SimpleIcon/operator new not resolved");
|
||||
LogUtil::Log("[WeaveLoader] Mod texture injection unavailable: SimpleIcon/operator new not resolved");
|
||||
}
|
||||
|
||||
if (symbols.pCreativeStaticCtor)
|
||||
@@ -113,11 +113,11 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_CreativeStaticCtor),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_CreativeStaticCtor)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: Failed to hook CreativeStaticCtor");
|
||||
LogUtil::Log("[WeaveLoader] Warning: Failed to hook CreativeStaticCtor");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hooked CreativeStaticCtor");
|
||||
LogUtil::Log("[WeaveLoader] Hooked CreativeStaticCtor");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,11 +127,11 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_MainMenuCustomDraw),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_MainMenuCustomDraw)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: Failed to hook MainMenuCustomDraw");
|
||||
LogUtil::Log("[WeaveLoader] Warning: Failed to hook MainMenuCustomDraw");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hooked MainMenuCustomDraw");
|
||||
LogUtil::Log("[WeaveLoader] Hooked MainMenuCustomDraw");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,11 +143,11 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_Present),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_Present)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: Failed to hook C4JRender::Present");
|
||||
LogUtil::Log("[WeaveLoader] Warning: Failed to hook C4JRender::Present");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hooked C4JRender::Present");
|
||||
LogUtil::Log("[WeaveLoader] Hooked C4JRender::Present");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -160,11 +160,11 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_GetString),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_GetString)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: Failed to hook CMinecraftApp::GetString (mod names unavailable)");
|
||||
LogUtil::Log("[WeaveLoader] Warning: Failed to hook CMinecraftApp::GetString (mod names unavailable)");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hooked CMinecraftApp::GetString (mod localization)");
|
||||
LogUtil::Log("[WeaveLoader] Hooked CMinecraftApp::GetString (mod localization)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -175,11 +175,11 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_GetResourceAsStream),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_GetResourceAsStream)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: Failed to hook InputStream::getResourceAsStream (mod atlas unavailable)");
|
||||
LogUtil::Log("[WeaveLoader] Warning: Failed to hook InputStream::getResourceAsStream (mod atlas unavailable)");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hooked InputStream::getResourceAsStream (mod textures)");
|
||||
LogUtil::Log("[WeaveLoader] Hooked InputStream::getResourceAsStream (mod textures)");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,22 +192,22 @@ bool HookManager::Install(const SymbolResolver& symbols)
|
||||
reinterpret_cast<void*>(&GameHooks::Hooked_OutputDebugStringA),
|
||||
reinterpret_cast<void**>(&GameHooks::Original_OutputDebugStringA)) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: Failed to hook OutputDebugStringA");
|
||||
LogUtil::Log("[WeaveLoader] Warning: Failed to hook OutputDebugStringA");
|
||||
}
|
||||
else
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Hooked OutputDebugStringA (game log capture)");
|
||||
LogUtil::Log("[WeaveLoader] Hooked OutputDebugStringA (game log capture)");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MH_EnableHook(MH_ALL_HOOKS) != MH_OK)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] MH_EnableHook(MH_ALL_HOOKS) failed");
|
||||
LogUtil::Log("[WeaveLoader] MH_EnableHook(MH_ALL_HOOKS) failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] All hooks installed and enabled");
|
||||
LogUtil::Log("[WeaveLoader] All hooks installed and enabled");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -34,7 +34,7 @@ int IdRegistry::Register(Type type, const std::string& namespacedId)
|
||||
|
||||
if (reg.nextFreeId > maxId)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] IdRegistry: No free IDs for type %d (max %d)",
|
||||
LogUtil::Log("[WeaveLoader] IdRegistry: No free IDs for type %d (max %d)",
|
||||
static_cast<int>(type), maxId);
|
||||
return -1;
|
||||
}
|
||||
@@ -26,7 +26,7 @@ void SetBaseDir(const char* baseDir)
|
||||
{
|
||||
s_logsDir = std::string(baseDir) + "logs\\";
|
||||
CreateDirectoryA(s_logsDir.c_str(), nullptr);
|
||||
s_logPath = s_logsDir + "legacyforge.log";
|
||||
s_logPath = s_logsDir + "weaveloader.log";
|
||||
s_gameLogPath = s_logsDir + "game_debug.log";
|
||||
s_crashLogPath = s_logsDir + "crash.log";
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace LogUtil
|
||||
// Returns the logs directory path (with trailing backslash)
|
||||
const char* GetLogsDir();
|
||||
|
||||
// Appends a timestamped line to legacyforge.log and prints to stdout
|
||||
// Appends a timestamped line to weaveloader.log and prints to stdout
|
||||
void Log(const char* fmt, ...);
|
||||
|
||||
// Writes game debug output to game_debug.log with a timestamp
|
||||
@@ -83,9 +83,9 @@ bool ResolveSymbols(SymbolResolver& resolver)
|
||||
fnMatrixTranslate && fnDepthTest && fnDrawShadow;
|
||||
|
||||
if (s_symbolsOk)
|
||||
LogUtil::Log("[LegacyForge] MainMenuOverlay symbols resolved OK");
|
||||
LogUtil::Log("[WeaveLoader] MainMenuOverlay symbols resolved OK");
|
||||
else
|
||||
LogUtil::Log("[LegacyForge] Warning: some MainMenuOverlay symbols missing -- branding text disabled");
|
||||
LogUtil::Log("[WeaveLoader] Warning: some MainMenuOverlay symbols missing -- branding text disabled");
|
||||
|
||||
return s_symbolsOk;
|
||||
}
|
||||
@@ -115,7 +115,7 @@ void RenderBranding()
|
||||
|
||||
if (!s_loggedOnce)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] MainMenuOverlay: first render (screen %dx%d, font=%p, rm=%p)",
|
||||
LogUtil::Log("[WeaveLoader] MainMenuOverlay: first render (screen %dx%d, font=%p, rm=%p)",
|
||||
pixelW, pixelH, font, pRenderManager);
|
||||
s_loggedOnce = true;
|
||||
}
|
||||
@@ -145,7 +145,7 @@ void RenderBranding()
|
||||
fnDepthTest(rm, false);
|
||||
if (fnBlendEnable) fnBlendEnable(rm, true);
|
||||
|
||||
std::wstring line1 = L"LegacyForge v" LEGACYFORGE_VERSION;
|
||||
std::wstring line1 = L"WeaveLoader v" LEGACYFORGE_VERSION;
|
||||
|
||||
wchar_t line2Buf[64];
|
||||
swprintf(line2Buf, 64, L"%d mod(s) loaded successfully", s_modCount);
|
||||
@@ -168,7 +168,7 @@ namespace ModAtlas
|
||||
}
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: found %zu empty cells in %dx%d atlas",
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: found %zu empty cells in %dx%d atlas",
|
||||
emptyCells.size(), gridCols, gridRows);
|
||||
|
||||
size_t cellIdx = 0;
|
||||
@@ -179,7 +179,7 @@ namespace ModAtlas
|
||||
|
||||
if (cellIdx >= emptyCells.size())
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: no empty cells left for %s!", iconName.c_str());
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: no empty cells left for %s!", iconName.c_str());
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -187,7 +187,7 @@ namespace ModAtlas
|
||||
unsigned char* src = nullptr;
|
||||
if (!LoadPng(path, &sw, &sh, &sc, &src))
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: failed to load %s", path.c_str());
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: failed to load %s", path.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -201,7 +201,7 @@ namespace ModAtlas
|
||||
std::wstring wname(iconName.begin(), iconName.end());
|
||||
entries.push_back({ wname, 0, row, col });
|
||||
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: placed '%s' at row=%d col=%d", iconName.c_str(), row, col);
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: placed '%s' at row=%d col=%d", iconName.c_str(), row, col);
|
||||
}
|
||||
|
||||
std::string dir = outPath.substr(0, outPath.find_last_of("\\/"));
|
||||
@@ -223,7 +223,7 @@ namespace ModAtlas
|
||||
|
||||
if (blockPaths.empty() && itemPaths.empty())
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: no mod textures found");
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: no mod textures found");
|
||||
return "";
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ namespace ModAtlas
|
||||
if (BuildAtlas(vanillaTerrain, outTerrain, blockPaths, 16, 32, 16, s_blockEntries))
|
||||
{
|
||||
s_hasModTextures = true;
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: built terrain.png with %zu mod textures", s_blockEntries.size());
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: built terrain.png with %zu mod textures", s_blockEntries.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,7 +258,7 @@ namespace ModAtlas
|
||||
{
|
||||
s_hasModTextures = true;
|
||||
for (auto& e : s_itemEntries) e.atlasType = 1;
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: built items.png with %zu mod textures", s_itemEntries.size());
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: built items.png with %zu mod textures", s_itemEntries.size());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,32 +312,32 @@ namespace ModAtlas
|
||||
|
||||
if (!mergedTerrain.empty() && !s_blockEntries.empty())
|
||||
{
|
||||
s_backupTerrainPath = vanillaTerrain + ".legacyforge_backup";
|
||||
s_backupTerrainPath = vanillaTerrain + ".weaveloader_backup";
|
||||
CopyFileA(vanillaTerrain.c_str(), s_backupTerrainPath.c_str(), FALSE);
|
||||
if (CopyFileA(mergedTerrain.c_str(), vanillaTerrain.c_str(), FALSE))
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: installed merged terrain.png over game file");
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: installed merged terrain.png over game file");
|
||||
else
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: WARNING - failed to copy merged terrain.png (err=%lu)", GetLastError());
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: WARNING - failed to copy merged terrain.png (err=%lu)", GetLastError());
|
||||
}
|
||||
|
||||
if (!mergedItems.empty() && !s_itemEntries.empty())
|
||||
{
|
||||
s_backupItemsPath = vanillaItems + ".legacyforge_backup";
|
||||
s_backupItemsPath = vanillaItems + ".weaveloader_backup";
|
||||
CopyFileA(vanillaItems.c_str(), s_backupItemsPath.c_str(), FALSE);
|
||||
if (CopyFileA(mergedItems.c_str(), vanillaItems.c_str(), FALSE))
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: installed merged items.png over game file");
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: installed merged items.png over game file");
|
||||
else
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: WARNING - failed to copy merged items.png (err=%lu)", GetLastError());
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: WARNING - failed to copy merged items.png (err=%lu)", GetLastError());
|
||||
}
|
||||
}
|
||||
|
||||
void CreateModIcons(void* textureMap)
|
||||
{
|
||||
if (!s_hasModTextures || !s_simpleIconCtor || !textureMap) return;
|
||||
if (!s_operatorNew) { LogUtil::Log("[LegacyForge] ModAtlas: operator new not resolved, skipping icon creation"); return; }
|
||||
if (!s_operatorNew) { LogUtil::Log("[WeaveLoader] ModAtlas: operator new not resolved, skipping icon creation"); return; }
|
||||
|
||||
int iconType = *reinterpret_cast<int*>(reinterpret_cast<char*>(textureMap) + 8);
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: CreateModIcons called for atlas type %d (textureMap=%p)", iconType, textureMap);
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: CreateModIcons called for atlas type %d (textureMap=%p)", iconType, textureMap);
|
||||
|
||||
if (iconType == 0) s_terrainTextureMap = textureMap;
|
||||
else if (iconType == 1) s_itemsTextureMap = textureMap;
|
||||
@@ -363,7 +363,7 @@ namespace ModAtlas
|
||||
memset(icon, 0, 128);
|
||||
ctor(icon, &e.iconName, &e.iconName, u0, v0, u1, v1);
|
||||
s_modIcons[e.iconName] = icon;
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: created icon '%ls' (atlas=%d, row=%d, col=%d)",
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: created icon '%ls' (atlas=%d, row=%d, col=%d)",
|
||||
e.iconName.c_str(), iconType, e.row, e.col);
|
||||
}
|
||||
}
|
||||
@@ -374,7 +374,7 @@ namespace ModAtlas
|
||||
else if (iconType == 1)
|
||||
create(s_itemEntries, 1.0f / 16.0f);
|
||||
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: s_modIcons now has %zu entries total", s_modIcons.size());
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: s_modIcons now has %zu entries total", s_modIcons.size());
|
||||
}
|
||||
|
||||
void FixupModIcons()
|
||||
@@ -391,16 +391,16 @@ namespace ModAtlas
|
||||
void* probeIcon = s_originalRegisterIcon(textureMap, probeStr);
|
||||
if (!probeIcon)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] FixupModIcons: could not find vanilla icon '%ls'", probeName);
|
||||
LogUtil::Log("[WeaveLoader] FixupModIcons: could not find vanilla icon '%ls'", probeName);
|
||||
return;
|
||||
}
|
||||
|
||||
void* srcPtr = *reinterpret_cast<void**>(static_cast<char*>(probeIcon) + 0x48);
|
||||
LogUtil::Log("[LegacyForge] FixupModIcons: vanilla '%ls' field_0x48 = %p", probeName, srcPtr);
|
||||
LogUtil::Log("[WeaveLoader] FixupModIcons: vanilla '%ls' field_0x48 = %p", probeName, srcPtr);
|
||||
|
||||
if (!srcPtr)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] FixupModIcons: WARNING - vanilla source ptr still NULL for atlas %d", atlasType);
|
||||
LogUtil::Log("[WeaveLoader] FixupModIcons: WARNING - vanilla source ptr still NULL for atlas %d", atlasType);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -415,7 +415,7 @@ namespace ModAtlas
|
||||
fixed++;
|
||||
}
|
||||
}
|
||||
LogUtil::Log("[LegacyForge] FixupModIcons: patched field_0x48 on %d mod icons (atlas %d, srcPtr=%p)",
|
||||
LogUtil::Log("[WeaveLoader] FixupModIcons: patched field_0x48 on %d mod icons (atlas %d, srcPtr=%p)",
|
||||
fixed, atlasType, srcPtr);
|
||||
};
|
||||
|
||||
@@ -427,14 +427,14 @@ namespace ModAtlas
|
||||
{
|
||||
std::string vanillaTerrain = s_gameResPath + "\\terrain.png";
|
||||
if (MoveFileExA(s_backupTerrainPath.c_str(), vanillaTerrain.c_str(), MOVEFILE_REPLACE_EXISTING))
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: restored original terrain.png");
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: restored original terrain.png");
|
||||
s_backupTerrainPath.clear();
|
||||
}
|
||||
if (!s_backupItemsPath.empty())
|
||||
{
|
||||
std::string vanillaItems = s_gameResPath + "\\items.png";
|
||||
if (MoveFileExA(s_backupItemsPath.c_str(), vanillaItems.c_str(), MOVEFILE_REPLACE_EXISTING))
|
||||
LogUtil::Log("[LegacyForge] ModAtlas: restored original items.png");
|
||||
LogUtil::Log("[WeaveLoader] ModAtlas: restored original items.png");
|
||||
s_backupItemsPath.clear();
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ namespace ModStrings
|
||||
if (!value) return;
|
||||
std::lock_guard<std::mutex> lock(s_mutex);
|
||||
s_strings[descriptionId] = value;
|
||||
LogUtil::Log("[LegacyForge] ModStrings: registered id=%d -> %ls", descriptionId, value);
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: registered id=%d -> %ls", descriptionId, value);
|
||||
}
|
||||
|
||||
const wchar_t* Get(int descriptionId)
|
||||
@@ -51,13 +51,13 @@ namespace ModStrings
|
||||
if (!pGetStringFunc) return;
|
||||
|
||||
const uint8_t* code = static_cast<const uint8_t*>(pGetStringFunc);
|
||||
LogUtil::Log("[LegacyForge] ModStrings: scanning GetString prologue at %p", pGetStringFunc);
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: scanning GetString prologue at %p", pGetStringFunc);
|
||||
|
||||
// Log first 32 bytes for diagnostics
|
||||
char hexBuf[200];
|
||||
for (int i = 0; i < 32 && i < 200/3; i++)
|
||||
sprintf(hexBuf + i * 3, "%02X ", code[i]);
|
||||
LogUtil::Log("[LegacyForge] ModStrings: bytes: %s", hexBuf);
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: bytes: %s", hexBuf);
|
||||
|
||||
// Search for RIP-relative memory accesses in first 80 bytes.
|
||||
// GetString is: return app.m_stringTable->getString(iID);
|
||||
@@ -86,7 +86,7 @@ namespace ModStrings
|
||||
// For a static member or global struct, the compiler often uses a direct
|
||||
// RIP-relative MOV to load the m_stringTable pointer field.
|
||||
s_pStringTableField = reinterpret_cast<void**>(effectiveAddr);
|
||||
LogUtil::Log("[LegacyForge] ModStrings: MOV [RIP+disp] -> field at %p", s_pStringTableField);
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: MOV [RIP+disp] -> field at %p", s_pStringTableField);
|
||||
break;
|
||||
}
|
||||
else // LEA
|
||||
@@ -104,14 +104,14 @@ namespace ModStrings
|
||||
{
|
||||
int8_t off = static_cast<int8_t>(code[j + 3]);
|
||||
s_pStringTableField = reinterpret_cast<void**>(appAddr + off);
|
||||
LogUtil::Log("[LegacyForge] ModStrings: LEA+MOV [reg+%d] -> field at %p", (int)off, s_pStringTableField);
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: LEA+MOV [reg+%d] -> field at %p", (int)off, s_pStringTableField);
|
||||
break;
|
||||
}
|
||||
else if (mod2 == 2)
|
||||
{
|
||||
int32_t off = *reinterpret_cast<const int32_t*>(code + j + 3);
|
||||
s_pStringTableField = reinterpret_cast<void**>(appAddr + off);
|
||||
LogUtil::Log("[LegacyForge] ModStrings: LEA+MOV [reg+%d] -> field at %p", off, s_pStringTableField);
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: LEA+MOV [reg+%d] -> field at %p", off, s_pStringTableField);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -119,7 +119,7 @@ namespace ModStrings
|
||||
}
|
||||
|
||||
if (!s_pStringTableField)
|
||||
LogUtil::Log("[LegacyForge] ModStrings: WARNING - could not locate string table reference");
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: WARNING - could not locate string table reference");
|
||||
}
|
||||
|
||||
// Heuristic: find the vector<wstring> inside a StringTable object.
|
||||
@@ -154,7 +154,7 @@ namespace ModStrings
|
||||
if (first->size() > 0 && first->size() < 10000)
|
||||
{
|
||||
s_vecOffset = off;
|
||||
LogUtil::Log("[LegacyForge] ModStrings: found m_stringsVec at StringTable+0x%X (%zu entries)",
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: found m_stringsVec at StringTable+0x%X (%zu entries)",
|
||||
off, count);
|
||||
return reinterpret_cast<std::vector<std::wstring>*>(base + off);
|
||||
}
|
||||
@@ -166,30 +166,30 @@ namespace ModStrings
|
||||
{
|
||||
if (!s_pStringTableField)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ModStrings: no string table ref - cannot inject");
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: no string table ref - cannot inject");
|
||||
return;
|
||||
}
|
||||
|
||||
void* stringTable = *s_pStringTableField;
|
||||
if (!stringTable)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ModStrings: m_stringTable pointer is NULL");
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: m_stringTable pointer is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] ModStrings: StringTable object at %p", stringTable);
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: StringTable object at %p", stringTable);
|
||||
|
||||
std::vector<std::wstring>* vec = FindStringsVec(stringTable);
|
||||
if (!vec)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ModStrings: FAILED to locate m_stringsVec in StringTable");
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: FAILED to locate m_stringsVec in StringTable");
|
||||
return;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(s_mutex);
|
||||
if (s_strings.empty())
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ModStrings: no mod strings to inject");
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: no mod strings to inject");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ namespace ModStrings
|
||||
if (static_cast<size_t>(maxId) >= oldSize)
|
||||
{
|
||||
vec->resize(maxId + 1);
|
||||
LogUtil::Log("[LegacyForge] ModStrings: resized m_stringsVec %zu -> %zu", oldSize, vec->size());
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: resized m_stringsVec %zu -> %zu", oldSize, vec->size());
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
@@ -212,6 +212,6 @@ namespace ModStrings
|
||||
count++;
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] ModStrings: injected %d mod strings into game string table", count);
|
||||
LogUtil::Log("[WeaveLoader] ModStrings: injected %d mod strings into game string table", count);
|
||||
}
|
||||
}
|
||||
@@ -37,11 +37,11 @@ int native_register_block(
|
||||
int id = IdRegistry::Instance().Register(IdRegistry::Type::Block, namespacedId);
|
||||
if (id < 0)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to allocate block ID for '%s'", namespacedId);
|
||||
LogUtil::Log("[WeaveLoader] Failed to allocate block ID for '%s'", namespacedId);
|
||||
return -1;
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] Registered block '%s' -> ID %d (hardness=%.1f, resistance=%.1f)",
|
||||
LogUtil::Log("[WeaveLoader] Registered block '%s' -> ID %d (hardness=%.1f, resistance=%.1f)",
|
||||
namespacedId, id, hardness, resistance);
|
||||
|
||||
std::wstring wIcon = Utf8ToWide(iconName);
|
||||
@@ -57,7 +57,7 @@ int native_register_block(
|
||||
if (!GameObjectFactory::CreateTile(id, materialId, hardness, resistance,
|
||||
soundType, wIcon.empty() ? nullptr : wIcon.c_str(), descId))
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: failed to create game Tile for block '%s' id=%d", namespacedId, id);
|
||||
LogUtil::Log("[WeaveLoader] Warning: failed to create game Tile for block '%s' id=%d", namespacedId, id);
|
||||
}
|
||||
|
||||
return id;
|
||||
@@ -75,11 +75,11 @@ int native_register_item(
|
||||
int id = IdRegistry::Instance().Register(IdRegistry::Type::Item, namespacedId);
|
||||
if (id < 0)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to allocate item ID for '%s'", namespacedId);
|
||||
LogUtil::Log("[WeaveLoader] Failed to allocate item ID for '%s'", namespacedId);
|
||||
return -1;
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] Registered item '%s' -> ID %d (stack=%d, durability=%d)",
|
||||
LogUtil::Log("[WeaveLoader] Registered item '%s' -> ID %d (stack=%d, durability=%d)",
|
||||
namespacedId, id, maxStackSize, maxDamage);
|
||||
|
||||
std::wstring wIcon = Utf8ToWide(iconName);
|
||||
@@ -94,7 +94,7 @@ int native_register_item(
|
||||
|
||||
if (!GameObjectFactory::CreateItem(id, maxStackSize, wIcon.empty() ? nullptr : wIcon.c_str(), descId))
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Warning: failed to create game Item for '%s' id=%d", namespacedId, id);
|
||||
LogUtil::Log("[WeaveLoader] Warning: failed to create game Item for '%s' id=%d", namespacedId, id);
|
||||
}
|
||||
|
||||
return id;
|
||||
@@ -123,11 +123,11 @@ int native_register_entity(
|
||||
int id = IdRegistry::Instance().Register(IdRegistry::Type::Entity, namespacedId);
|
||||
if (id < 0)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to allocate entity ID for '%s'", namespacedId);
|
||||
LogUtil::Log("[WeaveLoader] Failed to allocate entity ID for '%s'", namespacedId);
|
||||
return -1;
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] Registered entity '%s' -> ID %d (%.1fx%.1f)",
|
||||
LogUtil::Log("[WeaveLoader] Registered entity '%s' -> ID %d (%.1fx%.1f)",
|
||||
namespacedId, id, width, height);
|
||||
|
||||
return id;
|
||||
@@ -139,7 +139,7 @@ void native_add_shaped_recipe(
|
||||
const char* pattern,
|
||||
const char* ingredientIds)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Added shaped recipe: %dx %s", resultCount, resultId);
|
||||
LogUtil::Log("[WeaveLoader] Added shaped recipe: %dx %s", resultCount, resultId);
|
||||
}
|
||||
|
||||
void native_add_furnace_recipe(
|
||||
@@ -147,7 +147,7 @@ void native_add_furnace_recipe(
|
||||
const char* outputId,
|
||||
float xp)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Added furnace recipe: %s -> %s (%.1f xp)", inputId, outputId, xp);
|
||||
LogUtil::Log("[WeaveLoader] Added furnace recipe: %s -> %s (%.1f xp)", inputId, outputId, xp);
|
||||
}
|
||||
|
||||
void native_log(const char* message, int level)
|
||||
@@ -176,7 +176,7 @@ int native_get_entity_id(const char* namespacedId)
|
||||
|
||||
void native_subscribe_event(const char* eventName, void* managedFnPtr)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Event subscription: %s", eventName ? eventName : "(null)");
|
||||
LogUtil::Log("[WeaveLoader] Event subscription: %s", eventName ? eventName : "(null)");
|
||||
}
|
||||
|
||||
void native_add_to_creative(int numericId, int count, int auxValue, int groupIndex)
|
||||
@@ -104,17 +104,17 @@ bool Open(const char* pdbPath)
|
||||
{
|
||||
if (s_open) Close();
|
||||
|
||||
LogUtil::Log("[LegacyForge] PdbParser: opening %s", pdbPath);
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: opening %s", pdbPath);
|
||||
|
||||
if (!OpenMappedFile(pdbPath, s_mapped))
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] PdbParser: failed to memory-map PDB file");
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: failed to memory-map PDB file");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (PDB::ValidateFile(s_mapped.baseAddress, s_mapped.fileSize) != PDB::ErrorCode::Success)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] PdbParser: PDB validation failed");
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: PDB validation failed");
|
||||
CloseMappedFile(s_mapped);
|
||||
return false;
|
||||
}
|
||||
@@ -123,7 +123,7 @@ bool Open(const char* pdbPath)
|
||||
|
||||
if (PDB::HasValidDBIStream(*s_rawFile) != PDB::ErrorCode::Success)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] PdbParser: invalid DBI stream");
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: invalid DBI stream");
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
@@ -131,7 +131,7 @@ bool Open(const char* pdbPath)
|
||||
const PDB::InfoStream infoStream(*s_rawFile);
|
||||
if (infoStream.UsesDebugFastLink())
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] PdbParser: PDB uses unsupported /DEBUG:FASTLINK");
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: PDB uses unsupported /DEBUG:FASTLINK");
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
@@ -140,25 +140,25 @@ bool Open(const char* pdbPath)
|
||||
|
||||
if (s_dbiStream->HasValidImageSectionStream(*s_rawFile) != PDB::ErrorCode::Success)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] PdbParser: invalid image section stream");
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: invalid image section stream");
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
if (s_dbiStream->HasValidPublicSymbolStream(*s_rawFile) != PDB::ErrorCode::Success)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] PdbParser: invalid public symbol stream");
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: invalid public symbol stream");
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
if (s_dbiStream->HasValidGlobalSymbolStream(*s_rawFile) != PDB::ErrorCode::Success)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] PdbParser: invalid global symbol stream");
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: invalid global symbol stream");
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
if (s_dbiStream->HasValidSymbolRecordStream(*s_rawFile) != PDB::ErrorCode::Success)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] PdbParser: invalid symbol record stream");
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: invalid symbol record stream");
|
||||
Close();
|
||||
return false;
|
||||
}
|
||||
@@ -170,7 +170,7 @@ bool Open(const char* pdbPath)
|
||||
s_moduleStream = new PDB::ModuleInfoStream(s_dbiStream->CreateModuleInfoStream(*s_rawFile));
|
||||
|
||||
s_open = true;
|
||||
LogUtil::Log("[LegacyForge] PdbParser: PDB opened successfully");
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: PDB opened successfully");
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ void DumpMatching(const char* substring)
|
||||
{
|
||||
if (!s_open) return;
|
||||
|
||||
LogUtil::Log("[LegacyForge] PdbParser: dumping symbols containing '%s'...", substring);
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: dumping symbols containing '%s'...", substring);
|
||||
int count = 0;
|
||||
|
||||
// Public symbols
|
||||
@@ -369,7 +369,7 @@ void DumpMatching(const char* substring)
|
||||
}
|
||||
}
|
||||
|
||||
LogUtil::Log("[LegacyForge] PdbParser: found %d matching symbols", count);
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: found %d matching symbols", count);
|
||||
}
|
||||
|
||||
void BuildAddressIndex()
|
||||
@@ -454,7 +454,7 @@ void BuildAddressIndex()
|
||||
[](const SymEntry& a, const SymEntry& b) { return a.rva == b.rva; });
|
||||
s_addrIndex.erase(last, s_addrIndex.end());
|
||||
|
||||
LogUtil::Log("[LegacyForge] PdbParser: built address index with %zu symbols", s_addrIndex.size());
|
||||
LogUtil::Log("[WeaveLoader] PdbParser: built address index with %zu symbols", s_addrIndex.size());
|
||||
}
|
||||
|
||||
bool FindNameByRVA(uint32_t rva, char* outName, size_t nameSize, uint32_t* outOffset)
|
||||
@@ -24,7 +24,7 @@ bool SymbolResolver::Initialize()
|
||||
m_moduleBase = reinterpret_cast<uintptr_t>(GetModuleHandleA(nullptr));
|
||||
if (!m_moduleBase)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Failed to get module base address");
|
||||
LogUtil::Log("[WeaveLoader] Failed to get module base address");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -38,12 +38,12 @@ bool SymbolResolver::Initialize()
|
||||
else
|
||||
pdbPath += ".pdb";
|
||||
|
||||
LogUtil::Log("[LegacyForge] PDB path: %s", pdbPath.c_str());
|
||||
LogUtil::Log("[LegacyForge] Module base: %p", reinterpret_cast<void*>(m_moduleBase));
|
||||
LogUtil::Log("[WeaveLoader] PDB path: %s", pdbPath.c_str());
|
||||
LogUtil::Log("[WeaveLoader] Module base: %p", reinterpret_cast<void*>(m_moduleBase));
|
||||
|
||||
if (!PdbParser::Open(pdbPath.c_str()))
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ERROR: Failed to open PDB file");
|
||||
LogUtil::Log("[WeaveLoader] ERROR: Failed to open PDB file");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ void* SymbolResolver::Resolve(const char* decoratedName)
|
||||
uint32_t rva = PdbParser::FindSymbolRVA(decoratedName);
|
||||
if (rva == 0)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Symbol not found in PDB: '%s'", decoratedName);
|
||||
LogUtil::Log("[WeaveLoader] Symbol not found in PDB: '%s'", decoratedName);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ void* SymbolResolver::Resolve(const char* decoratedName)
|
||||
|
||||
bool SymbolResolver::ResolveGameFunctions()
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] Resolving game functions via raw PDB parser...");
|
||||
LogUtil::Log("[WeaveLoader] Resolving game functions via raw PDB parser...");
|
||||
|
||||
pRunStaticCtors = Resolve(SYM_RUN_STATIC_CTORS);
|
||||
pMinecraftTick = Resolve(SYM_MINECRAFT_TICK);
|
||||
@@ -96,9 +96,9 @@ bool SymbolResolver::ResolveGameFunctions()
|
||||
|
||||
auto logSym = [](const char* name, void* ptr) {
|
||||
if (ptr)
|
||||
LogUtil::Log("[LegacyForge] %-25s @ %p", name, ptr);
|
||||
LogUtil::Log("[WeaveLoader] %-25s @ %p", name, ptr);
|
||||
else
|
||||
LogUtil::Log("[LegacyForge] MISSING: %s", name);
|
||||
LogUtil::Log("[WeaveLoader] MISSING: %s", name);
|
||||
};
|
||||
|
||||
logSym("RunStaticCtors", pRunStaticCtors);
|
||||
@@ -117,9 +117,9 @@ bool SymbolResolver::ResolveGameFunctions()
|
||||
|
||||
bool ok = pRunStaticCtors && pMinecraftTick && pMinecraftInit;
|
||||
if (ok)
|
||||
LogUtil::Log("[LegacyForge] All critical symbols resolved (via raw PDB parser)");
|
||||
LogUtil::Log("[WeaveLoader] All critical symbols resolved (via raw PDB parser)");
|
||||
else
|
||||
LogUtil::Log("[LegacyForge] CRITICAL symbols missing - hooks will not be installed");
|
||||
LogUtil::Log("[WeaveLoader] CRITICAL symbols missing - hooks will not be installed");
|
||||
|
||||
return ok;
|
||||
}
|
||||
@@ -24,41 +24,41 @@ static std::string GetDllDirectory(HMODULE hModule)
|
||||
|
||||
DWORD WINAPI InitThread(LPVOID lpParam)
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] InitThread started (module=%p)", g_hModule);
|
||||
LogUtil::Log("[WeaveLoader] InitThread started (module=%p)", g_hModule);
|
||||
|
||||
std::string baseDir = GetDllDirectory(g_hModule);
|
||||
LogUtil::Log("[LegacyForge] Runtime DLL directory: %s", baseDir.c_str());
|
||||
LogUtil::Log("[WeaveLoader] Runtime DLL directory: %s", baseDir.c_str());
|
||||
|
||||
char cwd[MAX_PATH] = {0};
|
||||
GetCurrentDirectoryA(MAX_PATH, cwd);
|
||||
LogUtil::Log("[LegacyForge] Game working directory: %s", cwd);
|
||||
LogUtil::Log("[WeaveLoader] Game working directory: %s", cwd);
|
||||
|
||||
char exePath[MAX_PATH] = {0};
|
||||
GetModuleFileNameA(nullptr, exePath, MAX_PATH);
|
||||
LogUtil::Log("[LegacyForge] Host executable: %s", exePath);
|
||||
LogUtil::Log("[WeaveLoader] Host executable: %s", exePath);
|
||||
|
||||
SymbolResolver symbols;
|
||||
if (!symbols.Initialize())
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ERROR: Failed to initialize symbol resolver. Is the PDB present?");
|
||||
LogUtil::Log("[WeaveLoader] ERROR: Failed to initialize symbol resolver. Is the PDB present?");
|
||||
return 1;
|
||||
}
|
||||
LogUtil::Log("[LegacyForge] Symbol resolver initialized");
|
||||
LogUtil::Log("[WeaveLoader] Symbol resolver initialized");
|
||||
|
||||
if (!symbols.ResolveGameFunctions())
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ERROR: Failed to resolve critical game functions.");
|
||||
LogUtil::Log("[WeaveLoader] ERROR: Failed to resolve critical game functions.");
|
||||
return 1;
|
||||
}
|
||||
LogUtil::Log("[LegacyForge] Game functions resolved from PDB");
|
||||
LogUtil::Log("[WeaveLoader] Game functions resolved from PDB");
|
||||
|
||||
if (!HookManager::Install(symbols))
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ERROR: Failed to install hooks");
|
||||
LogUtil::Log("[WeaveLoader] ERROR: Failed to install hooks");
|
||||
symbols.Cleanup();
|
||||
return 1;
|
||||
}
|
||||
LogUtil::Log("[LegacyForge] Hooks installed");
|
||||
LogUtil::Log("[WeaveLoader] Hooks installed");
|
||||
|
||||
// Build the RVA->name index before releasing the PDB.
|
||||
// This index survives PdbParser::Close() and is used by the crash handler.
|
||||
@@ -69,18 +69,18 @@ DWORD WINAPI InitThread(LPVOID lpParam)
|
||||
|
||||
if (!DotNetHost::Initialize())
|
||||
{
|
||||
LogUtil::Log("[LegacyForge] ERROR: Failed to initialize .NET host");
|
||||
LogUtil::Log("[WeaveLoader] ERROR: Failed to initialize .NET host");
|
||||
return 1;
|
||||
}
|
||||
LogUtil::Log("[LegacyForge] .NET runtime initialized");
|
||||
LogUtil::Log("[WeaveLoader] .NET runtime initialized");
|
||||
|
||||
std::string modsPath = baseDir + "mods";
|
||||
LogUtil::Log("[LegacyForge] Mods directory: %s", modsPath.c_str());
|
||||
LogUtil::Log("[WeaveLoader] Mods directory: %s", modsPath.c_str());
|
||||
|
||||
DotNetHost::CallManagedInit();
|
||||
int modCount = DotNetHost::CallDiscoverMods(modsPath.c_str());
|
||||
MainMenuOverlay::SetModCount(modCount);
|
||||
LogUtil::Log("[LegacyForge] Mod discovery complete (%d mods). Ready.", modCount);
|
||||
LogUtil::Log("[WeaveLoader] Mod discovery complete (%d mods). Ready.", modCount);
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user