Skip to content

Commit

Permalink
AllowCommand per cmdId registration (#3899)
Browse files Browse the repository at this point in the history
* Introduce a mechanism for gadget AllowCommand callins to only receive subscribed cmdID.
* Implement this mechanism for all current gadgets using AllowCommand (~40).
* Allows blanket subscription through CMD.ANY
  • Loading branch information
saurtron authored Nov 14, 2024
1 parent 157be4d commit 9e305e8
Show file tree
Hide file tree
Showing 43 changed files with 269 additions and 62 deletions.
87 changes: 86 additions & 1 deletion luarules/gadgets.lua
Original file line number Diff line number Diff line change
Expand Up @@ -537,6 +537,12 @@ function gadgetHandler:NewGadget()
gh.RemoveChatAction = function(_, cmd)
return actionHandler.RemoveChatAction(gadget, cmd)
end
gh.RegisterAllowCommand = function(_, cmdID)
return self:RegisterAllowCommand(gadget, cmdID)
end
gh.DeregisterAllowCommands = function(_)
return self:DeregisterAllowCommands(gadget)
end

if not IsSyncedCode() then
gh.AddSyncAction = function(_, cmd, func, help)
Expand Down Expand Up @@ -694,6 +700,11 @@ function gadgetHandler:InsertGadget(gadget)
end
self:UpdateCallIns()

if gadget.AllowCommand and not self:HasAllowCommands(gadget) then
Spring.Log('AllowCommand', LOG.WARNING, "<" .. gadget.ghInfo.basename .. "> AllowCommand defined but didn't register any commands. Autoregistering for all commands!")
self:RegisterAllowCommand(gadget, CMD.ANY)
end

if kbytes then
collectgarbage("collect")
collectgarbage("collect")
Expand All @@ -718,6 +729,7 @@ function gadgetHandler:RemoveGadget(gadget)
for _, listname in ipairs(callInLists) do
ArrayRemove(self[listname .. 'List'], gadget)
end
self:DeregisterAllowCommands(gadget)

for id, g in pairs(self.CMDIDs) do
if g == gadget then
Expand Down Expand Up @@ -888,6 +900,7 @@ function gadgetHandler:RaiseGadget(gadget)
for _, listname in ipairs(callInLists) do
Raise(self[listname .. 'List'], gadget[listname], gadget)
end
self:ReorderAllowCommands(gadget, Raise)
end

local function FindHighestIndex(t, i, layer)
Expand Down Expand Up @@ -922,6 +935,7 @@ function gadgetHandler:LowerGadget(gadget)
for _, listname in ipairs(callInLists) do
Lower(self[listname .. 'List'], gadget[listname], gadget)
end
self:ReorderAllowCommands(gadget, Lower)
end

function gadgetHandler:FindGadget(name)
Expand Down Expand Up @@ -1241,6 +1255,72 @@ function gadgetHandler:PlayerRemoved(playerID, reason)
return
end

--------------------------------------------------------------------------------
--
-- AllowCommand subscription
--

local CMD_ANY = CMD.ANY
local CMD_NIL = CMD.NIL
local allowCommandList = {[CMD_ANY] = {}}

function gadgetHandler:ReorderAllowCommands(gadget, f)
if not gadget.AllowCommand then return true end
for _, list in pairs(allowCommandList) do
f(list, true, gadget)
end
end

function gadgetHandler:HasAllowCommands(gadget)
for _, list in pairs(allowCommandList) do
for _, g in ipairs(list) do
if g == gadget then
return true
end
end
end
end

function gadgetHandler:DeregisterAllowCommands(gadget)
for _, list in pairs(allowCommandList) do
ArrayRemove(list, gadget)
end
end

function gadgetHandler:RegisterAllowCommand(gadget, cmdID)
-- cmdID accepts CMD.ANY and CMD.NIL in addition to usual cmdIDs
-- CMD.ANY subscribes to any command
Spring.Log('AllowCommand', LOG.INFO, "<" .. gadget.ghInfo.basename .. "> Register "..tostring(cmdID))
if cmdID == nil then
-- use CMD.NIL instead
Spring.Log('AllowCommand', LOG.ERROR, "<" .. gadget.ghInfo.basename .. "> Invalid cmdID "..tostring(cmdID))
return
end
if not gadget.AllowCommand then
Spring.Log('AllowCommand', LOG.ERROR, "<" .. gadget.ghInfo.basename .. "> No callin method")
return
end
cmdList = allowCommandList[cmdID]
-- create list if needed
if not cmdList then
cmdList = {}
allowCommandList[cmdID] = cmdList
-- on a new list, register all known CMD.ANY commands
if cmdID ~= CMD_ANY then
for _, g in ipairs(allowCommandList[CMD_ANY]) do
ArrayInsert(cmdList, true, g)
end
end
end
-- insert into the list
ArrayInsert(cmdList, true, gadget)
-- if it's a CMD.ANY registration, insert into all lists
if cmdID == CMD_ANY then
for _, list in pairs(allowCommandList) do
ArrayInsert(list, true, gadget)
end
end
end

--------------------------------------------------------------------------------
--
Expand Down Expand Up @@ -1319,13 +1399,18 @@ end

function gadgetHandler:AllowCommand(unitID, unitDefID, unitTeam,
cmdID, cmdParams, cmdOptions, cmdTag, playerID, fromSynced, fromLua)
local cmdKey = cmdID or CMD_NIL
if not allowCommandList[cmdKey] then cmdKey = CMD_ANY end

tracy.ZoneBeginN("G:AllowCommand")
for _, g in ipairs(self.AllowCommandList) do
for _, g in ipairs(allowCommandList[cmdKey]) do
--tracy.ZoneBeginN("G:AllowCommand:"..g.ghInfo.name)
if not g:AllowCommand(unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag, playerID, fromSynced, fromLua) then
--tracy.ZoneEnd()
tracy.ZoneEnd()
return false
end
--tracy.ZoneEnd()
end
tracy.ZoneEnd()
return true
Expand Down
3 changes: 2 additions & 1 deletion luarules/gadgets/cmd_factory_stop_production.lua
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ if gadgetHandler:IsSyncedCode() then
end

function gadget:AllowCommand(unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions)
if (cmdID ~= CMD_STOP_PRODUCTION) or not isFactory[unitDefID] then
if not isFactory[unitDefID] then
return true
end

Expand Down Expand Up @@ -115,6 +115,7 @@ if gadgetHandler:IsSyncedCode() then

function gadget:Initialize()
gadgetHandler:RegisterCMDID(CMD_STOP_PRODUCTION)
gadgetHandler:RegisterAllowCommand(CMD_STOP_PRODUCTION)
for _, unitID in pairs(Spring.GetAllUnits()) do
gadget:UnitCreated(unitID, Spring.GetUnitDefID(unitID))
end
Expand Down
8 changes: 4 additions & 4 deletions luarules/gadgets/cmd_manual_launch.lua
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,7 @@ function gadget:AllowCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOpt
cmdParams[2] = CMD.MANUALFIRE
Spring.GiveOrderToUnit(unitID, CMD.INSERT, cmdParams, cmdOptions.coded)
return false
end

if cmdID == CMD_MANUAL_LAUNCH then
elseif cmdID == CMD_MANUAL_LAUNCH then
Spring.GiveOrderToUnit(unitID, CMD.MANUALFIRE, cmdParams, cmdOptions.coded)
return false
end
Expand All @@ -56,4 +54,6 @@ end

function gadget:Initialize()
gadgetHandler:RegisterCMDID(CMD_MANUAL_LAUNCH)
end
gadgetHandler:RegisterAllowCommand(CMD.INSERT)
gadgetHandler:RegisterAllowCommand(CMD_MANUAL_LAUNCH)
end
1 change: 1 addition & 0 deletions luarules/gadgets/cmd_mex_denier.lua
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ end
local metalSpotsList

function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(CMD.ANY)
local isMetalMap = GG["resource_spot_finder"].isMetalMap
if isMetalMap then
Spring.Log(gadget:GetInfo().name, LOG.INFO, "Metal map detected, removing self")
Expand Down
4 changes: 4 additions & 0 deletions luarules/gadgets/cmd_paused_is_paused.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,7 @@ function gadget:AllowCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOpt
return true
end
end

function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(CMD.ANY)
end
6 changes: 4 additions & 2 deletions luarules/gadgets/cmd_remove_stop.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ function gadget:AllowCommand_GetWantedUnitDefID()
end

function gadget:AllowCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOptions, cmdTag, playerID, fromSynced, fromLua)
if (cmdID == CMD_STOP and stopRemoveDefs[unitDefID]) then
-- accepts: CMD.STOP
if stopRemoveDefs[unitDefID] then
return false
end
return true
Expand All @@ -60,9 +61,10 @@ function gadget:UnitCreated(unitID, unitDefID)
end

