News A server update was released on July 20. Server patch notes and downloads are here. Additionally, a client update was released on the same day. Client patch notes are here.
« [C++] Vice Racing
Introduction to the Plugin SDK

hotdogcat

  • Jr. Member
  • Posts: 78
Introduction to the Plugin SDK
« on October 17th, 2014, 12:24 AM »Last edited on March 5th, 2015, 08:26 PM by stormeus
Note: i just imported this documentation from old forum, so credits goes to stormeus


One of the major new features available in the 0.4 server is the plugin SDK. Any user can now use an official SDK header to create plugins that can be used to interact with the server, clients, game world and other plugins.

The current plugin SDK can be found here:
https://bitbucket.org/stormeus/0.4-squirrel/src/3a1c0e0bf0ed6760455c14ccf684e38346443cd1/VCMP.h?at=master



Creating a Loadable Plugin
The VC:MP server expects the existence of a special exported function, VcmpPluginInit, to exist in a plugin in order to be able to load one. As part of this function, the server will pass a set of callable functions, a structure for the plugin to set the callbacks it accepts, and a structure for the plugin to set information about itself.

The structure of VcmpPluginInit is as follows:
Code: [Select]
#ifdef WIN32
#define EXPORT __declspec(dllexport)
#else
#define EXPORT
#endif

extern "C" EXPORT unsigned int VcmpPluginInit( PluginFuncs* pluginFuncs, PluginCallbacks* pluginCalls, PluginInfo* pluginInfo )
{
    return 1;
}

  • pluginFuncs is the PluginFuncs struct from the server header, which can be used to call any function available through the plugin SDK.
  • pluginCalls is a struct of PluginCallbacks. pluginCalls essentially starts off empty; your plugin must provide its own callbacks and set them in the struct in order for them to be called, and you must use the same pointer to the struct provided.
  • pluginInfo is a struct of PluginInfo (from the SDK) that, again, is empty at first. You can set your plugin's version and name (max 32 characters) through it, but you must use the same pointer to the struct.



Setting a Callback
To receive callbacks from the server, you need to create a function in the same format as the defined type of the callback:

Code: [Select]
typedef int (*SDK_OnInitServer) (void);
typedef void (*SDK_OnShutdownServer) (void);
typedef void (*SDK_OnFrame) (float fElapsedTime);
typedef void (*SDK_OnPlayerConnect) (int nPlayerId);
typedef void (*SDK_OnPlayerDisconnect) (int nPlayerId, int nReason);
typedef void (*SDK_OnPlayerBeginTyping) (int nPlayerId);
typedef void (*SDK_OnPlayerEndTyping) (int nPlayerId);
typedef int (*SDK_OnPlayerRequestClass) (int nPlayerId, int nOffset);
typedef int (*SDK_OnPlayerRequestSpawn) (int nPlayerId);
typedef void (*SDK_OnPlayerSpawn) (int nPlayerId);
typedef void (*SDK_OnPlayerDeath) (int nPlayerId, int nKillerId, int nReason, int nBodyPart);
typedef void (*SDK_OnPlayerUpdate) (int nPlayerId, int nUpdateType);
typedef int (*SDK_OnPlayerRequestEnter) (int nPlayerId, int nVehicleId, int nSlotId);
typedef void (*SDK_OnPlayerEnterVehicle) (int nPlayerId, int nVehicleId, int nSlotId);
typedef void (*SDK_OnPlayerExitVehicle) (int nPlayerId, int nVehicleId);
typedef int (*SDK_OnPickupClaimPicked) (int nPickupId, int nPlayerId);
typedef void (*SDK_OnPickupPickedUp) (int nPickupId, int nPlayerId);
typedef void (*SDK_OnPickupRespawn) (int nPickupId);
typedef void (*SDK_OnVehicleUpdate) (int nVehicleId, int nUpdateType);
typedef void (*SDK_OnVehicleExplode) (int nVehicleId);
typedef void (*SDK_OnVehicleRespawn) (int nVehicleId);
typedef void (*SDK_OnObjectShot) (int nObjectId, int nPlayerId, int nWeapon);
typedef void (*SDK_OnObjectBump) (int nObjectId, int nPlayerId);
typedef int (*SDK_OnPublicMessage) (int nPlayerId, const char* pszText);
typedef int (*SDK_OnCommandMessage) (int nPlayerId, const char* pszText);
typedef int (*SDK_OnPrivateMessage) (int nPlayerId, int nTargetId, const char* pszText);
typedef int (*SDK_OnInternalCommand) (unsigned int uCmdType, const char* pszText);
typedef int (*SDK_OnLoginAttempt) (char* pszPlayerName, const char* pszUserPassword, const char* pszIpAddress);
typedef void (*SDK_OnEntityPoolChange) (int nEntityType, int nEntityId, unsigned int bDeleted);
typedef void (*SDK_OnKeyBindDown) (int nPlayerId, int nBindId);
typedef void (*SDK_OnKeyBindUp) (int nPlayerId, int nBindId);
typedef void (*SDK_OnPlayerAwayChange) (int nPlayerId, unsigned int bNewStatus);
typedef void (*SDK_OnPlayerSpectate) (int nPlayerId, int nTargetId);
typedef void (*SDK_OnPlayerCrashReport) (int nPlayerId, const char* pszReport);
typedef void (*SDK_OnServerPerformanceReport) (int nNumStats, const char** ppszDescription, unsigned long long* pnMillisecsSpent);

