slotty = {} slotty.version = "1.2.0" --[[-- Single-player slot blocking and slot blocking fallback for multiplayer when SSB is not installed on server. Uses SSB's method of marking groups with flags (c) 2024 by Christian Franz Slotty can be disabled by setting the value of the flag named "noSlotty" to a value greater than zero Version history 1.0.0 - Initial version 1.1.0 - "noSlotty" global disable flag, anti-mirror SSB flag 1.2.0 - better (delayed) nilling for cfxSSB occupied clients to - avoid a race condition --]]-- function slotty.delayedSSBNil(args) uName = args if cfxSSBClient.verbose then trigger.action.outText("slotty-->SSBClient: nilling <" .. args .. ">, now unoccupied", 30) end cfxSSBClient.occupiedUnits[uName] = nil end function slotty:onEvent(event) if not event.initiator then return end local theUnit = event.initiator if not theUnit.getPlayerName then return end local pName = theUnit:getPlayerName() if not pName then return end local uName = theUnit:getName() local theGroup = theUnit:getGroup() local gName = theGroup:getName() if event.id == 15 then -- birth if trigger.misc.getUserFlag("noSlotty") > 0 then return end local np = net.get_player_list() -- retruns a list of PID local isSP = false if not np or (#np < 1) then isSP = true -- we are in single-player mode end -- now see if that group name is currently blocked local blockstate = false if trigger.misc.getUserFlag(gName) > 0 then trigger.action.outText("Group <" .. gName .. "> is currently blocked and can't be entered", 30) blockstate = true end if not blockstate then return end -- nothing left to do, all is fine -- interface with SSBClient for compatibility if cfxSSBClient and cfxSSBClient.occupiedUnits then -- to resolve a race condition, we schedule nilling the -- ssbClientSlot in 1/2 second -- cfxSSBClient.occupiedUnits[uName] = nil timer.scheduleFunction(slotty.delayedSSBNil, uName, timer.getTime() + 0.5) end if isSP then theUnit:destroy() -- SP kill, works only in Single-player return end -- we would leave the rest to SSB, but if we get here, SSB is -- not installed on host, so we proceed with invoking netAPI for idx,pid in pairs(np) do local netName = net.get_name(pid) if netName == pName then timer.scheduleFunction(slotty.kick, pid, timer.getTime() + 0.1) return end end end end function slotty.kick(pid) net.force_player_slot(pid, 0, '') -- '', thanks Dz! end function slotty.start() world.addEventHandler(slotty) trigger.action.outText("slotty v " .. slotty.version .. " running.", 30) end slotty.start()