function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(CMD_STOP)
-- load active units
for _, unitID in ipairs(Spring.GetAllUnits()) do
local unitDefID = Spring.GetUnitDefID(unitID)
gadget:UnitCreated(unitID, unitDefID)
end
end
end
6 changes: 4 additions & 2 deletions luarules/gadgets/cmd_remove_wait.lua
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ function gadget:AllowCommand_GetWantedUnitDefID()
end

function gadget:AllowCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOptions, cmdTag, playerID, fromSynced, fromLua)
if (cmdID == CMD_WAIT and waitRemoveDefs[unitDefID]) then
-- accepts: CMD.WAIT
if waitRemoveDefs[unitDefID] then
return false
end
return true
Expand All @@ -60,9 +61,10 @@ function gadget:UnitCreated(unitID, unitDefID)
end

function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(CMD_WAIT)
-- load active units
for _, unitID in ipairs(Spring.GetAllUnits()) do
local unitDefID = Spring.GetUnitDefID(unitID)
gadget:UnitCreated(unitID, unitDefID)
end
end
end
10 changes: 5 additions & 5 deletions luarules/gadgets/gaia_critters.lua
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ end
local mapConfig

function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(CMD.ATTACK)
local allUnits = Spring.GetAllUnits()
for _, unitID in pairs(allUnits) do
local unitDefID = GetUnitDefID(unitID)
Expand Down Expand Up @@ -577,11 +578,10 @@ end

