• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

SharpCraft, a managed replacement for Reinventing the Craft

Status
Not open for further replies.
Level 2
Joined
Sep 17, 2015
Messages
13
Yes, most important thing for me is .blp files (to draw them as gui on screen)

EDIT:
please take a look at this, this is exactly what I mean but with SC (if possible).
 
Last edited:

MindWorX

Tool Moderator
Level 20
Joined
Aug 3, 2004
Messages
709
It should be possible to add MPQ file reading, but adding the different elements to the UI would need to be a different plugin with DirectX/OpenGL hooks in place. There are different hacks like it, but I have no idea how well they place with SharpCraft.
 
It should be possible to add MPQ file reading, but adding the different elements to the UI would need to be a different plugin with DirectX/OpenGL hooks in place. There are different hacks like it, but I have no idea how well they place with SharpCraft.

RenderEdge only works in 1.26a.

You can't just use MpqLib?
 

MindWorX

Tool Moderator
Level 20
Joined
Aug 3, 2004
Messages
709
RenderEdge only works in 1.26a.

You can't just use MpqLib?
Reading MPQ's aren't the problem. It's obtaining a handle without the file being locked that might be tricky. I do read out some files when loading in-map plugins, maybe I can just clone them and keep them in memory for later. Not very efficient, but who cares about a few megabytes of memory.
 

MindWorX

Tool Moderator
Level 20
Joined
Aug 3, 2004
Messages
709
upload_2016-9-19_21-46-49.png

Injecting SharpDX was a relatively straight forward process, so custom UI should easily be possible, provided you want to fiddle around with DirectX.
 
Last edited:
Level 2
Joined
Sep 17, 2015
Messages
13
RenderEdge only works in 1.26a.

You can't just use MpqLib?

Injecting SlimDX was a relatively straight forward process, so custom UI should easily be possible, provided you want to fiddle around with DirectX.

Thank you for your interest but they are pretty old and obsolete tools so I don't like them... :confused: (It's why I choose SC, vrJASS, JNGP, ...)

Thanks to SharpDX and StormLibSharp, with just these lines of code we can do the job:
code.png


That was very tasty, wasn't? ;)
 
Last edited:
Level 2
Joined
Sep 17, 2015
Messages
13
RenderEdge only works in 1.26a.

I know but I do not think that upgrading to 1.27 is something other than find and place new addresses/offsets; is it?
(I don't have installed that patch so maybe like block the RtC functionality, RenderEdge also can't work with patch and I am not informed about)
 

MindWorX

Tool Moderator
Level 20
Joined
Aug 3, 2004
Messages
709
Thank you for your interest but they are pretty old and I don't like old and obsolete things... (It's why I choose SC, vrJASS, JNGP, ...)

Thanks to SharpDX and StormLibSharp, with just these lines of code we can do the job:
View attachment 248699

That was very tasty, isn't? ;)
Yeah, I used SharpDX actually, since SlimDX didn't have a version that worked, so it was just a typing error in the previous post. Looks like you have something going, which is great. I hope you can make something that people can use.
I know but I do not think that upgrading to 1.27 is something other than find and place new addresses/offsets; is it?
(I don't have that patch so maybe like block the RtC functionality, RenderEdge also can't work with patch and I am not informed about)
Since 1.26 used directx 8 and 1.27 uses directx 9 it might not be so simple. Depends on how the code in RenderEdge is designed.
 
Level 2
Joined
Sep 17, 2015
Messages
13
Yeah, I used SharpDX actually, since SlimDX didn't have a version that worked, so it was just a typing error in the previous post. Looks like you have something going, which is great. I hope you can make something that people can use.
Yeah I'm making a GUI plugin(ok, module :| ) for SharpCraft, but with Warcraft "Black Border" :| UI, I can't speak about UI so first I have to remove that.
However, It's currently intergrated with (Ugly) AntTweakBar and also some natives for interact with Direct3D (Actually SharpDX);
and also It will be placed on github after release;

Since 1.26 used directx 8 and 1.27 uses directx 9 it might not be so simple. Depends on how the code in RenderEdge is designed.
I'm using this for solve this issue :D
 

MindWorX

