2020-07-28 22:36:04 +02:00
minetest.register_privilege ( " playerfactions_admin " , { description = " Authorize to use every /factions commands " , give_to_singleplayer = false } )
2019-09-09 04:11:55 +02:00
-- Load support for intllib.
local MP = minetest.get_modpath ( minetest.get_current_modname ( ) )
local S , NS = dofile ( MP .. " /intllib.lua " )
-- Data
2019-09-09 21:56:38 +02:00
factions = { }
2019-09-09 04:11:55 +02:00
local facts = { }
local storage = minetest.get_mod_storage ( )
2019-09-09 23:59:09 +02:00
if storage : get_string ( " facts " ) ~= " " then
2019-09-09 04:11:55 +02:00
facts = minetest.deserialize ( storage : get_string ( " facts " ) )
end
2020-02-08 18:08:01 +01:00
-- Fix factions
for fname , fact in pairs ( facts ) do
if fact.members == nil then
fact.members = { }
end
end
2019-09-09 04:11:55 +02:00
local function save_factions ( )
storage : set_string ( " facts " , minetest.serialize ( facts ) )
end
-- Data manipulation
2019-09-09 21:56:38 +02:00
function factions . get_player_faction ( name )
2019-09-09 04:11:55 +02:00
local player = minetest.get_player_by_name ( name )
2020-07-28 22:29:38 +02:00
2020-02-08 18:08:01 +01:00
-- Look in faction objects if we can't do the shortcut
2019-09-09 04:11:55 +02:00
if player == nil then
2020-02-08 18:08:01 +01:00
for fname , fact in pairs ( facts ) do
if fact.members [ name ] then
return fname
end
end
2019-09-09 04:11:55 +02:00
return nil
2020-07-28 22:29:38 +02:00
2020-02-08 18:08:01 +01:00
-- Player is online, we can take a shortcut using the player object
-- In the future, we can always do this; see https://github.com/minetest/minetest/issues/6193
2019-09-09 04:11:55 +02:00
else
2019-09-09 21:56:38 +02:00
local faction = player : get_meta ( ) : get_string ( " faction " )
2019-09-09 04:11:55 +02:00
if faction == " " then
return nil
else
2019-09-10 00:20:58 +02:00
-- Check that faction still exists
if facts [ faction ] == nil then
factions.leave_faction ( name )
return nil
else
2020-02-08 18:08:01 +01:00
local found = false
if facts [ faction ] . members [ name ] == nil then
facts [ faction ] . members [ name ] = true
save_factions ( )
end
2019-09-10 00:20:58 +02:00
return faction
end
2019-09-09 04:11:55 +02:00
end
end
end
2019-09-09 21:56:38 +02:00
function factions . get_owner ( name )
2019-09-09 04:11:55 +02:00
if facts [ name ] == nil then
return nil
else
return facts [ name ] . owner
end
end
2019-09-10 00:20:58 +02:00
function factions . chown ( name , owner )
facts [ name ] . owner = owner
end
2019-09-09 21:56:38 +02:00
function factions . register_faction ( fname , founder , pw )
2019-09-09 04:11:55 +02:00
facts [ fname ] = {
name = fname ,
owner = founder ,
2020-02-08 18:08:01 +01:00
password = pw ,
members = { }
2019-09-09 04:11:55 +02:00
}
save_factions ( )
2019-09-10 00:20:58 +02:00
factions.join_faction ( fname , founder )
2019-09-09 04:11:55 +02:00
end
2019-09-09 21:56:38 +02:00
function factions . disband_faction ( name )
2019-09-09 04:11:55 +02:00
facts [ name ] = nil
save_factions ( )
end
2019-09-09 21:56:38 +02:00
function factions . get_password ( name )
2019-09-09 04:11:55 +02:00
return facts [ name ] . password
end
2019-09-09 21:56:38 +02:00
function factions . set_password ( name , password )
2019-09-09 04:11:55 +02:00
facts [ name ] . password = password
end
2019-09-09 21:56:38 +02:00
function factions . join_faction ( name , player )
2019-09-09 23:59:09 +02:00
minetest.get_player_by_name ( player ) : get_meta ( ) : set_string ( " faction " , name )
2020-02-08 18:08:01 +01:00
facts [ name ] . members [ player ] = true
2019-09-09 04:11:55 +02:00
end
2019-09-09 21:56:38 +02:00
function factions . leave_faction ( name )
2019-09-09 23:59:09 +02:00
minetest.get_player_by_name ( name ) : get_meta ( ) : set_string ( " faction " , " " )
2020-02-08 18:08:01 +01:00
if facts [ name ] ~= nil then
facts [ name ] . members [ player ] = nil
end
2019-09-09 04:11:55 +02:00
end
-- Chat commands
local function handle_command ( name , param )
local params = { }
for p in string.gmatch ( param , " [^%s]+ " ) do
table.insert ( params , p )
end
if params == nil then
2019-09-18 22:52:14 +02:00
minetest.chat_send_player ( name , S ( " Unknown subcommand. Run '/help factions' for help " ) )
2019-09-09 04:11:55 +02:00
end
local action = params [ 1 ]
if action == " create " then
local faction_name = params [ 2 ]
local password = params [ 3 ]
if faction_name == nil then
minetest.chat_send_player ( name , S ( " Missing faction name " ) )
elseif password == nil then
minetest.chat_send_player ( name , S ( " Missing password " ) )
2019-09-09 21:56:38 +02:00
elseif factions.get_owner ( faction_name ) ~= nil then
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " That faction already exists " ) )
else
2019-09-09 21:56:38 +02:00
factions.register_faction ( faction_name , name , password )
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " Registered @1 " , faction_name ) )
return true
end
2019-09-10 00:20:58 +02:00
elseif action == " disband " then
2019-09-09 21:56:38 +02:00
local faction_name = factions.get_player_faction ( name )
2019-09-09 05:30:31 +02:00
local password = params [ 2 ]
if faction_name == nil then
minetest.chat_send_player ( name , S ( " You are not in a faction " ) )
2020-07-28 22:36:04 +02:00
elseif name ~= factions.get_owner ( faction_name ) and not minetest.get_player_privs ( name ) . playerfactions_admin then
2019-09-09 05:30:31 +02:00
minetest.chat_send_player ( name , S ( " Permission denied " ) )
elseif password == nil then
minetest.chat_send_player ( name , S ( " WARNING! This cannot be reversed! Run again with the password if you're absolutely certain " ) )
2019-09-09 21:56:38 +02:00
elseif password ~= factions.get_password ( faction_name ) then
2019-09-10 00:20:58 +02:00
print ( " wrong password " )
2019-09-09 05:30:31 +02:00
minetest.chat_send_player ( name , S ( " Permission denied " ) )
else
2019-09-09 21:56:38 +02:00
factions.disband_faction ( faction_name , name , name )
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " Disbanded @1 " , faction_name ) )
return true
end
elseif action == " list " then
local faction_list = { }
for k , f in pairs ( facts ) do
table.insert ( faction_list , k )
end
if # faction_list ~= 0 then
minetest.chat_send_player ( name , " Factions( " .. # faction_list .. " ): " .. table.concat ( faction_list , " , " ) )
else
minetest.chat_send_player ( name , S ( " There are no factions yet " ) )
end
return true
elseif action == " info " then
2020-07-28 22:29:38 +02:00
local faction_name = params [ 2 ]
if faction_name == nil then
faction_name = factions.get_player_faction ( name )
minetest.chat_send_player ( name , S ( " No faction were given, returning information about your oldest faction (e.g. the oldest created faction you are in) " ) )
end
if faction_name == nil then
minetest.chat_send_player ( name , S ( " Missing faction name " ) )
elseif facts [ faction_name ] == nil then
minetest.chat_send_player ( name , S ( " This faction is not registered " ) )
else
local fmembers = " "
for play , _ in pairs ( facts [ faction_name ] . members ) do
if fmembers == " " then
fmembers = play
else
fmembers = fmembers .. " , " .. play
2019-09-09 04:11:55 +02:00
end
end
2020-07-28 22:29:38 +02:00
minetest.chat_send_player ( name , S ( " Name: @1 \n Owner: @2 \n Members: #@3 " , faction_name , factions.get_owner ( faction_name ) , fmembers ) )
2020-07-28 22:36:04 +02:00
if factions.get_owner ( faction_name ) == name or minetest.get_player_privs ( name ) . playerfactions_admin then
2020-07-28 22:29:38 +02:00
minetest.chat_send_player ( name , S ( " Password: @1 " , factions.get_password ( faction_name ) ) )
end
end
2019-09-09 04:11:55 +02:00
elseif action == " join " then
local faction_name = params [ 2 ]
local password = params [ 3 ]
2019-09-09 21:56:38 +02:00
if factions.get_player_faction ( name ) ~= nil then
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " You are already in a faction " ) )
2019-09-09 21:56:38 +02:00
elseif factions.get_owner ( faction_name ) == nil then
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " The faction @1 doesn't exist " , faction_name ) )
2019-09-09 21:56:38 +02:00
elseif factions.get_password ( faction_name ) ~= password then
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " Permission denied " ) )
else
2019-09-09 21:56:38 +02:00
factions.join_faction ( faction_name , name )
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " Joined @1 " , faction_name ) )
return true
end
elseif action == " leave " then
2019-09-09 21:56:38 +02:00
local faction_name = factions.get_player_faction ( name )
2019-09-09 04:11:55 +02:00
if faction_name == nil then
2019-09-09 23:59:09 +02:00
minetest.chat_send_player ( name , S ( " You are not in a faction " ) )
2019-09-09 21:56:38 +02:00
elseif factions.get_owner ( faction_name ) == name then
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " You cannot leave your own faction " ) )
else
2019-09-09 21:56:38 +02:00
factions.leave_faction ( name )
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " Left @1 " , faction_name ) )
return true
end
elseif action == " kick " then
2019-09-09 21:56:38 +02:00
local faction_name = factions.get_player_faction ( name )
2019-09-09 04:11:55 +02:00
local target = params [ 2 ]
if faction_name == nil then
minetest.chat_send_player ( name , S ( " You are not in a faction " ) )
elseif target == nil then
minetest.chat_send_player ( name , S ( " Missing player name " ) )
2020-07-28 22:36:04 +02:00
elseif factions.get_owner ( faction_name ) ~= name and not minetest.get_player_privs ( name ) . playerfactions_admin or factions.get_player_faction ( target ) ~= faction_name then
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " Permission denied " ) )
elseif target == name then
minetest.chat_send_player ( name , S ( " You cannot kick yourself " ) )
else
2019-09-09 21:56:38 +02:00
factions.leave_faction ( name )
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " Kicked @1 from faction " , target ) )
return true
end
elseif action == " passwd " then
2019-09-09 21:56:38 +02:00
local faction_name = factions.get_player_faction ( name )
2019-09-09 04:11:55 +02:00
local password = params [ 2 ]
if faction_name == nil then
minetest.chat_send_player ( name , S ( " You are not in a faction " ) )
elseif password == nil then
minetest.chat_send_player ( name , S ( " Missing password " ) )
2020-07-28 22:36:04 +02:00
elseif factions.get_owner ( faction_name ) ~= name and not minetest.get_player_privs ( name ) . playerfactions_admin then
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " Permission denied " ) )
else
2019-09-09 21:56:38 +02:00
factions.set_password ( faction_name , password )
2019-09-09 04:11:55 +02:00
minetest.chat_send_player ( name , S ( " Password has been updated " ) )
return true
end
2019-09-09 05:30:31 +02:00
elseif action == " chown " then
2019-09-09 21:56:38 +02:00
local faction_name = factions.get_player_faction ( name )
2019-09-09 05:30:31 +02:00
local target = params [ 2 ]
local password = params [ 3 ]
if faction_name == nil then
minetest.chat_send_player ( name , S ( " You are not in a faction " ) )
2019-09-10 00:20:58 +02:00
elseif target == nil then
minetest.chat_send_player ( name , S ( " Missing player name " ) )
elseif factions.get_player_faction ( target ) ~= faction_name then
minetest.chat_send_player ( name , S ( " @1 isn't in your faction " , target ) )
2020-07-28 22:36:04 +02:00
elseif factions.get_owner ( faction_name ) ~= name and not minetest.get_player_privs ( name ) . playerfactions_admin then
2019-09-09 05:30:31 +02:00
minetest.chat_send_player ( name , S ( " Permission denied " ) )
elseif password == nil then
minetest.chat_send_player ( name , S ( " WARNING! This cannot be reversed! Run again with the password if you're absolutely certain " ) )
2019-09-09 21:56:38 +02:00
elseif password ~= factions.get_password ( faction_name ) then
2019-09-09 05:30:31 +02:00
minetest.chat_send_player ( name , S ( " Permission denied " ) )
else
2019-09-10 00:20:58 +02:00
factions.chown ( faction_name , target )
minetest.chat_send_player ( name , S ( " Ownership has been transferred to @1 " , target ) )
2019-09-09 05:30:31 +02:00
return true
end
2020-07-28 22:42:57 +02:00
elseif action == " invite " then
if not minetest.get_player_privs ( name ) . playerfactions_admin then
minetest.chat_send_player ( name , " Permission denied: You can't use this command, playerfactions_admin priv is needed. " )
else
local target = params [ 2 ]
local faction_name = params [ 3 ]
if facts [ faction_name ] == nil then
minetest.chat_send_player ( name , " The faction doesn't exist " )
elseif not minetest.player_exists ( target ) then
minetest.chat_send_player ( name , " The player doesn't exist " )
elseif factions.get_player_faction ( target ) ~= nil then
minetest.chat_send_player ( name , S ( " The player is already in the faction \" @1 \" " , factions.get_player_faction ( target ) ) )
else
if factions.join_faction ( faction_name , target ) then
minetest.chat_send_player ( name , " The player is now a member of the guild " )
return true
else
minetest.chat_send_player ( name , S ( " Error on adding @1 into @2, please verify parameters and try again " , target , faction_name ) )
return true
end
end
end
2019-09-18 22:52:14 +02:00
else
minetest.chat_send_player ( name , S ( " Unknown subcommand. Run '/help factions' for help " ) )
2019-09-09 04:11:55 +02:00
end
return false
end
2019-09-09 05:30:31 +02:00
minetest.register_chatcommand ( " factions " , {
2019-09-09 05:53:15 +02:00
params = " create <faction> <password>: " .. S ( " Create a new faction " ) .. " \n "
2019-09-09 04:11:55 +02:00
.. " list: " .. S ( " List available factions " ) .. " \n "
.. " info <faction>: " .. S ( " See information on a faction " ) .. " \n "
2019-09-09 05:53:15 +02:00
.. " join <faction> <password>: " .. S ( " Join an existing faction " ) .. " \n "
2019-09-09 04:11:55 +02:00
.. " leave: " .. S ( " Leave your faction " ) .. " \n "
.. " kick <player>: " .. S ( " Kick someone from your faction " ) .. " \n "
2019-09-16 23:12:10 +02:00
.. " disband: " .. S ( " Disband your faction " ) .. " \n "
2019-09-09 05:30:31 +02:00
.. " passwd <password>: " .. S ( " Change your faction's password " ) .. " \n "
2019-09-09 05:53:15 +02:00
.. " chown <player>: " .. S ( " Transfer ownership of your faction " ) .. " \n " ,
2020-07-28 22:29:38 +02:00
2019-09-09 04:11:55 +02:00
description = " " ,
privs = { } ,
func = handle_command
} )