HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

SharpCraft, a managed replacement for Reinventing the Craft

11-15-2013, 12:13 PM#1
MindWorX
Background
Some of you might have heard about Reinventing the Craft. It's an old project I initially started in 2007 and worked extensively on for several years along with SFilip. Reinventing the Craft changed goals several times, but in the end, the idea was that we wanted to provide a stable API for extending Warcraft III with new natives and features. Sadly, due to limited coding experience and time, the project ended up collecting dust.

Since we stopped working on it, I've been contacted several times by people asking for the source, but I was reluctant to release because of the mess it was and all the experimental features it had. On top of that, it was nearly impossible to maintain if an update were released.

This got me to slowly work on a replacement. The new goal for the replacement was that it should be easier to use and it should prioritize maintainability in favor of features, and above all, it should be open source. Over the past few years I've worked on and off on project SharpCraft.

SharpCraft is written from scratch in C# and using EasyHook to inject into Warcraft III, I'm able to do what Reinventing the Craft did. Currently it features adding new natives, calling existing natives, overriding old natives and more. All this is done simply by writing a C# plugin file in plain text which SharpCraft will compile and execute when started.

I've finally reached a point where I feel confident in calling it version 1.0 and as such, I wanted to announce it.

Feature List
  • Plugin system
  • Adding new natives
  • Calling old natives
  • Overriding old natives
  • Reading mouse terrain coordinates
  • A OOP approach to JASS types (far from complete)


Credits
  • MindWorX - for all initial development of SharpCraft
  • SFilip - for coding and research for our old project Reinventing the Craft.
  • PipeDream - for making Grimoire which have been used as reference and help on multiple occasions
  • xttocs - for making jAPI without which this probably wouldn't be possible

