Could the server be delivered as a DLL?

Started by ., Apr 11, 2016, 08:57 PM

Previous topic - Next topic

.

This evolved as a dumb chat on IRC and questions the possibility of delivering the VC:MP server as a DLL. Basically, you compile the server as a DLL and export a simple function that can be used to retrieve the interfaces required to work with the server.

Considering an API like the plugins:
#define SERVER_API_VER 7

// enumes etc.

typedef void (*SDK_OnFrame) (float elapsed);
// more callbacks...

typedef struct {
  unsigned int            uStructSize;
  SDK_OnFrame             OnFrame;
  // more callbacks...
} ServerCallbacks;

typedef int32_t (*SDK_LogOutput) (const char * fmt, ...);

typedef int32_t (*SDK_ProcArg) (int32_t argc, char **argv);
typedef int32_t (*SDK_BindHost) (const char * addr);
typedef int32_t (*SDK_BindPort) (uint16_t, addr);
typedef int32_t (*SDK_SetStorage) (const char * folderpath);
typedef int32_t (*SDK_SetLogFilter) (uint32_t filter);
typedef int32_t (*SDK_SetLogOutput) (SDK_LogOutput output);
typedef uint32_t (*SDK_GetServerVersion) (void);
typedef int32_t (*SDK_StartServer) (void);
typedef int32_t (*SDK_StopServer) (void);
typedef int32_t (*SDK_SetCallbacks) (ServerCallbacks * callbacks);
// more api...

typedef struct {
  unsigned int            uStructSize;
  SDK_ProcArg             ProcArg;
  SDK_BindHost            BindHost;
  SDK_BindPort            BindPort;
  SDK_SetStorage          SetStorage;
  SDK_SetLog              SetLog;
  SDK_GetServerVersion    GetServerVersion;
  SDK_StartServer         StartServer;
  SDK_StopServer          StopServer;
  SDK_SetCallbacks        SetCallbacks;
  // more api...
} ServerFuncs;

The server would export a function that accepts those structures and would fill them with it's internal function pointers:
export void InitServerAPI(ServerFuncs * func, int apiver)
{
    if (apiver != SERVER_API_VER)
    {
        return; // throw/report w/e
    }

    func->ProcArg           = VCAPI_ProcArg;
    func->BindHost          = VCAPI_BindHost;
    func->BindPort          = VCAPI_BindPort;
    func->SetStorage        = VCAPI_SetStorage;
    func->SetLogFilter      = VCAPI_SetLogFilter;
    func->SetLogOutput      = VCAPI_SetLogOutput;
    func->GetServerVersion  = VCAPI_GetServerVersion;
    func->StartServer       = VCAPI_StartServer;
    func->StopServer        = VCAPI_StopServer;
    func->SetCallbacks      = VCAPI_SetCallbacks;
}

And then in my code I'd load the DLL into my process, find the InitServerAPI symbol, call it to obtain the API and work with it from there.

And leave plugin system implementation to the user if necessary. Of course the developers could even provide an open source C/C++ program that starts the server and even provides a plugin system which would be the default choice if you don't want to implement it yourself. An approach like this would allow the user to have more control of the server. Maybe even allow the user to control transferred resources and other stuff.

Keeps the important parts closed source from people to mess with but also gives a decent amount of control to the user.

Another benefit I could see from this is that you don't have to embed the programming languages inside the server (which is very hard for mature and popular languages like Python/Perl/Ruby etc.). Instead, embed the server inside programming languages since most programming languages allow some kind plugin/module systems. I could easily embed the server inside Node.js I'd want something like that. Not to mention that embedding in other languages would be a lot easier.

I could even build a GUI for the server to make it easier to debug or develop since most popular languages have some decent IDEs, it would be much easier to debug the server if scripting for it. The possibilities are endless.



But the problem is that I'm not sure how the server is implemented and if something like this would be possible without extreme changes and a lot of effort.
.

Stormeus

Wouldn't this basically be a bastardization of the existing plugin system? You've just offloaded the problem of dealing with the C plugin interface to a new, redundant C server embedding interface.

This would also render all plugins incompatible across server flavors — you're going to end up with one announce plugin for the traditional C server, one for the Squirrel server, one for the Python server, etc.

