mirror of
https://github.com/Pax1601/DCSOlympus.git
synced 2025-10-29 16:56:34 +00:00
Added installation/deletion of camera control plugin from manager
This commit is contained in:
214
scripts/lua/backend/OlympusCameraControl.lua
Normal file
214
scripts/lua/backend/OlympusCameraControl.lua
Normal file
@@ -0,0 +1,214 @@
|
||||
local _prevLuaExportStart = LuaExportStart
|
||||
local _prevLuaExportBeforeNextFrame = LuaExportBeforeNextFrame
|
||||
local _prevLuaExportStop = LuaExportStop
|
||||
|
||||
local server = nil
|
||||
local port = 3003
|
||||
local headers = "Access-Control-Allow-Origin: *\r\nAccess-Control-Allow-Methods: PUT, OPTIONS\r\nAccess-Control-Allow-Headers: *\r\nAccess-Control-Max-Age: 86400\r\nVary: Accept-Encoding, Origin\r\nKeep-Alive: timeout=2, max=100\r\nConnection: Keep-Alive\r\n\r\n"
|
||||
|
||||
function startTCPServer()
|
||||
log.write('OLYMPUSCAMERACONTROL.EXPORT.LUA', log.INFO, 'Starting TCP Server')
|
||||
package.path = package.path..";"..lfs.currentdir().."/LuaSocket/?.lua"
|
||||
package.cpath = package.cpath..";"..lfs.currentdir().."/LuaSocket/?.dll"
|
||||
|
||||
socket = require("socket")
|
||||
|
||||
server = assert(socket.bind("127.0.0.1", port))
|
||||
if server then
|
||||
server:setoption("tcp-nodelay", true)
|
||||
server:settimeout(0)
|
||||
log.write('OLYMPUSCAMERACONTROL.EXPORT.LUA', log.INFO, 'TCP Server listening on port ' .. port)
|
||||
else
|
||||
log.write('OLYMPUSCAMERACONTROL.EXPORT.LUA', log.INFO, 'TCP Server did not start successfully')
|
||||
end
|
||||
end
|
||||
|
||||
function receiveTCP()
|
||||
if server then
|
||||
-- Accept a new connection without blocking
|
||||
local client = server:accept()
|
||||
|
||||
if client then
|
||||
-- Set the timeout of the connection to 5ms
|
||||
client:settimeout(0)
|
||||
client:setoption("tcp-nodelay", true)
|
||||
|
||||
local acc = ""
|
||||
local data = ""
|
||||
|
||||
-- Start receiving data, accumulate it in acc
|
||||
while data ~= nil do
|
||||
-- Receive a new line
|
||||
data, err, partial = client:receive('*l')
|
||||
if data then
|
||||
-- If we receive an empty string it means the header section of the message is over
|
||||
if data == "" then
|
||||
-- Is this an OPTIONS request?
|
||||
if string.find(acc, "OPTIONS") ~= nil then
|
||||
client:send("HTTP/1.1 200 OK\r\n" .. headers)
|
||||
client:close()
|
||||
|
||||
-- Is this a PUT request?
|
||||
elseif string.find(acc, "PUT") ~= nil then
|
||||
-- Extract the length of the body
|
||||
local contentLength = string.match(acc, "Content%-Length: (%d+)")
|
||||
if contentLength ~= nil then
|
||||
-- Receive the body
|
||||
body, err, partial = client:receive(tonumber(contentLength))
|
||||
if body ~= nil then
|
||||
local lat = string.match(body, '"lat":%s*([%+%-]?[%d%.]+)%s*[},]')
|
||||
local lng = string.match(body, '"lng":%s*([%+%-]?[%d%.]+)%s*[},]')
|
||||
local alt = string.match(body, '"alt":%s*([%+%-]?[%d%.]+)%s*[},]')
|
||||
local mode = string.match(body, '"mode":%s*"(%a+)"%s*[},]')
|
||||
|
||||
if lat ~= nil and lng ~= nil then
|
||||
client:send("HTTP/1.1 200 OK\r\n" .. headers)
|
||||
|
||||
local position = {}
|
||||
position["lat"] = tonumber(lat)
|
||||
position["lng"] = tonumber(lng)
|
||||
if alt ~= nil then
|
||||
position["alt"] = tonumber(alt)
|
||||
end
|
||||
|
||||
-- F11 view
|
||||
if mode == "live" or mode == nil then
|
||||
LoSetCommand(158)
|
||||
-- F10 view
|
||||
elseif mode == "map" then
|
||||
LoSetCommand(15)
|
||||
end
|
||||
|
||||
client:send(setCameraPosition(position))
|
||||
client:close()
|
||||
else
|
||||
client:send("HTTP/1.1 500 ERROR\r\n" .. headers)
|
||||
client:close()
|
||||
end
|
||||
else
|
||||
log.write('OLYMPUSCAMERACONTROL.EXPORT.LUA', log.ERROR, err)
|
||||
end
|
||||
end
|
||||
client:close()
|
||||
break
|
||||
end
|
||||
else
|
||||
-- Keep accumulating the incoming data
|
||||
acc = acc .. " " .. data
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function stopTCPServer()
|
||||
if server then
|
||||
log.write('OLYMPUSCAMERACONTROL.EXPORT.LUA', log.INFO, 'Stopping TCP Server')
|
||||
server:close()
|
||||
end
|
||||
server = nil
|
||||
end
|
||||
|
||||
function setCameraPosition(position)
|
||||
-- Get the old camera position
|
||||
local oldPos = LoGetCameraPosition()
|
||||
|
||||
-- Extract the commanded position
|
||||
local point = LoGeoCoordinatesToLoCoordinates(position.lng, position.lat)
|
||||
local pointNorth = LoGeoCoordinatesToLoCoordinates(position.lng, position.lat + 0.1)
|
||||
|
||||
-- Compute the local map rotation and scale and send it back to the server
|
||||
local rotation = math.atan2(pointNorth.z - point.z, pointNorth.x - point.x)
|
||||
|
||||
-- If no altitude is provided, preserve the current camera altitude
|
||||
local altitude = nil
|
||||
if position.alt == nil then
|
||||
altitude = oldPos.p.y
|
||||
else
|
||||
altitude = position.alt
|
||||
end
|
||||
|
||||
-- Set the camera position
|
||||
local pos =
|
||||
{
|
||||
x = {x = 0, y = -1, z = 0},
|
||||
y = {x = 1, y = 0, z = 0},
|
||||
z = {x = 0, y = 0, z = 1},
|
||||
p = {x = point.x, y = altitude, z = point.z}
|
||||
}
|
||||
LoSetCameraPosition(pos)
|
||||
|
||||
return '{"northRotation": ' .. rotation .. '}'
|
||||
end
|
||||
|
||||
LuaExportStart = function()
|
||||
package.path = package.path..";"..lfs.currentdir().."/LuaSocket/?.lua"
|
||||
package.cpath = package.cpath..";"..lfs.currentdir().."/LuaSocket/?.dll"
|
||||
|
||||
startTCPServer()
|
||||
|
||||
-- call original
|
||||
if _prevLuaExportStart then
|
||||
_status, _result = pcall(_prevLuaExportStart)
|
||||
if not _status then
|
||||
log.write('OLYMPUSCAMERACONTROL.EXPORT.LUA', log.ERROR, 'ERROR Calling other LuaExportStart from another script', _result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
LuaExportBeforeNextFrame = function()
|
||||
receiveTCP()
|
||||
|
||||
-- call original
|
||||
if _prevLuaExportBeforeNextFrame then
|
||||
_status, _result = pcall(_prevLuaExportBeforeNextFrame)
|
||||
if not _status then
|
||||
log.write('OLYMPUSCAMERACONTROL.EXPORT.LUA', log.ERROR, 'ERROR Calling other LuaExportBeforeNextFrame from another script', _result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
LuaExportStop = function()
|
||||
stopTCPServer()
|
||||
|
||||
-- call original
|
||||
if _prevLuaExportStop then
|
||||
_status, _result = pcall(_prevLuaExportStop)
|
||||
if not _status then
|
||||
log.write('OLYMPUSCAMERACONTROL.EXPORT.LUA', log.ERROR, 'ERROR Calling other LuaExportStop from another script', _result)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function serializeTable(val, name, skipnewlines, depth)
|
||||
skipnewlines = skipnewlines or false
|
||||
depth = depth or 0
|
||||
|
||||
local tmp = string.rep(" ", depth)
|
||||
if name then
|
||||
if type(name) == "number" then
|
||||
tmp = tmp .. "[" .. name .. "]" .. " = "
|
||||
else
|
||||
tmp = tmp .. name .. " = "
|
||||
end
|
||||
end
|
||||
|
||||
if type(val) == "table" then
|
||||
tmp = tmp .. "{" .. (not skipnewlines and "\n" or "")
|
||||
for k, v in pairs(val) do
|
||||
tmp = tmp .. serializeTable(v, k, skipnewlines, depth + 1) .. "," .. (not skipnewlines and "\n" or "")
|
||||
end
|
||||
tmp = tmp .. string.rep(" ", depth) .. "}"
|
||||
elseif type(val) == "number" then
|
||||
tmp = tmp .. tostring(val)
|
||||
elseif type(val) == "string" then
|
||||
tmp = tmp .. string.format("%q", val)
|
||||
elseif type(val) == "boolean" then
|
||||
tmp = tmp .. (val and "true" or "false")
|
||||
else
|
||||
tmp = tmp .. "\"[inserializeable datatype:" .. type(val) .. "]\""
|
||||
end
|
||||
|
||||
return tmp
|
||||
end
|
||||
Reference in New Issue
Block a user