Well, I finally finished the wrappers. I'm sure there will be several bugs. The code isn't exactly clean. But it works.
[b]Download:[/b] [url]http://cdbarrett.com/dump/GarrysmodNET.zip[/url]
[b]Source:[/b] [url]http://cdbarrett.com/dump/GarrysmodNET_src.zip[/url]
[b]Installation:[/b]
[list]
[*]Copy Garrysmod.Modules.dll into the garrysmod folder. The one with hl2.exe in it.
[*]Copy gm_GarrysmodDotNet.dll into the garrysmod/lua/includes/modules/ folder
[*]Place .NET Modules inside garrysmod/lua/includes/modules/DotNet/
[/list]
All things must derive from GMModule, this includes Modules and MetaTables.
Each module/metatable should contain the proper attribute.
You need to add Garrysmod.Modules.dll as a reference to your project.
[b]Example:[/b]
[code]/*------------------------------------
Types
------------------------------------*/
public class XmlTypes
{
public const int XmlDocument = 15000;
public const int XmlNode = 15001;
}
/*------------------------------------
MetaXmlDocument
------------------------------------*/
[LuaMetaTable( "XmlDocument", XmlTypes.XmlDocument )]
public class MetaXmlDocument : GMModule
{
// -------- GC
[LuaFunction( "__gc", Function.Meta )]
[LuaTypeCheck( 1, XmlTypes.XmlDocument )]
public int GarbageCollect( )
{
Lua.Msg( "Collected XmlDocument\n" );
// Free
Lua.FreeManagedObject( 1 );
return 0;
}
// -------- DocumentElement
[LuaFunction( "DocumentElement", Function.Normal )]
[LuaTypeCheck( 1, XmlTypes.XmlDocument )]
public int DocumentElement( )
{
// get document
XmlDocument doc = (XmlDocument)Lua.GetManagedObject( 1 );
// push the document element
LuaObject metatable = Lua.GetMetaTable( "XmlNode", XmlTypes.XmlNode );
Lua.PushManagedObject( metatable, doc.DocumentElement );
return 1;
}
// -------- SelectNodes
[LuaFunction( "SelectNodes", Function.Normal )]
[LuaTypeCheck( 1, XmlTypes.XmlDocument )]
[LuaTypeCheck( 2, Types.String )]
public int SelectNodes( )
{
// get document
XmlDocument doc = (XmlDocument)Lua.GetManagedObject( 1 );
// get the path
string path = Lua.GetString( 2 );
// get the namespace manager
XmlNamespaceManager namespacemanager = new XmlNamespaceManager( doc.NameTable );
namespacemanager.AddNamespace( String.Empty, doc.NamespaceURI );
// select nodes
XmlNodeList list = doc.SelectNodes( path, namespacemanager );
// node metatable
LuaObject meta = Lua.GetMetaTable( "XmlNode", XmlTypes.XmlNode );
// populate a lua table with the nodes
LuaObject table = Lua.GetNewTable();
float count = 1.0f;
foreach( XmlNode node in list )
{
// create a new temporary object
LuaObject temp = Lua.NewTemporaryObject();
Lua.PushManagedObject( meta, node );
temp.SetFromStack( -1 );
// add
table.SetMember( count++, temp );
}
// push the table
Lua.Push( table );
return 1;
}
// -------- SelectSingleNode
[LuaFunction( "SelectSingleNode", Function.Normal )]
[LuaTypeCheck( 1, XmlTypes.XmlDocument )]
[LuaTypeCheck( 2, Types.String )]
public int SelectSingleNode( )
{
// get document
XmlDocument doc = (XmlDocument)Lua.GetManagedObject( 1 );
// get the path
string path = Lua.GetString( 2 );
// get the namespace manager
XmlNamespaceManager namespacemanager = new XmlNamespaceManager( doc.NameTable );
namespacemanager.AddNamespace( String.Empty, doc.NamespaceURI );
// select nodes
XmlNode node = doc.SelectSingleNode( path, namespacemanager );
// valid node?
if( node != null )
{
// push node
LuaObject meta = Lua.GetMetaTable( "XmlNode", XmlTypes.XmlNode );
Lua.PushManagedObject( meta, node );
return 1;
}
return 0;
}
}
/*------------------------------------
MetaXmlNode
------------------------------------*/
[LuaMetaTable( "XmlNode", XmlTypes.XmlNode )]
public class MetaXmlNode : GMModule
{
// -------- GC
[LuaFunction( "__gc", Function.Meta )]
[LuaTypeCheck( 1, XmlTypes.XmlNode )]
public int GarbageCollect( )
{
Lua.Msg( "Collected XmlNode\n" );
// free
Lua.FreeManagedObject( 1 );
return 0;
}
// -------- NextSibling
[LuaFunction( "NextSibling", Function.Normal )]
[LuaTypeCheck( 1, XmlTypes.XmlNode )]
public int NextSibling( )
{
// get document
XmlNode node = (XmlNode)Lua.GetManagedObject( 1 );
// have a sibling?
if( node.NextSibling != null )
{
// push the document element
LuaObject metatable = Lua.GetMetaTable( "XmlNode", XmlTypes.XmlNode );
Lua.PushManagedObject( metatable, node.NextSibling );
return 1;
}
return 0;
}
// -------- FirstChild
[LuaFunction( "FirstChild", Function.Normal )]
[LuaTypeCheck( 1, XmlTypes.XmlNode )]
public int FirstChild( )
{
// get document
XmlNode node = (XmlNode)Lua.GetManagedObject( 1 );
// have a child?
if( node.FirstChild != null )
{
// push the document element
LuaObject metatable = Lua.GetMetaTable( "XmlNode", XmlTypes.XmlNode );
Lua.PushManagedObject( metatable, node.FirstChild );
return 1;
}
return 0;
}
// -------- InnerText
[LuaFunction( "InnerText", Function.Normal )]
[LuaTypeCheck( 1, XmlTypes.XmlNode )]
public int InnerText( )
{
// get document
XmlNode node = (XmlNode)Lua.GetManagedObject( 1 );
// push the text
Lua.Push( node.InnerText );
return 1;
}
// -------- InnerXml
[LuaFunction( "InnerXml", Function.Normal )]
[LuaTypeCheck( 1, XmlTypes.XmlNode )]
public int InnerXml( )
{
// get document
XmlNode node = (XmlNode)Lua.GetManagedObject( 1 );
// push the text
Lua.Push( node.InnerXml );
return 1;
}
// -------- OuterXml
[LuaFunction( "OuterXml", Function.Normal )]
[LuaTypeCheck( 1, XmlTypes.XmlNode )]
public int OuterXml( )
{
// get document
XmlNode node = (XmlNode)Lua.GetManagedObject( 1 );
// push the text
Lua.Push( node.OuterXml );
return 1;
}
}
/*------------------------------------
XmlModule
------------------------------------*/
[LuaModule( "Xml" )]
public class XmlModule : GMModule
{
// -------- NewDocument
[LuaFunction( "LoadDocument", Function.Normal )]
[LuaTypeCheck( 1, Types.String )]
public int LoadDocument( )
{
// create a document
XmlDocument doc = new XmlDocument();
doc.Load( Lua.GetString( 1 ) );
// push it
LuaObject metatable = Lua.GetMetaTable( "XmlDocument", XmlTypes.XmlDocument );
Lua.PushManagedObject( metatable, doc );
return 1;
}
}[/code]
And now I have to learn .Net. (C#/VB I know, don't rip my balls off.)
Yay, you released it :D
Ummmm... What does it do?
Awesome!
This is great, thanks a lot for this Jinto.
What exactly is this ?
It lets you make LUA DLL's for GMODE using .NET (Microsoft's Java-like software). Only interesting to developers using that, of course.
I tried recompiling your binary (the C++.net one) with debug but it spammed a shit load of errors, apparently you're calling functions which are not in ILuaInterface (I checked, their not), am I using the wrong version of that header or is the one from google code's svn correct? Or am I a moron?
[QUOTE=HiddenScript]I tried recompiling your binary (the C++.net one) with debug but it spammed a shit load of errors, apparently you're calling functions which are not in ILuaInterface (I checked, their not), am I using the wrong version of that header or is the one from google code's svn correct? Or am I a moron?[/QUOTE]
You're most likely using an older version, the latest version of the interface headers are in the SQLite module over at googlecode. You also need to mark ILuaInterface as public and compile with /clr.
Ah, thanks, I was using the old original module base (the one with the Msg function in it).
[b]Edit:[/b]
Wait a sec... Tier1/utlvector.h!? Isn't that part of the source engine code? You mean I'll have to completely install the source code for source?
[QUOTE=HiddenScript]Ah, thanks, I was using the old original module base (the one with the Msg function in it).
[b]Edit:[/b]
Wait a sec... Tier1/utlvector.h!? Isn't that part of the source engine code? You mean I'll have to completely install the source code for source?[/QUOTE]
exact
Yes I succeeded in compiling but VS is still complaining about the link missing the Lua symbols. I'm unsure if this will affect the build so I'll leave it at that before getting mad at the wrong problem, till Chad fixes the bugs in the table get all members I'll just use a work around.
[QUOTE=HiddenScript]Yes I succeeded in compiling but VS is still complaining about the link missing the Lua symbols. I'm unsure if this will affect the build so I'll leave it at that before getting mad at the wrong problem, till Chad fixes the bugs in the table get all members I'll just use a work around.[/QUOTE]
Yes, I know what's wrong with that method. I'll be fixing it soon. Just need to find the time.
Sorry to bump this but what is the XmlTypes class used for?
For example:
[code]Lua.GetMetaTable( "XmlNode", XmlTypes.XmlNode );[/code]
What is it doing?
It's my way of using globals. I could just as easily have placed those constants within each of the meta tables, which on second thought would have been a better idea.
[QUOTE=Jinto]It's my way of using globals. I could just as easily have placed those constants within each of the meta tables, which on second thought would have been a better idea.[/QUOTE]
But.. what do the numbers actually do/represent?
They are a unique number that represents that metatable.
Basically everything in the C++ GML interface is represented in type by a unique enumerator.
This works great so far! But I have a question... Why does the Lua.PushLong take integers? Shouldn't it be a long?
Sorry to bump this, but I'm having trouble getting it to work...
Do your classes have to be in a certain namespace? I've tried
[code]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Garrysmod;
namespace TestModule
{
[LuaModule( "test" )]
public class TestModule : GMModule
{
[LuaFunction( "hello", Function.Normal )]
[LuaTypeCheck( 1, Types.String )]
public int hello( )
{
string str = Lua.GetString( 1 );
Lua.Msg( str );
return 1;
}
}
}
[/code]
and
[code]
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Garrysmod;
[LuaModule("test")]
public class TestModule : GMModule
{
[LuaFunction("hello", Function.Normal)]
[LuaTypeCheck(1, Types.String)]
public int hello( )
{
string str = Lua.GetString( 1 );
Lua.Msg( str );
return 1;
}
}
[/code]
but..
[code]
] lua_run require( 'garrysmoddotnet' )
> require( 'garrysmoddotnet' )...
] lua_run test.hello()
> test.hello()...
:1: attempt to index global 'test' (a nil value)
[/code]
It's probably something stupid but I can't spot it, I'm rather tired. (It's 1:30am..)
Looking for answer to above...
Xera, the module name is case sensitive, it's "GarrysmodDotNet".
I tested this with VB and it works perfectly.
Jinto, may i have your permission to add the functions this module uses into my [url=http://forums.facepunchstudios.com/showthread.php?t=588255]N++ auto complete[/url] mod please?
[QUOTE=Nevec]Xera, the module name is case sensitive, it's "GarrysmodDotNet".
I tested this with VB and it works perfectly.[/QUOTE]
When I required GarrysmodDotNet my game would crash...
I tested it today and it works fine. Do you have everything in the right folders? Maybe you have a module that does something wrong.
My bad, I never saw:
[quote=Jinto]
Place .NET Modules inside garrysmod/lua/includes/modules/DotNet/
[/quote]
[QUOTE=Nevec]Xera, the module name is case sensitive, it's "GarrysmodDotNet".
I tested this with VB and it works perfectly.[/QUOTE]
The module name doesn't matter, if you look at the date of my post it's pretty old. When I posted this was broken.
It's broken? I want to try and make Gmod cheats with this. :( Lol Joking :P
It's not broken. It works fine for me.
Sorry, you need to Log In to post a reply to this thread.