diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..cf54999 --- /dev/null +++ b/init.lua @@ -0,0 +1,250 @@ +--[[ INITIALIZING: basics ]]-- + +-- global API table +modpol = { +} + +-- table for all active governance data +modpol.orgs = { +} + +-- record of governance interactions +-- every state change should appear here +modpol.ledger = { +} + +-- update from mod_storage +-- https://dev.minetest.net/StorageRef +local mod_storage = minetest.get_mod_storage() +-- load orgs +local stored_orgs = minetest.deserialize(mod_storage:get_string("orgs")) +if (stored_orgs ~= nil) then + modpol.orgs = stored_orgs +end +-- load orgs +local stored_ledger = minetest.deserialize(mod_storage:get_string("ledger")) +if (stored_ledger ~= nil) then + modpol.ledger = stored_ledger +end + + +--[[ FUNCTIONS:basics ]]-- + +-- record(message, org) +-- writes all governance events to storage and ledger +function modpol.record(message, org) + -- record to ledger + table.insert(modpol.ledger, message) + -- record to org_ledger + if (modpol.orgs[org] ~= nil) then + local org_ledg = modpol.orgs[org]["ledger"] + if (org_ledg == nil) then + modpol.orgs[org]["ledger"] = {message} + else + modpol.orgs[org]["ledger"] = table.insert(org_ledg,message) + end + end + -- record to storage + mod_storage:set_string("orgs", minetest.serialize(modpol.orgs)) + mod_storage:set_string("ledger", minetest.serialize(modpol.ledger)) +end + +--[[ FUNCTIONS:orgs ]]-- + +-- new_org() +-- create an org and add it to the list +function modpol.new_org(orgName, orgMembers) + if (orgName == "") then -- blank orgName input + return "-!- Org needs a name" + end + if (modpol.orgs[orgName] == nil) then -- copy check + modpol.orgs[orgName] = {members = orgMembers} + else return "-!- Org already exists" + end + local message = "New org: " .. orgName .. + " (" .. table.concat(orgMembers, ", ") .. ")" + modpol.record(message, orgName) + return message +end + +-- /neworg [name] +-- creates a new org with the current user as sole member +minetest.register_chatcommand( + "neworg", { + privs = {}, + func = function(user, param) + local result = + modpol.new_org(param,{user}) + return true, result + end, +}) + +-- rename_org() +function modpol.rename_org(oldName, newName) + -- TKTK + local message = "Org renamed: " .. oldName .. " > " .. newName + modpol.record(message, newName) +end + + +-- /listorgs +-- lists the orgs currently in the game +minetest.register_chatcommand( + "listorgs", { + privs = {}, + func = function(user, param) + local orglist = "" + for key, value in pairs(modpol.orgs) do + -- first, set up member list + local membs = modpol.orgs[key]["members"] + if (membs == nil) then membs = "" + else membs = " (" .. table.concat(membs, ", ") .. ")" + end + -- now, assemble the list + if (orglist == "") -- first element only + then orglist = key .. membs + else orglist = orglist .. ", " .. key .. membs + end + end + return true, "Orgs: " .. orglist + end, +}) + +-- rm_orgs() +-- removes all orgs +function modpol.rm_orgs() + modpol.orgs["instance"] = {members = modpol.list_members()} + local message = "Orgs purged" + modpol.record(message, nil) + return message +end + +-- /rmorgs +minetest.register_chatcommand( + "rmorgs", { + privs = {}, + func = function(user, param) + modpol.orgs = {} + return true, modpol.rm_orgs() + end, +}) + +--[[ FUNCTIONS:users ]]-- + +-- list_members(domain) +-- produces a table with names of players currently in the game +-- if empty, lists all players; if an org name, lists its members +function modpol.list_members(domain) + local members = {} + if (domain == nil) then -- no specified domain; all players + for _,player in ipairs(minetest.get_connected_players()) do + local name = player:get_player_name() + table.insert(members,name) + end + else -- if an org is specified + if (modpol.orgs[domain] ~= nil) then -- org exists + members = modpol.orgs[domain]["members"] + end + end + return members +end + +-- /listplayers +minetest.register_chatcommand( + "listplayers", { + privs = {}, + func = function(user) + local result = table.concat(modpol.list_members(),", ") + return true, "All players: " .. result + end, +}) + +function modpol.add_member(org, member) + if (modpol.orgs.org == nil) then + return "-!- No such org" + else + table.insert(modpol.orgs.org["members"], member) + local message = member .. " added to org " .. org + modpol.record(message, org) + return message + end + +end + +-- /joinorg +minetest.register_chatcommand( + "joinorg", { + privs = {}, + func = function(user, param) + local result = modpol.add_member(param, user) + return true, result + end, +}) + + +function modpol.remove_member(org, member) +-- remove from all child orgs also + local message = member .. " removed from org " .. org + modpol.record(message, org) + return message +end + +-- /listmembers [org] +-- lists the members of an org +minetest.register_chatcommand( + "listmembers", { + privs = {}, + func = function(user, param) + local orglist = modpol.list_members(param) + return true, param .. ": " .. table.concat(orglist,", ") + end, +}) + + +-- PERMISSIONS FUNCTIONS + + +-- PRIVILEGE FUNCTIONS +-- Minetest-specific +-- manages user privileges according to org membership + +function modpol.assign_privilege(org, privilege) +-- add privilege to all members of an org +end + + +function modpol.remove_privilege(org, privilege) +-- remove privilege from all members of an org, unless they have it from other orgs +end + +-- POLLING FUNCTIONS + +function modpol.poll_org(org, question) + -- create formspec for all org members + -- return their answers +end + + +-- MESSAGE FUNCTIONS + +function modpol.org_message(org, speaker, message) + -- If org doesn't exit, broadcast to all + -- If org doesn't exist, don't broadcast + -- use: minetest.chat_send_player("player1", "This is a chat message for player1") +end +-- register at chat command for this + + +-- Add HUD interface that shows status: orgs, privileges https://rubenwardy.com/minetest_modding_book/en/players/hud.html + +-- toggle it on and off + + + +--[[ INITIALIZING: post-functions ]]-- + +-- create instance if not present +if (modpol.orgs["instance"] == nil) then + modpol.new_org("instance", modpol.list_members()) +end +-- TKTK does this need to be on_joinplayer? still isn't adding the singleplayer