[Windows] Writing a C++ plugin

Started by Xmair, Dec 26, 2019, 03:17 PM

Previous topic - Next topic

Xmair

No this isn't the best guide you can get. I wrote this tutorial reaaaaaaaallllllllly long ago for someone in Discord.

Firstly, you need to choose a good IDE for writing C++, what I personally use is Visual Studio.
So here the second step becomes loading up and creating a project in Visual Studio

Click the Create a new project button to start
Then you choose Dynamic-Link Library as that's what we're gonna be needing

Next you'd want to select a name for your project, choose whatever name you want and name the solution to your desire aswell

Click on Create, this may take some time

We won't be needing dllmain.cpp and framework.h so you can delete them
Now firstly we need to include the VCMP header file, you can find the updated one here:
https://bitbucket.org/stormeus/0.4-squirrel/src/
Search for the VCMP.h file and click on it

Now copy all the file and come back to your Visual Studio project
Right click on Header Files
Go to Add -> New Item or simply press CTRL + SHIFT + A
Set the file type to Header File (.h)
Set the name to VCMP.h

Click on Add
Paste your clipboard (VCMP.h copied from BitBucket) into the new opened file
Now your file should look like this

Create a new file in the Source Files folder named Main.cpp
Now before we move on to code, we need to select the compiling platform
In my case I needed x64 builds as Release and not Debug (it doesn't really matter at this point but anyway) so I changed my configuration to Release x64

Now we create another file in Header Files named Main.h which will serve as a header file for our main file
In the Main.h file, we do:
#pragma once // Only load this file once (#include)
#ifndef __MAIN_H // Include guard; makes sure that this file is only included once and subsequent #includes are ignored
#define __MAIN_H // Include guard

#include "VCMP.h"
#include <cstdio>

#ifdef _WIN32 // If we're on windows
#include "Windows.h"

#define DLL_EXPORT __declspec( dllexport ) // This is required in windows so that other programs can access the function
#else // We're not on windows
#define DLL_EXPORT // Nothing like that is required in linux so we leave it blank
#define MAX_PATH 250
#endif

#ifdef __cplusplus // We don't need to (and can not) extern "C" if we're already in C. so we make sure that we are in C++
extern "C" { // We need to extern "C" the function because windows expects a C-style function
#endif
    DLL_EXPORT    unsigned int            VcmpPluginInit(PluginFuncs* pluginFuncs, PluginCallbacks* pluginCalls, PluginInfo* pluginInfo); // This is a blank function and it's exported (check the #define tags above). VCMP requires it
#ifdef __cplusplus // We opened a brace in C++, so we need to close it in C++ only as well
}
#endif

#endif // Include guard
Now we come back to the Main.cpp file and,
#include "pch.h" // Pre-compiled header
#include "VCMP.h" // We need to include the VCMP header file first so we can access it's functons
#include "Main.h" // Including the main header file we created

uint8_t serverInitialise() {
    printf("Plugin initialised.\n"); // Sending a message to make sure our plugin has loaded
    return 1;
}

// This event is called when the plugin is loaded
// We can also make a global variable to store the plugin functions, callbacks and info
unsigned int VcmpPluginInit(PluginFuncs* pluginFuncs, PluginCallbacks* pluginCalls, PluginInfo* pluginInfo)
{
    pluginInfo -> apiMinorVersion = PLUGIN_API_MINOR; // This step is very important, in this step
    pluginInfo -> apiMajorVersion = PLUGIN_API_MAJOR; // we set the version of the API, if you skip this step, your server will not load this plugin

    pluginCalls -> OnServerInitialise = serverInitialise; // uint8_t(*OnServerInitialise) (void) - Line 915 @ VCMP.h
    return 1;
}

Now right click on your project name, in my case, VCMP
Click on Build

Your output should show something similar to this

Now go to the compiled directory, in my case, C:\Users\Xmair\source\repos\VCMP\x64\Release

Copy the VCMP.dll to a VC:MP server
Paste it in the plugins folder

Now edit your server.cfg file to include your plugin

Now load up your server.

Credits: Xmair & Fleka (for the comments in VCMP.h file)

Credits to Boystang!

VU Full Member | VCDC 6 Coordinator & Scripter | EG A/D Contributor | Developer of VCCNR | Developer of KTB | Ex-Scripter of EAD

D4rkR420R


habi

thanks. it worked for me just now.
In the new version of visual studio, you need to comment this line in pch.h
//#include "framework.h"

UncleRus

I LoperkinDead.My brothers scripters TimyrSem,VladSem

Alpays

Plugin works but i cant use functions in vcmp.h i try calling from pluginFuncs->but server crashes

Xmair

Quote from: Alpays on Dec 07, 2020, 10:44 AMPlugin works but i cant use functions in vcmp.h i try calling from pluginFuncs->but server crashes
What function? Where? How? Any code?

Credits to Boystang!

VU Full Member | VCDC 6 Coordinator & Scripter | EG A/D Contributor | Developer of VCCNR | Developer of KTB | Ex-Scripter of EAD

Alpays

#6
I build a plugin it works
#include "VCMP.h" // plugin api
#include "Main.h" // main.h same as the tutorial

PluginFuncs* globalFuncs;


uint8_t serverInitialise() {
    printf("Plugin initialised.\n");
   
    return 1;
}

void playerJoin(int32_t playerid) {
    printf("Player joined with id %d", playerid);
}

unsigned int VcmpPluginInit(PluginFuncs* pluginFuncs, PluginCallbacks* pluginCalls, PluginInfo* pluginInfo)
{
    pluginInfo->apiMinorVersion = PLUGIN_API_MINOR;
    pluginInfo->apiMajorVersion = PLUGIN_API_MAJOR;

    pluginCalls->OnServerInitialise = serverInitialise;
    pluginCalls->OnPlayerConnect = playerJoin;

    pluginFuncs = globalFuncs;

    return 1;
}

but when i add a function from plugin.h like
globalFuncs->SetPlayerWeapon(playerid, 26, 999); to onPlayerConnect callback


it builds fine but crashes when a player join (or if i add pluginFuncs->SetServerName("blabla"); in on server init it crashes on server start) this happens at every function without anything simply server closes with no error

habi

Now it is clear.

pluginFuncs = globalFuncs;

Put it reverse like
globalFuncs =pluginFuncs

Alpays

Quote from: habi on Dec 07, 2020, 01:49 PMNow it is clear.

pluginFuncs = globalFuncs;

Put it reverse like
globalFuncs =pluginFuncs

How did i missed this xD  thank you for your help
also xmair for this tutorial