Exported cServerHandle and cNetwork:Listen to Lua.
Also added an example to the NetworkTest plugin.
This commit is contained in:
parent
17498a97a2
commit
014b96adb3
@ -37,6 +37,32 @@ g_PluginInfo =
|
||||
}, -- ParameterCombinations
|
||||
}, -- client
|
||||
|
||||
close =
|
||||
{
|
||||
HelpString = "Close a listening socket",
|
||||
Handler = HandleConsoleNetClose,
|
||||
ParameterCombinations =
|
||||
{
|
||||
{
|
||||
Params = "[Port]",
|
||||
Help = "Closes a socket listening on the specified port [1024]",
|
||||
},
|
||||
}, -- ParameterCombinations
|
||||
}, -- close
|
||||
|
||||
listen =
|
||||
{
|
||||
HelpString = "Creates a new listening socket on the specified port with the specified service attached to it",
|
||||
Handler = HandleConsoleNetListen,
|
||||
ParameterCombinations =
|
||||
{
|
||||
{
|
||||
Params = "[Port] [Service]",
|
||||
Help = "Starts listening on the specified port [1024] providing the specified service [echo]",
|
||||
},
|
||||
}, -- ParameterCombinations
|
||||
}, -- listen
|
||||
|
||||
lookup =
|
||||
{
|
||||
HelpString = "Looks up the IP addresses corresponding to the given hostname (google.com by default)",
|
||||
@ -57,6 +83,7 @@ g_PluginInfo =
|
||||
},
|
||||
},
|
||||
}, -- lookup
|
||||
|
||||
}, -- Subcommands
|
||||
}, -- net
|
||||
},
|
||||
|
@ -7,11 +7,109 @@
|
||||
|
||||
|
||||
|
||||
function Initialize()
|
||||
--- Map of all servers currently open
|
||||
-- g_Servers[PortNum] = cServerHandle
|
||||
local g_Servers = {}
|
||||
|
||||
--- List of fortune messages for the fortune server
|
||||
-- A random message is chosen for each incoming connection
|
||||
-- The contents are loaded from the splashes.txt file on plugin startup
|
||||
local g_Fortunes =
|
||||
{
|
||||
"Empty splashes.txt",
|
||||
}
|
||||
|
||||
--- Map of all services that can be run as servers
|
||||
-- g_Services[ServiceName] = function() -> callbacks
|
||||
local g_Services =
|
||||
{
|
||||
-- Echo service: each connection echoes back what has been sent to it
|
||||
echo = function (a_Port)
|
||||
return
|
||||
{
|
||||
-- A new connection has come, give it new link callbacks:
|
||||
OnIncomingConnection = function (a_RemoteIP, a_RemotePort)
|
||||
return
|
||||
{
|
||||
OnError = function (a_Link, a_ErrorCode, a_ErrorMsg)
|
||||
LOG("EchoServer(" .. a_Port .. ": Connection to " .. a_Link:GetRemoteIP() .. ":" .. a_Link:GetRemotePort() .. " failed: " .. a_ErrorCode .. " (" .. a_ErrorMsg .. ")")
|
||||
end,
|
||||
|
||||
OnReceivedData = function (a_Link, a_Data)
|
||||
-- Echo the received data back to the link:
|
||||
a_Link:Send(a_Data)
|
||||
end,
|
||||
|
||||
OnRemoteClosed = function (a_Link)
|
||||
end
|
||||
} -- Link callbacks
|
||||
end, -- OnIncomingConnection()
|
||||
|
||||
-- Send a welcome message to newly accepted connections:
|
||||
OnAccepted = function (a_Link)
|
||||
a_Link:Send("Hello, " .. a_Link:GetRemoteIP() .. ", welcome to the echo server @ MCServer-Lua\r\n")
|
||||
end, -- OnAccepted()
|
||||
|
||||
-- There was an error listening on the port:
|
||||
OnError = function (a_ErrorCode, a_ErrorMsg)
|
||||
LOGINFO("EchoServer(" .. a_Port .. ": Cannot listen: " .. a_ErrorCode .. " (" .. a_ErrorMsg .. ")")
|
||||
end, -- OnError()
|
||||
} -- Listen callbacks
|
||||
end, -- echo
|
||||
|
||||
fortune = function (a_Port)
|
||||
return
|
||||
{
|
||||
-- A new connection has come, give it new link callbacks:
|
||||
OnIncomingConnection = function (a_RemoteIP, a_RemotePort)
|
||||
return
|
||||
{
|
||||
OnError = function (a_Link, a_ErrorCode, a_ErrorMsg)
|
||||
LOG("FortuneServer(" .. a_Port .. ": Connection to " .. a_Link:GetRemoteIP() .. ":" .. a_Link:GetRemotePort() .. " failed: " .. a_ErrorCode .. " (" .. a_ErrorMsg .. ")")
|
||||
end,
|
||||
|
||||
OnReceivedData = function (a_Link, a_Data)
|
||||
-- Ignore any received data
|
||||
end,
|
||||
|
||||
OnRemoteClosed = function (a_Link)
|
||||
end
|
||||
} -- Link callbacks
|
||||
end, -- OnIncomingConnection()
|
||||
|
||||
-- Send a welcome message to newly accepted connections:
|
||||
OnAccepted = function (a_Link)
|
||||
a_Link:Send("Hello, " .. a_Link:GetRemoteIP() .. ", welcome to the fortune server @ MCServer-Lua\r\n\r\nYour fortune:\r\n")
|
||||
a_Link:Send(g_Fortunes[math.random(#g_Fortunes)] .. "\r\n")
|
||||
end, -- OnAccepted()
|
||||
|
||||
-- There was an error listening on the port:
|
||||
OnError = function (a_ErrorCode, a_ErrorMsg)
|
||||
LOGINFO("FortuneServer(" .. a_Port .. ": Cannot listen: " .. a_ErrorCode .. " (" .. a_ErrorMsg .. ")")
|
||||
end, -- OnError()
|
||||
} -- Listen callbacks
|
||||
end, -- fortune
|
||||
|
||||
-- TODO: Other services (fortune, daytime, ...)
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function Initialize(a_Plugin)
|
||||
-- Load the splashes.txt file into g_Fortunes:
|
||||
for line in io.lines(a_Plugin:GetLocalFolder() .. "/splashes.txt") do
|
||||
table.insert(g_Fortunes, line)
|
||||
end
|
||||
|
||||
-- Use the InfoReg shared library to process the Info.lua file:
|
||||
dofile(cPluginManager:GetPluginsPath() .. "/InfoReg.lua")
|
||||
RegisterPluginInfoCommands()
|
||||
RegisterPluginInfoConsoleCommands()
|
||||
|
||||
-- Seed the random generator:
|
||||
math.randomseed(os.time())
|
||||
|
||||
return true
|
||||
end
|
||||
@ -62,6 +160,26 @@ end
|
||||
|
||||
|
||||
|
||||
function HandleConsoleNetClose(a_Split)
|
||||
-- Get the port to close:
|
||||
local Port = tonumber(a_Split[3] or 1024)
|
||||
if not(Port) then
|
||||
return true, "Bad port number: \"" .. Port .. "\"."
|
||||
end
|
||||
|
||||
-- Close the server, if there is one:
|
||||
if not(g_Servers[Port]) then
|
||||
return true, "There is no server currently listening on port " .. Port .. "."
|
||||
end
|
||||
g_Servers[Port]:Close()
|
||||
g_Servers[Port] = nil
|
||||
return true, "Port " .. Port .. " closed."
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleConsoleNetLookup(a_Split)
|
||||
-- Get the name to look up:
|
||||
local Addr = a_Split[3] or "google.com"
|
||||
@ -103,3 +221,31 @@ end
|
||||
|
||||
|
||||
|
||||
|
||||
function HandleConsoleNetListen(a_Split)
|
||||
-- Get the params:
|
||||
local Port = tonumber(a_Split[3] or 1024)
|
||||
if not(Port) then
|
||||
return true, "Invalid port: \"" .. Port .. "\"."
|
||||
end
|
||||
local Service = string.lower(a_Split[4] or "echo")
|
||||
|
||||
-- Create the callbacks specific for the service:
|
||||
if (g_Services[Service] == nil) then
|
||||
return true, "No such service: " .. Service
|
||||
end
|
||||
local Callbacks = g_Services[Service](Port)
|
||||
|
||||
-- Start the server:
|
||||
local srv = cNetwork:Listen(Port, Callbacks)
|
||||
if not(srv:IsListening()) then
|
||||
-- The error message has already been printed in the Callbacks.OnError()
|
||||
return true
|
||||
end
|
||||
g_Servers[Port] = srv
|
||||
return true, Service .. " server started on port " .. Port
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
357
MCServer/Plugins/NetworkTest/splashes.txt
Normal file
357
MCServer/Plugins/NetworkTest/splashes.txt
Normal file
@ -0,0 +1,357 @@
|
||||
As seen on TV!
|
||||
Awesome!
|
||||
100% pure!
|
||||
May contain nuts!
|
||||
Better than Prey!
|
||||
More polygons!
|
||||
Sexy!
|
||||
Limited edition!
|
||||
Flashing letters!
|
||||
Made by Notch!
|
||||
It's here!
|
||||
Best in class!
|
||||
It's finished!
|
||||
Kind of dragon free!
|
||||
Excitement!
|
||||
More than 500 sold!
|
||||
One of a kind!
|
||||
Heaps of hits on YouTube!
|
||||
Indev!
|
||||
Spiders everywhere!
|
||||
Check it out!
|
||||
Holy cow, man!
|
||||
It's a game!
|
||||
Made in Sweden!
|
||||
Uses LWJGL!
|
||||
Reticulating splines!
|
||||
Minecraft!
|
||||
Yaaay!
|
||||
Singleplayer!
|
||||
Keyboard compatible!
|
||||
Undocumented!
|
||||
Ingots!
|
||||
Exploding creepers!
|
||||
That's no moon!
|
||||
l33t!
|
||||
Create!
|
||||
Survive!
|
||||
Dungeon!
|
||||
Exclusive!
|
||||
The bee's knees!
|
||||
Down with O.P.P.!
|
||||
Closed source!
|
||||
Classy!
|
||||
Wow!
|
||||
Not on steam!
|
||||
Oh man!
|
||||
Awesome community!
|
||||
Pixels!
|
||||
Teetsuuuuoooo!
|
||||
Kaaneeeedaaaa!
|
||||
Now with difficulty!
|
||||
Enhanced!
|
||||
90% bug free!
|
||||
Pretty!
|
||||
12 herbs and spices!
|
||||
Fat free!
|
||||
Absolutely no memes!
|
||||
Free dental!
|
||||
Ask your doctor!
|
||||
Minors welcome!
|
||||
Cloud computing!
|
||||
Legal in Finland!
|
||||
Hard to label!
|
||||
Technically good!
|
||||
Bringing home the bacon!
|
||||
Indie!
|
||||
GOTY!
|
||||
Ceci n'est pas une title screen!
|
||||
Euclidian!
|
||||
Now in 3D!
|
||||
Inspirational!
|
||||
Herregud!
|
||||
Complex cellular automata!
|
||||
Yes, sir!
|
||||
Played by cowboys!
|
||||
OpenGL 2.1 (if supported)!
|
||||
Thousands of colors!
|
||||
Try it!
|
||||
Age of Wonders is better!
|
||||
Try the mushroom stew!
|
||||
Sensational!
|
||||
Hot tamale, hot hot tamale!
|
||||
Play him off, keyboard cat!
|
||||
Guaranteed!
|
||||
Macroscopic!
|
||||
Bring it on!
|
||||
Random splash!
|
||||
Call your mother!
|
||||
Monster infighting!
|
||||
Loved by millions!
|
||||
Ultimate edition!
|
||||
Freaky!
|
||||
You've got a brand new key!
|
||||
Water proof!
|
||||
Uninflammable!
|
||||
Whoa, dude!
|
||||
All inclusive!
|
||||
Tell your friends!
|
||||
NP is not in P!
|
||||
Notch <3 ez!
|
||||
Music by C418!
|
||||
Livestreamed!
|
||||
Haunted!
|
||||
Polynomial!
|
||||
Terrestrial!
|
||||
All is full of love!
|
||||
Full of stars!
|
||||
Scientific!
|
||||
Cooler than Spock!
|
||||
Collaborate and listen!
|
||||
Never dig down!
|
||||
Take frequent breaks!
|
||||
Not linear!
|
||||
Han shot first!
|
||||
Nice to meet you!
|
||||
Buckets of lava!
|
||||
Ride the pig!
|
||||
Larger than Earth!
|
||||
sqrt(-1) love you!
|
||||
Phobos anomaly!
|
||||
Punching wood!
|
||||
Falling off cliffs!
|
||||
0% sugar!
|
||||
150% hyperbole!
|
||||
Synecdoche!
|
||||
Let's danec!
|
||||
Seecret Friday update!
|
||||
Reference implementation!
|
||||
Lewd with two dudes with food!
|
||||
Kiss the sky!
|
||||
20 GOTO 10!
|
||||
Verlet intregration!
|
||||
Peter Griffin!
|
||||
Do not distribute!
|
||||
Cogito ergo sum!
|
||||
4815162342 lines of code!
|
||||
A skeleton popped out!
|
||||
The Work of Notch!
|
||||
The sum of its parts!
|
||||
BTAF used to be good!
|
||||
I miss ADOM!
|
||||
umop-apisdn!
|
||||
OICU812!
|
||||
Bring me Ray Cokes!
|
||||
Finger-licking!
|
||||
Thematic!
|
||||
Pneumatic!
|
||||
Sublime!
|
||||
Octagonal!
|
||||
Une baguette!
|
||||
Gargamel plays it!
|
||||
Rita is the new top dog!
|
||||
SWM forever!
|
||||
Representing Edsbyn!
|
||||
Matt Damon!
|
||||
Supercalifragilisticexpialidocious!
|
||||
Consummate V's!
|
||||
Cow Tools!
|
||||
Double buffered!
|
||||
Fan fiction!
|
||||
Flaxkikare!
|
||||
Jason! Jason! Jason!
|
||||
Hotter than the sun!
|
||||
Internet enabled!
|
||||
Autonomous!
|
||||
Engage!
|
||||
Fantasy!
|
||||
DRR! DRR! DRR!
|
||||
Kick it root down!
|
||||
Regional resources!
|
||||
Woo, facepunch!
|
||||
Woo, somethingawful!
|
||||
Woo, /v/!
|
||||
Woo, tigsource!
|
||||
Woo, minecraftforum!
|
||||
Woo, worldofminecraft!
|
||||
Woo, reddit!
|
||||
Woo, 2pp!
|
||||
Google anlyticsed!
|
||||
Now supports åäö!
|
||||
Give us Gordon!
|
||||
Tip your waiter!
|
||||
Very fun!
|
||||
12345 is a bad password!
|
||||
Vote for net neutrality!
|
||||
Lives in a pineapple under the sea!
|
||||
MAP11 has two names!
|
||||
Omnipotent!
|
||||
Gasp!
|
||||
...!
|
||||
Bees, bees, bees, bees!
|
||||
Jag känner en bot!
|
||||
This text is hard to read if you play the game at the default resolution, but at 1080p it's fine!
|
||||
Haha, LOL!
|
||||
Hampsterdance!
|
||||
Switches and ores!
|
||||
Menger sponge!
|
||||
idspispopd!
|
||||
Eple (original edit)!
|
||||
So fresh, so clean!
|
||||
Slow acting portals!
|
||||
Try the Nether!
|
||||
Don't look directly at the bugs!
|
||||
Oh, ok, Pigmen!
|
||||
Finally with ladders!
|
||||
Scary!
|
||||
Play Minecraft, Watch Topgear, Get Pig!
|
||||
Twittered about!
|
||||
Jump up, jump up, and get down!
|
||||
Joel is neat!
|
||||
A riddle, wrapped in a mystery!
|
||||
Huge tracts of land!
|
||||
Welcome to your Doom!
|
||||
Stay a while, stay forever!
|
||||
Stay a while and listen!
|
||||
Treatment for your rash!
|
||||
"Autological" is!
|
||||
Information wants to be free!
|
||||
"Almost never" is an interesting concept!
|
||||
Lots of truthiness!
|
||||
The creeper is a spy!
|
||||
Turing complete!
|
||||
It's groundbreaking!
|
||||
Let our battle's begin!
|
||||
The sky is the limit!
|
||||
Jeb has amazing hair!
|
||||
Ryan also has amazing hair!
|
||||
Casual gaming!
|
||||
Undefeated!
|
||||
Kinda like Lemmings!
|
||||
Follow the train, CJ!
|
||||
Leveraging synergy!
|
||||
This message will never appear on the splash screen, isn't that weird?
|
||||
DungeonQuest is unfair!
|
||||
110813!
|
||||
90210!
|
||||
Check out the far lands!
|
||||
Tyrion would love it!
|
||||
Also try VVVVVV!
|
||||
Also try Super Meat Boy!
|
||||
Also try Terraria!
|
||||
Also try Mount And Blade!
|
||||
Also try Project Zomboid!
|
||||
Also try World of Goo!
|
||||
Also try Limbo!
|
||||
Also try Pixeljunk Shooter!
|
||||
Also try Braid!
|
||||
That's super!
|
||||
Bread is pain!
|
||||
Read more books!
|
||||
Khaaaaaaaaan!
|
||||
Less addictive than TV Tropes!
|
||||
More addictive than lemonade!
|
||||
Bigger than a bread box!
|
||||
Millions of peaches!
|
||||
Fnord!
|
||||
This is my true form!
|
||||
Totally forgot about Dre!
|
||||
Don't bother with the clones!
|
||||
Pumpkinhead!
|
||||
Hobo humping slobo babe!
|
||||
Made by Jeb!
|
||||
Has an ending!
|
||||
Finally complete!
|
||||
Feature packed!
|
||||
Boots with the fur!
|
||||
Stop, hammertime!
|
||||
Testificates!
|
||||
Conventional!
|
||||
Homeomorphic to a 3-sphere!
|
||||
Doesn't avoid double negatives!
|
||||
Place ALL the blocks!
|
||||
Does barrel rolls!
|
||||
Meeting expectations!
|
||||
PC gaming since 1873!
|
||||
Ghoughpteighbteau tchoghs!
|
||||
Déjà vu!
|
||||
Déjà vu!
|
||||
Got your nose!
|
||||
Haley loves Elan!
|
||||
Afraid of the big, black bat!
|
||||
Doesn't use the U-word!
|
||||
Child's play!
|
||||
See you next Friday or so!
|
||||
From the streets of Södermalm!
|
||||
150 bpm for 400000 minutes!
|
||||
Technologic!
|
||||
Funk soul brother!
|
||||
Pumpa kungen!
|
||||
日本ハロー!
|
||||
한국 안녕하세요!
|
||||
Helo Cymru!
|
||||
Cześć Polsko!
|
||||
你好中国!
|
||||
Привет Россия!
|
||||
Γεια σου Ελλάδα!
|
||||
My life for Aiur!
|
||||
Lennart lennart = new Lennart();
|
||||
I see your vocabulary has improved!
|
||||
Who put it there?
|
||||
You can't explain that!
|
||||
if not ok then return end
|
||||
§1C§2o§3l§4o§5r§6m§7a§8t§9i§ac
|
||||
§kFUNKY LOL
|
||||
SOPA means LOSER in Swedish!
|
||||
Big Pointy Teeth!
|
||||
Bekarton guards the gate!
|
||||
Mmmph, mmph!
|
||||
Don't feed avocados to parrots!
|
||||
Swords for everyone!
|
||||
Plz reply to my tweet!
|
||||
.party()!
|
||||
Take her pillow!
|
||||
Put that cookie down!
|
||||
Pretty scary!
|
||||
I have a suggestion.
|
||||
Now with extra hugs!
|
||||
Now Java 6!
|
||||
Woah.
|
||||
HURNERJSGER?
|
||||
What's up, Doc?
|
||||
Now contains 32 random daily cats!
|
||||
That's Numberwang!
|
||||
pls rt
|
||||
Do you want to join my server?
|
||||
Put a little fence around it!
|
||||
Throw a blanket over it!
|
||||
One day, somewhere in the future, my work will be quoted!
|
||||
Now with additional stuff!
|
||||
Extra things!
|
||||
Yay, puppies for everyone!
|
||||
So sweet, like a nice bon bon!
|
||||
Popping tags!
|
||||
Very influential in its circle!
|
||||
Now With Multiplayer!
|
||||
Rise from your grave!
|
||||
Warning! A huge battleship "STEVE" is approaching fast!
|
||||
Blue warrior shot the food!
|
||||
Run, coward! I hunger!
|
||||
Flavor with no seasoning!
|
||||
Strange, but not a stranger!
|
||||
Tougher than diamonds, rich like cream!
|
||||
Getting ready to show!
|
||||
Getting ready to know!
|
||||
Getting ready to drop!
|
||||
Getting ready to shock!
|
||||
Getting ready to freak!
|
||||
Getting ready to speak!
|
||||
It swings, it jives!
|
||||
Cruising streets for gold!
|
||||
Take an eggbeater and beat it against a skillet!
|
||||
Make me a table, a funky table!
|
||||
Take the elevator to the mezzanine!
|
||||
Stop being reasonable, this is the Internet!
|
||||
/give @a hugs 64
|
||||
This is good for Realms.
|
||||
Any computer is a laptop if you're brave enough!
|
@ -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
|
||||
|
@ -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. */
|
||||
|
213
src/Bindings/LuaServerHandle.cpp
Normal file
213
src/Bindings/LuaServerHandle.cpp
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
89
src/Bindings/LuaServerHandle.h
Normal file
89
src/Bindings/LuaServerHandle.h
Normal file
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
// Close the link:
|
||||
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);
|
||||
}
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
@ -325,6 +389,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:
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -381,6 +381,7 @@ void inline LOG(const char * a_Format, ...)
|
||||
|
||||
// Unified shared ptr from before C++11. Also no silly undercores.
|
||||
#define SharedPtr std::shared_ptr
|
||||
#define WeakPtr std::weak_ptr
|
||||
|
||||
|
||||
|
||||
|
@ -90,6 +90,9 @@ public:
|
||||
Sends the RST packet, queued outgoing and incoming data is lost. */
|
||||
virtual void Close(void) = 0;
|
||||
|
||||
/** Returns the callbacks that are used. */
|
||||
cCallbacksPtr GetCallbacks(void) const { return m_Callbacks; }
|
||||
|
||||
protected:
|
||||
/** Callbacks to be used for the various situations. */
|
||||
cCallbacksPtr m_Callbacks;
|
||||
|
@ -119,6 +119,7 @@ void DoTest(void)
|
||||
LOG("Server terminating.");
|
||||
Server->Close();
|
||||
ASSERT(!Server->IsListening());
|
||||
Server.reset();
|
||||
LOGD("Server has been closed.");
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user