--http://springrts.com/phpbb/viewtopic.php?f=23&t=30109
function gadget:AllowCommand(unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag, playerID, fromSynced, fromLua)
if cmdID and cmdID == CMD.ATTACK then
if cmdParams and #cmdParams == 1 then
if critterUnits[cmdParams[1]] ~= nil then
return false
end
-- accepts: CMD.ATTACK
if cmdParams and #cmdParams == 1 then
if critterUnits[cmdParams[1]] ~= nil then
return false
end
end
return true
Expand Down
2 changes: 2 additions & 0 deletions luarules/gadgets/game_apm_broadcast.lua
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ if gadgetHandler:IsSyncedCode() then
function gadget:Initialize()
GG['apm'] = {}
GG['apm'].addSkipOrder = addSkipOrder

gadgetHandler:RegisterAllowCommand(CMD.ANY)
end

function gadget:UnitFinished(unitID, unitDefID, teamID, builderID)
Expand Down
3 changes: 3 additions & 0 deletions luarules/gadgets/game_no_rush_mode.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,9 @@ end


if gadgetHandler:IsSyncedCode() then
function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(CMD.ANY)
end
function gadget:AllowCommand(unitID, unitDefID, unitTeam, cmdID, cmdParams, cmdOptions, cmdTag, synced)
local allowed = true
local frame = Spring.GetGameFrame()
Expand Down
6 changes: 5 additions & 1 deletion luarules/gadgets/game_selfd_resign.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@ if gadgetHandler:IsSyncedCode() then
end
end

function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(CMD_SELFD)
end

function gadget:GameFrame(n)
if n % 15 == 1 then
for teamID, _ in pairs(selfdCheckTeamUnits) do
Expand Down Expand Up @@ -95,7 +99,7 @@ if gadgetHandler:IsSyncedCode() then
end

