• C++ Module
    8 replies, posted
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.