summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattes D <github@xoft.cz>2015-01-28 15:14:05 +0100
committerMattes D <github@xoft.cz>2015-02-04 08:40:50 +0100
commit360c632e36acfe8b271c3212feef9b6f93623ba1 (patch)
tree58f1e1d9c7cdf62b2937333661d855462080bc0d
parentSwitched LuaState to use sizeof... (diff)
downloadcuberite-360c632e36acfe8b271c3212feef9b6f93623ba1.tar
cuberite-360c632e36acfe8b271c3212feef9b6f93623ba1.tar.gz
cuberite-360c632e36acfe8b271c3212feef9b6f93623ba1.tar.bz2
cuberite-360c632e36acfe8b271c3212feef9b6f93623ba1.tar.lz
cuberite-360c632e36acfe8b271c3212feef9b6f93623ba1.tar.xz
cuberite-360c632e36acfe8b271c3212feef9b6f93623ba1.tar.zst
cuberite-360c632e36acfe8b271c3212feef9b6f93623ba1.zip
-rw-r--r--src/Bindings/CMakeLists.txt3
-rw-r--r--src/Bindings/LuaState.cpp12
-rw-r--r--src/Bindings/LuaState.h2
-rw-r--r--src/Bindings/LuaTCPLink.cpp229
-rw-r--r--src/Bindings/LuaTCPLink.h77
-rw-r--r--src/Bindings/ManualBindings.cpp3
-rw-r--r--src/Bindings/ManualBindings.h10
-rw-r--r--src/Bindings/ManualBindings_Network.cpp279
8 files changed, 614 insertions, 1 deletions
diff --git a/src/Bindings/CMakeLists.txt b/src/Bindings/CMakeLists.txt
index d47579cd6..a72611f76 100644
--- a/src/Bindings/CMakeLists.txt
+++ b/src/Bindings/CMakeLists.txt
@@ -9,8 +9,10 @@ SET (SRCS
DeprecatedBindings.cpp
LuaChunkStay.cpp
LuaState.cpp
+ LuaTCPLink.cpp
LuaWindow.cpp
ManualBindings.cpp
+ ManualBindings_Network.cpp
ManualBindings_RankManager.cpp
Plugin.cpp
PluginLua.cpp
@@ -24,6 +26,7 @@ SET (HDRS
LuaChunkStay.h
LuaFunctions.h
LuaState.h
+ LuaTCPLink.h
LuaWindow.h
ManualBindings.h
Plugin.h
diff --git a/src/Bindings/LuaState.cpp b/src/Bindings/LuaState.cpp
index 01d3ac687..4de34c88d 100644
--- a/src/Bindings/LuaState.cpp
+++ b/src/Bindings/LuaState.cpp
@@ -656,6 +656,18 @@ void cLuaState::Push(cItems * a_Items)
+void cLuaState::Push(cLuaTCPLink * a_TCPLink)
+{
+ ASSERT(IsValid());
+
+ tolua_pushusertype(m_LuaState, a_TCPLink, "cTCPLink");
+ m_NumCurrentFunctionArgs += 1;
+}
+
+
+
+
+
void cLuaState::Push(cMonster * a_Monster)
{
ASSERT(IsValid());
diff --git a/src/Bindings/LuaState.h b/src/Bindings/LuaState.h
index 97e6b47e1..0dcd248fe 100644
--- a/src/Bindings/LuaState.h
+++ b/src/Bindings/LuaState.h
@@ -59,6 +59,7 @@ class cTNTEntity;
class cHopperEntity;
class cBlockEntity;
class cBoundingBox;
+class cLuaTCPLink;
typedef cBoundingBox * pBoundingBox;
typedef cWorld * pWorld;
@@ -202,6 +203,7 @@ public:
void Push(cHopperEntity * a_Hopper);
void Push(cItem * a_Item);
void Push(cItems * a_Items);
+ void Push(cLuaTCPLink * a_TCPLink);
void Push(cMonster * a_Monster);
void Push(cPickup * a_Pickup);
void Push(cPlayer * a_Player);
diff --git a/src/Bindings/LuaTCPLink.cpp b/src/Bindings/LuaTCPLink.cpp
new file mode 100644
index 000000000..f88aeff84
--- /dev/null
+++ b/src/Bindings/LuaTCPLink.cpp
@@ -0,0 +1,229 @@
+
+// LuaTCPLink.cpp
+
+// Implements the cLuaTCPLink class representing a Lua wrapper for the cTCPLink class and the callbacks it needs
+
+#include "Globals.h"
+#include "LuaTCPLink.h"
+
+
+
+
+
+cLuaTCPLink::cLuaTCPLink(cPluginLua & a_Plugin, int a_CallbacksTableStackPos):
+ m_Plugin(a_Plugin),
+ m_Callbacks(a_Plugin.GetLuaState(), a_CallbacksTableStackPos)
+{
+}
+
+
+
+
+
+bool cLuaTCPLink::Send(const AString & a_Data)
+{
+ // Safely grab a copy of the link:
+ cTCPLinkPtr Link = m_Link;
+ if (Link == nullptr)
+ {
+ return false;
+ }
+
+ // Send the data:
+ return Link->Send(a_Data);
+}
+
+
+
+
+
+AString cLuaTCPLink::GetLocalIP(void) const
+{
+ // Safely grab a copy of the link:
+ cTCPLinkPtr Link = m_Link;
+ if (Link == nullptr)
+ {
+ return "";
+ }
+
+ // Get the IP address:
+ return Link->GetLocalIP();
+}
+
+
+
+
+
+UInt16 cLuaTCPLink::GetLocalPort(void) const
+{
+ // Safely grab a copy of the link:
+ cTCPLinkPtr Link = m_Link;
+ if (Link == nullptr)
+ {
+ return 0;
+ }
+
+ // Get the port:
+ return Link->GetLocalPort();
+}
+
+
+
+
+
+AString cLuaTCPLink::GetRemoteIP(void) const
+{
+ // Safely grab a copy of the link:
+ cTCPLinkPtr Link = m_Link;
+ if (Link == nullptr)
+ {
+ return "";
+ }
+
+ // Get the IP address:
+ return Link->GetRemoteIP();
+}
+
+
+
+
+
+UInt16 cLuaTCPLink::GetRemotePort(void) const
+{
+ // Safely grab a copy of the link:
+ cTCPLinkPtr Link = m_Link;
+ if (Link == nullptr)
+ {
+ return 0;
+ }
+
+ // Get the port:
+ return Link->GetRemotePort();
+}
+
+
+
+
+
+void cLuaTCPLink::Shutdown(void)
+{
+ // Safely grab a copy of the link:
+ cTCPLinkPtr Link = m_Link;
+ if (Link == nullptr)
+ {
+ return;
+ }
+
+ // Shutdown:
+ Link->Shutdown();
+}
+
+
+
+
+
+void cLuaTCPLink::Close(void)
+{
+ // Safely grab a copy of the link:
+ cTCPLinkPtr Link = m_Link;
+ if (Link == nullptr)
+ {
+ return;
+ }
+
+ // Close the link:
+ Link->Close();
+}
+
+void cLuaTCPLink::OnConnected(cTCPLink & a_Link)
+{
+ // Check if we're still valid:
+ if (!m_Callbacks.IsValid())
+ {
+ return;
+ }
+
+ // Call the callback:
+ cPluginLua::cOperation Op(m_Plugin);
+ if (!Op().Call(cLuaState::cTableRef(m_Callbacks, "OnConnected"), this))
+ {
+ LOGINFO("cTCPLink OnConnected() callback failed in plugin %s.", m_Plugin.GetName().c_str());
+ }
+}
+
+
+
+
+
+void cLuaTCPLink::OnError(int a_ErrorCode, const AString & a_ErrorMsg)
+{
+ // Check if we're still valid:
+ if (!m_Callbacks.IsValid())
+ {
+ return;
+ }
+
+ // Call the callback:
+ cPluginLua::cOperation Op(m_Plugin);
+ if (!Op().Call(cLuaState::cTableRef(m_Callbacks, "OnError"), this, a_ErrorCode, a_ErrorMsg))
+ {
+ LOGINFO("cTCPLink OnError() callback failed in plugin %s; the link error is %d (%s).",
+ m_Plugin.GetName().c_str(), a_ErrorCode, a_ErrorMsg.c_str()
+ );
+ }
+}
+
+
+
+
+
+void cLuaTCPLink::OnLinkCreated(cTCPLinkPtr a_Link)
+{
+ // Store the cTCPLink for later use:
+ m_Link = a_Link;
+}
+
+
+
+
+
+void cLuaTCPLink::OnReceivedData(const char * a_Data, size_t a_Length)
+{
+ // Check if we're still valid:
+ if (!m_Callbacks.IsValid())
+ {
+ return;
+ }
+
+ // Call the callback:
+ cPluginLua::cOperation Op(m_Plugin);
+ if (!Op().Call(cLuaState::cTableRef(m_Callbacks, "OnReceivedData"), this, AString(a_Data, a_Length)))
+ {
+ LOGINFO("cTCPLink OnReceivedData callback failed in plugin %s.", m_Plugin.GetName().c_str());
+ }
+}
+
+
+
+
+
+void cLuaTCPLink::OnRemoteClosed(void)
+{
+ // Check if we're still valid:
+ if (!m_Callbacks.IsValid())
+ {
+ return;
+ }
+
+ // Call the callback:
+ cPluginLua::cOperation Op(m_Plugin);
+ if (!Op().Call(cLuaState::cTableRef(m_Callbacks, "OnRemoteClosed"), this))
+ {
+ LOGINFO("cTCPLink OnRemoteClosed() callback failed in plugin %s.", m_Plugin.GetName().c_str());
+ }
+ m_Link.reset();
+}
+
+
+
+
diff --git a/src/Bindings/LuaTCPLink.h b/src/Bindings/LuaTCPLink.h
new file mode 100644
index 000000000..54c1d2dbf
--- /dev/null
+++ b/src/Bindings/LuaTCPLink.h
@@ -0,0 +1,77 @@
+
+// LuaTCPLink.h
+
+// Declares the cLuaTCPLink class representing a Lua wrapper for the cTCPLink class and the callbacks it needs
+
+
+
+
+
+#pragma once
+
+#include "../OSSupport/Network.h"
+#include "LuaState.h"
+#include "PluginLua.h"
+
+
+
+
+
+class cLuaTCPLink:
+ public cNetwork::cConnectCallbacks,
+ public cTCPLink::cCallbacks
+{
+public:
+ /** Creates a new instance of the link, attached to the specified lua state and wrapping the callbacks that are in a table at the specified stack pos. */
+ cLuaTCPLink(cPluginLua & a_Plugin, int a_CallbacksTableStackPos);
+
+ /** 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);
+
+ /** Returns the IP address of the local endpoint of the connection. */
+ AString GetLocalIP(void) const;
+
+ /** Returns the port used by the local endpoint of the connection. */
+ UInt16 GetLocalPort(void) const;
+
+ /** Returns the IP address of the remote endpoint of the connection. */
+ AString GetRemoteIP(void) const;
+
+ /** Returns the port used by the remote endpoint of the connection. */
+ UInt16 GetRemotePort(void) const;
+
+ /** Closes the link gracefully.
+ The link will send any queued outgoing data, then it will send the FIN packet.
+ The link will still receive incoming data from remote until the remote closes the connection. */
+ void Shutdown(void);
+
+ /** Drops the connection without any more processing.
+ Sends the RST packet, queued outgoing and incoming data is lost. */
+ void Close(void);
+
+protected:
+ /** The plugin for which the link is created. */
+ cPluginLua & m_Plugin;
+
+ /** The Lua table that holds the callbacks to be invoked. */
+ cLuaState::cRef m_Callbacks;
+
+ /** The underlying link representing the connection.
+ May be nullptr. */
+ cTCPLinkPtr m_Link;
+
+ // cNetwork::cConnectCallbacks overrides:
+ virtual void OnConnected(cTCPLink & a_Link) override;
+ virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override;
+
+ // cTCPLink::cCallbacks overrides:
+ virtual void OnLinkCreated(cTCPLinkPtr a_Link) override;
+ virtual void OnReceivedData(const char * a_Data, size_t a_Length) override;
+ virtual void OnRemoteClosed(void) override;
+ // The OnError() callback is shared with cNetwork::cConnectCallbacks
+};
+
+
+
+
diff --git a/src/Bindings/ManualBindings.cpp b/src/Bindings/ManualBindings.cpp
index 56f2e73bc..24e3f0052 100644
--- a/src/Bindings/ManualBindings.cpp
+++ b/src/Bindings/ManualBindings.cpp
@@ -256,7 +256,7 @@ static int tolua_Base64Decode(lua_State * tolua_S)
-static cPluginLua * GetLuaPlugin(lua_State * L)
+cPluginLua * GetLuaPlugin(lua_State * L)
{
// Get the plugin identification out of LuaState:
lua_getglobal(L, LUA_PLUGIN_INSTANCE_VAR_NAME);
@@ -3556,6 +3556,7 @@ void ManualBindings::Bind(lua_State * tolua_S)
tolua_function(tolua_S, "md5", tolua_md5);
BindRankManager(tolua_S);
+ BindNetwork(tolua_S);
tolua_endmodule(tolua_S);
}
diff --git a/src/Bindings/ManualBindings.h b/src/Bindings/ManualBindings.h
index 1b6e65654..74d24d5f5 100644
--- a/src/Bindings/ManualBindings.h
+++ b/src/Bindings/ManualBindings.h
@@ -1,6 +1,7 @@
#pragma once
struct lua_State;
+class cPluginLua;
@@ -17,8 +18,17 @@ protected:
/** Binds the manually implemented cRankManager glue code to tolua_S.
Implemented in ManualBindings_RankManager.cpp. */
static void BindRankManager(lua_State * tolua_S);
+
+ /** Binds the manually implemented cNetwork-related API to tolua_S.
+ Implemented in ManualBindings_Network.cpp. */
+ static void BindNetwork(lua_State * tolua_S);
};
+extern cPluginLua * GetLuaPlugin(lua_State * L);
+
+
+
+
diff --git a/src/Bindings/ManualBindings_Network.cpp b/src/Bindings/ManualBindings_Network.cpp
new file mode 100644
index 000000000..882af4e9e
--- /dev/null
+++ b/src/Bindings/ManualBindings_Network.cpp
@@ -0,0 +1,279 @@
+
+// ManualBindings_Network.cpp
+
+// Implements the cNetwork-related API bindings for Lua
+
+#include "Globals.h"
+#include "LuaTCPLink.h"
+#include "ManualBindings.h"
+#include "tolua++/include/tolua++.h"
+#include "LuaState.h"
+#include "LuaTCPLink.h"
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// cNetwork API functions:
+
+/** Binds cNetwork::Connect */
+static int tolua_cNetwork_Connect(lua_State * L)
+{
+ // Function signature:
+ // cNetwork:Connect(Host, Port, Callbacks) -> bool
+
+ cLuaState S(L);
+ if (
+ !S.CheckParamUserTable(1, "cNetwork") ||
+ !S.CheckParamString(2) ||
+ !S.CheckParamNumber(3) ||
+ !S.CheckParamTable(4) ||
+ !S.CheckParamEnd(5)
+ )
+ {
+ 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:
+ AString Host;
+ int Port;
+ S.GetStackValues(2, Host, Port);
+
+ // Check validity:
+ if ((Port < 0) || (Port > 65535))
+ {
+ LOGWARNING("cNetwork:Connect() called with invalid port (%d), failing the request.", Port);
+ S.Push(false);
+ return 1;
+ }
+
+ // Create the LuaTCPLink glue class:
+ auto Link = std::make_shared<cLuaTCPLink>(*Plugin, 4);
+
+ // Try to connect:
+ bool res = cNetwork::Connect(Host, static_cast<UInt16>(Port), Link, Link);
+ S.Push(res);
+
+ return 1;
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// cTCPLink bindings (routed through cLuaTCPLink):
+
+static int tolua_cTCPLink_Send(lua_State * L)
+{
+ // Function signature:
+ // LinkInstance:Send(DataString) -> bool
+
+ cLuaState S(L);
+ if (
+ !S.CheckParamUserType(1, "cTCPLink") ||
+ !S.CheckParamString(2) ||
+ !S.CheckParamEnd(3)
+ )
+ {
+ return 0;
+ }
+
+ // Get the link:
+ cLuaTCPLink * Link;
+ if (lua_isnil(L, 1))
+ {
+ LOGWARNING("cTCPLink:Send(): invalid link object. Stack trace:");
+ S.LogStackTrace();
+ return 0;
+ }
+ Link = *static_cast<cLuaTCPLink **>(lua_touserdata(L, 1));
+
+ // Get the data to send:
+ AString Data;
+ S.GetStackValues(2, Data);
+
+ // Send the data:
+ Link->Send(Data);
+ return 0;
+}
+
+
+
+
+
+static int tolua_cTCPLink_GetLocalIP(lua_State * L)
+{
+ // Function signature:
+ // LinkInstance:GetLocalIP() -> string
+
+ cLuaState S(L);
+ if (
+ !S.CheckParamUserType(1, "cTCPLink") ||
+ !S.CheckParamEnd(2)
+ )
+ {
+ return 0;
+ }
+
+ // Get the link:
+ cLuaTCPLink * Link;
+ if (lua_isnil(L, 1))
+ {
+ LOGWARNING("cTCPLink:GetLocalIP(): invalid link object. Stack trace:");
+ S.LogStackTrace();
+ return 0;
+ }
+ Link = *static_cast<cLuaTCPLink **>(lua_touserdata(L, 1));
+
+ // Get the IP:
+ S.Push(Link->GetLocalIP());
+ return 1;
+}
+
+
+
+
+
+static int tolua_cTCPLink_GetLocalPort(lua_State * L)
+{
+ // Function signature:
+ // LinkInstance:GetLocalPort() -> number
+
+ cLuaState S(L);
+ if (
+ !S.CheckParamUserType(1, "cTCPLink") ||
+ !S.CheckParamEnd(2)
+ )
+ {
+ return 0;
+ }
+
+ // Get the link:
+ cLuaTCPLink * Link;
+ if (lua_isnil(L, 1))
+ {
+ LOGWARNING("cTCPLink:GetLocalPort(): invalid link object. Stack trace:");
+ S.LogStackTrace();
+ return 0;
+ }
+ Link = *static_cast<cLuaTCPLink **>(lua_touserdata(L, 1));
+
+ // Get the Port:
+ S.Push(Link->GetLocalPort());
+ return 1;
+}
+
+
+
+
+
+static int tolua_cTCPLink_GetRemoteIP(lua_State * L)
+{
+ // Function signature:
+ // LinkInstance:GetRemoteIP() -> string
+
+ cLuaState S(L);
+ if (
+ !S.CheckParamUserType(1, "cTCPLink") ||
+ !S.CheckParamEnd(2)
+ )
+ {
+ return 0;
+ }
+
+ // Get the link:
+ cLuaTCPLink * Link;
+ if (lua_isnil(L, 1))
+ {
+ LOGWARNING("cTCPLink:GetRemoteIP(): invalid link object. Stack trace:");
+ S.LogStackTrace();
+ return 0;
+ }
+ Link = *static_cast<cLuaTCPLink **>(lua_touserdata(L, 1));
+
+ // Get the IP:
+ S.Push(Link->GetRemoteIP());
+ return 1;
+}
+
+
+
+
+
+static int tolua_cTCPLink_GetRemotePort(lua_State * L)
+{
+ // Function signature:
+ // LinkInstance:GetRemotePort() -> number
+
+ cLuaState S(L);
+ if (
+ !S.CheckParamUserType(1, "cTCPLink") ||
+ !S.CheckParamEnd(2)
+ )
+ {
+ return 0;
+ }
+
+ // Get the link:
+ cLuaTCPLink * Link;
+ if (lua_isnil(L, 1))
+ {
+ LOGWARNING("cTCPLink:GetRemotePort(): invalid link object. Stack trace:");
+ S.LogStackTrace();
+ return 0;
+ }
+ Link = *static_cast<cLuaTCPLink **>(lua_touserdata(L, 1));
+
+ // Get the Port:
+ S.Push(Link->GetRemotePort());
+ return 1;
+}
+
+
+
+
+
+////////////////////////////////////////////////////////////////////////////////
+// Register the bindings:
+
+void ManualBindings::BindNetwork(lua_State * tolua_S)
+{
+ // Create the cNetwork API classes:
+ tolua_usertype(tolua_S, "cNetwork");
+ tolua_cclass(tolua_S, "cNetwork", "cNetwork", "", nullptr);
+ tolua_usertype(tolua_S, "cTCPLink");
+ tolua_cclass(tolua_S, "cTCPLink", "cTCPLink", "", nullptr);
+
+ // 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");
+ tolua_function(tolua_S, "Send", tolua_cTCPLink_Send);
+ tolua_function(tolua_S, "GetLocalIP", tolua_cTCPLink_GetLocalIP);
+ tolua_function(tolua_S, "GetLocalPort", tolua_cTCPLink_GetLocalPort);
+ tolua_function(tolua_S, "GetRemoteIP", tolua_cTCPLink_GetRemoteIP);
+ tolua_function(tolua_S, "GetRemotePort", tolua_cTCPLink_GetRemotePort);
+ tolua_endmodule(tolua_S);
+}
+
+
+
+