Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
devmode.txt
*code-workspace
.vscode/settings.json

# Game mode presets (BAR export_game_modes widget). The ModeCommand plugin
# self-fetches these from the BAR `game-modes` release into game_modes.cache.json;
# game_modes.json is an optional host-dropped fallback. Neither is source.
spads-plugins/ModeCommand/game_modes.json
spads-plugins/ModeCommand/game_modes.cache.json
45 changes: 23 additions & 22 deletions LuaMenu/widgets/api_analytics.lua
Original file line number Diff line number Diff line change
Expand Up @@ -462,29 +462,30 @@ local function GetDesyncGameStates()
local infolog = VFS.LoadFile(filename)
if infolog == nil then
Spring.Echo("Failed to load desync dump", filename)
else
if string.len(infolog) > 16000000 then
infolog = string.sub(infolog,1,16000000)
end
local t0 = Spring.GetTimer()
infolog = ascii(infolog)
local compressedlog = Spring.Utilities.Base64Encode(VFS.ZlibCompress(infolog))
local t1 = Spring.GetTimer()
--local validate = io.open("tempdump.txt",'w')
--validate:write(compressedlog)
--validate:close()
--Spring.Echo("Crash Dump Header is",string.sub(compressedlog, 1, 1000))
local header = string.sub(infolog, 1, 1000)
-- Parse the following fields in the lines of the header:
local versionData = {
map = string.match(header, "mapName: ([^\n]+)"),
game = string.match(header, "modName: ([^\n]+)"),
engine = string.match(header, "syncVer: ([^\n]+)"),
gameID = string.match(header, "gameID: ([^\n]+)"),
}

Analytics.SendCrashReportOneTimeEvent(filename, "SyncError", filename, compressedlog, false, versionData)
Spring.Echo("Dump done in ", Spring.DiffTimers(Spring.GetTimer(), t1), Spring.DiffTimers(t1,t0))
end
if string.len(infolog) > 16000000 then
infolog = string.sub(infolog,1,16000000)
end
local t0 = Spring.GetTimer()
infolog = ascii(infolog)
local compressedlog = Spring.Utilities.Base64Encode(VFS.ZlibCompress(infolog))
local t1 = Spring.GetTimer()
--local validate = io.open("tempdump.txt",'w')
--validate:write(compressedlog)
--validate:close()
--Spring.Echo("Crash Dump Header is",string.sub(compressedlog, 1, 1000))
local header = string.sub(infolog, 1, 1000)
-- Parse the following fields in the lines of the header:
local versionData = {
map = string.match(header, "mapName: ([^\n]+)"),
game = string.match(header, "modName: ([^\n]+)"),
engine = string.match(header, "syncVer: ([^\n]+)"),
gameID = string.match(header, "gameID: ([^\n]+)"),
}

Analytics.SendCrashReportOneTimeEvent(filename, "SyncError", filename, compressedlog, false, versionData)
Spring.Echo("Dump done in ", Spring.DiffTimers(Spring.GetTimer(), t1), Spring.DiffTimers(t1,t0))
end
end
end
Expand Down
149 changes: 147 additions & 2 deletions LuaMenu/widgets/gui_battle_room_window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,141 @@ local isMapDownloading = false
local vote_votingsPattern = "(%d+)/(%d+).-:(%d+)"
local vote_whoCalledPattern = "%* (.*) called a vote for command"
local vote_mapPattern = 'set map (.*)"'
local vote_modePattern = "^[Mm]ode (%S+) (%S+)(.*)"

local COLOR_GREEN = "\255\100\255\100"
local COLOR_GREY = "\255\150\150\150"
local COLOR_WHITE = "\255\255\255\255"
local COLOR_GOLD = "\255\255\220\100"

local function GetModoptionName(key)
local defs = WG.ModoptionDefs
if not defs then return key end
for i = 1, #defs do
if defs[i].key == key then
return defs[i].name or key
end
end
return key
end

local function IsOptionalModoption(key)
local defs = WG.ModoptionDefs
if not defs then return false end
for i = 1, #defs do
if defs[i].key == key then
return defs[i].optional == true
end
end
return false
end

local function ParseModeVoteTitle(rawTitle)
local category, modeKey, rest = string.match(rawTitle, vote_modePattern)
if not modeKey then return nil end

local votedOptions = {}
if rest then
for k, v in string.gmatch(rest, "(%S+)=(%S+)") do
votedOptions[k] = v
end
end

return category, modeKey, votedOptions
end

local function FormatModeVoteTitle(rawTitle)
local category, modeKey, votedOptions = ParseModeVoteTitle(rawTitle)
if not modeKey then return rawTitle, nil end

local allModes = WG.Modes
local catModes = allModes and allModes[category]
if not (catModes and catModes.modes) then return rawTitle, nil end

local mode
for _, m in ipairs(catModes.modes) do
if m.key == modeKey then mode = m; break end
end
if not mode then return rawTitle, nil end

local modeName = mode.name or modeKey

local deviations = {}
local defaults = {}
local disabled = {}