Tool Moderator
Level 20
Joined
Aug 3, 2004
Messages
709
Yeah I'm making a GUI plugin(ok, module :| ) for SharpCraft, but with Warcraft "Black Border" :| UI, I can't speak about UI so first I have to remove that.
However, It's currently intergrated with (Ugly) AntTweakBar and also some natives for interact with Direct3D (Actually SharpDX);
and also It will be placed on github after release;
Sounds cool, looking forward to seeing it.
No, it is very simple. To RenderEdge work on the last patch, I should only replace old offsets and change some attributes in d3d hook function: simply replace "d3d8.dll" to "d3d9.dll" and "Direct3DCreate8" to "Direct3DCreate9".
That's great. How does it work with SharpCraft though? Is it possible to use them together?
 
Level 2
Joined
Sep 17, 2015
Messages
13
There is a bad thing about the RenderEdge and it's that RenderEdge is based on Nirvana (I Don't know why)
and also it needs a luncher and it has homonymous natives with SharpCraft... :(
 
Level 2
Joined
Sep 17, 2015
Messages
13
In release v2.2.5.124b there is a plugins.old directory and also there is a great plugin called "DevelopmentPlugin";
It's exactly what I need to hide the Native UI of game. (By change offsets to Render funcs)

I think redirecting the 0x60C580 call must do that but it has no effects.

It's my code:
Code:
        // 0x60C580 RENDER_MAYJOR_UI_FUNC (for 1.26a)
        [UnmanagedFunctionPointer(CallingConvention.FastCall)]
        private delegate void sub_6F60C580Delegate(Int32 a1, Int32 a2);

        private void sub_6F60C580Hook(Int32 a1, Int32 a2)
        {
            // sub_6F60C580(a1, a2); // disable function
        }

        sub_6F60C580 = Memory.InstallHook(GetModuleHandle("game.dll") + 0x60C580, new sub_6F60C580Delegate(this.sub_6F60C580Hook), false,  true);

What's going wrong here? :cq:
 

MindWorX

Tool Moderator
Level 20
Joined
Aug 3, 2004
Messages
709
In release v2.2.5.124b there is a plugins.old directory and also there is a great plugin called "DevelopmentPlugin";
It's exactly what I need to hide the Native UI of game. (By change offsets to Render funcs)

I think redirecting the 0x60C580 call must do that but it has no effects.

It's my code:
Code:
        // 0x60C580 RENDER_MAYJOR_UI_FUNC (for 1.26a)
        [UnmanagedFunctionPointer(CallingConvention.FastCall)]
        private delegate void sub_6F60C580Delegate(Int32 a1, Int32 a2);

        private void sub_6F60C580Hook(Int32 a1, Int32 a2)
        {
            // sub_6F60C580(a1, a2); // disable function
        }

        sub_6F60C580 = Memory.InstallHook(GetModuleHandle("game.dll") + 0x60C580, new sub_6F60C580Delegate(this.sub_6F60C580Hook), false,  true);

What's going wrong here? :cq:
CallingConvention.FastCall isn't supported in C# sadly, which means hooking fastcall functions isn't supported in C# natively. Not sure if there is an easy way to fix this, but it's a big problem which has also given me problems. If you want to venture into this area, you can look at the EasyHook source code and see if you can add a trampoline that works with __fastcall. I can't help you with it though.
 
Level 2
Joined
Sep 17, 2015
Messages
13
CallingConvention.FastCall isn't supported in C# sadly, which means hooking fastcall functions isn't supported in C# natively. Not sure if there is an easy way to fix this, but it's a big problem which has also given me problems. If you want to venture into this area, you can look at the EasyHook source code and see if you can add a trampoline that works with __fastcall. I can't help you with it though.

Thanks, I'll do my try... :)
 
Level 2
Joined
Sep 17, 2015
Messages
13
After some days I was able to find a little free time and thus i'd "connected" my SharpCraft plugin with c++ plugin (and Yes, actually I had no succeed for plain C#) using SWIG;

EDIT:
Now It's what I have:
Untitled.jpg


As you see everything is gone Except black borders [as I predict]
Now I have a question: Do I have to search for 0xFF000000 (full non-transparency black color in Direct3D) in the memory and replace that with: 0 (full transparency black color) or search for rendering area dimensions and try to extend them?
I mean: Is game rendered under black borders and it's just needed to clear them or it's different than I think?

Anybody has any experience about this?
 
Last edited:
Level 8
Joined
Nov 29, 2014
Messages
191
No, game not rendered under black borders. You should to hook SetViewport function from d3d8.dll/d3d9.dll, then understand that is rendered at the moment, if it's game area, just replace viewport by your own.

You can also look at the first screenshots of RenderEdge experimental version thread, where I hide the black borders by this method.

Update:
There is my code:
C:
STDMETHODIMP CDirect3DDevice8::SetViewport(THIS_ CONST D3DVIEWPORT8* pViewport)
{
    double rate = (double)pViewport->Y / (double)pViewport->Height;
    gamerender = rate >= 0.02 && rate <= 0.05;
    if (gamerender)
    {
        D3DVIEWPORT9 pNewViewport{ 0, 0, g_deviceWidth, g_deviceHeight, 0, 1 };
        return pDevice9->SetViewport(&pNewViewport);
    }
    return pDevice9->SetViewport(pViewport);
}
 
Last edited:
Level 8
Joined
Nov 29, 2014
Messages
191
And this is my implementation of widescreen fix that's work on 1.26a and 1.27a path, It also doesn't require d3d hook:
C:
uintptr_t pWideScreenFix = 0;
int __fastcall WideScreenFix(float a2, float a3, float a4, float a5)
{
    float fWideScreenMul = ((float)GetWindowWidth() / (float)GetWindowHeight()) / (4.0f / 3.0f);

    a2 *= fWideScreenMul; // 1.26f;
    a3 *= fWideScreenMul;

    return fast_call<int>(pWideScreenFix, a2, a3, a4, a5);
}

void Init()
{
    if (GetWar3Version() == version_126)
        pWideScreenFix = (DWORD)GetModuleHandle("Game.dll") + 0x7B66F0;
    else if (GetWar3Version() == version_127a)
        pWideScreenFix = (DWORD)GetModuleHandle("Game.dll") + 0x0D31D0;
    hook::inline_install(&pWideScreenFix, (uintptr_t)WideScreenFix);
}

There hook::inline_install is function written using detours:
C:
bool inline_install(uintptr_t* pointer_ptr, uintptr_t detour)
{
    LONG status;
    if ((status = DetourTransactionBegin()) == NO_ERROR)
    {
        if ((status = DetourUpdateThread:):GetCurrentThread())) == NO_ERROR)
        {
            if ((status = DetourAttach((PVOID*)pointer_ptr, (PVOID)detour)) == NO_ERROR)
            {
                if ((status = DetourTransactionCommit()) == NO_ERROR)
                {
                    return true;
                }
            }
        }
        DetourTransactionAbort();
    }
    ::SetLastError(status);
    return false;
}
 