For example, to create a callback for OnPublicMessage:
Code: [Select]
typedef int (*SDK_OnPublicMessage) (int nPlayerId, const char* pszText);

You would need to create a function like so:
Code: [Select]
int MyOnPublicMessage (int nPlayerId, const char* pszText)
{
    return 1;
}

void functions need not return anything (and should not), whereas callbacks with a return type expect a value to be returned, and will react differently according to their return values. For example, returning 0 in OnPublicMessage will reject a given chat message and essentially mute it. Returning 1 will send it to other players if no other plugins suppress it.

To have the server recognize the callback and make use of it, set it in VcmpPluginInit:
Code: [Select]
extern "C" EXPORT unsigned int VcmpPluginInit( PluginFuncs* pluginFuncs, PluginCallbacks* pluginCalls, PluginInfo* pluginInfo )
{
    pluginCalls->OnPublicMessage = MyOnPublicMessage;
    return 1;
}



Using Plugin Functions
Using plugin functions is easier still than dealing with callbacks. To use a function, you can simply make a direct call to a function in the pluginFuncs struct:

Code: [Select]
extern "C" EXPORT unsigned int VcmpPluginInit( PluginFuncs* pluginFuncs, PluginCallbacks* pluginCalls, PluginInfo* pluginInfo )
{
    pluginFuncs->SetServerName("My VC:MP Server");
    return 1;
}


Credits to Bart.

theahmadzai

  • Newbie
  • Programmer, Web developer & SEO Expert
  • Posts: 3
Re: Introduction to the Plugin SDK
« Reply #1, on October 28th, 2014, 05:00 PM »
I think so only developers may post SDK's etc.. If a newbie comes and search related to SDK and he see your rank as a member and Your post about development..He won't trust the source.

Want to learn Squirrel and Web development? ->Best Coding Skills
Wanna be a Web Developer or a good Scripter? Do not worry Just Join us our community www.bestcodingskills.com!

sseebbyy

  • Wiki Contributor
  • Something like this: hga hga hga
  • Posts: 752
Re: Introduction to the Plugin SDK
« Reply #2, on October 28th, 2014, 05:03 PM »
Quote from theahmadzai on October 28th, 2014, 05:00 PM
I think so only developers may post SDK's etc.. If a newbie comes and search related to SDK and he see your rank as a member and Your post about development..He won't trust the source.
Since it is stickied, they should trust the source. ;)

ysc3839

  • Wiki Contributor
  • A bad English learner.
  • Posts: 537

jWeb

  • Full Member
  • Posts: 150
Re: Introduction to the Plugin SDK
« Reply #4,  »
Sorry for the bump. But after the last updates, people that create plugins must also include the SDK version for which their plugin was compiled. Otherwise the server will reject your plugin.

To do that, you should add have this somewhere before you return out of the `VcmpPluginInit()` function:
Code: [Select]

pluginInfo->apiMajorVersion = PLUGIN_API_MAJOR;
pluginInfo->apiMinorVersion = PLUGIN_API_MINOR;