Changelog
Code:
v2.2.5.124b
 * Expanded the managed JASS type wrappers.
 * Implemented script-side events (issue #4) 
 * Implemented new method for calling natives with strings, resulting in more speed, since we're avoiding conversion.
 * Implemented a better method for adding trigger actions.
 * Implemented a few more Jass types.
 * Minor improvement for the InternalNatives.JassStringHandleToString if check.
 * Added missing DelegateAction type.
 * Included commit number in the version number.
 * Fixed a bug with returned JassStrings when calling natives directly.

v2.2.4
 * Giant refactor. Too many changes to list them all.
 * Added three new base classes for scripting.
 * * FullPluginBase; // This class is for plugins that need full access, which means file writing and more.
 * * SafePluginBase; // This class is for plugins that only need safe access.
 * * MapScriptBase;  // This class is for internal war3map.cs scripts. It is similar to SafePluginBase.
 * The sandbox milestone reached 100%, meaning more safety.
 * Interplugin usage it possible through simple dependency.

v1.2.4a
 * Fixed type return bug in CDestructable, CItem and CUnit.

v1.2.4
 * Fixed a directory launcher issue.
 * Fixed version reporting.
 * Added several unmanaged classes to tinker with at your own risk.
 * Improved launcher error reporting.

v1.2.3
 * Refactored the API. It will be backwards compatible until v2.
 * Added Input API for detecting keyboard and mouse input.
 * Added Interface API for detecting FPS and writing messages.
 * Added events for initializing systems that needs the JASS virtual machine ready.
 * Improved on various Jass types.
 * Improved on core functionality.

v1.1.3
 * Improved the missing assembly loader.
 * Added casting from Int32 to JassUnitId.
 * Fixed WarcraftIII.IsMouseOverUI inverted return values.

v1.1.2
 * Fixed issue with inferring return types of natives.

v1.1.1
 * Fixed an issue with multiple plugins.
 * Fixed an issue with loading Lidgren.Network.

v1.1.0
 * Added Lidgren networking support.

v1.0.0
 * First stable release

v0.1pre
 * Initial prerelease

SharpCraft binaries and source can be found on GitHub.

I've attached the latest release to this post, along with a map that showcases a few features in the example plugin that comes with the release.
Attached Files
File type: zipSharpCraft.v2.2.5.124b.zip (1.1 MB)
11-15-2013, 12:14 PM#2
MindWorX
<Reserved for later use>
11-15-2013, 02:20 PM#3
<?White-Tiger?>
yay! (let's hope it isn't to late already)

Now port it to C/C++ and I'll be happy xD

addendum: how about crash reports? Your example actually crashes Warcraft III :P I guess once the remaining(corpse) of a unit is about to leave the map... (you move dead units)
And what about multiplayer... RtC had synchronization problems... but otherwise it worked... is SharpCraft improved in this area?
Also RtC had some "native" problems with strings... they didn't work if passed to custom natives (IIRC)
11-15-2013, 05:23 PM#4
MindWorX
Quote:
Originally Posted by <?White-Tiger?>
Now port it to C/C++ and I'll be happy xD
I won't be porting it to C or C++. However, the EasyHook library works for C and C++ as well, and the source for SharpCraft is open, so there's plenty of possibility for someone who wants to, to port it.

Quote:
Originally Posted by <?White-Tiger?>
addendum: how about crash reports? Your example actually crashes Warcraft III :P I guess once the remaining(corpse) of a unit is about to leave the map... (you move dead units)
Yeah, I forgot about that. I might be able to install some safety into the SetUnitX/Y natives, but normally it would be up to the map maker to ensure correct usage of vanilla natives.

Quote:
Originally Posted by <?White-Tiger?>
And what about multiplayer... RtC had synchronization problems... but otherwise it worked... is SharpCraft improved in this area?
SharpCraft has the same issues, anything that happens locally will have to be synced some way to be used.

Quote:
Originally Posted by <?White-Tiger?>
Also RtC had some "native" problems with strings... they didn't work if passed to custom natives (IIRC)
This has been completely fixed. You can call existing natives and get whatever the natives return with no issues. Same goes for custom.
11-16-2013, 03:54 AM#5
<?White-Tiger?>
Quote:
Originally Posted by MindWorX
[...] I might be able to install some safety into the SetUnitX/Y natives, but normally it would be up to the map maker to ensure correct usage of vanilla natives.[...]
well.. you didn't in your example :P

Anyway.. here's my version of the example plugin... but the map boundary code should be changed to detect the current boundaries.
C#:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TinkerWorX.SharpCraft.Game;
using TinkerWorX.SharpCraft.Game.Jass;

public class ExamplePlugin2 : GamePluginBase
{
//private:
	//native Cheat takes string cheatStr returns nothing
	private delegate void CheatPrototype(JassStringArg cheatStr);
	private static CheatPrototype Cheat = WarcraftIII.GetNative("Cheat").ToDelegate<CheatPrototype>();
	// native DisplayTextToPlayer takes player toPlayer, real x, real y, string message returns nothing 
	private delegate void DisplayTextToPlayerPrototype(JassPlayer toPlayer, JassRealArg x, JassRealArg y, JassStringArg message);
	private static DisplayTextToPlayerPrototype DisplayTextToPlayer = WarcraftIII.GetNative("DisplayTextToPlayer").ToDelegate<DisplayTextToPlayerPrototype>();
	private List<JassUnit> units=new List<JassUnit>();
//public:
	public override string Name{get{return "Example-Plugin-II";}}
	public override Version Version{get{return new Version(0,0,1);}}
	
	static float DegreeToRadian(float angle) {return (float)Math.PI * angle / 180.00f;}
	static float RadianToDegree(float angle) {return angle * (180.00f / (float)Math.PI);}
	private const float mapX1=-3328+64-16;//left
	private const float mapX2=3328-1;//right
	private const float mapY1=-3072-512+32;//down
	private const float mapY2=3584-512-1;//up
	public void hookedCheat(JassStringArg cheatStr)
	{
		switch(cheatStr){
		case "mapinit":
			DisplayTextToPlayer(JassPlayer.FromLocal(), 0, 0, "Example-Plugin-II: |cff00FF00active|r");
			DisplayTextToPlayer(JassPlayer.FromLocal(), 0, 0, "Press |cffFFCC00ESC|r to spawn some units at your cursor");
			break;
		case "tick":
			const float dt=0.01f;//this is how often the timer is updating.
			const float speed=128.00f;//this is how far we want the unit to move per second.
			for(int i=this.units.Count; i!=0; ){
				JassUnit unit=this.units[--i];
				if(unit.GetLife()<1) {this.units.RemoveAt(i); continue;}
				float facing = unit.GetFacing();
				float posX=unit.GetX() + speed * dt * (float)Math.Cos(DegreeToRadian(facing));
				float posY=unit.GetY() + speed * dt * (float)Math.Sin(DegreeToRadian(facing));
				if(posX<mapX1) posX=mapX1; else if(posX>mapX2) posX=mapX2;
				if(posY<mapY1) posY=mapY1; else if(posY>mapY2) posY=mapY2;
				unit.SetX(posX); unit.SetY(posY);
			}
			break;
		case "esc":
			var random = new Random();
			DisplayTextToPlayer(JassPlayer.FromLocal(), 0, 0, "|cffCCCCFFmoar units!|r :P");
			this.units.Add(JassUnit.Create(JassPlayer.FromIndex(0), (JassUnitId)"hfoo", WarcraftIII.MouseTerrain.X, WarcraftIII.MouseTerrain.Y, random.Next() * 360));
			this.units.Add(JassUnit.Create(JassPlayer.FromIndex(1), (JassUnitId)"hfoo", WarcraftIII.MouseTerrain.X, WarcraftIII.MouseTerrain.Y, random.Next() * 360));
			this.units.Add(JassUnit.Create(JassPlayer.FromIndex(2), (JassUnitId)"hfoo", WarcraftIII.MouseTerrain.X, WarcraftIII.MouseTerrain.Y, random.Next() * 360));
			this.units.Add(JassUnit.Create(JassPlayer.FromIndex(3), (JassUnitId)"hfoo", WarcraftIII.MouseTerrain.X, WarcraftIII.MouseTerrain.Y, random.Next() * 360));
			break;
		default:
			Cheat(cheatStr);
			break;
		}
	}

	public void onMapStart()
	{
		this.units.Clear();
	}
	public override void Initialize()
	{
		WarcraftIII.MapStart+=this.onMapStart;//add our "onMapStart" callback
		WarcraftIII.AddNative(new CheatPrototype(this.hookedCheat),"Cheat");//Override the original cheat native, so we can intercept calls.
	}
}


And I've got a new question :P
What does Sharpcraft.Editor actually do? It would be nice if it allowed at least the testing of maps with SharpCraft loaded...
11-16-2013, 11:33 AM#6
MindWorX
Quote:
Originally Posted by <?White-Tiger?>
What does Sharpcraft.Editor actually do?
It doesn't do anything at the moment, but the source is there, ready for someone to add functionality they'd like. :)
11-16-2013, 01:05 PM#7
MindWorX
New release!