function gadget:AllowCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOptions, cmdTag, playerID, fromSynced, fromLua)
if cmdID == CMD_SELFD and teamID ~= gaiaTeamID then
if teamID ~= gaiaTeamID then
selfdCheckTeamUnits[teamID] = true
end
return true
Expand Down
12 changes: 6 additions & 6 deletions luarules/gadgets/game_unit_market.lua
Original file line number Diff line number Diff line change
Expand Up @@ -320,12 +320,11 @@ function gadget:UnitFinished(unitID, unitDefID, teamID, builderID)
end

function gadget:AllowCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOptions, cmdTag, playerID, fromSynced, fromLua)
if (cmdID == CMD_SELL_UNIT) then
local unitDef = UnitDefs[unitDefID]
if unitDef then
local price = unitDef.metalCost
setUnitOnSale(unitID, price, true)
end
-- accepts: CMD_SELL_UNIT
local unitDef = UnitDefs[unitDefID]
if unitDef then
local price = unitDef.metalCost
setUnitOnSale(unitID, price, true)
end
return true
end
Expand All @@ -335,6 +334,7 @@ local function isTeamSaving(teamID)
end

function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(CMD_SELL_UNIT)
local teamList = spGetTeamList()
for _, teamID in ipairs(teamList) do
TeamIsSaving[teamID] = false
Expand Down
7 changes: 6 additions & 1 deletion luarules/gadgets/unit_air_plants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,13 @@ function gadget:UnitFinished(unitID, unitDefID, unitTeam)
end
end

function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(34569) -- LandAt
gadgetHandler:RegisterAllowCommand(34570) -- AirRepair
end

function gadget:AllowCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOptions, cmdTag, playerID, fromSynced, fromLua)
if (cmdID == 34569 or cmdID == 34570) and isAirplant[unitDefID] and plantList[unitID] then
if isAirplant[unitDefID] and plantList[unitID] then
if cmdID == 34569 then
local cmdDescID = FindUnitCmdDesc(unitID, 34569)
landCmd.params[1] = cmdParams[1]
Expand Down
1 change: 1 addition & 0 deletions luarules/gadgets/unit_airunitsturnradius.lua
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ end
isBomb = nil

function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(CMD.ANY)
for ct, unitID in pairs(Spring.GetAllUnits()) do
gadget:UnitCreated(unitID, Spring.GetUnitDefID(unitID))
end
Expand Down
12 changes: 5 additions & 7 deletions luarules/gadgets/unit_areaattack.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,14 +56,11 @@ if gadgetHandler:IsSyncedCode() then
end

function gadget:AllowCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOptions, cmdTag, playerID, fromSynced, fromLua)
if cmdID == CMD_AREAATTACK then
if canAreaAttack[unitDefID] then
return true
else
return false
end
else
-- accepts: CMD_AREAATTACK
if canAreaAttack[unitDefID] then
return true
else
return false
end
end

Expand All @@ -90,6 +87,7 @@ if gadgetHandler:IsSyncedCode() then

function gadget:Initialize()
gadgetHandler:RegisterCMDID(CMD_AREAATTACK)
gadgetHandler:RegisterAllowCommand(CMD_AREAATTACK)
end

else -- UNSYNCED
Expand Down
4 changes: 3 additions & 1 deletion luarules/gadgets/unit_attributes.lua
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,7 @@ local function SetAllowUnitCoast(unitID, allowed)
end

function gadget:Initialize()
gadgetHandler:RegisterAllowCommand(70)
GG.UpdateUnitAttributes = UpdateUnitAttributes
GG.SetAllowUnitCoast = SetAllowUnitCoast

Expand Down Expand Up @@ -683,7 +684,8 @@ function gadget:AllowCommand_GetWantedUnitDefID()
end

function gadget:AllowCommand(unitID, unitDefID, teamID, cmdID, cmdParams, cmdOptions)
if (cmdID == 70 and unitSlowed[unitID]) then
-- accepts: 70 (SET_WANTED_MAX_SPEED, but not registered anywhere)
if unitSlowed[unitID] then
return false
else
return true
Expand Down
Loading

0 comments on commit 9e305e8

Please sign in to comment.