Merge pull request #3311 from cuberite/LuaTrackedRef
This commit is contained in:
commit
0a58d1de58
@ -10,9 +10,8 @@
|
||||
|
||||
|
||||
|
||||
cLuaNameLookup::cLuaNameLookup(const AString & a_Query, cPluginLua & a_Plugin, int a_CallbacksTableStackPos):
|
||||
m_Plugin(a_Plugin),
|
||||
m_Callbacks(cPluginLua::cOperation(a_Plugin)(), a_CallbacksTableStackPos),
|
||||
cLuaNameLookup::cLuaNameLookup(const AString & a_Query, cLuaState::cTableRefPtr && a_Callbacks):
|
||||
m_Callbacks(std::move(a_Callbacks)),
|
||||
m_Query(a_Query)
|
||||
{
|
||||
}
|
||||
@ -23,20 +22,7 @@ cLuaNameLookup::cLuaNameLookup(const AString & a_Query, cPluginLua & a_Plugin, i
|
||||
|
||||
void cLuaNameLookup::OnNameResolved(const AString & a_Name, const AString & a_IP)
|
||||
{
|
||||
// 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, "OnNameResolved"), a_Name, a_IP))
|
||||
{
|
||||
LOGINFO("cNetwork name lookup OnNameResolved callback failed in plugin %s looking up %s. %s resolves to %s.",
|
||||
m_Plugin.GetName().c_str(), m_Query.c_str(), a_Name.c_str(), a_IP.c_str()
|
||||
);
|
||||
}
|
||||
m_Callbacks->CallTableFn("OnNameResolved", a_Name, a_IP);
|
||||
}
|
||||
|
||||
|
||||
@ -45,20 +31,7 @@ void cLuaNameLookup::OnNameResolved(const AString & a_Name, const AString & a_IP
|
||||
|
||||
void cLuaNameLookup::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"), m_Query, a_ErrorCode, a_ErrorMsg))
|
||||
{
|
||||
LOGINFO("cNetwork name lookup OnError callback failed in plugin %s looking up %s. The error is %d (%s)",
|
||||
m_Plugin.GetName().c_str(), m_Query.c_str(), a_ErrorCode, a_ErrorMsg.c_str()
|
||||
);
|
||||
}
|
||||
m_Callbacks->CallTableFn("OnError", m_Query, a_ErrorCode, a_ErrorMsg);
|
||||
}
|
||||
|
||||
|
||||
@ -67,20 +40,7 @@ void cLuaNameLookup::OnError(int a_ErrorCode, const AString & a_ErrorMsg)
|
||||
|
||||
void cLuaNameLookup::OnFinished(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, "OnFinished"), m_Query))
|
||||
{
|
||||
LOGINFO("cNetwork name lookup OnFinished callback failed in plugin %s, looking up %s.",
|
||||
m_Plugin.GetName().c_str(), m_Query.c_str()
|
||||
);
|
||||
}
|
||||
m_Callbacks->CallTableFn("OnFinished", m_Query);
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../OSSupport/Network.h"
|
||||
#include "PluginLua.h"
|
||||
#include "LuaState.h"
|
||||
|
||||
|
||||
|
||||
@ -21,15 +21,12 @@ class cLuaNameLookup:
|
||||
{
|
||||
public:
|
||||
/** Creates a new instance of the lookup callbacks for the specified query,
|
||||
attached to the specified lua plugin and wrapping the callbacks that are in a table at the specified stack pos. */
|
||||
cLuaNameLookup(const AString & a_Query, cPluginLua & a_Plugin, int a_CallbacksTableStackPos);
|
||||
using the callbacks that are in the specified table. */
|
||||
cLuaNameLookup(const AString & a_Query, cLuaState::cTableRefPtr && a_Callbacks);
|
||||
|
||||
protected:
|
||||
/** The plugin for which the query is created. */
|
||||
cPluginLua & m_Plugin;
|
||||
|
||||
/** The Lua table that holds the callbacks to be invoked. */
|
||||
cLuaState::cRef m_Callbacks;
|
||||
cLuaState::cTableRefPtr m_Callbacks;
|
||||
|
||||
/** The query used to start the lookup (either hostname or IP). */
|
||||
AString m_Query;
|
||||
|
@ -12,9 +12,8 @@
|
||||
|
||||
|
||||
|
||||
cLuaServerHandle::cLuaServerHandle(UInt16 a_Port, cPluginLua & a_Plugin, int a_CallbacksTableStackPos):
|
||||
m_Plugin(a_Plugin),
|
||||
m_Callbacks(cPluginLua::cOperation(a_Plugin)(), a_CallbacksTableStackPos),
|
||||
cLuaServerHandle::cLuaServerHandle(UInt16 a_Port, cLuaState::cTableRefPtr && a_Callbacks):
|
||||
m_Callbacks(std::move(a_Callbacks)),
|
||||
m_Port(a_Port)
|
||||
{
|
||||
}
|
||||
@ -127,28 +126,19 @@ void cLuaServerHandle::Release(void)
|
||||
|
||||
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;
|
||||
cLuaState::cTableRefPtr LinkCallbacks;
|
||||
if (
|
||||
!Op().Call(cLuaState::cTableRef(m_Callbacks, "OnIncomingConnection"), a_RemoteIPAddress, a_RemotePort, m_Port, cLuaState::Return, LinkCallbacks) ||
|
||||
!LinkCallbacks.IsValid()
|
||||
!m_Callbacks->CallTableFn("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()
|
||||
);
|
||||
LOGINFO("cNetwork server (port %d) OnIncomingConnection callback failed. Dropping connection.", m_Port);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create the link wrapper to use with the callbacks:
|
||||
auto res = std::make_shared<cLuaTCPLink>(m_Plugin, std::move(LinkCallbacks), m_Self);
|
||||
auto res = std::make_shared<cLuaTCPLink>(std::move(LinkCallbacks), m_Self);
|
||||
|
||||
// Add the link to the list of our connections:
|
||||
cCSLock Lock(m_CSConnections);
|
||||
@ -163,21 +153,8 @@ cTCPLink::cCallbacksPtr cLuaServerHandle::OnIncomingConnection(const AString & a
|
||||
|
||||
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;
|
||||
}
|
||||
m_Callbacks->CallTableFn("OnAccepted", static_cast<cLuaTCPLink *>(a_Link.GetCallbacks().get()));
|
||||
}
|
||||
|
||||
|
||||
@ -186,21 +163,8 @@ void cLuaServerHandle::OnAccepted(cTCPLink & a_Link)
|
||||
|
||||
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;
|
||||
}
|
||||
m_Callbacks->CallTableFn("OnError", a_ErrorCode, a_ErrorMsg);
|
||||
}
|
||||
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../OSSupport/Network.h"
|
||||
#include "PluginLua.h"
|
||||
#include "LuaState.h"
|
||||
|
||||
|
||||
|
||||
@ -31,8 +31,8 @@ class cLuaServerHandle:
|
||||
{
|
||||
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);
|
||||
wrapping the (listen-) callbacks that are in the specified table. */
|
||||
cLuaServerHandle(UInt16 a_Port, cLuaState::cTableRefPtr && a_Callbacks);
|
||||
|
||||
~cLuaServerHandle();
|
||||
|
||||
@ -54,11 +54,8 @@ public:
|
||||
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;
|
||||
cLuaState::cTableRefPtr m_Callbacks;
|
||||
|
||||
/** The port on which the server is listening.
|
||||
Used mainly for better error reporting. */
|
||||
|
@ -122,9 +122,9 @@ cLuaStateTracker & cLuaStateTracker::Get(void)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cLuaState::cCallback:
|
||||
// cLuaState::cTrackedRef:
|
||||
|
||||
cLuaState::cCallback::cCallback(void):
|
||||
cLuaState::cTrackedRef::cTrackedRef(void):
|
||||
m_CS(nullptr)
|
||||
{
|
||||
}
|
||||
@ -133,20 +133,14 @@ cLuaState::cCallback::cCallback(void):
|
||||
|
||||
|
||||
|
||||
bool cLuaState::cCallback::RefStack(cLuaState & a_LuaState, int a_StackPos)
|
||||
bool cLuaState::cTrackedRef::RefStack(cLuaState & a_LuaState, int a_StackPos)
|
||||
{
|
||||
// Check if the stack contains a function:
|
||||
if (!lua_isfunction(a_LuaState, a_StackPos))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Clear any previous callback:
|
||||
Clear();
|
||||
|
||||
// Add self to LuaState's callback-tracking:
|
||||
auto canonState = a_LuaState.QueryCanonLuaState();
|
||||
canonState->TrackCallback(*this);
|
||||
canonState->TrackRef(*this);
|
||||
|
||||
// Store the new callback:
|
||||
m_CS = &(canonState->m_CS);
|
||||
@ -158,9 +152,9 @@ bool cLuaState::cCallback::RefStack(cLuaState & a_LuaState, int a_StackPos)
|
||||
|
||||
|
||||
|
||||
void cLuaState::cCallback::Clear(void)
|
||||
void cLuaState::cTrackedRef::Clear(void)
|
||||
{
|
||||
// Free the callback reference:
|
||||
// Free the reference:
|
||||
lua_State * luaState = nullptr;
|
||||
{
|
||||
auto cs = m_CS;
|
||||
@ -175,20 +169,21 @@ void cLuaState::cCallback::Clear(void)
|
||||
m_Ref.UnRef();
|
||||
}
|
||||
}
|
||||
m_CS = nullptr;
|
||||
|
||||
// Remove from LuaState's callback-tracking:
|
||||
if (luaState == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
cLuaState(luaState).UntrackCallback(*this);
|
||||
cLuaState(luaState).UntrackRef(*this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::cCallback::IsValid(void)
|
||||
bool cLuaState::cTrackedRef::IsValid(void)
|
||||
{
|
||||
auto cs = m_CS;
|
||||
if (cs == nullptr)
|
||||
@ -203,7 +198,7 @@ bool cLuaState::cCallback::IsValid(void)
|
||||
|
||||
|
||||
|
||||
bool cLuaState::cCallback::IsSameLuaState(cLuaState & a_LuaState)
|
||||
bool cLuaState::cTrackedRef::IsSameLuaState(cLuaState & a_LuaState)
|
||||
{
|
||||
auto cs = m_CS;
|
||||
if (cs == nullptr)
|
||||
@ -227,7 +222,7 @@ bool cLuaState::cCallback::IsSameLuaState(cLuaState & a_LuaState)
|
||||
|
||||
|
||||
|
||||
void cLuaState::cCallback::Invalidate(void)
|
||||
void cLuaState::cTrackedRef::Invalidate(void)
|
||||
{
|
||||
auto cs = m_CS;
|
||||
if (cs == nullptr)
|
||||
@ -244,6 +239,43 @@ void cLuaState::cCallback::Invalidate(void)
|
||||
return;
|
||||
}
|
||||
m_Ref.UnRef();
|
||||
m_CS = nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cLuaState::cCallback:
|
||||
|
||||
bool cLuaState::cCallback::RefStack(cLuaState & a_LuaState, int a_StackPos)
|
||||
{
|
||||
// Check if the stack contains a function:
|
||||
if (!lua_isfunction(a_LuaState, a_StackPos))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Super::RefStack(a_LuaState, a_StackPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// cLuaState::cTableRef:
|
||||
|
||||
bool cLuaState::cTableRef::RefStack(cLuaState & a_LuaState, int a_StackPos)
|
||||
{
|
||||
// Check if the stack contains a table:
|
||||
if (!lua_istable(a_LuaState, a_StackPos))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return Super::RefStack(a_LuaState, a_StackPos);
|
||||
}
|
||||
|
||||
|
||||
@ -365,12 +397,12 @@ void cLuaState::Close(void)
|
||||
return;
|
||||
}
|
||||
|
||||
// Invalidate all callbacks:
|
||||
// Invalidate all tracked refs:
|
||||
{
|
||||
cCSLock Lock(m_CSTrackedCallbacks);
|
||||
for (auto & c: m_TrackedCallbacks)
|
||||
cCSLock Lock(m_CSTrackedRefs);
|
||||
for (auto & r: m_TrackedRefs)
|
||||
{
|
||||
c->Invalidate();
|
||||
r->Invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@ -592,22 +624,28 @@ bool cLuaState::PushFunction(const cRef & a_FnRef)
|
||||
|
||||
|
||||
|
||||
bool cLuaState::PushFunction(const cTableRef & a_TableRef)
|
||||
bool cLuaState::PushFunction(const cRef & a_TableRef, const char * a_FnName)
|
||||
{
|
||||
ASSERT(IsValid());
|
||||
ASSERT(m_NumCurrentFunctionArgs == -1); // If not, there's already something pushed onto the stack
|
||||
|
||||
if (!a_TableRef.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Push the error handler for lua_pcall()
|
||||
lua_pushcfunction(m_LuaState, &ReportFnCallErrors);
|
||||
|
||||
lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, a_TableRef.GetTableRef()); // Get the table ref
|
||||
// Get the function from the table:
|
||||
lua_rawgeti(m_LuaState, LUA_REGISTRYINDEX, static_cast<int>(a_TableRef));
|
||||
if (!lua_istable(m_LuaState, -1))
|
||||
{
|
||||
// Not a table, bail out
|
||||
lua_pop(m_LuaState, 2);
|
||||
return false;
|
||||
}
|
||||
lua_getfield(m_LuaState, -1, a_TableRef.GetFnName());
|
||||
lua_getfield(m_LuaState, -1, a_FnName);
|
||||
if (lua_isnil(m_LuaState, -1) || !lua_isfunction(m_LuaState, -1))
|
||||
{
|
||||
// Not a valid function, bail out
|
||||
@ -618,7 +656,7 @@ bool cLuaState::PushFunction(const cTableRef & a_TableRef)
|
||||
// Pop the table off the stack:
|
||||
lua_remove(m_LuaState, -2);
|
||||
|
||||
Printf(m_CurrentFunctionName, "<table-callback %s>", a_TableRef.GetFnName());
|
||||
Printf(m_CurrentFunctionName, "<table-callback %s>", a_FnName);
|
||||
m_NumCurrentFunctionArgs = 0;
|
||||
return true;
|
||||
}
|
||||
@ -1061,6 +1099,28 @@ bool cLuaState::GetStackValue(int a_StackPos, cCallbackSharedPtr & a_Callback)
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int a_StackPos, cTableRef & a_TableRef)
|
||||
{
|
||||
return a_TableRef.RefStack(*this, a_StackPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int a_StackPos, cTableRefPtr & a_TableRef)
|
||||
{
|
||||
if (a_TableRef == nullptr)
|
||||
{
|
||||
a_TableRef = cpp14::make_unique<cTableRef>();
|
||||
}
|
||||
return a_TableRef->RefStack(*this, a_StackPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int a_StackPos, cPluginManager::CommandResult & a_Result)
|
||||
{
|
||||
if (lua_isnumber(m_LuaState, a_StackPos))
|
||||
@ -1085,6 +1145,41 @@ bool cLuaState::GetStackValue(int a_StackPos, cRef & a_Ref)
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int a_StackPos, cTrackedRef & a_Ref)
|
||||
{
|
||||
return a_Ref.RefStack(*this, a_StackPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int a_StackPos, cTrackedRefPtr & a_Ref)
|
||||
{
|
||||
if (a_Ref == nullptr)
|
||||
{
|
||||
a_Ref = cpp14::make_unique<cTrackedRef>();
|
||||
}
|
||||
return a_Ref->RefStack(*this, a_StackPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int a_StackPos, cTrackedRefSharedPtr & a_Ref)
|
||||
{
|
||||
if (a_Ref == nullptr)
|
||||
{
|
||||
a_Ref = std::make_shared<cTrackedRef>();
|
||||
}
|
||||
return a_Ref->RefStack(*this, a_StackPos);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
bool cLuaState::GetStackValue(int a_StackPos, double & a_ReturnedVal)
|
||||
{
|
||||
if (lua_isnumber(m_LuaState, a_StackPos))
|
||||
@ -1930,7 +2025,7 @@ int cLuaState::BreakIntoDebugger(lua_State * a_LuaState)
|
||||
|
||||
|
||||
|
||||
void cLuaState::TrackCallback(cCallback & a_Callback)
|
||||
void cLuaState::TrackRef(cTrackedRef & a_Ref)
|
||||
{
|
||||
// Get the CanonLuaState global from Lua:
|
||||
auto canonState = QueryCanonLuaState();
|
||||
@ -1941,15 +2036,15 @@ void cLuaState::TrackCallback(cCallback & a_Callback)
|
||||
}
|
||||
|
||||
// Add the callback:
|
||||
cCSLock Lock(canonState->m_CSTrackedCallbacks);
|
||||
canonState->m_TrackedCallbacks.push_back(&a_Callback);
|
||||
cCSLock Lock(canonState->m_CSTrackedRefs);
|
||||
canonState->m_TrackedRefs.push_back(&a_Ref);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void cLuaState::UntrackCallback(cCallback & a_Callback)
|
||||
void cLuaState::UntrackRef(cTrackedRef & a_Ref)
|
||||
{
|
||||
// Get the CanonLuaState global from Lua:
|
||||
auto canonState = QueryCanonLuaState();
|
||||
@ -1960,12 +2055,12 @@ void cLuaState::UntrackCallback(cCallback & a_Callback)
|
||||
}
|
||||
|
||||
// Remove the callback:
|
||||
cCSLock Lock(canonState->m_CSTrackedCallbacks);
|
||||
auto & trackedCallbacks = canonState->m_TrackedCallbacks;
|
||||
trackedCallbacks.erase(std::remove_if(trackedCallbacks.begin(), trackedCallbacks.end(),
|
||||
[&a_Callback](cCallback * a_StoredCallback)
|
||||
cCSLock Lock(canonState->m_CSTrackedRefs);
|
||||
auto & trackedRefs = canonState->m_TrackedRefs;
|
||||
trackedRefs.erase(std::remove_if(trackedRefs.begin(), trackedRefs.end(),
|
||||
[&a_Ref](cTrackedRef * a_StoredRef)
|
||||
{
|
||||
return (a_StoredCallback == &a_Callback);
|
||||
return (a_StoredRef == &a_Ref);
|
||||
}
|
||||
));
|
||||
}
|
||||
|
@ -120,46 +120,84 @@ public:
|
||||
} ;
|
||||
|
||||
|
||||
/** Used for calling functions stored in a reference-stored table */
|
||||
class cTableRef
|
||||
/** Represents a reference to a Lua object that has a tracked lifetime -
|
||||
- when the Lua state to which it belongs is closed, the object is kept alive, but invalidated.
|
||||
Is thread-safe and unload-safe.
|
||||
To receive the cTrackedRef instance from the Lua side, use RefStack() or (better) cLuaState::GetStackValue().
|
||||
Note that instances of this class are tracked in the canon LuaState instance, so that
|
||||
they can be invalidated when the LuaState is unloaded; due to multithreading issues they can only be tracked
|
||||
by-ptr, which has an unfortunate effect of disabling the copy and move constructors. */
|
||||
class cTrackedRef
|
||||
{
|
||||
int m_TableRef;
|
||||
const char * m_FnName;
|
||||
friend class ::cLuaState;
|
||||
public:
|
||||
cTableRef(int a_TableRef, const char * a_FnName) :
|
||||
m_TableRef(a_TableRef),
|
||||
m_FnName(a_FnName)
|
||||
/** Creates an unbound ref instance. */
|
||||
cTrackedRef(void);
|
||||
|
||||
~cTrackedRef()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
|
||||
cTableRef(const cRef & a_TableRef, const char * a_FnName) :
|
||||
m_TableRef(static_cast<int>(a_TableRef)),
|
||||
m_FnName(a_FnName)
|
||||
{
|
||||
}
|
||||
/** Set the contained reference to the object at the specified Lua state's stack position.
|
||||
If another reference has been previously contained, it is freed first. */
|
||||
bool RefStack(cLuaState & a_LuaState, int a_StackPos);
|
||||
|
||||
int GetTableRef(void) const { return m_TableRef; }
|
||||
const char * GetFnName(void) const { return m_FnName; }
|
||||
} ;
|
||||
/** Frees the contained reference, if any. */
|
||||
void Clear(void);
|
||||
|
||||
/** Returns true if the contained reference is valid. */
|
||||
bool IsValid(void);
|
||||
|
||||
/** Returns true if the reference resides in the specified Lua state.
|
||||
Internally, compares the reference's canon Lua state. */
|
||||
bool IsSameLuaState(cLuaState & a_LuaState);
|
||||
|
||||
protected:
|
||||
friend class cLuaState;
|
||||
|
||||
/** The mutex protecting m_Ref against multithreaded access */
|
||||
cCriticalSection * m_CS;
|
||||
|
||||
/** Reference to the Lua callback */
|
||||
cRef m_Ref;
|
||||
|
||||
|
||||
/** Represents a callback to Lua that C++ code can call.
|
||||
/** Invalidates the callback, without untracking it from the cLuaState.
|
||||
Called only from cLuaState when closing the Lua state. */
|
||||
void Invalidate(void);
|
||||
|
||||
/** Returns the internal reference.
|
||||
Only to be used when the cLuaState's CS is held and the cLuaState is known to be valid. */
|
||||
cRef & GetRef() { return m_Ref; }
|
||||
|
||||
/** This class cannot be copied, because it is tracked in the LuaState by-ptr.
|
||||
Use a smart pointer for a copyable object. */
|
||||
cTrackedRef(const cTrackedRef &) = delete;
|
||||
|
||||
/** This class cannot be moved, because it is tracked in the LuaState by-ptr.
|
||||
Use a smart pointer for a copyable object. */
|
||||
cTrackedRef(cTrackedRef &&) = delete;
|
||||
};
|
||||
typedef UniquePtr<cTrackedRef> cTrackedRefPtr;
|
||||
typedef SharedPtr<cTrackedRef> cTrackedRefSharedPtr;
|
||||
|
||||
|
||||
/** Represents a stored callback to Lua that C++ code can call.
|
||||
Is thread-safe and unload-safe.
|
||||
When the Lua state is unloaded, the callback returns an error instead of calling into non-existent code.
|
||||
To receive the callback instance from the Lua side, use RefStack() or (better) cLuaState::GetStackValue()
|
||||
with a cCallbackPtr. Note that instances of this class are tracked in the canon LuaState instance, so that
|
||||
they can be invalidated when the LuaState is unloaded; due to multithreading issues they can only be tracked
|
||||
by-ptr, which has an unfortunate effect of disabling the copy and move constructors. */
|
||||
class cCallback
|
||||
class cCallback:
|
||||
public cTrackedRef
|
||||
{
|
||||
public:
|
||||
/** Creates an unbound callback instance. */
|
||||
cCallback(void);
|
||||
typedef cTrackedRef Super;
|
||||
|
||||
~cCallback()
|
||||
{
|
||||
Clear();
|
||||
}
|
||||
public:
|
||||
|
||||
cCallback(void) {}
|
||||
|
||||
/** Calls the Lua callback, if still available.
|
||||
Returns true if callback has been called.
|
||||
@ -181,32 +219,11 @@ public:
|
||||
}
|
||||
|
||||
/** Set the contained callback to the function in the specified Lua state's stack position.
|
||||
If a callback has been previously contained, it is freed first. */
|
||||
If a callback has been previously contained, it is unreferenced first.
|
||||
Returns true on success, false on failure (not a function at the specified stack pos). */
|
||||
bool RefStack(cLuaState & a_LuaState, int a_StackPos);
|
||||
|
||||
/** Frees the contained callback, if any. */
|
||||
void Clear(void);
|
||||
|
||||
/** Returns true if the contained callback is valid. */
|
||||
bool IsValid(void);
|
||||
|
||||
/** Returns true if the callback resides in the specified Lua state.
|
||||
Internally, compares the callback's canon Lua state. */
|
||||
bool IsSameLuaState(cLuaState & a_LuaState);
|
||||
|
||||
protected:
|
||||
friend class cLuaState;
|
||||
|
||||
/** The mutex protecting m_Ref against multithreaded access */
|
||||
cCriticalSection * m_CS;
|
||||
|
||||
/** Reference to the Lua callback */
|
||||
cRef m_Ref;
|
||||
|
||||
|
||||
/** Invalidates the callback, without untracking it from the cLuaState.
|
||||
Called only from cLuaState when closing the Lua state. */
|
||||
void Invalidate(void);
|
||||
|
||||
/** This class cannot be copied, because it is tracked in the LuaState by-ptr.
|
||||
Use cCallbackPtr for a copyable object. */
|
||||
@ -220,6 +237,47 @@ public:
|
||||
typedef SharedPtr<cCallback> cCallbackSharedPtr;
|
||||
|
||||
|
||||
/** Represents a stored Lua table with callback functions that C++ code can call.
|
||||
Is thread-safe and unload-safe.
|
||||
When Lua state is unloaded, the CallFn() will return failure instead of calling into non-existent code.
|
||||
To receive the callback instance from the Lua side, use RefStack() or (better) cLuaState::GetStackValue()
|
||||
with a cCallbackPtr. Note that instances of this class are tracked in the canon LuaState instance, so that
|
||||
they can be invalidated when the LuaState is unloaded; due to multithreading issues they can only be tracked
|
||||
by-ptr, which has an unfortunate effect of disabling the copy and move constructors. */
|
||||
class cTableRef:
|
||||
public cTrackedRef
|
||||
{
|
||||
typedef cTrackedRef Super;
|
||||
public:
|
||||
cTableRef(void) {}
|
||||
|
||||
/** Calls the Lua function stored under the specified name in the referenced table, if still available.
|
||||
Returns true if callback has been called.
|
||||
Returns false if the Lua state isn't valid anymore, or the function doesn't exist. */
|
||||
template <typename... Args>
|
||||
bool CallTableFn(const char * a_FnName, Args &&... args)
|
||||
{
|
||||
auto cs = m_CS;
|
||||
if (cs == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
cCSLock Lock(*cs);
|
||||
if (!m_Ref.IsValid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return cLuaState(m_Ref.GetLuaState()).CallTableFn(m_Ref, a_FnName, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/** Set the contained reference to the table in the specified Lua state's stack position.
|
||||
If another table has been previously contained, it is unreferenced first.
|
||||
Returns true on success, false on failure (not a table at the specified stack pos). */
|
||||
bool RefStack(cLuaState & a_LuaState, int a_StackPos);
|
||||
};
|
||||
typedef UniquePtr<cTableRef> cTableRefPtr;
|
||||
|
||||
|
||||
/** A dummy class that's used only to delimit function args from return values for cLuaState::Call() */
|
||||
class cRet
|
||||
{
|
||||
@ -381,8 +439,13 @@ public:
|
||||
bool GetStackValue(int a_StackPos, cCallback & a_Callback);
|
||||
bool GetStackValue(int a_StackPos, cCallbackPtr & a_Callback);
|
||||
bool GetStackValue(int a_StackPos, cCallbackSharedPtr & a_Callback);
|
||||
bool GetStackValue(int a_StackPos, cTableRef & a_TableRef);
|
||||
bool GetStackValue(int a_StackPos, cTableRefPtr & a_TableRef);
|
||||
bool GetStackValue(int a_StackPos, cPluginManager::CommandResult & a_Result);
|
||||
bool GetStackValue(int a_StackPos, cRef & a_Ref);
|
||||
bool GetStackValue(int a_StackPos, cTrackedRef & a_Ref);
|
||||
bool GetStackValue(int a_StackPos, cTrackedRefPtr & a_Ref);
|
||||
bool GetStackValue(int a_StackPos, cTrackedRefSharedPtr & a_Ref);
|
||||
bool GetStackValue(int a_StackPos, double & a_Value);
|
||||
bool GetStackValue(int a_StackPos, eBlockFace & a_Value);
|
||||
bool GetStackValue(int a_StackPos, eWeather & a_Value);
|
||||
@ -583,15 +646,30 @@ protected:
|
||||
/** Number of arguments currently pushed (for the Push / Call chain) */
|
||||
int m_NumCurrentFunctionArgs;
|
||||
|
||||
/** The tracked callbacks.
|
||||
This object will invalidate all of these when it is about to be closed.
|
||||
Protected against multithreaded access by m_CSTrackedCallbacks. */
|
||||
std::vector<cCallback *> m_TrackedCallbacks;
|
||||
/** The tracked references.
|
||||
The cLuaState will invalidate all of these when it is about to be closed.
|
||||
Protected against multithreaded access by m_CSTrackedRefs. */
|
||||
std::vector<cTrackedRef *> m_TrackedRefs;
|
||||
|
||||
/** Protects m_TrackedTallbacks against multithreaded access. */
|
||||
cCriticalSection m_CSTrackedCallbacks;
|
||||
/** Protects m_TrackedRefs against multithreaded access. */
|
||||
cCriticalSection m_CSTrackedRefs;
|
||||
|
||||
|
||||
/** Call the Lua function specified by name in the table stored as a reference.
|
||||
Returns true if call succeeded, false if there was an error (not a table ref, function name not found).
|
||||
A special param of cRet & signifies the end of param list and the start of return values.
|
||||
Example call: CallTableFn(TableRef, "FnName", Param1, Param2, Param3, cLuaState::Return, Ret1, Ret2) */
|
||||
template <typename... Args>
|
||||
bool CallTableFn(const cRef & a_TableRef, const char * a_FnName, Args &&... args)
|
||||
{
|
||||
if (!PushFunction(a_TableRef, a_FnName))
|
||||
{
|
||||
// Pushing the function failed
|
||||
return false;
|
||||
}
|
||||
return PushCallPop(std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
/** Variadic template terminator: If there's nothing more to push / pop, just call the function.
|
||||
Note that there are no return values either, because those are prefixed by a cRet value, so the arg list is never empty. */
|
||||
bool PushCallPop(void)
|
||||
@ -646,10 +724,9 @@ protected:
|
||||
*/
|
||||
bool PushFunction(const cRef & a_FnRef);
|
||||
|
||||
/** Pushes a function that is stored in a referenced table by name
|
||||
Returns true if successful. Logs a warning on failure
|
||||
*/
|
||||
bool PushFunction(const cTableRef & a_TableRef);
|
||||
/** Pushes a function that is stored under the specified name in a table that has been saved as a reference.
|
||||
Returns true if successful. */
|
||||
bool PushFunction(const cRef & a_TableRef, const char * a_FnName);
|
||||
|
||||
/** Pushes a usertype of the specified class type onto the stack */
|
||||
// void PushUserType(void * a_Object, const char * a_Type);
|
||||
@ -667,13 +744,13 @@ protected:
|
||||
/** Tries to break into the MobDebug debugger, if it is installed. */
|
||||
static int BreakIntoDebugger(lua_State * a_LuaState);
|
||||
|
||||
/** Adds the specified callback to tracking.
|
||||
The callback will be invalidated when this Lua state is about to be closed. */
|
||||
void TrackCallback(cCallback & a_Callback);
|
||||
/** Adds the specified reference to tracking.
|
||||
The reference will be invalidated when this Lua state is about to be closed. */
|
||||
void TrackRef(cTrackedRef & a_Ref);
|
||||
|
||||
/** Removes the specified callback from tracking.
|
||||
The callback will no longer be invalidated when this Lua state is about to be closed. */
|
||||
void UntrackCallback(cCallback & a_Callback);
|
||||
/** Removes the specified reference from tracking.
|
||||
The reference will no longer be invalidated when this Lua state is about to be closed. */
|
||||
void UntrackRef(cTrackedRef & a_Ref);
|
||||
} ;
|
||||
|
||||
|
||||
|
@ -11,35 +11,19 @@
|
||||
|
||||
|
||||
|
||||
cLuaTCPLink::cLuaTCPLink(cPluginLua & a_Plugin, int a_CallbacksTableStackPos):
|
||||
m_Plugin(a_Plugin),
|
||||
m_Callbacks(cPluginLua::cOperation(a_Plugin)(), a_CallbacksTableStackPos)
|
||||
cLuaTCPLink::cLuaTCPLink(cLuaState::cTableRefPtr && a_Callbacks):
|
||||
m_Callbacks(std::move(a_Callbacks))
|
||||
{
|
||||
// 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)),
|
||||
cLuaTCPLink::cLuaTCPLink(cLuaState::cTableRefPtr && a_Callbacks, cLuaServerHandleWPtr a_ServerHandle):
|
||||
m_Callbacks(std::move(a_Callbacks)),
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -49,10 +33,10 @@ cLuaTCPLink::cLuaTCPLink(cPluginLua & a_Plugin, cLuaState::cRef && a_CallbacksTa
|
||||
cLuaTCPLink::~cLuaTCPLink()
|
||||
{
|
||||
// If the link is still open, close it:
|
||||
cTCPLinkPtr Link = m_Link;
|
||||
if (Link != nullptr)
|
||||
auto link = m_Link;
|
||||
if (link != nullptr)
|
||||
{
|
||||
Link->Close();
|
||||
link->Close();
|
||||
}
|
||||
|
||||
Terminated();
|
||||
@ -72,14 +56,14 @@ bool cLuaTCPLink::Send(const AString & a_Data)
|
||||
}
|
||||
|
||||
// Safely grab a copy of the link:
|
||||
cTCPLinkPtr Link = m_Link;
|
||||
if (Link == nullptr)
|
||||
auto link = m_Link;
|
||||
if (link == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the data:
|
||||
return Link->Send(a_Data);
|
||||
return link->Send(a_Data);
|
||||
}
|
||||
|
||||
|
||||
@ -89,14 +73,14 @@ bool cLuaTCPLink::Send(const AString & a_Data)
|
||||
AString cLuaTCPLink::GetLocalIP(void) const
|
||||
{
|
||||
// Safely grab a copy of the link:
|
||||
cTCPLinkPtr Link = m_Link;
|
||||
if (Link == nullptr)
|
||||
auto link = m_Link;
|
||||
if (link == nullptr)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get the IP address:
|
||||
return Link->GetLocalIP();
|
||||
return link->GetLocalIP();
|
||||
}
|
||||
|
||||
|
||||
@ -106,14 +90,14 @@ AString cLuaTCPLink::GetLocalIP(void) const
|
||||
UInt16 cLuaTCPLink::GetLocalPort(void) const
|
||||
{
|
||||
// Safely grab a copy of the link:
|
||||
cTCPLinkPtr Link = m_Link;
|
||||
if (Link == nullptr)
|
||||
auto link = m_Link;
|
||||
if (link == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the port:
|
||||
return Link->GetLocalPort();
|
||||
return link->GetLocalPort();
|
||||
}
|
||||
|
||||
|
||||
@ -123,14 +107,14 @@ UInt16 cLuaTCPLink::GetLocalPort(void) const
|
||||
AString cLuaTCPLink::GetRemoteIP(void) const
|
||||
{
|
||||
// Safely grab a copy of the link:
|
||||
cTCPLinkPtr Link = m_Link;
|
||||
if (Link == nullptr)
|
||||
cTCPLinkPtr link = m_Link;
|
||||
if (link == nullptr)
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
// Get the IP address:
|
||||
return Link->GetRemoteIP();
|
||||
return link->GetRemoteIP();
|
||||
}
|
||||
|
||||
|
||||
@ -140,14 +124,14 @@ AString cLuaTCPLink::GetRemoteIP(void) const
|
||||
UInt16 cLuaTCPLink::GetRemotePort(void) const
|
||||
{
|
||||
// Safely grab a copy of the link:
|
||||
cTCPLinkPtr Link = m_Link;
|
||||
if (Link == nullptr)
|
||||
cTCPLinkPtr link = m_Link;
|
||||
if (link == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the port:
|
||||
return Link->GetRemotePort();
|
||||
return link->GetRemotePort();
|
||||
}
|
||||
|
||||
|
||||
@ -157,8 +141,8 @@ UInt16 cLuaTCPLink::GetRemotePort(void) const
|
||||
void cLuaTCPLink::Shutdown(void)
|
||||
{
|
||||
// Safely grab a copy of the link and shut it down:
|
||||
cTCPLinkPtr Link = m_Link;
|
||||
if (Link != nullptr)
|
||||
cTCPLinkPtr link = m_Link;
|
||||
if (link != nullptr)
|
||||
{
|
||||
if (m_SslContext != nullptr)
|
||||
{
|
||||
@ -166,7 +150,7 @@ void cLuaTCPLink::Shutdown(void)
|
||||
m_SslContext->ResetSelf();
|
||||
m_SslContext.reset();
|
||||
}
|
||||
Link->Shutdown();
|
||||
link->Shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,8 +161,8 @@ void cLuaTCPLink::Shutdown(void)
|
||||
void cLuaTCPLink::Close(void)
|
||||
{
|
||||
// If the link is still open, close it:
|
||||
cTCPLinkPtr Link = m_Link;
|
||||
if (Link != nullptr)
|
||||
cTCPLinkPtr link = m_Link;
|
||||
if (link != nullptr)
|
||||
{
|
||||
if (m_SslContext != nullptr)
|
||||
{
|
||||
@ -186,7 +170,7 @@ void cLuaTCPLink::Close(void)
|
||||
m_SslContext->ResetSelf();
|
||||
m_SslContext.reset();
|
||||
}
|
||||
Link->Close();
|
||||
link->Close();
|
||||
}
|
||||
|
||||
Terminated();
|
||||
@ -303,9 +287,9 @@ AString cLuaTCPLink::StartTLSServer(
|
||||
void cLuaTCPLink::Terminated(void)
|
||||
{
|
||||
// Disable the callbacks:
|
||||
if (m_Callbacks.IsValid())
|
||||
if (m_Callbacks->IsValid())
|
||||
{
|
||||
m_Callbacks.UnRef();
|
||||
m_Callbacks->Clear();
|
||||
}
|
||||
|
||||
// If the managing server is still alive, let it know we're terminating:
|
||||
@ -317,10 +301,10 @@ void cLuaTCPLink::Terminated(void)
|
||||
|
||||
// If the link is still open, close it:
|
||||
{
|
||||
cTCPLinkPtr Link = m_Link;
|
||||
if (Link != nullptr)
|
||||
auto link= m_Link;
|
||||
if (link != nullptr)
|
||||
{
|
||||
Link->Close();
|
||||
link->Close();
|
||||
m_Link.reset();
|
||||
}
|
||||
}
|
||||
@ -335,18 +319,8 @@ void cLuaTCPLink::Terminated(void)
|
||||
|
||||
void cLuaTCPLink::ReceivedCleartextData(const char * a_Data, size_t a_NumBytes)
|
||||
{
|
||||
// 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_NumBytes)))
|
||||
{
|
||||
LOGINFO("cTCPLink OnReceivedData callback failed in plugin %s.", m_Plugin.GetName().c_str());
|
||||
}
|
||||
m_Callbacks->CallTableFn("OnReceivedData", this, AString(a_Data, a_NumBytes));
|
||||
}
|
||||
|
||||
|
||||
@ -355,18 +329,8 @@ void cLuaTCPLink::ReceivedCleartextData(const char * a_Data, size_t a_NumBytes)
|
||||
|
||||
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());
|
||||
}
|
||||
m_Callbacks->CallTableFn("OnConnected", this);
|
||||
}
|
||||
|
||||
|
||||
@ -375,21 +339,10 @@ void cLuaTCPLink::OnConnected(cTCPLink & a_Link)
|
||||
|
||||
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()
|
||||
);
|
||||
}
|
||||
m_Callbacks->CallTableFn("OnError", this, a_ErrorCode, a_ErrorMsg);
|
||||
|
||||
// Terminate all processing on the link:
|
||||
Terminated();
|
||||
}
|
||||
|
||||
@ -409,12 +362,6 @@ void cLuaTCPLink::OnLinkCreated(cTCPLinkPtr a_Link)
|
||||
|
||||
void cLuaTCPLink::OnReceivedData(const char * a_Data, size_t a_Length)
|
||||
{
|
||||
// Check if we're still valid:
|
||||
if (!m_Callbacks.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're running in SSL mode, put the data into the SSL decryptor:
|
||||
auto sslContext = m_SslContext;
|
||||
if (sslContext != nullptr)
|
||||
@ -424,11 +371,7 @@ void cLuaTCPLink::OnReceivedData(const char * a_Data, size_t a_Length)
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
m_Callbacks->CallTableFn("OnReceivedData", this, AString(a_Data, a_Length));
|
||||
}
|
||||
|
||||
|
||||
@ -437,12 +380,6 @@ void cLuaTCPLink::OnReceivedData(const char * a_Data, size_t a_Length)
|
||||
|
||||
void cLuaTCPLink::OnRemoteClosed(void)
|
||||
{
|
||||
// Check if we're still valid:
|
||||
if (!m_Callbacks.IsValid())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If running in SSL mode and there's data left in the SSL contect, report it:
|
||||
auto sslContext = m_SslContext;
|
||||
if (sslContext != nullptr)
|
||||
@ -451,12 +388,9 @@ void cLuaTCPLink::OnRemoteClosed(void)
|
||||
}
|
||||
|
||||
// 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_Callbacks->CallTableFn("OnRemoteClosed", this);
|
||||
|
||||
// Terminate all processing on the link:
|
||||
Terminated();
|
||||
}
|
||||
|
||||
|
@ -10,8 +10,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "../OSSupport/Network.h"
|
||||
#include "PluginLua.h"
|
||||
#include "../PolarSSL++/SslContext.h"
|
||||
#include "LuaState.h"
|
||||
|
||||
|
||||
|
||||
@ -30,11 +30,11 @@ class cLuaTCPLink:
|
||||
public cTCPLink::cCallbacks
|
||||
{
|
||||
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, wrapping the callbacks that are in the specified table. */
|
||||
cLuaTCPLink(cLuaState::cTableRefPtr && a_Callbacks);
|
||||
|
||||
/** 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(cLuaState::cTableRefPtr && a_Callbacks, cLuaServerHandleWPtr a_Server);
|
||||
|
||||
~cLuaTCPLink();
|
||||
|
||||
@ -139,11 +139,8 @@ 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;
|
||||
cLuaState::cTableRefPtr m_Callbacks;
|
||||
|
||||
/** The underlying link representing the connection.
|
||||
May be nullptr. */
|
||||
|
@ -10,17 +10,9 @@
|
||||
|
||||
|
||||
|
||||
cLuaUDPEndpoint::cLuaUDPEndpoint(cPluginLua & a_Plugin, int a_CallbacksTableStackPos):
|
||||
m_Plugin(a_Plugin),
|
||||
m_Callbacks(cPluginLua::cOperation(a_Plugin)(), a_CallbacksTableStackPos)
|
||||
cLuaUDPEndpoint::cLuaUDPEndpoint(cLuaState::cTableRefPtr && a_Callbacks):
|
||||
m_Callbacks(std::move(a_Callbacks))
|
||||
{
|
||||
// Warn if the callbacks aren't valid:
|
||||
if (!m_Callbacks.IsValid())
|
||||
{
|
||||
LOGWARNING("cLuaUDPEndpoint in plugin %s: callbacks could not be retrieved", m_Plugin.GetName().c_str());
|
||||
cPluginLua::cOperation Op(m_Plugin);
|
||||
Op().LogStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -30,10 +22,10 @@ cLuaUDPEndpoint::cLuaUDPEndpoint(cPluginLua & a_Plugin, int a_CallbacksTableStac
|
||||
cLuaUDPEndpoint::~cLuaUDPEndpoint()
|
||||
{
|
||||
// If the endpoint is still open, close it:
|
||||
cUDPEndpointPtr Endpoint = m_Endpoint;
|
||||
if (Endpoint != nullptr)
|
||||
auto endpoint = m_Endpoint;
|
||||
if (endpoint != nullptr)
|
||||
{
|
||||
Endpoint->Close();
|
||||
endpoint->Close();
|
||||
}
|
||||
|
||||
Terminated();
|
||||
@ -60,14 +52,14 @@ bool cLuaUDPEndpoint::Open(UInt16 a_Port, cLuaUDPEndpointPtr a_Self)
|
||||
bool cLuaUDPEndpoint::Send(const AString & a_Data, const AString & a_RemotePeer, UInt16 a_RemotePort)
|
||||
{
|
||||
// Safely grab a copy of the endpoint:
|
||||
cUDPEndpointPtr Endpoint = m_Endpoint;
|
||||
if (Endpoint == nullptr)
|
||||
auto endpoint = m_Endpoint;
|
||||
if (endpoint == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send the data:
|
||||
return Endpoint->Send(a_Data, a_RemotePeer, a_RemotePort);
|
||||
return endpoint->Send(a_Data, a_RemotePeer, a_RemotePort);
|
||||
}
|
||||
|
||||
|
||||
@ -77,14 +69,14 @@ bool cLuaUDPEndpoint::Send(const AString & a_Data, const AString & a_RemotePeer,
|
||||
UInt16 cLuaUDPEndpoint::GetPort(void) const
|
||||
{
|
||||
// Safely grab a copy of the endpoint:
|
||||
cUDPEndpointPtr Endpoint = m_Endpoint;
|
||||
if (Endpoint == nullptr)
|
||||
auto endpoint = m_Endpoint;
|
||||
if (endpoint == nullptr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the port:
|
||||
return Endpoint->GetPort();
|
||||
return endpoint->GetPort();
|
||||
}
|
||||
|
||||
|
||||
@ -94,15 +86,15 @@ UInt16 cLuaUDPEndpoint::GetPort(void) const
|
||||
bool cLuaUDPEndpoint::IsOpen(void) const
|
||||
{
|
||||
// Safely grab a copy of the endpoint:
|
||||
cUDPEndpointPtr Endpoint = m_Endpoint;
|
||||
if (Endpoint == nullptr)
|
||||
auto endpoint = m_Endpoint;
|
||||
if (endpoint == nullptr)
|
||||
{
|
||||
// No endpoint means that we're not open
|
||||
return false;
|
||||
}
|
||||
|
||||
// Get the state:
|
||||
return Endpoint->IsOpen();
|
||||
return endpoint->IsOpen();
|
||||
}
|
||||
|
||||
|
||||
@ -112,10 +104,10 @@ bool cLuaUDPEndpoint::IsOpen(void) const
|
||||
void cLuaUDPEndpoint::Close(void)
|
||||
{
|
||||
// If the endpoint is still open, close it:
|
||||
cUDPEndpointPtr Endpoint = m_Endpoint;
|
||||
if (Endpoint != nullptr)
|
||||
auto endpoint = m_Endpoint;
|
||||
if (endpoint != nullptr)
|
||||
{
|
||||
Endpoint->Close();
|
||||
endpoint->Close();
|
||||
m_Endpoint.reset();
|
||||
}
|
||||
|
||||
@ -129,10 +121,10 @@ void cLuaUDPEndpoint::Close(void)
|
||||
void cLuaUDPEndpoint::EnableBroadcasts(void)
|
||||
{
|
||||
// Safely grab a copy of the endpoint:
|
||||
cUDPEndpointPtr Endpoint = m_Endpoint;
|
||||
if (Endpoint != nullptr)
|
||||
auto endpoint = m_Endpoint;
|
||||
if (endpoint != nullptr)
|
||||
{
|
||||
Endpoint->EnableBroadcasts();
|
||||
endpoint->EnableBroadcasts();
|
||||
}
|
||||
}
|
||||
|
||||
@ -156,17 +148,14 @@ void cLuaUDPEndpoint::Release(void)
|
||||
void cLuaUDPEndpoint::Terminated(void)
|
||||
{
|
||||
// Disable the callbacks:
|
||||
if (m_Callbacks.IsValid())
|
||||
{
|
||||
m_Callbacks.UnRef();
|
||||
}
|
||||
m_Callbacks.reset();
|
||||
|
||||
// If the endpoint is still open, close it:
|
||||
{
|
||||
cUDPEndpointPtr Endpoint = m_Endpoint;
|
||||
if (Endpoint != nullptr)
|
||||
auto endpoint = m_Endpoint;
|
||||
if (endpoint != nullptr)
|
||||
{
|
||||
Endpoint->Close();
|
||||
endpoint->Close();
|
||||
m_Endpoint.reset();
|
||||
}
|
||||
}
|
||||
@ -178,18 +167,7 @@ void cLuaUDPEndpoint::Terminated(void)
|
||||
|
||||
void cLuaUDPEndpoint::OnReceivedData(const char * a_Data, size_t a_NumBytes, const AString & a_RemotePeer, UInt16 a_RemotePort)
|
||||
{
|
||||
// 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_NumBytes), a_RemotePeer, a_RemotePort))
|
||||
{
|
||||
LOGINFO("cUDPEndpoint OnReceivedData callback failed in plugin %s.", m_Plugin.GetName().c_str());
|
||||
}
|
||||
m_Callbacks->CallTableFn("OnReceivedData", this, AString(a_Data, a_NumBytes), a_RemotePeer, a_RemotePort);
|
||||
}
|
||||
|
||||
|
||||
@ -198,21 +176,10 @@ void cLuaUDPEndpoint::OnReceivedData(const char * a_Data, size_t a_NumBytes, con
|
||||
|
||||
void cLuaUDPEndpoint::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"), a_ErrorCode, a_ErrorMsg))
|
||||
{
|
||||
LOGINFO("cUDPEndpoint OnError() callback failed in plugin %s; the endpoint error is %d (%s).",
|
||||
m_Plugin.GetName().c_str(), a_ErrorCode, a_ErrorMsg.c_str()
|
||||
);
|
||||
}
|
||||
// Notify the plugin:
|
||||
m_Callbacks->CallTableFn("OnError", a_ErrorCode, a_ErrorMsg);
|
||||
|
||||
// Terminate all processing on the endpoint:
|
||||
Terminated();
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "../OSSupport/Network.h"
|
||||
#include "PluginLua.h"
|
||||
#include "LuaState.h"
|
||||
|
||||
|
||||
|
||||
@ -28,8 +28,8 @@ class cLuaUDPEndpoint:
|
||||
public cUDPEndpoint::cCallbacks
|
||||
{
|
||||
public:
|
||||
/** Creates a new instance of the endpoint, attached to the specified plugin and wrapping the callbacks that are in a table at the specified stack pos. */
|
||||
cLuaUDPEndpoint(cPluginLua & a_Plugin, int a_CallbacksTableStackPos);
|
||||
/** Creates a new instance of the endpoint, wrapping the callbacks that are in the specified table. */
|
||||
cLuaUDPEndpoint(cLuaState::cTableRefPtr && a_Callbacks);
|
||||
|
||||
~cLuaUDPEndpoint();
|
||||
|
||||
@ -58,11 +58,8 @@ public:
|
||||
void Release(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;
|
||||
cLuaState::cTableRefPtr m_Callbacks;
|
||||
|
||||
/** SharedPtr to self, so that the object can keep itself alive for as long as it needs (for Lua). */
|
||||
cLuaUDPEndpointPtr m_Self;
|
||||
|
@ -2647,17 +2647,16 @@ class cLuaBlockTracerCallbacks :
|
||||
public cBlockTracer::cCallbacks
|
||||
{
|
||||
public:
|
||||
cLuaBlockTracerCallbacks(cLuaState & a_LuaState, int a_ParamNum) :
|
||||
m_LuaState(a_LuaState),
|
||||
m_TableRef(a_LuaState, a_ParamNum)
|
||||
cLuaBlockTracerCallbacks(cLuaState::cTableRefPtr && a_Callbacks):
|
||||
m_Callbacks(std::move(a_Callbacks))
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool OnNextBlock(int a_BlockX, int a_BlockY, int a_BlockZ, BLOCKTYPE a_BlockType, NIBBLETYPE a_BlockMeta, char a_EntryFace) override
|
||||
{
|
||||
bool res = false;
|
||||
if (!m_LuaState.Call(
|
||||
cLuaState::cTableRef(m_TableRef, "OnNextBlock"),
|
||||
if (!m_Callbacks->CallTableFn(
|
||||
"OnNextBlock",
|
||||
a_BlockX, a_BlockY, a_BlockZ, a_BlockType, a_BlockMeta, a_EntryFace,
|
||||
cLuaState::Return, res
|
||||
))
|
||||
@ -2671,8 +2670,8 @@ public:
|
||||
virtual bool OnNextBlockNoData(int a_BlockX, int a_BlockY, int a_BlockZ, char a_EntryFace) override
|
||||
{
|
||||
bool res = false;
|
||||
if (!m_LuaState.Call(
|
||||
cLuaState::cTableRef(m_TableRef, "OnNextBlockNoData"),
|
||||
if (!m_Callbacks->CallTableFn(
|
||||
"OnNextBlockNoData",
|
||||
a_BlockX, a_BlockY, a_BlockZ, a_EntryFace,
|
||||
cLuaState::Return, res
|
||||
))
|
||||
@ -2686,8 +2685,8 @@ public:
|
||||
virtual bool OnOutOfWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override
|
||||
{
|
||||
bool res = false;
|
||||
if (!m_LuaState.Call(
|
||||
cLuaState::cTableRef(m_TableRef, "OnOutOfWorld"),
|
||||
if (!m_Callbacks->CallTableFn(
|
||||
"OnOutOfWorld",
|
||||
a_BlockX, a_BlockY, a_BlockZ,
|
||||
cLuaState::Return, res
|
||||
))
|
||||
@ -2701,8 +2700,8 @@ public:
|
||||
virtual bool OnIntoWorld(double a_BlockX, double a_BlockY, double a_BlockZ) override
|
||||
{
|
||||
bool res = false;
|
||||
if (!m_LuaState.Call(
|
||||
cLuaState::cTableRef(m_TableRef, "OnIntoWorld"),
|
||||
if (!m_Callbacks->CallTableFn(
|
||||
"OnIntoWorld",
|
||||
a_BlockX, a_BlockY, a_BlockZ,
|
||||
cLuaState::Return, res
|
||||
))
|
||||
@ -2715,17 +2714,16 @@ public:
|
||||
|
||||
virtual void OnNoMoreHits(void) override
|
||||
{
|
||||
m_LuaState.Call(cLuaState::cTableRef(m_TableRef, "OnNoMoreHits"));
|
||||
m_Callbacks->CallTableFn("OnNoMoreHits");
|
||||
}
|
||||
|
||||
virtual void OnNoChunk(void) override
|
||||
{
|
||||
m_LuaState.Call(cLuaState::cTableRef(m_TableRef, "OnNoChunk"));
|
||||
m_Callbacks->CallTableFn("OnNoChunk");
|
||||
}
|
||||
|
||||
protected:
|
||||
cLuaState & m_LuaState;
|
||||
cLuaState::cRef m_TableRef;
|
||||
cLuaState::cTableRefPtr m_Callbacks;
|
||||
} ;
|
||||
|
||||
|
||||
@ -2759,16 +2757,22 @@ static int tolua_cLineBlockTracer_Trace(lua_State * tolua_S)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the params:
|
||||
cWorld * world;
|
||||
double startX, startY, startZ;
|
||||
double endX, endY, endZ;
|
||||
cLuaState::cTableRefPtr callbacks;
|
||||
if (!L.GetStackValues(idx, world, callbacks, startX, startY, startZ, endX, endY, endZ))
|
||||
{
|
||||
LOGWARNING("cLineBlockTracer:Trace(): Cannot read parameters (starting at idx %d), aborting the trace.", idx);
|
||||
L.LogStackTrace();
|
||||
L.LogStackValues("Values on the stack");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Trace:
|
||||
cWorld * World = reinterpret_cast<cWorld *>(tolua_tousertype(L, idx, nullptr));
|
||||
cLuaBlockTracerCallbacks Callbacks(L, idx + 1);
|
||||
double StartX = tolua_tonumber(L, idx + 2, 0);
|
||||
double StartY = tolua_tonumber(L, idx + 3, 0);
|
||||
double StartZ = tolua_tonumber(L, idx + 4, 0);
|
||||
double EndX = tolua_tonumber(L, idx + 5, 0);
|
||||
double EndY = tolua_tonumber(L, idx + 6, 0);
|
||||
double EndZ = tolua_tonumber(L, idx + 7, 0);
|
||||
bool res = cLineBlockTracer::Trace(*World, Callbacks, StartX, StartY, StartZ, EndX, EndY, EndZ);
|
||||
cLuaBlockTracerCallbacks tracerCallbacks(std::move(callbacks));
|
||||
bool res = cLineBlockTracer::Trace(*world, tracerCallbacks, startX, startY, startZ, endX, endY, endZ);
|
||||
tolua_pushboolean(L, res ? 1 : 0);
|
||||
return 1;
|
||||
}
|
||||
|
@ -38,33 +38,34 @@ static int tolua_cNetwork_Connect(lua_State * L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the plugin instance:
|
||||
cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
|
||||
if (Plugin == nullptr)
|
||||
// Read the params:
|
||||
AString host;
|
||||
int port = 0;
|
||||
cLuaState::cTableRefPtr callbacks;
|
||||
if (!S.GetStackValues(2, host, port, callbacks))
|
||||
{
|
||||
// An error message has been already printed in GetLuaPlugin()
|
||||
LOGWARNING("cNetwork::Connect() cannot read its parameters, failing the request.");
|
||||
S.LogStackTrace();
|
||||
S.LogStackValues("Values on the stack");
|
||||
S.Push(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read the params:
|
||||
AString Host;
|
||||
int Port = 0;
|
||||
S.GetStackValues(2, Host, Port);
|
||||
|
||||
// Check validity:
|
||||
if ((Port < 0) || (Port > 65535))
|
||||
if ((port < 0) || (port > 65535))
|
||||
{
|
||||
LOGWARNING("cNetwork:Connect() called with invalid port (%d), failing the request.", Port);
|
||||
LOGWARNING("cNetwork:Connect() called with invalid port (%d), failing the request.", port);
|
||||
S.LogStackTrace();
|
||||
S.Push(false);
|
||||
return 1;
|
||||
}
|
||||
ASSERT(callbacks != nullptr); // Invalid callbacks would have resulted in GetStackValues() returning false
|
||||
|
||||
// Create the LuaTCPLink glue class:
|
||||
auto Link = std::make_shared<cLuaTCPLink>(*Plugin, 4);
|
||||
auto link = std::make_shared<cLuaTCPLink>(std::move(callbacks));
|
||||
|
||||
// Try to connect:
|
||||
bool res = cNetwork::Connect(Host, static_cast<UInt16>(Port), Link, Link);
|
||||
bool res = cNetwork::Connect(host, static_cast<UInt16>(port), link, link);
|
||||
S.Push(res);
|
||||
|
||||
return 1;
|
||||
@ -91,36 +92,38 @@ static int tolua_cNetwork_CreateUDPEndpoint(lua_State * L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the plugin instance:
|
||||
cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
|
||||
if (Plugin == nullptr)
|
||||
// Read the params:
|
||||
UInt16 port;
|
||||
cLuaState::cTableRefPtr callbacks;
|
||||
if (!S.GetStackValues(2, port, callbacks))
|
||||
{
|
||||
// An error message has been already printed in GetLuaPlugin()
|
||||
LOGWARNING("cNetwork:CreateUDPEndpoint() cannot read its parameters, failing the request.");
|
||||
S.LogStackTrace();
|
||||
S.LogStackValues("Values on the stack");
|
||||
S.Push(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read the params:
|
||||
UInt16 Port;
|
||||
|
||||
// Check validity:
|
||||
if (!S.GetStackValues(2, Port))
|
||||
if ((port < 0) || (port > 65535))
|
||||
{
|
||||
LOGWARNING("cNetwork:CreateUDPEndpoint() called with invalid port, failing the request.");
|
||||
LOGWARNING("cNetwork:CreateUDPEndpoint() called with invalid port (%d), failing the request.", port);
|
||||
S.LogStackTrace();
|
||||
S.Push(false);
|
||||
return 1;
|
||||
}
|
||||
ASSERT(callbacks != nullptr); // Invalid callbacks would have resulted in GetStackValues() returning false
|
||||
|
||||
// Create the LuaUDPEndpoint glue class:
|
||||
auto Endpoint = std::make_shared<cLuaUDPEndpoint>(*Plugin, 3);
|
||||
Endpoint->Open(Port, Endpoint);
|
||||
auto endpoint = std::make_shared<cLuaUDPEndpoint>(std::move(callbacks));
|
||||
endpoint->Open(port, endpoint);
|
||||
|
||||
// Register the endpoint to be garbage-collected by Lua:
|
||||
tolua_pushusertype(L, Endpoint.get(), "cUDPEndpoint");
|
||||
tolua_pushusertype(L, endpoint.get(), "cUDPEndpoint");
|
||||
tolua_register_gc(L, lua_gettop(L));
|
||||
|
||||
// Return the endpoint object:
|
||||
S.Push(Endpoint.get());
|
||||
S.Push(endpoint.get());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -169,21 +172,21 @@ static int tolua_cNetwork_HostnameToIP(lua_State * L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the plugin instance:
|
||||
cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
|
||||
if (Plugin == nullptr)
|
||||
// Read the params:
|
||||
AString host;
|
||||
cLuaState::cTableRefPtr callbacks;
|
||||
if (!S.GetStackValues(2, host, callbacks))
|
||||
{
|
||||
// An error message has been already printed in GetLuaPlugin()
|
||||
LOGWARNING("cNetwork::HostnameToIP() cannot read its parameters, failing the request.");
|
||||
S.LogStackTrace();
|
||||
S.LogStackValues("Values on the stack");
|
||||
S.Push(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read the params:
|
||||
AString Host;
|
||||
S.GetStackValue(2, Host);
|
||||
ASSERT(callbacks != nullptr); // Invalid callbacks would have resulted in GetStackValues() returning false
|
||||
|
||||
// Try to look up:
|
||||
bool res = cNetwork::HostnameToIP(Host, std::make_shared<cLuaNameLookup>(Host, *Plugin, 3));
|
||||
bool res = cNetwork::HostnameToIP(host, std::make_shared<cLuaNameLookup>(host, std::move(callbacks)));
|
||||
S.Push(res);
|
||||
|
||||
return 1;
|
||||
@ -210,21 +213,21 @@ static int tolua_cNetwork_IPToHostname(lua_State * L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the plugin instance:
|
||||
cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
|
||||
if (Plugin == nullptr)
|
||||
// Read the params:
|
||||
AString ip;
|
||||
cLuaState::cTableRefPtr callbacks;
|
||||
if (!S.GetStackValues(2, ip, callbacks))
|
||||
{
|
||||
// An error message has been already printed in GetLuaPlugin()
|
||||
LOGWARNING("cNetwork::IPToHostname() cannot read its parameters, failing the request.");
|
||||
S.LogStackTrace();
|
||||
S.LogStackValues("Values on the stack");
|
||||
S.Push(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read the params:
|
||||
AString Host;
|
||||
S.GetStackValue(2, Host);
|
||||
ASSERT(callbacks != nullptr); // Invalid callbacks would have resulted in GetStackValues() returning false
|
||||
|
||||
// Try to look up:
|
||||
bool res = cNetwork::IPToHostName(Host, std::make_shared<cLuaNameLookup>(Host, *Plugin, 3));
|
||||
bool res = cNetwork::IPToHostName(ip, std::make_shared<cLuaNameLookup>(ip, std::move(callbacks)));
|
||||
S.Push(res);
|
||||
|
||||
return 1;
|
||||
@ -251,38 +254,40 @@ static int tolua_cNetwork_Listen(lua_State * L)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the plugin instance:
|
||||
cPluginLua * Plugin = cManualBindings::GetLuaPlugin(L);
|
||||
if (Plugin == nullptr)
|
||||
// Read the params:
|
||||
int port = 0;
|
||||
cLuaState::cTableRefPtr callbacks;
|
||||
if (!S.GetStackValues(2, port, callbacks))
|
||||
{
|
||||
// An error message has been already printed in GetLuaPlugin()
|
||||
LOGWARNING("cNetwork::Listen() cannot read its parameters, failing the request.");
|
||||
S.LogStackTrace();
|
||||
S.LogStackValues("Values on the stack");
|
||||
S.Push(false);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Read the params:
|
||||
int Port = 0;
|
||||
S.GetStackValues(2, Port);
|
||||
if ((Port < 0) || (Port > 65535))
|
||||
// Check the validity:
|
||||
if ((port < 0) || (port > 65535))
|
||||
{
|
||||
LOGWARNING("cNetwork:Listen() called with invalid port (%d), failing the request.", Port);
|
||||
LOGWARNING("cNetwork:Listen() called with invalid port (%d), failing the request.", port);
|
||||
S.LogStackTrace();
|
||||
S.Push(false);
|
||||
return 1;
|
||||
}
|
||||
UInt16 Port16 = static_cast<UInt16>(Port);
|
||||
auto port16 = static_cast<UInt16>(port);
|
||||
|
||||
// Create the LuaTCPLink glue class:
|
||||
auto Srv = std::make_shared<cLuaServerHandle>(Port16, *Plugin, 3);
|
||||
auto srv = std::make_shared<cLuaServerHandle>(port16, std::move(callbacks));
|
||||
|
||||
// Listen:
|
||||
Srv->SetServerHandle(cNetwork::Listen(Port16, Srv), Srv);
|
||||
srv->SetServerHandle(cNetwork::Listen(port16, srv), srv);
|
||||
|
||||
// Register the server to be garbage-collected by Lua:
|
||||
tolua_pushusertype(L, Srv.get(), "cServerHandle");
|
||||
tolua_pushusertype(L, srv.get(), "cServerHandle");
|
||||
tolua_register_gc(L, lua_gettop(L));
|
||||
|
||||
// Return the server handle wrapper:
|
||||
S.Push(Srv.get());
|
||||
S.Push(srv.get());
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -103,7 +103,13 @@ bool cNetwork::IPToHostName(
|
||||
{
|
||||
auto res = std::make_shared<cIPLookup>(a_Callbacks);
|
||||
cNetworkSingleton::Get().AddIPLookup(res);
|
||||
return res->Lookup(a_IP);
|
||||
if (!res->Lookup(a_IP))
|
||||
{
|
||||
// Lookup failed early on, remove the object completely:
|
||||
cNetworkSingleton::Get().RemoveIPLookup(res.get());
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user