-- SRB2 Lua Script -- No skins for some plyers! -- Copyright 2019 James R. -- This file is placed in the public domain. -- -- The commands blacklistskin, whitelistskin, and skinrlist are added by this -- script. The global table skinblacklist is defined. And the the skinblacklist -- and skinwhitelist tables are defined for each player. Specification of -- commands is written below. local INFO = "It is pertinent that you understand how the blacklist- and whitelist-\n".. "skin commands work!\n\n".. "Blacklisting a skin removes it from the whitelist, and vice-versa.\n".. "There is no universal whitelist--just use the blacklist.\n\n".. "Each parameter of the command must be a skin name. The following except-\n".. "ions apply.\n\n".. "A parameter that begins with a at-symbol (@) shall set the player to whom\n".. "skin restrictions apply thereafter. The text that follows in the parameter\n".. "must be a player's name or number. If no text follows, the restrictions\n".. "apply universally.\n\n".. "A parameter that begins with a hyphen (-) shall remove the skin name that\n".. "follows in the parameter from restriction.\n\n".. "If a parameter begins with a backward-slash (\\), the text that follows\n".. "in the parameter is accepted as a skin name.\n\n".. "The skinrlist command may be used to list the restrictions applicable to\n".. "all players and yourself; or, with parameter, for a specific player, by\n".. "name or number." local firsttime = CV_RegisterVar( { "ihavusdnoskinforu", 0, CV_SAVE, CV_YesNo }) local function ReverseBlacklist (t, k, v) if (t[2])-- set value in this table too then rawset (t, k, v) end if (t[1] and v) then rawset (t[1], k, nil) end end local function SetupReverseBlacklist (t) setmetatable (t, { __newindex = ReverseBlacklist, __usedindex = ReverseBlacklist }) end rawset (_G, "skinblacklist", {}) rawset (_G, "skinwhitelist", { skinblacklist }) SetupReverseBlacklist(skinwhitelist) local function FindPlayer (s) local n = tonumber (s) if (n ~= nil) and (n >= 0 and n < #players) then return players[n] end s = $:lower() for p in players.iterate do if (s == p.name:lower()) then return p end end return nil end local function Blacklist (who, how, rem, what) if (what) then what = tostring ($) if (skins[what] == nil) then return -1 end if (rem) then who[how][what] = nil else who[how][what] = 1 end else if (rem) then who[how] = {} else for sk in skins.iterate do who[how][sk.name] = 1 end end end return 0 end local function ResetSkin (p, skn) R_SetPlayerSkin(p, skn) COM_BufInsertText(p, "skin ".. skn)-- reset the client's record CONS_Printf(p, "\x83NOTICE:\x80".. "You cannot use that skin. Type `skinrlist` in console to see why.") end local function SkinlistIterator (how) local k return function () repeat k = next (how, k) if type (k) == "string" then return k end-- skin entry until k == nil end end local function CheckBlacklist (needreset, ok, how, skn) if (how[skn]) then needreset = true end for sk in skins.iterate do if (how[ok]) and not (how[sk.name]) then ok = sk.name break end end return needreset, ok end local function Restrict (p, fallback) local needreset = false local ok = fallback needreset, ok = CheckBlacklist(needreset, ok, skinblacklist, p.mo.skin) needreset, ok = CheckBlacklist(needreset, ok, p.skinblacklist, p.mo.skin) for k in SkinlistIterator(p.skinwhitelist) do if (p.mo.skin == k) then return end if (ok == nil) then ok = k end end if (needreset and ok ~= p.mo.skin) then ResetSkin(p, ok) end end local function Command_skinrlist (how, p, ...) if (firsttime.value == 0) then CONS_Printf (p, INFO) CONS_Printf (p, "\n\nYou will not see this text in sequential games that use this program.\n".. "No action has been taken using this command; please reenter it!") COM_BufInsertText(p, firsttime.name .." 1") return end local who = _G local at = { ... } if (#at == 0) then Blacklist(who, how, false) end for k,arg in ipairs (at) do if (arg:sub(1,1) == "@")-- for player then local s = arg:sub(2) if (s == "")-- no player then who = _G else who = FindPlayer(s) if (who == nil) then CONS_Printf (p, "I couldn't find a player `" ..s.. "'.") CONS_Printf (p, "Ammend your command; I will not continue!") break end end if (k == #at) then Blacklist(who, how, false) end else local rem = false if (arg:sub(1,1) == "-") then rem = true ; arg = $:sub(2) elseif (arg:sub(1,1) == "\\") then arg = $:sub(2) end if (Blacklist(who, how, rem, arg:lower()) == -1) then CONS_Printf (p, "No such skin named `" ..arg.. "'.") end end end -- We need to restrict the players for p in players.iterate do Restrict(p, p.mo.skin) end end local function TabulateSkinrlist (p, who, header) CONS_Printf (p, header) CONS_Printf (p, "\n--- Blacklist ---") for skn in SkinlistIterator(who.skinblacklist) do CONS_Printf (p, skn) end if (who ~= _G) then CONS_Printf (p, "\n--- Whitelist ---") for skn in SkinlistIterator(who.skinwhitelist) do CONS_Printf (p, skn) end end CONS_Printf (p, "") end COM_AddCommand ("blacklistskin", function (...) Command_skinrlist("skinblacklist", ...) end, 1) COM_AddCommand ("whitelistskin", function (...) Command_skinrlist("skinwhitelist", ...) end, 1) COM_AddCommand ("skinrlist", function (p, tp) local who = _G if (tp) then who = FindPlayer(tp) if (who == nil) then CONS_Printf (p, "No such player `" ..tp.. "'") end if (who == nil or xparm) then CONS_Printf (p, "The correct usage is: skinrlist PLAYER; where PLAYER is optional.") return end TabulateSkinrlist(p, who, tp .." has the following restrictions.") else TabulateSkinrlist(p, _G, "All players have the following restrictions.") TabulateSkinrlist(p, p, "You have the following restrictions.") end end) addHook ("ThinkFrame", function () for p in players.iterate do if (p.skinblacklist == nil) then p.skinblacklist = { p.skinwhitelist, 1 } SetupReverseBlacklist(p.skinblacklist) end if (p.skinwhitelist == nil) then p.skinwhitelist = { p.skinblacklist, 1 } SetupReverseBlacklist(p.skinwhitelist) end if (p.prevskin) and (p.prevskin ~= p.mo.skin) then Restrict(p, p.prevskin)-- I hope thos is goof enough end p.prevskin = p.mo.skin end end) -- vim: ts=3 sw=3