.

#2
Quote from: Stormeus on Apr 11, 2016, 09:27 PMThis would also render all plugins incompatible across server flavors — you're going to end up with one announce plugin for the traditional C server, one for the Squirrel server, one for the Python server, etc.

Not really. I could implement the plugin SDK in the program that launches the server and load the plugins from that. Basically, instead of the plugins being loaded by the server, they're loaded by me. I'd have the choice to do that or not if I don't want to. Besides, Squirrel is kinda starting to be obsolete.

And besides. The announce plugin is nothing more than a HTTP call to a web-server. I could just as easily do that with a cURL executable. Or even the python script since python has some HTTP client library.
.

Stormeus

#3
The announce plugin is just one example, though. What about:

These aren't dependent on scripting languages either.

EDIT: Plus there's still the layer of redundancy in going from "Download server -> Download plugins -> Configure -> Run" to "Download server core -> Download desired implementation -> Download plugins for said implementation -> Configure -> Run." I don't see what significant benefits there are to doing this over having scripting plugins.

maxorator

Quote from: S.L.C on Apr 11, 2016, 08:57 PMAnd then in my code I'd load the DLL into my process, find the InitServerAPI symbol, call it to obtain the API and work with it from there.

And leave plugin system implementation to the user if necessary. Of course the developers could even provide an open source C/C++ program that starts the server and even provides a plugin system which would be the default choice if you don't want to implement it yourself. An approach like this would allow the user to have more control of the server. Maybe even allow the user to control transferred resources and other stuff.
I don't really see what this would give. The only thing it could give that can't be very easily added to the server now is allowing plugins to start/stop the server. Besides, everyone uses plugins, it doesn't make sense to not have that as built-in functionality. The application loading the server would just be a plugin multiplexer, which is what the server can handle on its own at the moment.


Quote from: S.L.C on Apr 11, 2016, 08:57 PMAnother benefit I could see from this is that you don't have to embed the programming languages inside the server (which is very hard for mature and popular languages like Python/Perl/Ruby etc.). Instead, embed the server inside programming languages since most programming languages allow some kind plugin/module systems. I could easily embed the server inside Node.js I'd want something like that. Not to mention that embedding in other languages would be a lot easier.
The only difference would be the bootstrap part - setting up the VM/interpreter. The rest would be identical. It doesn't give you new interfaces to work with, you're still stuck with what the VM/interpreter sdk provides.

Quote from: S.L.C on Apr 11, 2016, 08:57 PMI could even build a GUI for the server to make it easier to debug or develop since most popular languages have some decent IDEs, it would be much easier to debug the server if scripting for it. The possibilities are endless.
You can also do that with a plugin. There is no conceptual difference in whether your application starts the server or the server loads your library, you are free to do anything you want in your plugin library. The only limitation is that when the server shuts down, the whole process does.

.

I could literally, load those plugins just as I did with the server and give to them a structure with functions that they need to operate with the server ad also forward callbacks that I receive from the server to them as well, if necessary.
.

Stormeus

Quote from: S.L.C on Apr 11, 2016, 09:39 PMI could literally, load those plugins just as I did with the server and give to them a structure with functions that they need to operate with the server ad also forward callbacks that I receive from the server to them as well, if necessary.

In that case you've established complete redundancy.

.

Quote from: Stormeus on Apr 11, 2016, 09:40 PMIn that case you've established complete redundancy.

Isn't that what the Squirrel plugin does? Export the squirrel API for other plugins to use.



Anyway, was just a simple question. I've received my answers.
.

Stormeus

Quote from: S.L.C on Apr 11, 2016, 09:43 PM
Quote from: Stormeus on Apr 11, 2016, 09:40 PMIn that case you've established complete redundancy.

Isn't that what the Squirrel plugin does? Export the squirrel API for other plugins to use.

The Squirrel API exists because the server core doesn't have any facilities for other plugins to bind functions and events to a scripting language. Here you'd either have a redundant plugin compatibility API layer for each server implementation or having each implementation provide their own API, which the core can easily do on its own.

.

#9
MTA does this IIRC and it seemed to work nicely for them.


I'm going to close the topic because there are people on this forum that just love to enter discussions with no idea about it and generate useless spam.
.