Files
bbassieandClaude Fable 5 a25f8c8611 Fix lua lint warnings reported by emmylua
The largest source was compat.lua returning the setmetatable call
directly, which made emmylua infer the module type from the metatable
rather than the LibCompat class, hiding every field from consumers.

The remaining fixes are nil guards on gui element and character
accesses, type annotations for research_sync's script data and
player_auth's rcon arguments, casts where the api's read/write union
types are wider than the values at runtime, and scoped diagnostic
disables for the vendored json.lua and the version fallback code that
touches apis removed from the current typedefs.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-27 22:25:24 +00:00

223 lines
5.5 KiB
Lua

local clusterio_api = require("modules/clusterio/api")
local compat = require("modules/clusterio/compat")
local auth = {}
local v2_styles = compat.version_ge("2.0.0")
--- @param player LuaPlayer
--- @param url string
--- @param code string
local function open_dialog(player, url, code)
if player.gui.screen.player_auth_dialog then
player.gui.screen.player_auth_dialog.destroy()
end
local frame = player.gui.screen.add {
name = "player_auth_dialog",
type = "frame",
direction = "vertical",
}
local titlebar = frame.add {
type = "flow",
}
titlebar.drag_target = frame
local title = titlebar.add {
type = "label",
style = "frame_title",
caption = "Web Interface Login",
}
title.drag_target = frame
local filler = titlebar.add {
type = "empty-widget",
style = "draggable_space_header",
}
filler.style.horizontally_stretchable = true
filler.style.right_margin = 4
filler.style.height = 24
filler.drag_target = frame
titlebar.add {
name = "player_auth_dialog_close_button",
type = "sprite-button",
sprite = v2_styles and "utility/close" or "utility/close_white",
hovered_sprite = "utility/close_black",
clicked_sprite = "utility/close_black",
style = "frame_action_button",
}
local content = frame.add {
name = "player_auth_dialog_content",
type = "frame",
direction = "vertical",
style = "inside_shallow_frame_with_padding",
}
content.style.width = 300
local p1 = content.add {
type = "label",
caption = "Login to the web interface is a 3 step process:",
}
p1.style.single_line = false
p1.style.bottom_margin = 8
local p2 = content.add {
type = "label",
caption = "1. Open the web interface in a browser, the url to it is shown below:",
}
p2.style.single_line = false
p2.style.bottom_margin = 8
local url_textfield = content.add {
type = "textfield",
text = url,
}
url_textfield.style.bottom_margin = 8
url_textfield.style.width = 300 - 24
local p3 = content.add {
type = "label",
caption = "2. Enter the following code into step 2 of the Factorio login:",
}
p3.style.single_line = false
p3.style.bottom_margin = 8
local player_code_textfield = content.add {
type = "textfield",
text = code,
}
player_code_textfield.style.bottom_margin = 8
player_code_textfield.style.width = 180
local p4 = content.add {
type = "label",
caption = "3. Enter the code in step 3 of the Factorio login here:"
}
p4.style.single_line = false
p4.style.bottom_margin = 8
local verify_code_row = content.add {
type = "flow",
}
local verify_code_input = verify_code_row.add {
name = "player_auth_verify_code_input",
type = "textfield",
}
verify_code_input.style.bottom_margin = 8
verify_code_input.style.width = 180
local verify_code_button = verify_code_row.add {
name = "player_auth_verify_code_button",
type = "button",
style = "green_button",
sprite = "utility/check_mark",
caption = "Log in",
}
verify_code_button.style.minimal_width = 80
frame.force_auto_center()
player.opened = frame
end
function auth.add_commands()
commands.add_command("web-login", "Login to the web interface", function(event)
if event.player_index then
local player = game.players[event.player_index]
clusterio_api.send_json("player_auth", {
type = "open_dialog",
player = player.name,
})
return
end
if event.parameter then
--- @type string[]
local args = {}
for w in string.gmatch(event.parameter, "[^ ]+") do
args[#args + 1] = w
end
if #args < 1 then
rcon.print("Incorrect number of parameters")
return
end
local command = table.remove(args, 1)
if command == "open" then
if #args ~= 3 then
rcon.print("Incorrect number of parameters")
return
end
local player_name, url, code = table.unpack(args)
local player = game.get_player(player_name)
if not player then
rcon.print("Player " .. player_name .. " does not exist")
return
end
open_dialog(player, url, code)
elseif command == "code_set" then
local player_name = args[1]
local player = game.get_player(player_name)
if not player then
rcon.print("Player " .. player_name .. " does not exist")
return
end
if player.gui.screen.player_auth_dialog then
player.gui.screen.player_auth_dialog.destroy()
end
elseif command == "error" then
local player_name = table.remove(args, 1)
local player = game.get_player(player_name)
if not player then
rcon.print("Player " .. player_name .. " does not exist")
return
end
player.print("Error: " .. table.concat(args, " "))
end
end
end)
end
auth.events = {}
--- @param event EventData.on_gui_click
auth.events[defines.events.on_gui_click] = function(event)
if not event.element or not event.element.valid then
return
end
if event.element.name == "player_auth_dialog_close_button" then
local parent = assert(event.element.parent)
assert(parent.parent).destroy()
elseif event.element.name == "player_auth_verify_code_button" then
local parent = assert(event.element.parent)
local verify_code = assert(parent.player_auth_verify_code_input).text
local player_name = game.players[event.player_index].name
clusterio_api.send_json("player_auth", {
type = "set_verify_code",
player = player_name,
verify_code = verify_code,
})
end
end
--- @param event EventData.on_gui_closed
auth.events[defines.events.on_gui_closed] = function(event)
if
event.element
and event.element.valid
and event.element.name == "player_auth_dialog"
then
event.element.destroy()
end
end
return auth