summaryrefslogtreecommitdiffstats
path: root/src/Bindings
diff options
context:
space:
mode:
Diffstat (limited to 'src/Bindings')
-rw-r--r--src/Bindings/CMakeLists.txt2
-rw-r--r--src/Bindings/LuaNameLookup.h2
-rw-r--r--src/Bindings/LuaServerHandle.cpp213
-rw-r--r--src/Bindings/LuaServerHandle.h89
-rw-r--r--src/Bindings/LuaState.cpp33
-rw-r--r--src/Bindings/LuaState.h9
-rw-r--r--src/Bindings/LuaTCPLink.cpp97
-rw-r--r--src/Bindings/LuaTCPLink.h21
-rw-r--r--src/Bindings/ManualBindings_Network.cpp157
9 files changed, 609 insertions, 14 deletions
diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt
index 13428b5c6..40b8d4bd9 100644
--- a/src/Bindings/CMakeLists.txt
+++ b/src/Bindings/CMakeLists.txt
@@ -9,6 +9,7 @@ SET (SRCS
DeprecatedBindings.cpp
LuaChunkStay.cpp
LuaNameLookup.cpp
+ LuaServerHandle.cpp
LuaState.cpp
LuaTCPLink.cpp
LuaWindow.cpp
@@ -27,6 +28,7 @@ SET (HDRS
LuaChunkStay.h
LuaFunctions.h
LuaNameLookup.h
+ LuaServerHandle.h
LuaState.h
LuaTCPLink.h
LuaWindow.h
diff --git a/src/Bindings/LuaNameLookup.h b/src/Bindings/LuaNameLookup.h
index 8b456ad90..e4cdb9f53 100644
--- a/src/Bindings/LuaNameLookup.h
+++ b/src/Bindings/LuaNameLookup.h
@@ -25,7 +25,7 @@ public:
cLuaNameLookup(const AString & a_Query, cPluginLua & a_Plugin, int a_CallbacksTableStackPos);
protected:
- /** The plugin for which the link is created. */
+ /** The plugin for which the query is created. */
cPluginLua & m_Plugin;
/** The Lua table that holds the callbacks to be invoked. */
diff --git a/src/Bindings/LuaServerHandle.cpp b/src/Bindings/LuaServerHandle.cpp
new file mode 100644
index 000000000..7b82003bb
--- /dev/null
+++ b/src/Bindings/LuaServerHandle.cpp
@@ -0,0 +1,213 @@
+
+// LuaServerHandle.cpp
+
+// Implements the cLuaServerHandle class wrapping the cServerHandle functionality for Lua API
+
+#include "Globals.h"
+#include "LuaServerHandle.h"
+#include "LuaTCPLink.h"
+#include "tolua++/include/tolua++.h"
+
+
+
+
+
+cLuaServerHandle::cLuaServerHandle(UInt16 a_Port, cPluginLua & a_Plugin, int a_CallbacksTableStackPos):
+ m_Plugin(a_Plugin),
+ m_Callbacks(a_Plugin.GetLuaState(), a_CallbacksTableStackPos),
+ m_Port(a_Port)
+{
+ LOGD("Creating LuaServerHandle at %p.", this);
+}
+
+
+
+
+
+
+cLuaServerHandle::~cLuaServerHandle()
+{
+ // If the server handle is still open, close it explicitly:
+ LOGD("Deleting LuaServerHandle at %p.", this);
+ Close();
+}
+
+
+
+
+
+void cLuaServerHandle::SetServerHandle(cServerHandlePtr a_ServerHandle, cLuaServerHandlePtr a_Self)
+{
+ ASSERT(m_ServerHandle == nullptr); // The handle can be set only once
+
+ m_ServerHandle = a_ServerHandle;
+ m_Self = a_Self;
+}
+
+
+
+
+
+void cLuaServerHandle::Close(void)
+{
+ LOGD("Closing LuaServerHandle at %p.", this);
+
+ // Safely grab a copy of the server handle:
+ cServerHandlePtr ServerHandle = m_ServerHandle;
+ if (ServerHandle == nullptr)
+ {
+ return;
+ }
+
+ // Close the underlying server handle:
+ ServerHandle->Close();
+
+ // Close all connections at this server:
+ cLuaTCPLinkPtrs Connections;
+ {
+ cCSLock Lock(m_CSConnections);
+ std::swap(Connections, m_Connections);
+ }
+ for (auto & conn: Connections)
+ {
+ conn->Close();
+ }
+ Connections.clear();
+
+ // Allow the internal server handle to be deallocated:
+ m_ServerHandle.reset();
+}
+
+
+
+
+
+bool cLuaServerHandle::IsListening(void)
+{
+ // Safely grab a copy of the server handle:
+ cServerHandlePtr ServerHandle = m_ServerHandle;
+ if (ServerHandle == nullptr)
+ {
+ return false;
+ }
+
+ // Query the underlying server handle:
+ return ServerHandle->IsListening();
+}
+
+
+
+
+
+void cLuaServerHandle::RemoveLink(cLuaTCPLink * a_Link)
+{
+ cCSLock Lock(m_CSConnections);
+ for (auto itr = m_Connections.begin(), end = m_Connections.end(); itr != end; ++itr)
+ {
+ if (itr->get() == a_Link)
+ {
+ m_Connections.erase(itr);
+ break;
+ }
+ } // for itr - m_Connections[]
+}
+
+
+
+
+
+void cLuaServerHandle::Release(void)
+{
+ // Close the server, if it isn't closed yet:
+ Close();
+
+ // Allow self to deallocate:
+ m_Self.reset();
+}
+
+
+
+
+
+cTCPLink::cCallbacksPtr cLuaServerHandle::OnIncomingConnection(const AString & a_RemoteIPAddress, UInt16 a_RemotePort)
+{
+ // If not valid anymore, drop the connection:
+ if (!m_Callbacks.IsValid())
+ {
+ return nullptr;
+ }
+
+ // Ask the plugin for link callbacks:
+ cPluginLua::cOperation Op(m_Plugin);
+ cLuaState::cRef LinkCallbacks;
+ if (
+ !Op().Call(cLuaState::cTableRef(m_Callbacks, "OnIncomingConnection"), a_RemoteIPAddress, a_RemotePort, m_Port, cLuaState::Return, LinkCallbacks) ||
+ !LinkCallbacks.IsValid()
+ )
+ {
+ LOGINFO("cNetwork server (port %d) OnIncomingConnection callback failed in plugin %s. Dropping connection.",
+ m_Port, m_Plugin.GetName().c_str()
+ );
+ return nullptr;
+ }
+
+ // Create the link wrapper to use with the callbacks:
+ auto res = std::make_shared<cLuaTCPLink>(m_Plugin, std::move(LinkCallbacks), m_Self);
+
+ // Add the link to the list of our connections:
+ cCSLock Lock(m_CSConnections);
+ m_Connections.push_back(res);
+
+ return res;
+}
+
+
+
+
+
+void cLuaServerHandle::OnAccepted(cTCPLink & a_Link)
+{
+ // Check if we're still valid:
+ if (!m_Callbacks.IsValid())
+ {
+ return;
+ }
+
+ // Notify the plugin:
+ cPluginLua::cOperation Op(m_Plugin);
+ if (!Op().Call(cLuaState::cTableRef(m_Callbacks, "OnAccepted"), static_cast<cLuaTCPLink *>(a_Link.GetCallbacks().get())))
+ {
+ LOGINFO("cNetwork server (port %d) OnAccepted callback failed in plugin %s, connection to %s:%d.",
+ m_Port, m_Plugin.GetName().c_str(), a_Link.GetRemoteIP().c_str(), a_Link.GetRemotePort()
+ );
+ return;
+ }
+}
+
+
+
+
+
+void cLuaServerHandle::OnError(int a_ErrorCode, const AString & a_ErrorMsg)
+{
+ // Check if we're still valid:
+ if (!m_Callbacks.IsValid())
+ {
+ return;
+ }
+
+ // Notify the plugin:
+ cPluginLua::cOperation Op(m_Plugin);
+ if (!Op().Call(cLuaState::cTableRef(m_Callbacks, "OnError"), a_ErrorCode, a_ErrorMsg))
+ {
+ LOGINFO("cNetwork server (port %d) OnError callback failed in plugin %s. The error is %d (%s).",
+ m_Port, m_Plugin.GetName().c_str(), a_ErrorCode, a_ErrorMsg.c_str()
+ );
+ return;
+ }
+}
+
+
+
+
+
diff --git a/src/Bindings/LuaServerHandle.h b/src/Bindings/LuaServerHandle.h
new file mode 100644
index 000000000..9325bca3e
--- /dev/null
+++ b/src/Bindings/LuaServerHandle.h
@@ -0,0 +1,89 @@
+
+// LuaServerHandle.h
+
+// Declares the cLuaServerHandle class wrapping the cServerHandle functionality for Lua API
+
+
+
+
+
+#pragma once
+
+#include "../OSSupport/Network.h"
+#include "PluginLua.h"
+
+
+
+
+
+// fwd:
+class cLuaTCPLink;
+typedef SharedPtr<cLuaTCPLink> cLuaTCPLinkPtr;
+typedef std::vector<cLuaTCPLinkPtr> cLuaTCPLinkPtrs;
+class cLuaServerHandle;
+typedef SharedPtr<cLuaServerHandle> cLuaServerHandlePtr;
+
+
+
+
+class cLuaServerHandle:
+ public cNetwork::cListenCallbacks
+{
+public:
+ /** Creates a new instance of the server handle,
+ attached to the specified lua plugin and wrapping the (listen-) callbacks that are in a table at the specified stack pos. */
+ cLuaServerHandle(UInt16 a_Port, cPluginLua & a_Plugin, int a_CallbacksTableStackPos);
+
+ ~cLuaServerHandle();
+
+ /** Called by cNetwork::Listen()'s binding.
+ Sets the server handle around which this instance is wrapped, and a self SharedPtr for link management. */
+ void SetServerHandle(cServerHandlePtr a_ServerHandle, cLuaServerHandlePtr a_Self);
+
+ /** Terminates all connections and closes the listening socket. */
+ void Close(void);
+
+ /** Returns true if the server is currently listening. */
+ bool IsListening(void);
+
+ /** Removes the link from the list of links that the server is currently tracking. */
+ void RemoveLink(cLuaTCPLink * a_Link);
+
+ /** Called when Lua garbage-collects the object.
+ Releases the internal SharedPtr to self, so that the instance may be deallocated. */
+ void Release(void);
+
+protected:
+ /** The plugin for which the server is created. */
+ cPluginLua & m_Plugin;
+
+ /** The Lua table that holds the callbacks to be invoked. */
+ cLuaState::cRef m_Callbacks;
+
+ /** The port on which the server is listening.
+ Used mainly for better error reporting. */
+ UInt16 m_Port;
+
+ /** The cServerHandle around which this instance is wrapped. */
+ cServerHandlePtr m_ServerHandle;
+
+ /** Protects m_Connections against multithreaded access. */
+ cCriticalSection m_CSConnections;
+
+ /** All connections that are currently active in this server.
+ Protected by m_CSConnections. */
+ cLuaTCPLinkPtrs m_Connections;
+
+ /** SharedPtr to self, given out to newly created links. */
+ cLuaServerHandlePtr m_Self;
+
+
+ // cNetwork::cListenCallbacks overrides:
+ virtual cTCPLink::cCallbacksPtr OnIncomingConnection(const AString & a_RemoteIPAddress, UInt16 a_RemotePort) override;
+ virtual void OnAccepted(cTCPLink & a_Link) override;
+ virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override;
+};
+
+
+
+
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index 4de34c88d..73b114599 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -656,6 +656,18 @@ void cLuaState::Push(cItems * a_Items)
+void cLuaState::Push(cLuaServerHandle * a_ServerHandle)
+{
+ ASSERT(IsValid());
+
+ tolua_pushusertype(m_LuaState, a_ServerHandle, "cServerHandle");
+ m_NumCurrentFunctionArgs += 1;
+}
+
+
+
+
+
void cLuaState::Push(cLuaTCPLink * a_TCPLink)
{
ASSERT(IsValid());
@@ -970,6 +982,15 @@ void cLuaState::GetStackValue(int a_StackPos, pWorld & a_ReturnedVal)
+void cLuaState::GetStackValue(int a_StackPos, cRef & a_Ref)
+{
+ a_Ref.RefStack(*this, a_StackPos);
+}
+
+
+
+
+
bool cLuaState::CallFunction(int a_NumResults)
{
ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first
@@ -1539,6 +1560,18 @@ cLuaState::cRef::cRef(cLuaState & a_LuaState, int a_StackPos) :
+cLuaState::cRef::cRef(cRef && a_FromRef):
+ m_LuaState(a_FromRef.m_LuaState),
+ m_Ref(a_FromRef.m_Ref)
+{
+ a_FromRef.m_LuaState = nullptr;
+ a_FromRef.m_Ref = LUA_REFNIL;
+}
+
+
+
+
+
cLuaState::cRef::~cRef()
{
if (m_LuaState != nullptr)
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h
index 0dcd248fe..f68b022ea 100644
--- a/src/Bindings/LuaState.h
+++ b/src/Bindings/LuaState.h
@@ -60,6 +60,7 @@ class cHopperEntity;
class cBlockEntity;
class cBoundingBox;
class cLuaTCPLink;
+class cLuaServerHandle;
typedef cBoundingBox * pBoundingBox;
typedef cWorld * pWorld;
@@ -84,6 +85,10 @@ public:
/** Creates a reference in the specified LuaState for object at the specified StackPos */
cRef(cLuaState & a_LuaState, int a_StackPos);
+
+ /** Moves the reference from the specified instance into a newly created instance.
+ The old instance is then "!IsValid()". */
+ cRef(cRef && a_FromRef);
~cRef();
@@ -203,6 +208,7 @@ public:
void Push(cHopperEntity * a_Hopper);
void Push(cItem * a_Item);
void Push(cItems * a_Items);
+ void Push(cLuaServerHandle * a_ServerHandle);
void Push(cLuaTCPLink * a_TCPLink);
void Push(cMonster * a_Monster);
void Push(cPickup * a_Pickup);
@@ -242,6 +248,9 @@ public:
/** Retrieve value at a_StackPos, if it is a valid cWorld class. If not, a_Value is unchanged */
void GetStackValue(int a_StackPos, pWorld & a_Value);
+
+ /** Store the value at a_StackPos as a reference. */
+ void GetStackValue(int a_StackPos, cRef & a_Ref);
/** Call the specified Lua function.
Returns true if call succeeded, false if there was an error.
diff --git a/src/Bindings/LuaTCPLink.cpp b/src/Bindings/LuaTCPLink.cpp
index f88aeff84..6b8395806 100644
--- a/src/Bindings/LuaTCPLink.cpp
+++ b/src/Bindings/LuaTCPLink.cpp
@@ -5,6 +5,7 @@
#include "Globals.h"
#include "LuaTCPLink.h"
+#include "LuaServerHandle.h"
@@ -14,6 +15,47 @@ cLuaTCPLink::cLuaTCPLink(cPluginLua & a_Plugin, int a_CallbacksTableStackPos):
m_Plugin(a_Plugin),
m_Callbacks(a_Plugin.GetLuaState(), a_CallbacksTableStackPos)
{
+ // Warn if the callbacks aren't valid:
+ if (!m_Callbacks.IsValid())
+ {
+ LOGWARNING("cTCPLink in plugin %s: callbacks could not be retrieved", m_Plugin.GetName().c_str());
+ cPluginLua::cOperation Op(m_Plugin);
+ Op().LogStackTrace();
+ }
+}
+
+
+
+
+
+cLuaTCPLink::cLuaTCPLink(cPluginLua & a_Plugin, cLuaState::cRef && a_CallbacksTableRef, cLuaServerHandleWPtr a_ServerHandle):
+ m_Plugin(a_Plugin),
+ m_Callbacks(std::move(a_CallbacksTableRef)),
+ m_Server(std::move(a_ServerHandle))
+{
+ // Warn if the callbacks aren't valid:
+ if (!m_Callbacks.IsValid())
+ {
+ LOGWARNING("cTCPLink in plugin %s: callbacks could not be retrieved", m_Plugin.GetName().c_str());
+ cPluginLua::cOperation Op(m_Plugin);
+ Op().LogStackTrace();
+ }
+}
+
+
+
+
+
+cLuaTCPLink::~cLuaTCPLink()
+{
+ // If the link is still open, close it:
+ cTCPLinkPtr Link = m_Link;
+ if (Link != nullptr)
+ {
+ Link->Close();
+ }
+
+ Terminated();
}
@@ -107,15 +149,14 @@ UInt16 cLuaTCPLink::GetRemotePort(void) const
void cLuaTCPLink::Shutdown(void)
{
- // Safely grab a copy of the link:
+ // Safely grab a copy of the link and shut it down:
cTCPLinkPtr Link = m_Link;
- if (Link == nullptr)
+ if (Link != nullptr)
{
- return;
+ Link->Shutdown();
}
- // Shutdown:
- Link->Shutdown();
+ Terminated();
}
@@ -124,17 +165,48 @@ void cLuaTCPLink::Shutdown(void)
void cLuaTCPLink::Close(void)
{
- // Safely grab a copy of the link:
+ // If the link is still open, close it:
cTCPLinkPtr Link = m_Link;
- if (Link == nullptr)
+ if (Link != nullptr)
{
- return;
+ Link->Close();
+ }
+
+ Terminated();
+}
+
+
+
+
+
+void cLuaTCPLink::Terminated(void)
+{
+ // Disable the callbacks:
+ if (m_Callbacks.IsValid())
+ {
+ m_Callbacks.UnRef();
+ }
+
+ // If the managing server is still alive, let it know we're terminating:
+ auto Server = m_Server.lock();
+ if (Server != nullptr)
+ {
+ Server->RemoveLink(this);
}
- // Close the link:
- Link->Close();
+ // If the link is still open, close it:
+ cTCPLinkPtr Link = m_Link;
+ if (Link != nullptr)
+ {
+ Link->Close();
+ m_Link.reset();
+ }
}
+
+
+
+
void cLuaTCPLink::OnConnected(cTCPLink & a_Link)
{
// Check if we're still valid:
@@ -171,6 +243,8 @@ void cLuaTCPLink::OnError(int a_ErrorCode, const AString & a_ErrorMsg)
m_Plugin.GetName().c_str(), a_ErrorCode, a_ErrorMsg.c_str()
);
}
+
+ Terminated();
}
@@ -221,7 +295,8 @@ void cLuaTCPLink::OnRemoteClosed(void)
{
LOGINFO("cTCPLink OnRemoteClosed() callback failed in plugin %s.", m_Plugin.GetName().c_str());
}
- m_Link.reset();
+
+ Terminated();
}
diff --git a/src/Bindings/LuaTCPLink.h b/src/Bindings/LuaTCPLink.h
index 125cc1b31..f2af911ec 100644
--- a/src/Bindings/LuaTCPLink.h
+++ b/src/Bindings/LuaTCPLink.h
@@ -16,6 +16,14 @@
+// fwd:
+class cLuaServerHandle;
+typedef WeakPtr<cLuaServerHandle> cLuaServerHandleWPtr;
+
+
+
+
+
class cLuaTCPLink:
public cNetwork::cConnectCallbacks,
public cTCPLink::cCallbacks
@@ -24,6 +32,11 @@ public:
/** Creates a new instance of the link, attached to the specified plugin and wrapping the callbacks that are in a table at the specified stack pos. */
cLuaTCPLink(cPluginLua & a_Plugin, int a_CallbacksTableStackPos);
+ /** Creates a new instance of the link, attached to the specified plugin and wrapping the callbacks that are in the specified referenced table. */
+ cLuaTCPLink(cPluginLua & a_Plugin, cLuaState::cRef && a_CallbacksTableRef, cLuaServerHandleWPtr a_Server);
+
+ ~cLuaTCPLink();
+
/** Sends the data contained in the string to the remote peer.
Returns true if successful, false on immediate failure (queueing the data failed or link not available). */
bool Send(const AString & a_Data);
@@ -60,6 +73,14 @@ protected:
May be nullptr. */
cTCPLinkPtr m_Link;
+ /** The server that is responsible for this link, if any. */
+ cLuaServerHandleWPtr m_Server;
+
+
+ /** Common code called when the link is considered as terminated.
+ Releases m_Link, m_Callbacks and this from m_Server, each when applicable. */
+ void Terminated(void);
+
// cNetwork::cConnectCallbacks overrides:
virtual void OnConnected(cTCPLink & a_Link) override;
virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override;
diff --git a/src/Bindings/ManualBindings_Network.cpp b/src/Bindings/ManualBindings_Network.cpp
index 3123ef885..24c8c73b8 100644
--- a/src/Bindings/ManualBindings_Network.cpp
+++ b/src/Bindings/ManualBindings_Network.cpp
@@ -10,6 +10,7 @@
#include "LuaState.h"
#include "LuaTCPLink.h"
#include "LuaNameLookup.h"
+#include "LuaServerHandle.h"
@@ -72,6 +73,7 @@ static int tolua_cNetwork_Connect(lua_State * L)
+/** Binds cNetwork::HostnameToIP */
static int tolua_cNetwork_HostnameToIP(lua_State * L)
{
// Function signature:
@@ -112,6 +114,7 @@ static int tolua_cNetwork_HostnameToIP(lua_State * L)
+/** Binds cNetwork::IPToHostname */
static int tolua_cNetwork_IPToHostname(lua_State * L)
{
// Function signature:
@@ -152,9 +155,66 @@ static int tolua_cNetwork_IPToHostname(lua_State * L)
+/** Binds cNetwork::Listen */
+static int tolua_cNetwork_Listen(lua_State * L)
+{
+ // Function signature:
+ // cNetwork:Listen(Port, Callbacks) -> bool
+
+ cLuaState S(L);
+ if (
+ !S.CheckParamUserTable(1, "cNetwork") ||
+ !S.CheckParamNumber(2) ||
+ !S.CheckParamTable(3) ||
+ !S.CheckParamEnd(4)
+ )
+ {
+ return 0;
+ }
+
+ // Get the plugin instance:
+ cPluginLua * Plugin = GetLuaPlugin(L);
+ if (Plugin == nullptr)
+ {
+ // An error message has been already printed in GetLuaPlugin()
+ S.Push(false);
+ return 1;
+ }
+
+ // Read the params:
+ int Port;
+ S.GetStackValues(2, Port);
+ if ((Port < 0) || (Port > 65535))
+ {
+ LOGWARNING("cNetwork:Listen() called with invalid port (%d), failing the request.", Port);
+ S.Push(false);
+ return 1;
+ }
+ UInt16 Port16 = static_cast<UInt16>(Port);
+
+ // Create the LuaTCPLink glue class:
+ auto Srv = std::make_shared<cLuaServerHandle>(Port16, *Plugin, 3);
+
+ // Listen:
+ Srv->SetServerHandle(cNetwork::Listen(Port16, Srv), Srv);
+
+ // Register the server to be garbage-collected by Lua:
+ tolua_pushusertype(L, Srv.get(), "cServerHandle");
+ tolua_register_gc(L, lua_gettop(L));
+
+ // Return the server handle wrapper:
+ S.Push(Srv.get());
+ return 1;
+}
+
+
+
+
+
////////////////////////////////////////////////////////////////////////////////
// cTCPLink bindings (routed through cLuaTCPLink):
+/** Binds cLuaTCPLink::Send */
static int tolua_cTCPLink_Send(lua_State * L)
{
// Function signature:
@@ -193,6 +253,7 @@ static int tolua_cTCPLink_Send(lua_State * L)
+/** Binds cLuaTCPLink::GetLocalIP */
static int tolua_cTCPLink_GetLocalIP(lua_State * L)
{
// Function signature:
@@ -226,6 +287,7 @@ static int tolua_cTCPLink_GetLocalIP(lua_State * L)
+/** Binds cLuaTCPLink::GetLocalPort */
static int tolua_cTCPLink_GetLocalPort(lua_State * L)
{
// Function signature:
@@ -259,6 +321,7 @@ static int tolua_cTCPLink_GetLocalPort(lua_State * L)
+/** Binds cLuaTCPLink::GetRemoteIP */
static int tolua_cTCPLink_GetRemoteIP(lua_State * L)
{
// Function signature:
@@ -292,6 +355,7 @@ static int tolua_cTCPLink_GetRemoteIP(lua_State * L)
+/** Binds cLuaTCPLink::GetRemotePort */
static int tolua_cTCPLink_GetRemotePort(lua_State * L)
{
// Function signature:
@@ -326,6 +390,90 @@ static int tolua_cTCPLink_GetRemotePort(lua_State * L)
////////////////////////////////////////////////////////////////////////////////
+// cServerHandle bindings (routed through cLuaServerHandle):
+
+/** Called when Lua destroys the object instance.
+Close the server and let it deallocate on its own (it's in a SharedPtr). */
+static int tolua_collect_cServerHandle(lua_State * L)
+{
+ cLuaServerHandle * Srv = static_cast<cLuaServerHandle *>(tolua_tousertype(L, 1, nullptr));
+ Srv->Release();
+ return 0;
+}
+
+
+
+
+
+/** Binds cLuaServerHandle::Close */
+static int tolua_cServerHandle_Close(lua_State * L)
+{
+ // Function signature:
+ // ServerInstance:Close()
+
+ cLuaState S(L);
+ if (
+ !S.CheckParamUserType(1, "cServerHandle") ||
+ !S.CheckParamEnd(2)
+ )
+ {
+ return 0;
+ }
+
+ // Get the server handle:
+ cLuaServerHandle * Srv;
+ if (lua_isnil(L, 1))
+ {
+ LOGWARNING("cServerHandle:Close(): invalid server handle object. Stack trace:");
+ S.LogStackTrace();
+ return 0;
+ }
+ Srv = *static_cast<cLuaServerHandle **>(lua_touserdata(L, 1));
+
+ // Close it:
+ Srv->Close();
+ return 0;
+}
+
+
+
+
+
+/** Binds cLuaServerHandle::IsListening */
+static int tolua_cServerHandle_IsListening(lua_State * L)
+{
+ // Function signature:
+ // ServerInstance:IsListening() -> bool
+
+ cLuaState S(L);
+ if (
+ !S.CheckParamUserType(1, "cServerHandle") ||
+ !S.CheckParamEnd(2)
+ )
+ {
+ return 0;
+ }
+
+ // Get the server handle:
+ cLuaServerHandle * Srv;
+ if (lua_isnil(L, 1))
+ {
+ LOGWARNING("cServerHandle:IsListening(): invalid server handle object. Stack trace:");
+ S.LogStackTrace();
+ return 0;
+ }
+ Srv = *static_cast<cLuaServerHandle **>(lua_touserdata(L, 1));
+
+ // Close it:
+ S.Push(Srv->IsListening());
+ return 1;
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
// Register the bindings:
void ManualBindings::BindNetwork(lua_State * tolua_S)
@@ -335,15 +483,15 @@ void ManualBindings::BindNetwork(lua_State * tolua_S)
tolua_cclass(tolua_S, "cNetwork", "cNetwork", "", nullptr);
tolua_usertype(tolua_S, "cTCPLink");
tolua_cclass(tolua_S, "cTCPLink", "cTCPLink", "", nullptr);
+ tolua_usertype(tolua_S, "cServerHandle");
+ tolua_cclass(tolua_S, "cServerHandle", "cServerHandle", "", tolua_collect_cServerHandle);
// Fill in the functions (alpha-sorted):
tolua_beginmodule(tolua_S, "cNetwork");
tolua_function(tolua_S, "Connect", tolua_cNetwork_Connect);
tolua_function(tolua_S, "HostnameToIP", tolua_cNetwork_HostnameToIP);
tolua_function(tolua_S, "IPToHostname", tolua_cNetwork_IPToHostname);
- /*
tolua_function(tolua_S, "Listen", tolua_cNetwork_Listen);
- */
tolua_endmodule(tolua_S);
tolua_beginmodule(tolua_S, "cTCPLink");
@@ -353,6 +501,11 @@ void ManualBindings::BindNetwork(lua_State * tolua_S)
tolua_function(tolua_S, "GetRemoteIP", tolua_cTCPLink_GetRemoteIP);
tolua_function(tolua_S, "GetRemotePort", tolua_cTCPLink_GetRemotePort);
tolua_endmodule(tolua_S);
+
+ tolua_beginmodule(tolua_S, "cServerHandle");
+ tolua_function(tolua_S, "Close", tolua_cServerHandle_Close);
+ tolua_function(tolua_S, "IsListening", tolua_cServerHandle_IsListening);
+ tolua_endmodule(tolua_S);
}