1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
|
if not (Spring.GetConfigInt("LuaSocketEnabled", 0) == 1) then
Spring.Echo("LuaSocketEnabled is disabled")
return false
end
function widget:GetInfo()
return {
name = "ip console for spring",
desc = "opens a telnet console on localhost:8201",
author = "abma",
date = "Feb. 2012",
license = "GNU GPL, v2 or later",
layer = 0,
enabled = true,
}
end
--VFS.Include(LUAUI_DIRNAME .. "Widgets/socket/socket.lua")
local socket = socket
local set
local host = "localhost"
local port = 8201
local function newset()
local reverse = {}
local set = {}
return setmetatable(set, {__index = {
insert = function(set, value)
if not reverse[value] then
table.insert(set, value)
reverse[value] = table.getn(set)
end
end,
remove = function(set, value)
local index = reverse[value]
if index then
reverse[value] = nil
local top = table.remove(set)
if top ~= value then
reverse[top] = index
set[index] = top
end
end
end
}})
end
-- initiates a connection to host:port, returns true on success
local function SocketListen(host, port)
server = socket.bind(host, port)
if server==nil then
Spring.Echo("Error binding to " .. host .. ":" .. port)
return false
end
server:settimeout(0)
set = newset()
set:insert(server)
return true
end
function widget:Initialize()
SocketListen(host, port)
end
local data
-- called when data was received through a connection
local function SocketDataReceived(sock, str)
Spring.SendCommands(str)
end
local headersent
-- called when data can be written to a socket
local function SocketWriteAble(sock)
if data~=nil then
sock:send(data)
data=nil
end
end
-- called when a connection is closed
local function SocketClosed(sock)
Spring.Echo("closed connection")
end
local function ClientConnected(sock)
local client, err = sock:accept()
if client == nil then
Spring.Echo("Accept failed: " .. err)
end
client:settimeout(0)
set:insert(client)
ip, port = sock:getsockname()
Spring.Echo("Accepted connection from " .. ip ..":" .. port)
end
function widget:AddConsoleLine(line)
if data == nil then
data = line
else
data = data .."\n" .. line
end
end
function widget:Update()
if set==nil or #set<=0 then
return
end
-- get sockets ready for read
local readable, writeable, err = socket.select(set, set, 0)
if err~=nil then
-- some error happened in select
if err=="timeout" then
-- nothing to do, return
return
end
Spring.Echo("Error in select: " .. error)
end
for _, input in ipairs(readable) do
if input==server then -- server socket got readable (client connected)
ClientConnected(input)
else
local s, status, partial = input:receive('*a') --try to read all data
if status == "timeout" or status == nil then
SocketDataReceived(input, s or partial)
elseif status == "closed" then
SocketClosed(input)
input:close()
set:remove(input)
end
end
end
for __, output in ipairs(writeable) do
SocketWriteAble(output)
end
end
|