Level 2
Joined
Sep 17, 2015
Messages
13
At first that worked for me Successfully:

Code:
this.SetViewportLocalHook = LocalHook.Create(D3xContainer.RealDevice->VTable->SetViewportPtr, new D3D9.IDirect3DDevice9VTable.SetViewportPrototype(this.SetViewportHook), null);
this.SetViewportLocalHook.ThreadACL.SetInclusiveACL(new[] { 0 });


public Int32 SetViewportHook(D3D9.IDirect3DDevice9* This, D3D9.D3DVIEWPORT* pViewport) {
            double rate = (double)pViewport->Y / (double)pViewport->Height;
            if (rate >= 0.02 && rate <= 0.05) {
                        pViewport->Y = 0;
                        pViewport->Height = (UInt32) WindowDimensions.Height;
            }
            return This->SetViewport(pViewport);
}

but after a random period of time, I have encountered with this problem:
error.jpg


And also mouse couldn't work properly as you said... :/

Anyway thanks for your help... :)

I think it's time to "give in" against WC3 "Black Borders"... :
 

MindWorX

Tool Moderator
Level 20
Joined
Aug 3, 2004
Messages
709
How do I start it with loading a custom MPQ archive? Is there any documentation in the Wiki on GitHub? I'd really like to start my mod with this and use the JASS debugger.
I would love to help you, but I don't know how to inject an MPQ with high priority. If you can find an open source tool or some documentation on how to do it, I'll be more than happy to help you out.
 
Level 8
Joined
Nov 29, 2014
Messages
191
Is it not working?
This is what I use in my launcher:
Code:
typedef bool (CALLBACK* SFileOpenArchive)(const char* szMpqName, DWORD dwPriority, DWORD dwFlags, HANDLE* phMPQ);

void LoadMpq(char *mpqname)
{
        UINT priority = 0x10;
    HANDLE hMPQ;

    SFileOpenArchive OpenArchive = (SFileOpenArchive)((DWORD)GetModuleHandle("game.dll") + 0x006EB57C);
    if (!OpenArchive)
        MessageBox(0, "Could not find SFileOpenArchive", 0, 0);

    if (!OpenArchive(mpqname, priority, 0, &hMPQ))
        MessageBox(0, "Could not open archive", 0, 0);
}
And you need to do this before each .mpq loading:
priority++