if mode.modOptions then
for optKey, rule in pairs(mode.modOptions) do
if optKey == (category .. "_mode") then
-- skip
else
local modeDefault = tostring(rule.value)
if type(rule.value) == "boolean" then
modeDefault = rule.value and "1" or "0"
end
local votedVal = votedOptions[optKey]
local name = GetModoptionName(optKey)
if votedVal and votedVal ~= modeDefault then
deviations[#deviations + 1] = { name = name, value = votedVal, default = modeDefault }
else
defaults[#defaults + 1] = { name = name, value = votedVal or modeDefault }
end
end
end
end

local defs = WG.ModoptionDefs
if defs then
for i = 1, #defs do
local opt = defs[i]
if opt.key and opt.section == category and opt.key ~= (category .. "_mode") then
local inMode = mode.modOptions and mode.modOptions[opt.key]
if not inMode then
disabled[#disabled + 1] = opt.name or opt.key
end
end
end
end

-- Build compact display (for label)
local lines = {}
lines[#lines + 1] = COLOR_GOLD .. "Mode: " .. modeName .. COLOR_WHITE
if #deviations > 0 then
local parts = {}
for _, d in ipairs(deviations) do
parts[#parts + 1] = d.name .. ": " .. d.value
end
lines[#lines + 1] = COLOR_GREEN .. " Custom: " .. table.concat(parts, ", ") .. COLOR_WHITE
end

local displayText = table.concat(lines, "\n")

-- Build tooltip (full 4-section detail)
local tipLines = {}
tipLines[#tipLines + 1] = "MODE: " .. modeName
if #deviations > 0 then
tipLines[#tipLines + 1] = ""
tipLines[#tipLines + 1] = "CUSTOMIZED:"
for _, d in ipairs(deviations) do
tipLines[#tipLines + 1] = " " .. d.name .. ": " .. d.value .. " (default: " .. d.default .. ")"
end
end
if #defaults > 0 then
tipLines[#tipLines + 1] = ""
tipLines[#tipLines + 1] = "MODE DEFAULTS:"
for _, d in ipairs(defaults) do
tipLines[#tipLines + 1] = " " .. d.name .. ": " .. d.value
end
end
if #disabled > 0 then
tipLines[#tipLines + 1] = ""
tipLines[#tipLines + 1] = "NOT ACTIVE IN THIS MODE:"
tipLines[#tipLines + 1] = " " .. table.concat(disabled, ", ")
end
local tooltipText = table.concat(tipLines, "\n")

return displayText, tooltipText
end

local playerHandler

Expand Down Expand Up @@ -2925,7 +3060,7 @@ local function SetupVotePanel(votePanel, battle, battleID)
local oldVoteInitiator = ""
local oldTitle = ""

function externalFunctions.VoteUpdate(voteMessage, pollType, mapPoll, candidates, votesNeeded, pollUrl, voteInitiator, resetButtons)
function externalFunctions.VoteUpdate(voteMessage, pollType, mapPoll, candidates, votesNeeded, pollUrl, voteInitiator, resetButtons, modeTooltip)
--Spring.Echo("externalFunctions.VoteUpdate(voteMessage, pollType, mapPoll, candidates, votesNeeded, pollUrl, voteInitiator)",voteMessage, pollType, mapPoll, candidates, votesNeeded, pollUrl, voteInitiator)
UpdatePollType(pollType, mapPoll, pollUrl)

Expand All @@ -2941,6 +3076,7 @@ local function SetupVotePanel(votePanel, battle, battleID)
oldTitle = oldVoteInitiator.. " called a vote for:\n"..voteMessage..timeleft

voteName:SetCaption(oldTitle)
voteName.tooltip = modeTooltip
if votesNeeded == -1 then
voteCountLabel:SetCaption(tostring(candidates[1].votes))
voteProgressYes:SetValue(0)
Expand Down Expand Up @@ -4382,7 +4518,16 @@ local function InitializeControls(battleID, oldLobby, topPoportion, setupData)

local title = string.sub(message, string.find(message, ' "',nil,true) + 2, string.find(message, '" ', nil, true) - 1)
title = title:sub(1, 1):upper() .. title:sub(2)
votePanel.VoteUpdate(title,nil, ismapppoll, candidates, votesNeeded, mapname, userwhocalledvote, newlycalledvote)
local modeTooltip
local _, parsedModeKey = ParseModeVoteTitle(title)
if parsedModeKey then
title, modeTooltip = FormatModeVoteTitle(title)
Spring.Echo("[ModeVote] Display: " .. title)
if modeTooltip then
Spring.Echo("[ModeVote] Tooltip:\n" .. modeTooltip)
end
end
votePanel.VoteUpdate(title,nil, ismapppoll, candidates, votesNeeded, mapname, userwhocalledvote, newlycalledvote, modeTooltip)
return true

elseif string.match(message, "Vote for command.*passed" ) then --[21:13:58] * [teh]host * Vote for command "bSet coop 1" passed. --voteend
Expand Down
4 changes: 3 additions & 1 deletion LuaMenu/widgets/gui_login_window.lua
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,9 @@ local function InitializeListeners()
Configuration.password = registerPassword
registerName = nil
end
if Configuration.userName then
-- Skip auto-login when no password is saved (password == false): the user
-- logs in manually. Avoids gsub-on-boolean in Login/TextEraseNewline.
if Configuration.userName and (steamMode or type(Configuration.password) == "string") then
lobby:Login(Configuration.userName, Configuration.password, 3, nil, "Chobby", steamMode)
end
end
Expand Down
Loading