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
|
}, -- ParameterCombinations
|
||||||
}, -- client
|
}, -- 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 =
|
lookup =
|
||||||
{
|
{
|
||||||
HelpString = "Looks up the IP addresses corresponding to the given hostname (google.com by default)",
|
HelpString = "Looks up the IP addresses corresponding to the given hostname (google.com by default)",
|
||||||
@ -57,6 +83,7 @@ g_PluginInfo =
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, -- lookup
|
}, -- lookup
|
||||||
|
|
||||||
}, -- Subcommands
|
}, -- Subcommands
|
||||||
}, -- net
|
}, -- net
|
||||||
},
|
},
|
||||||
|
@ -7,12 +7,110 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
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:
|
-- Use the InfoReg shared library to process the Info.lua file:
|
||||||
dofile(cPluginManager:GetPluginsPath() .. "/InfoReg.lua")
|
dofile(cPluginManager:GetPluginsPath() .. "/InfoReg.lua")
|
||||||
RegisterPluginInfoCommands()
|
RegisterPluginInfoCommands()
|
||||||
RegisterPluginInfoConsoleCommands()
|
RegisterPluginInfoConsoleCommands()
|
||||||
|
|
||||||
|
-- Seed the random generator:
|
||||||
|
math.randomseed(os.time())
|
||||||
|
|
||||||
return true
|
return true
|
||||||
end
|
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)
|
function HandleConsoleNetLookup(a_Split)
|
||||||
-- Get the name to look up:
|
-- Get the name to look up:
|
||||||
local Addr = a_Split[3] or "google.com"
|
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
|
DeprecatedBindings.cpp
|
||||||
LuaChunkStay.cpp
|
LuaChunkStay.cpp
|
||||||
LuaNameLookup.cpp
|
LuaNameLookup.cpp
|
||||||
|
LuaServerHandle.cpp
|
||||||
LuaState.cpp
|
LuaState.cpp
|
||||||
LuaTCPLink.cpp
|
LuaTCPLink.cpp
|
||||||
LuaWindow.cpp
|
LuaWindow.cpp
|
||||||
@ -27,6 +28,7 @@ SET (HDRS
|
|||||||
LuaChunkStay.h
|
LuaChunkStay.h
|
||||||
LuaFunctions.h
|
LuaFunctions.h
|
||||||
LuaNameLookup.h
|
LuaNameLookup.h
|
||||||
|
LuaServerHandle.h
|
||||||
LuaState.h
|
LuaState.h
|
||||||
LuaTCPLink.h
|
LuaTCPLink.h
|
||||||
LuaWindow.h
|
LuaWindow.h
|
||||||
|
@ -25,7 +25,7 @@ public:
|
|||||||
cLuaNameLookup(const AString & a_Query, cPluginLua & a_Plugin, int a_CallbacksTableStackPos);
|
cLuaNameLookup(const AString & a_Query, cPluginLua & a_Plugin, int a_CallbacksTableStackPos);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** The plugin for which the link is created. */
|
/** The plugin for which the query is created. */
|
||||||
cPluginLua & m_Plugin;
|
cPluginLua & m_Plugin;
|
||||||
|
|
||||||
/** The Lua table that holds the callbacks to be invoked. */
|
/** 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)
|
void cLuaState::Push(cLuaTCPLink * a_TCPLink)
|
||||||
{
|
{
|
||||||
ASSERT(IsValid());
|
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)
|
bool cLuaState::CallFunction(int a_NumResults)
|
||||||
{
|
{
|
||||||
ASSERT (m_NumCurrentFunctionArgs >= 0); // A function must be pushed to stack first
|
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()
|
cLuaState::cRef::~cRef()
|
||||||
{
|
{
|
||||||
if (m_LuaState != nullptr)
|
if (m_LuaState != nullptr)
|
||||||
|
@ -60,6 +60,7 @@ class cHopperEntity;
|
|||||||
class cBlockEntity;
|
class cBlockEntity;
|
||||||
class cBoundingBox;
|
class cBoundingBox;
|
||||||
class cLuaTCPLink;
|
class cLuaTCPLink;
|
||||||
|
class cLuaServerHandle;
|
||||||
|
|
||||||
typedef cBoundingBox * pBoundingBox;
|
typedef cBoundingBox * pBoundingBox;
|
||||||
typedef cWorld * pWorld;
|
typedef cWorld * pWorld;
|
||||||
@ -85,6 +86,10 @@ public:
|
|||||||
/** Creates a reference in the specified LuaState for object at the specified StackPos */
|
/** Creates a reference in the specified LuaState for object at the specified StackPos */
|
||||||
cRef(cLuaState & a_LuaState, int a_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();
|
~cRef();
|
||||||
|
|
||||||
/** Creates a reference to Lua object at the specified stack pos, binds this object to it.
|
/** Creates a reference to Lua object at the specified stack pos, binds this object to it.
|
||||||
@ -203,6 +208,7 @@ public:
|
|||||||
void Push(cHopperEntity * a_Hopper);
|
void Push(cHopperEntity * a_Hopper);
|
||||||
void Push(cItem * a_Item);
|
void Push(cItem * a_Item);
|
||||||
void Push(cItems * a_Items);
|
void Push(cItems * a_Items);
|
||||||
|
void Push(cLuaServerHandle * a_ServerHandle);
|
||||||
void Push(cLuaTCPLink * a_TCPLink);
|
void Push(cLuaTCPLink * a_TCPLink);
|
||||||
void Push(cMonster * a_Monster);
|
void Push(cMonster * a_Monster);
|
||||||
void Push(cPickup * a_Pickup);
|
void Push(cPickup * a_Pickup);
|
||||||
@ -243,6 +249,9 @@ public:
|
|||||||
/** Retrieve value at a_StackPos, if it is a valid cWorld class. If not, a_Value is unchanged */
|
/** 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);
|
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.
|
/** Call the specified Lua function.
|
||||||
Returns true if call succeeded, false if there was an error.
|
Returns true if call succeeded, false if there was an error.
|
||||||
A special param of cRet & signifies the end of param list and the start of return values.
|
A special param of cRet & signifies the end of param list and the start of return values.
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
#include "LuaTCPLink.h"
|
#include "LuaTCPLink.h"
|
||||||
|
#include "LuaServerHandle.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -14,6 +15,47 @@ cLuaTCPLink::cLuaTCPLink(cPluginLua & a_Plugin, int a_CallbacksTableStackPos):
|
|||||||
m_Plugin(a_Plugin),
|
m_Plugin(a_Plugin),
|
||||||
m_Callbacks(a_Plugin.GetLuaState(), a_CallbacksTableStackPos)
|
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)
|
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;
|
cTCPLinkPtr Link = m_Link;
|
||||||
if (Link == nullptr)
|
if (Link != nullptr)
|
||||||
{
|
{
|
||||||
return;
|
Link->Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Shutdown:
|
Terminated();
|
||||||
Link->Shutdown();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -124,17 +165,48 @@ void cLuaTCPLink::Shutdown(void)
|
|||||||
|
|
||||||
void cLuaTCPLink::Close(void)
|
void cLuaTCPLink::Close(void)
|
||||||
{
|
{
|
||||||
// Safely grab a copy of the link:
|
// If the link is still open, close it:
|
||||||
cTCPLinkPtr Link = m_Link;
|
cTCPLinkPtr Link = m_Link;
|
||||||
if (Link == nullptr)
|
if (Link != nullptr)
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Close the link:
|
|
||||||
Link->Close();
|
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)
|
void cLuaTCPLink::OnConnected(cTCPLink & a_Link)
|
||||||
{
|
{
|
||||||
// Check if we're still valid:
|
// 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()
|
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());
|
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:
|
class cLuaTCPLink:
|
||||||
public cNetwork::cConnectCallbacks,
|
public cNetwork::cConnectCallbacks,
|
||||||
public cTCPLink::cCallbacks
|
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. */
|
/** 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);
|
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.
|
/** 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). */
|
Returns true if successful, false on immediate failure (queueing the data failed or link not available). */
|
||||||
bool Send(const AString & a_Data);
|
bool Send(const AString & a_Data);
|
||||||
@ -60,6 +73,14 @@ protected:
|
|||||||
May be nullptr. */
|
May be nullptr. */
|
||||||
cTCPLinkPtr m_Link;
|
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:
|
// cNetwork::cConnectCallbacks overrides:
|
||||||
virtual void OnConnected(cTCPLink & a_Link) override;
|
virtual void OnConnected(cTCPLink & a_Link) override;
|
||||||
virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override;
|
virtual void OnError(int a_ErrorCode, const AString & a_ErrorMsg) override;
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "LuaState.h"
|
#include "LuaState.h"
|
||||||
#include "LuaTCPLink.h"
|
#include "LuaTCPLink.h"
|
||||||
#include "LuaNameLookup.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)
|
static int tolua_cNetwork_HostnameToIP(lua_State * L)
|
||||||
{
|
{
|
||||||
// Function signature:
|
// 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)
|
static int tolua_cNetwork_IPToHostname(lua_State * L)
|
||||||
{
|
{
|
||||||
// Function signature:
|
// 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):
|
// cTCPLink bindings (routed through cLuaTCPLink):
|
||||||
|
|
||||||
|
/** Binds cLuaTCPLink::Send */
|
||||||
static int tolua_cTCPLink_Send(lua_State * L)
|
static int tolua_cTCPLink_Send(lua_State * L)
|
||||||
{
|
{
|
||||||
// Function signature:
|
// 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)
|
static int tolua_cTCPLink_GetLocalIP(lua_State * L)
|
||||||
{
|
{
|
||||||
// Function signature:
|
// 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)
|
static int tolua_cTCPLink_GetLocalPort(lua_State * L)
|
||||||
{
|
{
|
||||||
// Function signature:
|
// 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)
|
static int tolua_cTCPLink_GetRemoteIP(lua_State * L)
|
||||||
{
|
{
|
||||||
// Function signature:
|
// 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)
|
static int tolua_cTCPLink_GetRemotePort(lua_State * L)
|
||||||
{
|
{
|
||||||
// Function signature:
|
// 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:
|
// Register the bindings:
|
||||||
|
|
||||||
@ -335,15 +483,15 @@ void ManualBindings::BindNetwork(lua_State * tolua_S)
|
|||||||
tolua_cclass(tolua_S, "cNetwork", "cNetwork", "", nullptr);
|
tolua_cclass(tolua_S, "cNetwork", "cNetwork", "", nullptr);
|
||||||
tolua_usertype(tolua_S, "cTCPLink");
|
tolua_usertype(tolua_S, "cTCPLink");
|
||||||
tolua_cclass(tolua_S, "cTCPLink", "cTCPLink", "", nullptr);
|
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):
|
// Fill in the functions (alpha-sorted):
|
||||||
tolua_beginmodule(tolua_S, "cNetwork");
|
tolua_beginmodule(tolua_S, "cNetwork");
|
||||||
tolua_function(tolua_S, "Connect", tolua_cNetwork_Connect);
|
tolua_function(tolua_S, "Connect", tolua_cNetwork_Connect);
|
||||||
tolua_function(tolua_S, "HostnameToIP", tolua_cNetwork_HostnameToIP);
|
tolua_function(tolua_S, "HostnameToIP", tolua_cNetwork_HostnameToIP);
|
||||||
tolua_function(tolua_S, "IPToHostname", tolua_cNetwork_IPToHostname);
|
tolua_function(tolua_S, "IPToHostname", tolua_cNetwork_IPToHostname);
|
||||||
/*
|
|
||||||
tolua_function(tolua_S, "Listen", tolua_cNetwork_Listen);
|
tolua_function(tolua_S, "Listen", tolua_cNetwork_Listen);
|
||||||
*/
|
|
||||||
tolua_endmodule(tolua_S);
|
tolua_endmodule(tolua_S);
|
||||||
|
|
||||||
tolua_beginmodule(tolua_S, "cTCPLink");
|
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, "GetRemoteIP", tolua_cTCPLink_GetRemoteIP);
|
||||||
tolua_function(tolua_S, "GetRemotePort", tolua_cTCPLink_GetRemotePort);
|
tolua_function(tolua_S, "GetRemotePort", tolua_cTCPLink_GetRemotePort);
|
||||||
tolua_endmodule(tolua_S);
|
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.
|
// Unified shared ptr from before C++11. Also no silly undercores.
|
||||||
#define SharedPtr std::shared_ptr
|
#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. */
|
Sends the RST packet, queued outgoing and incoming data is lost. */
|
||||||
virtual void Close(void) = 0;
|
virtual void Close(void) = 0;
|
||||||
|
|
||||||
|
/** Returns the callbacks that are used. */
|
||||||
|
cCallbacksPtr GetCallbacks(void) const { return m_Callbacks; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/** Callbacks to be used for the various situations. */
|
/** Callbacks to be used for the various situations. */
|
||||||
cCallbacksPtr m_Callbacks;
|
cCallbacksPtr m_Callbacks;
|
||||||
|
@ -119,6 +119,7 @@ void DoTest(void)
|
|||||||
LOG("Server terminating.");
|
LOG("Server terminating.");
|
||||||
Server->Close();
|
Server->Close();
|
||||||
ASSERT(!Server->IsListening());
|
ASSERT(!Server->IsListening());
|
||||||
|
Server.reset();
|
||||||
LOGD("Server has been closed.");
|
LOGD("Server has been closed.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user