Skip to content

Instantly share code, notes, and snippets.

@EliterScripts
Created January 24, 2019 18:33
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save EliterScripts/3fd2be3193ea4366d3cf7a601590245b to your computer and use it in GitHub Desktop.
Save EliterScripts/3fd2be3193ea4366d3cf7a601590245b to your computer and use it in GitHub Desktop.
require('love.system')
require('love.timer')
require('love.math')
do
local json = require("engine/json/json")
local networkOutChannel = love.thread.getChannel( "network-server-thread" )
local globalKillChannel = love.thread.getChannel( "global-kill-thread" )
local printOutChannel = love.thread.getChannel( "printed-output" )
local receiveClientData = love.thread.getChannel("receieve-client-data")
local sendClientData = love.thread.getChannel("send-client-data")
local running = true
function printDebug(...)
--if(wait ~= false)then
-- printOutChannel:supply({type = debugType, message = message})
--else
printOutChannel:push({...})
--end
end
function safePrintDebug(...)
local Args = {...}
return pcall(function()
printDebug(unpack(Args))
end)
end
local function killMyself()
running = false
end
local function checkKillChannel()
local value = globalKillChannel:peek()
if(value == "command-line-user-input")then
globalKillChannel:pop()
killMyself()
elseif(value == "*")then
killMyself()
end
end
local function sendReceivedClientData(client, localAddress, localPort, sent_data, isPartial)
local json_encoded = ""
local stat, err = pcall(function()
local remoteAddress, remotePort = client:getpeername()
json_encoded = json.encode(
{
["remoteAddress"] = remoteAddress,
["remotePort"] = remotePort,
["localAddress"] = localAddress,
["localPort"] = localPort,
["type"] = "received_data",
["message"] = sent_data,
["isPartial"] = isPartial,
["time"] = love.timer.getTime()
}
)
end)
if(stat == false)then
printDebug("Error: networkThread: receivedClientData: error while compiling JSON string:" .. err)
return false
else
receiveClientData:push(json_encoded)
return true
end
end
local function sendClientDisconnect(remoteAddress, remotePort, server)
local json_encoded = ""
local stat, err = pcall(function()
local localAddress, localPort = server:getsockname()
json_encoded = json.encode(
{
["remoteAddress"] = remoteAddress,
["remotePort"] = remotePort,
["localAddress"] = localAddress,
["localPort"] = localPort,
["type"] = "meta",
["message"] = "disconnect",
["time"] = love.timer.getTime()
}
)
end)
if(stat == false)then
printDebug("Error: networkThread: sendClientDisconnect: error while compiling JSON string:" .. err)
return false
else
receiveClientData:push(json_encoded)
return true
end
end
local function sendClientConnect(client, localAddress, localPort)
local json_encoded = ""
local stat, err = pcall(function()
local remoteAddress, remotePort = client:getpeername()
json_encoded = json.encode(
{
["remoteAddress"] = remoteAddress,
["remotePort"] = remotePort,
["localAddress"] = localAddress,
["localPort"] = localPort,
["type"] = "meta",
["message"] = "connect",
["time"] = love.timer.getTime()
}
)
end)
if(stat == false)then
printDebug("Error: networkThread: sendClientConnect: error while compiling JSON string:" .. err)
return false
else
receiveClientData:push(json_encoded)
return true
end
end
local function receiveSendClientData(client, server)
local rawMessage = sendClientData:peek()
if(rawMessage == nil)then
sendClientData:pop()
return true
end
--print(rawMessage)
local stat, err = pcall(function()
local currentRemoteAddress, currentRemotePort = client:getpeername()
local currentLocalAddress, currentLocalPort = server:getsockname()
local decoded_json = json.decode(rawMessage)
local remoteAddress = decoded_json["remoteAddress"]
local remotePort = decoded_json["remotePort"]
local localAddress = decoded_json["localAddress"]
local localPort = decoded_json["localPort"]
local receiveType = decoded_json["type"]
local message = decoded_json["message"]
if(currentRemoteAddress == remoteAddress)and
(currentRemotePort == remotePort)and
(currentLocalPort == localPort)and
(currentLocalAddress == localAddress)then
sendClientData:pop()
if(receiveType == "meta")then
if(message == "close")then
printDebug(
string.format(
"Info: dropping client %s:%s on %s:%s...",
currentRemoteAddress, currentRemotePort, currentLocalAddress, currentLocalPort
)
)
client:close()
return true, "closed"
end
elseif(receiveType == "send_data")then
print("sending...")
print(client:send(message))
return true, "sent"
end
else
return false, "wrong_one"
end
end)
if(stat == false)then
printDebug("Error: networkThread: receiveSendClientData: " .. err)
end
end
while(running)do
checkKillChannel()
local socket = nil;
local server = nil;
local bound_port = nil;
local clients = {}
local localAddress;
local localPort;
local stat, err = pcall(function()
-- load namespace
socket = require("socket")
-- create a TCP socket and bind it to the local host, at any port
server = assert(socket.bind("*", 11055))
-- find out which port the OS chose for us
local localAddress, localPort = server:getsockname()
bound_port = localPort
server:settimeout(0.2)
server:setoption('keepalive', true)
-- print a message informing what's up
printDebug("Please telnet to localhost on port " .. localPort)
-- loop forever waiting for clients
while(true)do
-- wait for a connection from any client
local client;
while(true)do
client = server:accept()
if(client ~= nil)then
client:settimeout(0.2)
client:setoption('keepalive', true)
local remoteAddress, remotePort = client:getpeername()
sendClientConnect(client, localAddress, localPort)
table.insert(clients, {
remoteAddress = remoteAddress, remotePort = remotePort, client = client,
localAddress = localAddress, localPort = localPort
})
else
for k, v in pairs(clients)do
local client = v.client
if(client ~= nil)then
local stat, code = receiveSendClientData(client, server)
if(code == "closed")then
client:close()
--local stat, err = pcall(function()
while(true)do
local rawMessage = sendClientData:peek()
if(rawMessage == nil)then break end
local json_decoded = json.decode(rawMessage)
local localAddress = json_decoded["localAddress"]
local localPort = json_decoded["localPort"]
local remoteAddress = json_decoded["remoteAddress"]
local remotePort = json_decoded["remotePort"]
if(remoteAddress == v["remoteAddress"])and
(remotePort == v["remotePort"])and
(localPort == v["localPort"])and
(localAddress == v["localAddress"])then
sendClientData:pop()
else
break
end
end
--end)
table.remove(clients, k)
else
local full_data, s_status, partial_data = client:receive()
if(s_status == "closed")then
sendClientDisconnect(v.remoteAddress, v.remotePort, server)
client:close()
--local stat, err = pcall(function()
while(true)do
local rawMessage = sendClientData:peek()
if(rawMessage == nil)then break end
local json_decoded = json.decode(rawMessage)
local localAddress = json_decoded["localAddress"]
local localPort = json_decoded["localPort"]
local remoteAddress = json_decoded["remoteAddress"]
local remotePort = json_decoded["remotePort"]
if(remoteAddress == v["remoteAddress"])and
(remotePort == v["remotePort"])and
(localPort == v["localPort"])and
(localAddress == v["localAddress"])then
sendClientData:pop()
else
break
end
end
--end)
table.remove(clients, k)
else
local isPartial;
if(partial_data ~= nil)then
isPartial = true
end
if(full_data ~= nil)then
isPartial = false
end
sendReceivedClientData(client, localAddress, localPort, full_data or partial_data, isPartial)
end
end
end
end
end
end
--[[local client_host, client_port = client:getsockname()
local client_addr = client_host .. ":" .. client_port
-- make sure we don't block waiting for this client's line
printDebug("accepted connection. (" .. client_addr .. ")")
client:setoption('keepalive', true)
client:settimeout(0.2)
printDebug("connection timed out. (" .. client_addr .. ")")
-- receive the line
local line, err = client:receive()
-- if there was no error, send it back to the client
if not err then
client:send("RE: " .. line .. "\n")
printDebug("RECEIVE: " .. line .. "(" .. client_addr .. ")")
end
-- done with client, close the object
--client:close()]]--
end
end)
if(stat == false)then
pcall(function()
printDebug("Error: " .. err)
end)
--attempts to close TCP socket, if exists.
local stat1, err1 = pcall(function()
safePrintDebug("Info: Attempting to close potential server port from safe mode...")
local stat2, err2 = pcall(function()
if(server == nil)then
safePrintDebug("Info: server object does not exist.")
else
safePrintDebug("Info: Attempting to close server object...")
server:close()
safePrintDebug("Info: Successfully closed server object.")
end
end)
if(stat2 == false )then
safePrintDebug("Error: there was a problem while attempting to close server object: " .. err2)
end
end)
if(stat1 == false)then
pcall(function()
printDebug("Error: there was an error while attempting to close potential port: " .. err)
end)
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment