Last active
March 12, 2023 01:58
-
-
Save Kaidrick/e0a0967cbdb7562ec275ad66be847e28 to your computer and use it in GitHub Desktop.
DCS World超级航母着舰LSO评分分析插件
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
-- 两个文件放入C:\Users\Administrator\Saved Games\DCS.openbeta\Scripts\Hooks中 | |
-- 按Ctrl+Shift+X呼出记录窗口 | |
function scratchpad_load() | |
package.path = package.path..";.\\LuaSocket\\?.lua;"..'.\\Scripts\\?.lua;'.. '.\\Scripts\\UI\\?.lua;' | |
package.cpath = package.cpath..";.\\LuaSocket\\?.dll;" | |
local JSON = loadfile("Scripts\\JSON.lua")() | |
local lfs = require('lfs') | |
local U = require('me_utilities') | |
local Skin = require('Skin') | |
local DialogLoader = require('DialogLoader') | |
local Tools = require('tools') | |
local Input = require('Input') | |
local isHidden = true | |
local keyboardLocked = false | |
local window = nil | |
local windowDefaultSkin = nil | |
local windowSkinHidden = Skin.windowSkinChatMin() | |
local panel = nil | |
local textarea = nil | |
local scratchpad = { | |
logFile = io.open(lfs.writedir()..[[Logs\Scratchpad.log]], "w") | |
} | |
function scratchpad.loadConfiguration() | |
scratchpad.log("Loading config file...") | |
local tbl = Tools.safeDoFile(lfs.writedir() .. 'Config/ScratchpadConfig.lua', false) | |
if (tbl and tbl.config) then | |
scratchpad.log("Configuration exists...") | |
scratchpad.config = tbl.config | |
else | |
scratchpad.log("Configuration not found, creating defaults...") | |
scratchpad.config = { | |
hotkey = "Ctrl+Shift+x", | |
windowPosition = { x = 200, y = 200 }, | |
windowSize = { w = 350, h = 150 }, | |
content = "Carrier Landing Score", | |
} | |
scratchpad.saveConfiguration() | |
end | |
end | |
function scratchpad.saveConfiguration() | |
U.saveInFile(scratchpad.config, 'config', lfs.writedir() .. 'Config/ScratchpadConfig.lua') | |
end | |
function scratchpad.log(str) | |
if not str then | |
return | |
end | |
if scratchpad.logFile then | |
scratchpad.logFile:write("["..os.date("%H:%M:%S").."] "..str.."\r\n") | |
scratchpad.logFile:flush() | |
end | |
end | |
local function unlockKeyboardInput(releaseKeyboardKeys) | |
if keyboardLocked then | |
DCS.unlockKeyboardInput(releaseKeyboardKeys) | |
keyboardLocked = false | |
end | |
end | |
local function lockKeyboardInput() | |
if keyboardLocked then | |
return | |
end | |
local keyboardEvents = Input.getDeviceKeys(Input.getKeyboardDeviceName()) | |
DCS.lockKeyboardInput(keyboardEvents) | |
keyboardLocked = true | |
end | |
function scratchpad.createWindow() | |
window = DialogLoader.spawnDialogFromFile(lfs.writedir() .. 'Scripts\\\Hooks\\ScratchpadWindow.dlg', cdata) | |
windowDefaultSkin = window:getSkin() | |
panel = window.Box | |
textarea = panel.ScratchpadEditBox | |
-- setup textarea | |
textarea:setText(scratchpad.config.content) | |
textarea:addChangeCallback(function(self) | |
scratchpad.config.content = self:getText() | |
scratchpad.saveConfiguration() | |
end) | |
textarea:addFocusCallback(function(self) | |
if self:getFocused() then | |
lockKeyboardInput() | |
else | |
unlockKeyboardInput(true) | |
end | |
end) | |
textarea:addKeyDownCallback(function(self, keyName, unicode) | |
if keyName == 'escape' then | |
self:setFocused(false) | |
unlockKeyboardInput(true) | |
end | |
end) | |
-- setup window | |
window:setBounds( | |
scratchpad.config.windowPosition.x, | |
scratchpad.config.windowPosition.y, | |
scratchpad.config.windowSize.w, | |
scratchpad.config.windowSize.h | |
) | |
scratchpad.handleResize(window) | |
window:addHotKeyCallback(scratchpad.config.hotkey, function() | |
if isHidden == true then | |
scratchpad.show() | |
else | |
scratchpad.hide() | |
end | |
end) | |
window:addSizeCallback(scratchpad.handleResize) | |
window:addPositionCallback(scratchpad.handleMove) | |
window:setVisible(true) | |
scratchpad.hide() | |
scratchpad.log("Scratchpad Window created") | |
end | |
function scratchpad.setVisible(b) | |
window:setVisible(b) | |
end | |
function scratchpad.handleResize(self) | |
local w, h = self:getSize() | |
panel:setBounds(0, 0, w, h - 20) | |
textarea:setBounds(0, 0, w, h - 20) | |
scratchpad.config.windowSize = { w = w, h = h } | |
scratchpad.saveConfiguration() | |
end | |
function scratchpad.handleMove(self) | |
local x, y = self:getPosition() | |
scratchpad.config.windowPosition = { x = x, y = y } | |
scratchpad.saveConfiguration() | |
end | |
function scratchpad.show() | |
if window == nil then | |
local status, err = pcall(scratchpad.createWindow) | |
if not status then | |
net.log("[Scratchpad] Error creating window: " .. tostring(err)) | |
end | |
end | |
window:setVisible(true) | |
window:setSkin(windowDefaultSkin) | |
panel:setVisible(true) | |
window:setHasCursor(true) | |
isHidden = false | |
end | |
function scratchpad.hide() | |
window:setSkin(windowSkinHidden) | |
panel:setVisible(false) | |
textarea:setFocused(false) | |
window:setHasCursor(false) | |
-- window.setVisible(false) -- if you make the window invisible, its destroyed | |
unlockKeyboardInput(true) | |
isHidden = true | |
end | |
function scratchpad.onSimulationFrame() | |
if scratchpad.config == nil then | |
scratchpad.loadConfiguration() | |
end | |
if not window then | |
scratchpad.log("Creating Scratchpad window hidden...") | |
scratchpad.createWindow() | |
end | |
end | |
-------------------------------------------------------------------- | |
local GRADE = { | |
["WO"] = "复飞", | |
["OWO"] = "主动放弃着舰", | |
["_OK_"] = "完美的降落", | |
["OK"] = "优秀,及时进行了修正", | |
["(OK)"] = "及格,一次或多次偏差", | |
["---"] = "不及格,总体上处于在安全范围", | |
["C"] = "危险,超出安全范围", | |
["B"] = "脱钩" | |
} | |
local ACTION = { | |
["WO"] = "复飞", | |
} | |
local ERROR = { | |
["AFU"] = "全程“犯规”", | |
["DL"] = "向左偏移", | |
["DR"] = "向右偏移", | |
["EG"] = "着舰时缺乏推力", | |
["FD"] = "甲板阻塞", | |
["LL"] = "着舰位置偏左", | |
["LO"] = "过低", | |
["LR"] = "着舰位置偏右", | |
["LUL"] = "中线偏左", | |
["LUR"] = "中线偏右", | |
["NERD"] = "下降率不足", | |
["NSU"] = "未建立着舰构型", | |
["SLO"] = "过慢", | |
["TMRD"] = "下降率过大", | |
["LLWD"] = "左起落架先着舰", | |
["LRWD"] = "右起落架先着舰", | |
["LNF"] = "前轮先着舰", | |
["3PTS"] = "机轮三点同时着舰", | |
} | |
local ERROR_S = { | |
["F"] = "过快", | |
["H"] = "过高", | |
["N"] = "机头不稳", | |
["W"] = "坡度不稳", | |
["P"] = "油门不足", | |
} | |
local DISTMARK = { | |
["BC"] = "目视确认时", | |
["X"] = "起点", | |
["IM"] = "中段", | |
["IC"] = "接近阶段", | |
["AR"] = "船艉坡道上", | |
["TL"] = "着舰阶段", | |
["IW"] = "着舰区", | |
["AW"] = "全程", | |
} | |
local WIRE = { | |
["WIRE# 1"] = "第 1 根", | |
["WIRE# 2"] = "第 2 根", | |
["WIRE# 3"] = "第 3 根", | |
["WIRE# 4"] = "第 4 根", | |
} | |
function splitString(message, c) | |
chunks = {} | |
for substring in message:gmatch("%s?[^" .. c .. "]+%s-") do | |
table.insert(chunks, substring) | |
end | |
return chunks | |
end | |
function getSpace(comp) | |
local len = 12 | |
local res = "" | |
local count = string.len(comp) | |
while count < len do | |
res = res .. " " | |
count = count + 1 | |
end | |
return res | |
end | |
function parseMessage(checkString) | |
local record = "" | |
local dist = "" | |
local err = "" | |
local grade = "" | |
local wire_num = "" | |
local raw = checkString | |
-- get wire number if exists | |
if checkString:match("WIRE#") then | |
wire_num = checkString:match("WIRE#%s%d") | |
if wire_num ~= "" then | |
wire_num = WIRE[wire_num] | |
end | |
checkString = checkString:gsub("WIRE#%s%d", "") | |
end | |
-- for each error, match error name then error distance marker, then match brackets and underscore | |
local res = splitString(checkString, ":") | |
-- match grade using GRADE:[whatever]%s | |
grade = checkString:match("GRADE:.-:-%s"):gsub("GRADE:", ""):gsub(":", ""):gsub("%s+", "") | |
-- destruct string | |
checkString = checkString:gsub("LSO", ""):gsub("GRADE:.-:-%s", ""):gsub(":", "") | |
grade = grade .. "(" .. GRADE[grade] .. ")" | |
local errors = splitString(checkString, "%s") | |
local drop_first = false | |
for _, pick in pairs(errors) do | |
local ex = {} | |
local full = pick:gsub("%s+", "") | |
local fst = pick:gsub("%s+", "") | |
local error_assertion = false | |
-- waveoff action? | |
if fst:match("WO") then | |
table.insert(ex, ACTION["WO"]) | |
fst = fst:gsub("WO", "") | |
end | |
for k, v in pairs(DISTMARK) do | |
if fst:match(k) then | |
table.insert(ex, v) | |
-- remove from string | |
fst = fst:gsub(k, "") | |
break | |
end | |
end | |
for k, v in pairs(ERROR) do | |
if fst:match(k) then | |
table.insert(ex, v) | |
error_assertion = true | |
break | |
end | |
end | |
if not error_assertion then | |
for k, v in pairs(ERROR_S) do | |
if fst:match(k) then | |
table.insert(ex, v) | |
break | |
end | |
end | |
end | |
if fst:match("%[") then | |
table.insert(ex, "(不规范呼叫)") | |
end | |
if fst:match("_") then | |
table.insert(ex, "(严重)") | |
end | |
if fst:match("%(") then | |
table.insert(ex, "(轻微)") | |
end | |
record = record .. full .. getSpace(full) .. table.concat(ex, " ") .. "\n" .. dist | |
end | |
return raw .. "\n" .. grade .. "," .. wire_num .. "\n" .. record | |
end | |
function scratchpad.stringStartWiths(checkString, expectedString) | |
local length = string.len(expectedString) | |
-- get substring from 1 to length | |
return string.sub(checkString, 1, length) == expectedString | |
end | |
-- log trigger message if message string starts with LSO: GRADE: | |
function scratchpad.onTriggerMessage(message, duration, clearView) | |
if(scratchpad.stringStartWiths(message, "LSO: GRADE:")) then | |
textarea:setText(parseMessage(message)) | |
end | |
-- textarea:setText(textarea:getText() .. "\n" .. a_text) | |
end | |
DCS.setUserCallbacks(scratchpad) | |
net.log("[Scratchpad] Loaded ...") | |
end | |
local status, err = pcall(scratchpad_load) | |
if not status then | |
net.log("[Scratchpad] Load Error: " .. tostring(err)) | |
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dialog = { | |
["type"] = "Window", | |
["params"] = { | |
["bounds"] = { | |
[1] = { | |
["h"] = 200, | |
["w"] = 350, | |
["x"] = 0, | |
["y"] = 0, | |
}, | |
}, | |
["draggable"] = true, | |
["enabled"] = true, | |
["hasCursor"] = true, | |
["lockFlow"] = false, | |
["modal"] = false, | |
["offscreen"] = false, | |
["resizable"] = true, | |
["zOrder"] = 111, | |
["text"] = "着舰评分记录", | |
}, | |
["skin"] = { | |
["params"] = { | |
["name"] = "windowSkin", | |
}, | |
["skins"] = { | |
["header"] = { | |
["skinData"] = { | |
["params"] = { | |
["hasCloseButton"] = false, | |
["insets"] = { | |
["bottom"] = 2, | |
["left"] = 2, | |
["right"] = 2, | |
["top"] = 2, | |
}, | |
}, | |
["states"] = { | |
["released"] = { | |
[1] = { | |
["bkg"] = { | |
["center_center"] = "0x00000066", | |
}, | |
["text"] = { | |
["color"] = "0xffffffaa", | |
}, | |
}, | |
[2] = { | |
["bkg"] = { | |
["center_center"] = "0x00000066", | |
}, | |
["text"] = { | |
["color"] = "0xffffffaa", | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
}, | |
["states"] = { | |
["released"] = { | |
[1] = { | |
["bkg"] = { | |
["center_center"] = "0x00000000", | |
}, | |
}, | |
}, | |
}, | |
}, | |
["children"] = { | |
["Box"] = { | |
["children"] = { | |
["ScratchpadEditBox"] = { | |
["params"] = { | |
["acceptDecimalPoint"] = false, | |
["bounds"] = { | |
["h"] = 100, | |
["w"] = 250, | |
["x"] = 0, | |
["y"] = 0, | |
}, | |
["enabled"] = true, | |
["multiline"] = true, | |
["numeric"] = false, | |
["password"] = false, | |
["readOnly"] = false, | |
["tabOrder"] = 80, | |
["text"] = "...", | |
["textWrapping"] = true, | |
["tooltip"] = "", | |
["visible"] = true, | |
["zindex"] = 0, | |
}, | |
["skin"] = { | |
["params"] = { | |
["name"] = "editBoxNew", | |
}, | |
["states"] = { | |
["released"] = { | |
[1] = { | |
["bkg"] = { | |
["center_center"] = "0x00000080", | |
}, | |
}, | |
}, | |
}, | |
}, | |
["type"] = "EditBox", | |
}, | |
}, | |
["params"] = { | |
["bounds"] = { | |
[1] = { | |
["h"] = 467, | |
["w"] = 360, | |
["x"] = 0, | |
["y"] = 55, | |
}, | |
}, | |
["enabled"] = true, | |
["text"] = "", | |
["tooltip"] = "", | |
["visible"] = true, | |
["zindex"] = 0, | |
}, | |
["skin"] = { | |
["params"] = { | |
["name"] = "panelSkin", | |
}, | |
}, | |
["type"] = "Panel", | |
}, | |
["pNoVisible"] = { | |
["children"] = { | |
["windowModeMin"] = { | |
["params"] = { | |
["bounds"] = { | |
["h"] = 36, | |
["w"] = 40, | |
["x"] = 13, | |
["y"] = 203, | |
}, | |
["enabled"] = true, | |
["text"] = "Panel1", | |
["tooltip"] = "", | |
["visible"] = true, | |
["zindex"] = 0, | |
}, | |
["skin"] = { | |
["params"] = { | |
["name"] = "panelSkin", | |
}, | |
}, | |
["type"] = "Panel", | |
}, | |
["windowModeFull"] = { | |
["params"] = { | |
["bounds"] = { | |
["h"] = 36, | |
["w"] = 40, | |
["x"] = 13, | |
["y"] = 203, | |
}, | |
["enabled"] = true, | |
["text"] = "panel0", | |
["tooltip"] = "", | |
["visible"] = true, | |
["zindex"] = 0, | |
}, | |
["skin"] = { | |
["params"] = { | |
["name"] = "panelSkin", | |
}, | |
["states"] = { | |
["released"] = { | |
[1] = { | |
["bkg"] = { | |
["center_center"] = "0x00000064", | |
}, | |
}, | |
}, | |
}, | |
}, | |
["type"] = "Panel", | |
}, | |
}, | |
["params"] = { | |
["bounds"] = { | |
["h"] = 435, | |
["w"] = 228, | |
["x"] = 442, | |
["y"] = 31, | |
}, | |
["enabled"] = true, | |
["text"] = "panel0", | |
["tooltip"] = "", | |
["visible"] = false, | |
["zindex"] = 0, | |
}, | |
["skin"] = { | |
["params"] = { | |
["name"] = "panelSkin", | |
}, | |
}, | |
["type"] = "Panel", | |
}, | |
}, | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment