-- =================================================================== codergroups = {} codergroups.registered_groups = {} local storage = minetest.get_mod_storage() -- =================================================================== minetest.register_privilege ("groups", { description = "Group administrator" , }) -- =================================================================== codergroups.group_exists = function (grname) if codergroups.registered_groups [grname] ~= nil then return true else return false end end -- =================================================================== -- "codergroups.groups_to_string" is analogous to "minetest.privs_to_ -- string". It converts the 1st representation below to the 2nd: -- -- { group1=true, group2=true, ... } -- "group1,group2,..." -- If "delim" is specified, it's used as the delimiter instead of com- -- ma. -- =================================================================== codergroups.groups_to_string = function (ktable, delim) if ocutil.str_empty (delim) then delim = "," end local vtable = ocutil.ktable_to_vtable (ktable) return table.concat (vtable, delim) end -- =================================================================== -- "codergroups.string_to_groups" is analogous to "minetest.string_to_ -- privs". It converts the 1st representation below to the 2nd: -- -- "group1,group2,..." -- { group1=true, group2=true, ... } -- If "delim" is specified, it's used as the delimiter instead of com- -- ma. -- =================================================================== codergroups.string_to_groups = function (str, delim) if ocutil.str_empty (str ) then return {} end if ocutil.str_empty (delim) then delim = "," end if str == "all" then return codergroups.registered_groups end local vtable = ocutil.strtok (str, delim) local ktable = ocutil.vtable_to_ktable (vtable) return ktable end -- =================================================================== -- "codergroups.get_player_groups" is analogous to "minetest.get_ -- player_privs". It takes a player name and returns a table of the -- form: -- -- { group1=true, group2=true, ... } -- =================================================================== codergroups.get_player_groups = function (plname) return codergroups.string_to_groups (storage:get_string (plname)) end -- =================================================================== -- "codergroups.set_player_groups" is analogous to "minetest.set_play- -- er_privs". It takes a player name and a table of the form: -- -- { group1=true, group2=true, ... } -- =================================================================== codergroups.set_player_groups = function (plname, ktable) storage:set_string (plname, codergroups.groups_to_string (ktable)) end -- =================================================================== codergroups.check_player_groups = function (obj, ...) if core.is_player (obj) then obj = obj:get_plname() end if type (obj) ~= "string" then ocutil.panic ("Invalid arguments to check_player_groups") end local plname = obj local requested_groups = { ... } local player_groups = codergroups.get_player_groups (plname) local missing_groups = {} if type (requested_groups [1]) == "table" then -- We were provided with a table like -- { groupA = true, groupB = true } for group, value in pairs (requested_groups [1]) do if value and not player_groups [group] then missing_groups [#missing_groups + 1] = group end end else -- Only a list, we can process it directly -- for key, group in pairs (requested_groups) do if not player_groups [group] then missing_groups [#missing_groups + 1] = group end end end if #missing_groups > 0 then return false, missing_groups end return true, "" end -- =================================================================== codergroups.register_group = function (grname, param) local function fill_defaults (def) if def.give_to_singleplayer == nil then def.give_to_singleplayer = true end if def.description == nil then def.description = "(no description)" end end local def = {} if type (param) == "table" then def = param else def = { description = param } end fill_defaults (def) codergroups.registered_groups [grname] = def end -- =================================================================== local param_group = { params = "[]" , privs = {} , description = "List groups of yourself or another player" , func = function (caller, param) param = param:trim() local plname = (ocutil.str_nonempty (param) and param) or caller if not core.player_exists (plname) then return false, "Player " .. plname .. " doesn't exist" end local ktable = codergroups.get_player_groups (plname) local str = codergroups.groups_to_string (ktable, " ") if ocutil.str_empty (str) then str = plname .. " is in no groups" else str = plname .. " is in these group(s): " .. str end return true, str end , } core.register_chatcommand ("group" , param_group ) core.register_chatcommand ("groups" , param_group ) -- =================================================================== codergroups.ingroup_vtable = function (group) local group = group:trim() local gtable = storage:to_table() if gtable == nil then return {} end gtable = gtable ["fields"] if gtable == nil or type (gtable) ~= "table" then return {} end local pllist = {} for player, str in pairs (gtable) do if type (player) == "string" and type (str ) == "string" then local vtable = ocutil.strtok (str, ",") local ktable = ocutil.vtable_to_ktable (vtable) if ktable [group] ~= nil then table.insert (pllist, player) end end end return pllist end -- =================================================================== local param_ingroup = { params = "" , privs = {} , description = "List the players in a group" , func = function (caller, param) local group = param:trim() if param == "" then return false, "Invalid parameters (see /help ingroup)" end local pllist = codergroups.ingroup_vtable (group) str = table.concat (pllist, " ") if ocutil.str_empty (str) then str = "The group " .. group .. " is empty" end return true, str end } core.register_chatcommand ("hasgroup" , param_ingroup) core.register_chatcommand ("ingroup" , param_ingroup) -- =================================================================== codergroups.groupadd = function (adname, plname, group_str) local ktable local str if false then local caller_privs = core.get_player_privs (adname) if not (caller_privs.privs or caller_privs.basic_privs) then return false, "Your privileges are insufficient" end end if not core.get_auth_handler().get_auth (plname) then return false, "Player " .. plname .. " doesn't exist" end local addto_groups = codergroups.string_to_groups (group_str) if group_str == "all" then addto_groups = codergroups.registered_groups end local groups = codergroups.get_player_groups (plname) local groups_unknown = "" for group, _ in pairs (addto_groups) do if not codergroups.registered_groups [group] then groups_unknown = groups_unknown .. "Unknown group: " .. group .. "\n" end groups [group] = true end if groups_unknown ~= "" then return false, groups_unknown end codergroups.set_player_groups (plname, groups) str = codergroups.groups_to_string (addto_groups, " ") -- minetest.log ("action", adname .. " added " .. plname .. " to group(s): " .. str) if plname ~= adname then core.chat_send_player (plname, adname .. " added you to group(s): " .. str) end ktable = codergroups.get_player_groups (plname) str = codergroups.groups_to_string (ktable, " ") if ocutil.str_empty (str) then str = "None" end -- return true, "Groups of " .. plname .. ": " .. str end -- =================================================================== local param_groupadd = { params = " ( | all)" , description = "Add player to a group" , privs = { groups=true } , func = function (adname, param) local plname, group_str = string.match (param, "([^ ]+) (.+)") if not plname or not group_str then return false, "Invalid parameters (see /help groupadd)" end return codergroups.groupadd (adname, plname, group_str) end , } core.register_chatcommand ("groupadd" , param_groupadd) -- =================================================================== local param_groupme = { params = " | all" , description = "Add yourself to a group" , privs = { groups=true } , func = function (adname, param) if param == "" then return false, "Invalid parameters (see /help groupme)" end return codergroups.groupadd (adname, adname, param) end , } core.register_chatcommand ("groupme", param_groupme) -- =================================================================== -- This routine removes the player specified by "plname" from zero or -- more groups specified by the ktable "delta_groups". codergroups.grouprem = function (adname, plname, delta_groups) local tgt_groups = codergroups.get_player_groups (plname) local chg = {} for group, _ in pairs (delta_groups) do if tgt_groups [group] then tgt_groups [group] = nil table.insert (chg, group) end end if #chg then table.sort (chg) codergroups.set_player_groups (plname, tgt_groups) local str = table.concat (chg, " ") minetest.log ("action", adname .. " removed " .. plname .. " from group(s): " .. str) if plname ~= adname then minetest.chat_send_player (plname, adname .. " removed you from group(s): " .. str) end end end -- =================================================================== local param_grouprem = { params = "( | all) ( | all)" , description = "Remove player from a group" , privs = { groups=true } , func = function (adname, param) local obj local str if false then if not core.check_player_privs (adname, { privs=true }) and not core.check_player_privs (adname, { basic_privs=true }) then return false, "Your privileges are insufficient" end end local plname, group_str = string.match (param, "([^ ]+) (.+)") if not plname or not group_str then return false, "Invalid parameters (see /help grouprem)" elseif plname == "all" then plname = plname elseif not core.get_auth_handler().get_auth (plname) then return false, "Player " .. plname .. " doesn't exist" end local delta_groups = codergroups.string_to_groups (group_str) if group_str == "all" then group_str = "all groups" end if plname == "all" then for group, _ in pairs (delta_groups) do local pllist = codergroups.ingroup_vtable (group) for _, plname in ipairs (pllist) do codergroups.grouprem (adname, plname, delta_groups) end end return true, "Removed all players from " .. group_str else codergroups.grouprem (adname, plname, delta_groups) return true, "Removed " .. plname .. " from " .. group_str end end , } core.register_chatcommand ("grouprem" , param_grouprem) core.register_chatcommand ("groupremove" , param_grouprem) -- =================================================================== local param_listgroups = { params = "" , description = "List registered groups" , func = function (plname) local ktable = codergroups.registered_groups local str = codergroups.groups_to_string (ktable, " ") minetest.chat_send_player (plname, str) end , } core.register_chatcommand ("listgroup" , param_listgroups) core.register_chatcommand ("listgroups" , param_listgroups) core.register_chatcommand ("list_group" , param_listgroups) core.register_chatcommand ("list_groups" , param_listgroups) -- =================================================================== codergroups.register_group ("alpha" , "Alpha group") codergroups.register_group ("beta" , "Beta group" ) -- =================================================================== local addlist = minetest.setting_get ("codergroups") if ocutil.str_nonempty (addlist) then addlist = addlist:gsub (" ", ",") addlist = codergroups.string_to_groups (addlist) for group,_ in pairs (addlist) do codergroups.register_group (group, group .. " group") end end -- =================================================================== -- End of file.