This is code for SharpCraft:
Code:
[DllImport("storm.dll", EntryPoint = "#266")]
public static extern bool OpenArchive(string filename, uint priority, int flags, IntPtr handle);

public static bool OpenArchive(string filename, uint priority, IntPtr handle)
{
    return OpenArchive(filename, priority, 0, handle);
}
 
Last edited:

MindWorX

Tool Moderator
Level 20
Joined
Aug 3, 2004
Messages
709
Is it not working?


This is code for SharpCraft:
Code:
[DllImport("storm.dll", EntryPoint = "#266")]
public static extern bool OpenArchive(string filename, uint priority, int flags, IntPtr handle);

public static bool OpenArchive(string filename, uint priority, IntPtr handle)
{
    return OpenArchive(filename, priority, 0, handle);
}
You're right. I never knew how it did the injection in the first place. I'm rather busy at the moment, but I'll see if I can piece something together as soon as possible Barade.
 
Level 8
Joined
Nov 29, 2014
Messages
191
Barade, this is code used in Grimoire to load custom MPQs.
To use it in SharpCraft, just create new plugin and add something like that:
C#:
using System;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Collections.Generic;
using TinkerWorX.SharpCraft;

namespace MyFirstPlugin
{
    [DllImport("storm.dll", EntryPoint = "#266")]
    public static extern bool OpenArchive(string filename, uint priority, int flags, IntPtr handle);

    public class FirstPlugin : Iplugin
    {
        public void Initialize(PluginContext context)
        {
            IntPtr handle;
            if (!OpenArchive("MyArchive.mpq", 0, 0, handle))
                Debug.WriteLine("Failed to load MyArchive.mpq");
        }

        public void OnGameLoad(PluginContext context)
        {
         
        }
    }
}
 
Level 25
Joined
Feb 2, 2006
Messages
1,685
Can you maybe provide such a plugin using a config file where I can specify MPQ archives like loadmpq.lua? I would have to set up a C# development environment first. It would be VERY USEFUL if when I enable "Use SharpCraft" in the JNGP 2 it would start the game with sharpcraft considering loadmpq.lua of the JNGP.

This would also be cool for multiplayer tests with the JNGP.
 
Level 8
Joined
Jan 23, 2015
Messages
121
Hello there, wondering about the work done and work that will be done later on; though I was to try it, but got an error while loading the game:
Initializing natives api . . .
InitNativesHook: 0x6F1E9A50 . hook installed!
Scanning vanilla natives . OnGameLoad(MindWorX.SharpCraft.Modules.JassAPI.JassAPIPlugin): System.NullReferenceException: Object reference not set to an instance of an object.
in MindWorX.SharpCraft.Modules.JassAPI.Natives.InitializeVanillaNatives()
in MindWorX.SharpCraft.Modules.JassAPI.Natives.Initialize()
in MindWorX.SharpCraft.Modules.JassAPI.JassAPIPlugin.OnGameLoad(PluginContext context)
in TinkerWorX.SharpCraft.PluginSystem.OnGameLoad()
sub_6F7B0FA0Hook: 0x6F7B0FA0 . hook installed!
sub_6F660F00Hook: 0x6F845EE0 . hook installed!
sub_6F65DE40Hook: 0x6F8476B0 . hook installed!
sub_6F661A90Hook: 0x6F84AE20 . OnGameLoad(MindWorX.SharpCraft.Modules.JassDebugger.JassDebuggerPlugin): System.NotSupportedException: STATUS_NOT_SUPPORTED: Hooking far jumps is only supported if they are the first instruction. (Code: 2)
in EasyHook.LocalHook.Create(IntPtr InTargetProc, Delegate InNewProc, Object InCallback)
in TinkerWorX.SharpCraft.Utilities.Memory.InstallHook[T](IntPtr address, T newFunc, Boolean inclusive, Boolean exclusive)
in MindWorX.SharpCraft.Modules.JassDebugger.JassDebugger.OnGameLoad()
in MindWorX.SharpCraft.Modules.JassDebugger.JassDebuggerPlugin.OnGameLoad(PluginContext context)
in TinkerWorX.SharpCraft.PluginSystem.OnGameLoad()
I loaded into the /plugins folder everything from the latest Modules.zip from the 2nd post of this thread which I believe has the latest version of such plugins. I was loading from "Start game windowed (debug).bat"

