Files
fs2open.github.com/code/scripting/api/libs/multi.cpp
T
BMagnu 272d6261c4 Generic Lua Multiplayer RPC (#4835)
* Add automatic lua obj serialization function dispatch

* Implement fundamental and object de/serialization

* Proper default case for package deserialization

* Add No Multi func

* Add Serialization part

* Fix max encoding size for userdata

* Implement exception handling

* Start Implementing lua RPC

* Prepare waitAsync for RPC

* Add packet order enforcing and forwarding

* Add RPC registry

* Make RPCs callable

* Add waitRPC

* Add serializers

* Fix GCC error

* Explicitly specify lua_net_exception

* Fix Warnings

* Replace Seriliaze fundamental with cross-platform data types

* Appease Clang

* Prevent serialization CTD on invalid objects

* Actually use the temporaries assigned

* Fix OSWPT shadow

* Fix table deserialize order

* Incorporate Feedback

* Fix Warnigs

* ix WArnings 2

* Add sanity checks for OSWPT wing serialization

* Multi Bump

* Forgot we have american-style dates there
2023-03-28 03:07:03 +09:00

52 lines
2.9 KiB
C++

#include "multi.h"
#include "scripting/api/objs/rpc.h"
#include "network/multi.h"
namespace scripting {
namespace api {
//**********LIBRARY: Multi
ADE_LIB(l_Multi, "Multi", "multi", "Functions for scripting for and in multiplayer environments.");
ADE_FUNC(isServer, l_Multi, nullptr, "Prints a string", "boolean", "true if the script is running on the server, false if it is running on a client or in singleplayer.")
{
return ade_set_args(L, "b", MULTIPLAYER_MASTER);
}
ADE_FUNC(addRPC, l_Multi, "string name, function(any arg) => void rpc_body, [enumeration mode = RPC_RELIABLE, enumeration recipient = RPC_BOTH]", "Adds a remote procedure call. This call must run on all clients / the server where the RPC is expected to be able to execute. "
"The given RPC name must be unique.\nFor advanced users: "
"It is possible have different clients / servers add different RPC methods with the same name. "
"In this case, each client will run their registered method when a different client calls the RPC with the corresponding name. "
"Passing nil as the execution function means that the RPC can be called from this client, but not on this client.\n"
"The mode is used to determine how the data is transmitted. RPC_RELIABLE means that data is guaranteed to arrive, and to be in order. "
"RPC_ORDERED is a faster variant that guarantees that calls from the same caller to the same functions will always be in order, but can drop. "
"Calls to clients are expected to drop slightly more often than calls to servers in this mode. RPC_UNRELIABLE is the fastest mode, but has no "
"guarantees about ordering of calls, and does not guarantee arrival (but will be slightly better than RPC_ORDERED).\n"
"The recipient will be used as the default recipient for this RPC, but can be overridden on a per-call basis. "
"Valid are: RPC_SERVER, RPC_CLIENTS, RPC_BOTH", "rpc", "An RPC object, or an invalid RPC object on failure.")
{
const char* name;
luacpp::LuaFunction func;
enum_h recipient{LE_RPC_BOTH}, mode{LE_RPC_RELIABLE};
if (!ade_get_args(L, "su|oo", &name, &func, l_Enum.Get(&mode), l_Enum.Get(&recipient))) {
return ade_set_error(L, "o", l_RPC.Set(nullptr));
}
if (!recipient.IsValid() || (recipient.index != LE_RPC_SERVER && recipient.index != LE_RPC_CLIENTS && recipient.index != LE_RPC_BOTH)) {
LuaError(L, "Tried to create an RPC with an invalid recipient enumeration!");
return ade_set_error(L, "o", l_RPC.Set(nullptr));
}
if (!mode.IsValid() || (mode.index != LE_RPC_RELIABLE && mode.index != LE_RPC_ORDERED && mode.index != LE_RPC_UNRELIABLE)) {
LuaError(L, "Tried to create an RPC with an invalid mode enumeration!");
return ade_set_error(L, "o", l_RPC.Set(nullptr));
}
auto rpc = rpc_h_impl::create(L, name);
rpc->func = func;
rpc->recipient = recipient;
rpc->mode = mode;
return ade_set_args(L, "o", l_RPC.Set(std::move(rpc)));
}
}
}