I'm trying to make a C++ Module which should run a console command, but I'm kinda stuck where to start. Anybody there could help ?
Push -> global table
Push -> RunConCommand func
PushString -> command
Call stack
pop
[editline]asd[/editline]
I realize that may not have been enough info for a beginner. Try something like this
[cpp]
using namespace GarrysMod;
LUA->PushSpecial( Lua::SPECIAL_GLOB ); //push global table
LUA->GetField(-1, "RunConCommand"); //push reference to RunConCommand func
LUA->PushString("disconnect"); //push function argument as string datatype
LUA->Call(1, 0); //call with 1 argument, expecting 0 return value
LUA->Pop();
[/cpp]
You could start [URL="http://wiki.garrysmod.com/page/Setting_Visual_Studio_Up_for_Making_Binary_Modules"]here[/URL], [URL="http://wiki.garrysmod.com/page/C_Lua:_Functions"]here[/URL], [URL="http://wiki.garrysmod.com/page/Creating_Binary_Modules"]here[/URL], or [URL="http://www.lua.org/manual/5.2/manual.html#4.8"]here[/URL]. But first, you need to know c++, which you could also look [URL="http://www.cplusplus.com/"]here[/URL]. Lets say you want to make a command that will print your text. Here is an example:
[CODE]#define GMMODULE
#include "Interface.h"
#include <stdio.h> //////
#include <iostream>/////////
#include <cstring>///////////// Extra files/functions
#include <string>///////////
#include <sstream>//////
using namespace std; // A namespace shortcut
using namespace GarrysMod::Lua; // Same with this
int printtext(lua_State* state)
{
int iTop = LUA->Top(); // Get the number of arguments
if (!LUA->IsType(1, Type::STRING)){ // If the type is not a string, return 0
return 0;
}
if (iTop < 2){ // If there is only 1 argument, keep going, else, return 0
stringstream txt; // Declare a stringstream
const char* ttxt = LUA->GetString(1); // Get the first argument
txt << "Your string is: " << ttxt << "\n";
LUA->PushSpecial(SPECIAL_GLOB); // Push the special table
LUA->GetField(-1, "print"); // Grab the print function
LUA->PushString(txt.str().c_str()); // Push it with str() and c_str()
LUA->PCall(1, 0, 0); // Call it
LUA->Pop(); // Pop the table off the stack
return 1; // Return 1
}
else{
return 0;
}
}
GMOD_MODULE_OPEN(){ // When the Module Opens
LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB); // Push Table
LUA->PushCFunction(printtext); LUA->SetField(-2, "rprint"); // Push the function printtext and call it 'rprint'
LUA->Pop(); // Pop the table off the stack
return 0;
}
GMOD_MODULE_CLOSE() // When it closes
{
return 0;
}[/CODE]
So we need to call the dll which mine is called 'bird', So this would be my code to call it:
[CODE]
require("bird")
rprint(":D")[/CODE]
And, it works!
[IMG]http://i.imgur.com/exrqL4r.png[/IMG]
I'll probably update this post overtime, Hope I helped!
EDIT:
Another example using the boost random library to generate 2 numbers of your choice:
[CODE]
#define GMMODULE
#include "Interface.h"
#include <stdio.h> /////////////////////////////////////
#include <iostream>///////////////////////////////////////
#include <cstring>//////////////////////////////////////////
#include <string>///////////////////////////////////////////// Extra files/functions
#include <sstream>////////////////////////////////////////
#include <boost/random/mersenne_twister.hpp>//////////
#include "boost\random.hpp"//////////////////////
using namespace std; // A namespace shortcut
using namespace GarrysMod::Lua; // Same with this
int printtext(lua_State* state)
{
int iTop = LUA->Top();
if (!LUA->IsType(1, Type::NUMBER)) // Make sure 1st argument is a number
{
return 0;
}
if (!LUA->IsType(2, Type::NUMBER)){ // Make sure 2st argument is a number
return 0;
}
if (iTop < 3 && iTop > 1){ // If there is 2 arguments, continue
double num1 = LUA->GetNumber(1); // Get arg1
double num2 = LUA->GetNumber(2); // Get arg2
if (num1 == num2){ // If they are the same, don't continue
return 0;
}
boost::random::mt19937 gen; // Create number (2 to the 32nd power times negative 1)
boost::random::uniform_int_distribution<> dist(num1, num2); // Distribution selector
stringstream txt; // Declare a stringstream
uint64_t ttxt = dist(gen); // Make it an unsigned integer
txt << "Your random number between " << num1 << " and " << num2 << " is: " << ttxt << "\n"; // Ex. Your random number between 4 and 10 is 8 /NEWLINE
LUA->PushSpecial(SPECIAL_GLOB); // Push the special table
LUA->GetField(-1, "print"); // Grab the print function
LUA->PushString(txt.str().c_str()); // Push it with str() and c_str()
LUA->PCall(1, 0, 0); // Call it
LUA->Pop(); // Pop the table off the stack
return 1; // Return 1
}
else{
return 0; // Thing
}
return 0; // Fail-safe
}
GMOD_MODULE_OPEN(){ // When the Module Opens
LUA->PushSpecial(GarrysMod::Lua::SPECIAL_GLOB); // Push Table
LUA->PushCFunction(printtext); LUA->SetField(-2, "rand"); // Push the function printtext and call it 'rand'
LUA->Pop(); // Pop the table off the stack
return 0; // its k
}
GMOD_MODULE_CLOSE() // When it closes
{
return 0; // its k
}
[/CODE]
Lua File:
[CODE]
require("bird");
rand(1,90);
[/CODE]
Here is the result:
[IMG]http://i.imgur.com/TjRsKio.png[/IMG]
While we're on the topic:-
Is it possible to send binary modules to the client in the same way as you can with AddCSLuaFile?
I want to draw out to render targets from C++ code for part of my gamemode.
[QUOTE=ph:lxyz;47396424]While we're on the topic:-
Is it possible to send binary modules to the client in the same way as you can with AddCSLuaFile?
I want to draw to out to render targets from C++ code for part of my gamemode.[/QUOTE]
no
[QUOTE=Willox;47396457]no[/QUOTE]
That's a real shame. Not even via a client-installed add-on?
[QUOTE=ph:lxyz;47396505]That's a real shame. Not even via a client-installed add-on?[/QUOTE]
They must be in "garrysmod/lua/bin" (or the MOD game path through [url=https://github.com/wiox/plugin_mount]other hackery[/url]). You can't make clients automatically download them for security reasons.
[QUOTE=ph:lxyz;47396424]While we're on the topic:-
Is it possible to send binary modules to the client in the same way as you can with AddCSLuaFile?
I want to draw out to render targets from C++ code for part of my gamemode.[/QUOTE]
That would be huge security risk. Although if your really want clients to run C++ module, you can show warning which would ask clients to install the module manually.
[QUOTE=edgarasf123;47396573]That would be huge security risk. Although if your really want clients to run C++ module, you can show warning which would ask clients to install the module manually.[/QUOTE]
It would be - that's why I thought it might not work. Thanks for the suggestion.
I'll probably release that part separately then and people can compile it themselves if they wish / want to audit my code for hax.
Sorry, you need to Log In to post a reply to this thread.