Changelog
Code:
v1.1.0
 * Added Lidgren networking support.
11-16-2013, 01:14 PM#8
chobibo
Cool! you're back in action! I'll try testing if I can.
11-21-2013, 01:02 PM#9
MindWorX
New release!

Changelog
Code:
v1.1.1
 * Fixed an issue with multiple plugins.
 * Fixed an issue with loading Lidgren.Network.
11-22-2013, 11:56 PM#10
loktar
I downloaded and used SharpCraft, and now all the strings in the object editor have been replaced with variable names. Can I restore the strings or do I need to reinstall WC3?

Edit: I'm sorry, I must have pushed CTRL+D by accident, it's fixed :)
11-23-2013, 09:42 AM#11
MindWorX
Quote:
Originally Posted by loktar
I downloaded and used SharpCraft, and now all the strings in the object editor have been replaced with variable names. Can I restore the strings or do I need to reinstall WC3?

Edit: I'm sorry, I must have pushed CTRL+D by accident, it's fixed :)
You got me worried there for a second. SharpCraft should in no way make any permanent changes.
11-25-2013, 09:23 PM#12
MindWorX
New release!

Changelog
Code:
v1.1.3
 * Improved the missing assembly loader.
 * Added casting from Int32 to JassUnitId.
 * Fixed WarcraftIII.IsMouseOverUI inverted return values.

v1.1.2
 * Fixed issue with inferring return types of natives.
11-29-2013, 10:28 PM#13
<?White-Tiger?>
some possible use cases for RtC/#Craft:
  • *replace "GameCaptureX" which captures and shows all messages a map sends (useful to have a log of game messages, or for save codes ;))
  • *maybe possible to replace at least some parts from Visual Custom Kick which seems to be dead by now...
    ‏‏‏ 
  • map updater / installer / downloader (will have to somehow capture "player to player" messages... such as channel or lobby chat for download commands)
It's not really related to improve maps and such, but still :P
(*those replace cases might not be relevant yet, as tools exist already but they might have compatibility problems in the future.. so it can be done at least :P)
12-01-2013, 01:38 AM#14
MindWorX
New release!

Changelog
Code:
v1.2.3
 * Refactored the API. It will be backwards compatible until v2.
 * Added Input API for detecting keyboard and mouse input.
 * Added Interface API for detecting FPS and writing messages.
 * Added events for initializing systems that needs the JASS virtual machine ready.
 * Improved on various Jass types.
 * Improved on core functionality.
12-11-2013, 06:00 PM#15
MindWorX
New release!

Changelog
Code:
v1.2.4a
 * Fixed type return bug in CDestructable, CItem and CUnit.

v1.2.4
 * Fixed a directory launcher issue.
 * Fixed version reporting.
 * Added several unmanaged classes to tinker with at your own risk.
 * Improved launcher error reporting.