Also, do we have any kind of specialized to the sharpcraft forums, where could be submissions for plugins, for example? I guess this one lonely thread isn't enough for discussing everything.
 
Level 4
Joined
Jun 19, 2010
Messages
49
is there already a way that sharpcraft can be run multiple times for wc3.exe?
my map is based on sharpcraft & i really need to make some multiPLAYER tests...
also found a new kLoader, but i guess it doesn't work together with sharpcraft as it only comes as an EXE:
UnrealLoader [Universal kLoader]
 

MindWorX

Tool Moderator
Level 20
Joined
Aug 3, 2004
Messages
709
Hello there, wondering about the work done and work that will be done later on; though I was to try it, but got an error while loading the game:
Initializing natives api . . .
InitNativesHook: 0x6F1E9A50 . hook installed!
Scanning vanilla natives . OnGameLoad(MindWorX.SharpCraft.Modules.JassAPI.JassAPIPlugin): System.NullReferenceException: Object reference not set to an instance of an object.
in MindWorX.SharpCraft.Modules.JassAPI.Natives.InitializeVanillaNatives()
in MindWorX.SharpCraft.Modules.JassAPI.Natives.Initialize()
in MindWorX.SharpCraft.Modules.JassAPI.JassAPIPlugin.OnGameLoad(PluginContext context)
in TinkerWorX.SharpCraft.PluginSystem.OnGameLoad()
sub_6F7B0FA0Hook: 0x6F7B0FA0 . hook installed!
sub_6F660F00Hook: 0x6F845EE0 . hook installed!
sub_6F65DE40Hook: 0x6F8476B0 . hook installed!
sub_6F661A90Hook: 0x6F84AE20 . OnGameLoad(MindWorX.SharpCraft.Modules.JassDebugger.JassDebuggerPlugin): System.NotSupportedException: STATUS_NOT_SUPPORTED: Hooking far jumps is only supported if they are the first instruction. (Code: 2)
in EasyHook.LocalHook.Create(IntPtr InTargetProc, Delegate InNewProc, Object InCallback)
in TinkerWorX.SharpCraft.Utilities.Memory.InstallHook[T](IntPtr address, T newFunc, Boolean inclusive, Boolean exclusive)
in MindWorX.SharpCraft.Modules.JassDebugger.JassDebugger.OnGameLoad()
in MindWorX.SharpCraft.Modules.JassDebugger.JassDebuggerPlugin.OnGameLoad(PluginContext context)
in TinkerWorX.SharpCraft.PluginSystem.OnGameLoad()
I loaded into the /plugins folder everything from the latest Modules.zip from the 2nd post of this thread which I believe has the latest version of such plugins. I was loading from "Start game windowed (debug).bat"
As far as I can tell, you might be on the wrong version of Warcraft, can you check which one you're on?

Also, do we have any kind of specialized to the sharpcraft forums, where could be submissions for plugins, for example? I guess this one lonely thread isn't enough for discussing everything.
It's been discussed a few times. It's basically just about me saying so, and I'll get a hosted forum here, but I don't have a lot of time to dedicate to this project, and the hosted forum might give another impression.

is there already a way that sharpcraft can be run multiple times for wc3.exe?
my map is based on sharpcraft & i really need to make some multiPLAYER tests...
also found a new kLoader, but i guess it doesn't work together with sharpcraft as it only comes as an EXE:
UnrealLoader [Universal kLoader]
Sadly, SharpCraft doesn't currently support running multiple times on the same system. This is a known issue that might get fixed in the future.
 
Level 4
Joined
Jun 19, 2010
Messages
49
- on post #1 in the changelog, version v4.0.0.179 is already ready, but for download you only offer v4.0.0.160 ;D
(double checked it: SharpCraft.dll is also on 4.0.0.160...)
- is v4.0.0.160 & v4.0.0.179 ready for WC3-TFT-1.28a?
 
Level 4
Joined
Jun 19, 2010
Messages
49
ah, wait, so is this new SharpCraft WEX Bundle also containing this latest SharpCraft?!
Link to your SharpCraft WEX Bundle:
SharpCraft World Editor Extended Bundle

ah, i guess so, hence the word "bundle", lol :D my fault...
okay, confirmed:
MindWorX said:
WEX is a SharpCraft based replacement for JNGP. You can find a bundled download with SharpCraft and WEX here.

so the new official place to discuss SharpCraft & friends should be in the "Forum/Hosted Projects/SharpCraft & WEX":
SharpCraft & WEX
 
Last edited:
Status
Not open for further replies.
Top