Chat commands
This commit is contained in:
parent
2539ece481
commit
2853a8e3bc
150
chat.lua
150
chat.lua
@ -10,17 +10,127 @@ minetest.register_privilege("towny_admin", {
|
||||
give_to_singleplayer = false
|
||||
})
|
||||
|
||||
-- API
|
||||
|
||||
-- Send message to all town members who are online
|
||||
function towny.chat:announce_to_members(town,message)
|
||||
local tdata = towny.towns[town]
|
||||
if tdata then
|
||||
for member in pairs(tdata.members) do
|
||||
if minetest.get_player_by_name(member) then
|
||||
minetest.chat_send_player(member,message)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Commands
|
||||
|
||||
local function invite_player(town,player,target)
|
||||
local utown = towny:get_player_town(player)
|
||||
if not utown or utown ~= town then
|
||||
return false, "You are not in a town."
|
||||
end
|
||||
|
||||
local target_town = towny:get_player_town(target)
|
||||
if target_town then
|
||||
return false, "This player is already in a town!"
|
||||
end
|
||||
|
||||
if towny.chat.invites[town.."-"..target] then
|
||||
return false, "This player has already been invited to join your town!"
|
||||
end
|
||||
|
||||
local tdata = towny.towns[town]
|
||||
|
||||
minetest.chat_send_player(target, "You have been invited to join town '"..tdata.name.."' by "..player)
|
||||
minetest.chat_send_player(target, "You can accept this invite by typing '/town invite accept' or deny '/town invite deny'")
|
||||
|
||||
towny.chat.invites[town.."-"..target] = { rejected = false, town = town, player = target, invited = player }
|
||||
return true, "Player "..target.." has been invited to join your town."
|
||||
end
|
||||
|
||||
local function join_town(town,player,from_invite)
|
||||
local tdata = towny.towns[town]
|
||||
if not tdata then return false, "No such town" end
|
||||
if (not from_invite and not tdata.flags['joinable']) then return false, "You cannot join this town." end
|
||||
towny.chat:announce_to_members(town, minetest.colorize("#02aacc", player.." has joined the town!"))
|
||||
minetest.chat_send_player(player, "You have successfully joined the town '"..tdata.name.."'!")
|
||||
tdata.members[player] = {}
|
||||
return true
|
||||
end
|
||||
|
||||
local function invite_respond(player,response)
|
||||
local utown = towny:get_player_town(player)
|
||||
if utown or utown ~= town then
|
||||
return false, "You are already in a town."
|
||||
end
|
||||
|
||||
for id,data in pairs(towny.chat.invites) do
|
||||
if data.player == player then
|
||||
if not data.rejected then
|
||||
if response == true then
|
||||
towny.chat.invites[id] = nil
|
||||
return join_town(data.town,player,true)
|
||||
else
|
||||
towny.chat.invites[id] = { rejected = true }
|
||||
return true, "You have rejected the join request."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false, "You do not have any pending invites."
|
||||
end
|
||||
|
||||
local function send_flags (player,flags,message)
|
||||
local shiny = {}
|
||||
for flag,value in pairs(flags) do
|
||||
if type(value) == "table" then
|
||||
if value.x and value.y and value.z then
|
||||
value = minetest.pos_to_string(value)
|
||||
else
|
||||
value = dump(value)
|
||||
end
|
||||
elseif type(value) == "boolean" then
|
||||
local str_value = "true"
|
||||
if value == false then str_value = "false" end
|
||||
value = str_value
|
||||
end
|
||||
shiny[#shiny+1] = flag..": "..value
|
||||
end
|
||||
|
||||
return true, message ..": "..table.concat( shiny, ", " )
|
||||
end
|
||||
|
||||
local function town_command (name, param)
|
||||
if not minetest.get_player_by_name(name) then return false, "Can't run command on behalf of offline player." end
|
||||
local pr1, pr2 = string.match(param, "^([%a%d_-]+) (.+)$")
|
||||
local town = towny:get_player_town(name)
|
||||
|
||||
-- Pre town requirement
|
||||
local print_town_info = nil
|
||||
|
||||
if (pr1 == "create" or pr1 == "new") and pr2 then
|
||||
return towny:create_town(nil, name, pr2)
|
||||
elseif (pr1 == "invite" and not minetest.get_player_by_name(pr2)) then
|
||||
local tyes = pr2:lower()
|
||||
return invite_respond(name, (tyes == "accept" or tyes == "yes" or tyes == "y"))
|
||||
elseif pr1 == "join" and towny:get_town_by_name(pr2) and not town then
|
||||
return join_town(pr2,name,false)
|
||||
elseif pr1 == "show" or pr1 == "info" then
|
||||
if towny:get_town_by_name(pr2) then
|
||||
print_town_info = pr2
|
||||
else
|
||||
return false, "No such town."
|
||||
end
|
||||
elseif param == "" and town then
|
||||
print_town_info = town
|
||||
end
|
||||
|
||||
-- Print town information
|
||||
if print_town_info then
|
||||
return false, "Not yet implemented!"
|
||||
end
|
||||
|
||||
if not town then
|
||||
@ -39,6 +149,11 @@ local function town_command (name, param)
|
||||
elseif param == "visualize" then
|
||||
towny.regions:visualize_town(town)
|
||||
return true
|
||||
elseif param == "flags" then
|
||||
local flags = towny:get_flags(town)
|
||||
if flags then
|
||||
return send_flags(player,flags,"Flags of your town")
|
||||
end
|
||||
elseif (param == "delete" or param == "abandon") or (pr1 == "delete" or pr1 == "abandon") then
|
||||
if towny.chat['delete_verify_' .. name] and pr2 == "I WANT TO DELETE MY TOWN" then
|
||||
towny.chat['delete_verify_' .. name] = nil
|
||||
@ -49,12 +164,45 @@ local function town_command (name, param)
|
||||
"WARNING! Deleting your town will render ALL of the buildings in it without protection!"))
|
||||
return false, "Please run the command again with 'I WANT TO DELETE MY TOWN' in all caps written after it."
|
||||
end
|
||||
elseif pr1 == "kick" then
|
||||
return towny:kick_member(town,name,pr2)
|
||||
elseif pr1 == "set" then
|
||||
local flag, value = string.match(pr2, "^([%a%d_-]+) (.+)$")
|
||||
return towny:set_town_flags(nil,name,flag,value)
|
||||
end
|
||||
|
||||
-- Plot management commands
|
||||
if pr1 == "plot" then
|
||||
local pl1, pl2 = string.match(pr2, "^([%a%d_-]+) (.+)$")
|
||||
|
||||
if pr2 == "claim" then
|
||||
return towny:claim_plot(nil,name)
|
||||
elseif pr2 == "abandon" then
|
||||
return towny:abandon_plot(nil,name)
|
||||
elseif pr2 == "delete" then
|
||||
return towny:delete_plot(nil,name)
|
||||
elseif pr2 == "flags" then
|
||||
local flags = towny:get_plot_flags(town,nil,name)
|
||||
if flags then
|
||||
return send_flags(player,flags,"Flags of this plot")
|
||||
else
|
||||
return false, "There's no plot here."
|
||||
end
|
||||
elseif pl1 == "set" and pl2 then
|
||||
local flag, value = string.match(pl2, "^([%a%d_-]+) (.+)$")
|
||||
return towny:set_plot_flags(nil,name,flag,value)
|
||||
elseif pl1 == "member" and pl2 then
|
||||
local action, user = string.match(pl2, "^([%a%d_-]+) (.+)$")
|
||||
if action == "add" then
|
||||
return towny:plot_member(nil,name,user,1)
|
||||
elseif action == "remove" or action == "del" or action == "kick" then
|
||||
return towny:plot_member(nil,name,user,0)
|
||||
elseif action == "set" then
|
||||
local target, flag, value = string.match(user, "^([%a%d_-]+) ([%a%d_-]+) (.+)$")
|
||||
return towny:set_plot_member_flags(nil,name,target,flag,value)
|
||||
end
|
||||
end
|
||||
elseif pr1 == "invite" and minetest.get_player_by_name(pr2) then
|
||||
return invite_player(town,name,pr2)
|
||||
end
|
||||
|
||||
return false, "Invalid command usage."
|
||||
|
14
init.lua
14
init.lua
@ -3,11 +3,11 @@
|
||||
|
||||
local modpath = minetest.get_modpath(minetest.get_current_modname())
|
||||
towny = {
|
||||
claimbonus = minetest.settings:get('towny_claim_bonus') or 8,
|
||||
claimbonus = tonumber(minetest.settings:get('towny_claim_bonus')) or 8,
|
||||
regions = {
|
||||
size = minetest.settings:get('towny_claim_size') or 16,
|
||||
maxclaims = minetest.settings:get('towny_claim_max') or 128,
|
||||
distance = minetest.settings:get('towny_distance') or 80,
|
||||
size = tonumber(minetest.settings:get('towny_claim_size')) or 16,
|
||||
maxclaims = tonumber(minetest.settings:get('towny_claim_max')) or 128,
|
||||
distance = tonumber(minetest.settings:get('towny_distance')) or 80,
|
||||
|
||||
-- Regions loaded into memory cache, see "Town regions data structure"
|
||||
memloaded = {},
|
||||
@ -15,7 +15,11 @@ towny = {
|
||||
-- See "Town data structure"
|
||||
flatfile = {},
|
||||
towns = {},
|
||||
chat = {},
|
||||
chat = {
|
||||
chatmod = (minetest.settings:get('towny_chat') == "true") or true,
|
||||
questionaire = (minetest.settings:get('towny_questionaire') == "true") or true,
|
||||
invites = {},
|
||||
},
|
||||
|
||||
-- Set to true if files need to be updated
|
||||
dirty = false,
|
||||
|
272
town.lua
272
town.lua
@ -17,6 +17,7 @@ function towny:get_player_town(name)
|
||||
end
|
||||
|
||||
function towny:get_town_by_name(name)
|
||||
if not name then return nil end
|
||||
for town,data in pairs(towny.towns) do
|
||||
if data.name:lower() == name:lower() then
|
||||
return town
|
||||
@ -165,7 +166,7 @@ function towny:abridge_town(pos,player)
|
||||
return true
|
||||
end
|
||||
|
||||
function towny:leave_town(player)
|
||||
function towny:leave_town(player,kick)
|
||||
local town = towny:get_player_town(player)
|
||||
if not town then
|
||||
return err_msg(player, "You're not currently in a town!")
|
||||
@ -207,11 +208,39 @@ function towny:leave_town(player)
|
||||
pdata.members = members
|
||||
end
|
||||
|
||||
local msg = "You successfully left the town."
|
||||
if kick then
|
||||
msg = "You were kicked form town."
|
||||
end
|
||||
|
||||
towny:mark_dirty(town, false)
|
||||
minetest.chat_send_player(player, "You successfully left the town.")
|
||||
minetest.chat_send_player(player, msg)
|
||||
return true
|
||||
end
|
||||
|
||||
function towny:kick_member(town,player,member)
|
||||
local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
|
||||
local data = towny.towns[town]
|
||||
|
||||
if data.mayor ~= player and not towny_admin then
|
||||
return err_msg(player, "You do not have permission to kick people from this town.")
|
||||
end
|
||||
|
||||
if not data.members[member] then
|
||||
return err_msg(player, "User "..member.." is not in this town.")
|
||||
end
|
||||
|
||||
if member == data.mayor then
|
||||
return err_msg(player, "You cannot kick the town mayor.")
|
||||
end
|
||||
|
||||
if player == member then
|
||||
return err_msg(player, "You cannot kick yourself from town.")
|
||||
end
|
||||
|
||||
return towny:leave_town(member,true)
|
||||
end
|
||||
|
||||
function towny:delete_town(pos,player)
|
||||
local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
|
||||
if not pos then
|
||||
@ -267,7 +296,7 @@ function towny:delete_plot(pos,player)
|
||||
return err_msg(player, "You do not have permission to delete this plot.")
|
||||
end
|
||||
|
||||
towny.regions:set_plot(c,t,nil)
|
||||
towny.regions:set_plot(c[1],t,nil)
|
||||
data.plots[p] = nil
|
||||
towny:mark_dirty(t, true)
|
||||
|
||||
@ -320,12 +349,174 @@ function towny:create_plot(pos,player)
|
||||
return true
|
||||
end
|
||||
|
||||
local function flag_typeify(value)
|
||||
function towny:claim_plot(pos,player)
|
||||
if not pos then
|
||||
pos = minetest.get_player_by_name(player):get_pos()
|
||||
end
|
||||
|
||||
local town = towny:get_player_town(player)
|
||||
if not town then
|
||||
return err_msg(player, "You're not currently in a town!")
|
||||
end
|
||||
|
||||
local t,p,c = towny.regions:get_town_at(pos)
|
||||
if not t or t ~= town then
|
||||
return err_msg(player, "You are not in any town you can modify.")
|
||||
end
|
||||
|
||||
local tdata = towny.towns[t]
|
||||
if p ~= nil then
|
||||
local plot_data = tdata.plots[p]
|
||||
if plot_data.flags['claimable'] or player == tdata.mayor then
|
||||
if plot_data.owner == player or plot_data.members[player] then
|
||||
return err_msg(player, "You are already a member of this plot.")
|
||||
end
|
||||
|
||||
-- TODO: enconomy
|
||||
tdata.plots[p] = {
|
||||
owner = player,
|
||||
members = {[player] = {}},
|
||||
flags = {},
|
||||
}
|
||||
|
||||
towny:mark_dirty(t, false)
|
||||
|
||||
minetest.chat_send_player(player, "Successfully claimed the plot!")
|
||||
towny.regions:visualize_radius(vector.subtract(c[1], {x=tr/2,y=tr/2,z=tr/2}))
|
||||
|
||||
return true
|
||||
else
|
||||
return err_msg(player, "This plot is not for sale.")
|
||||
end
|
||||
end
|
||||
|
||||
return towny:create_plot(pos,player)
|
||||
end
|
||||
|
||||
function towny:abandon_plot(pos,player)
|
||||
if not pos then
|
||||
pos = minetest.get_player_by_name(player):get_pos()
|
||||
end
|
||||
|
||||
local town = towny:get_player_town(player)
|
||||
if not town then
|
||||
return err_msg(player, "You're not currently in a town!")
|
||||
end
|
||||
|
||||
local t,p,c = towny.regions:get_town_at(pos)
|
||||
if not t or t ~= town then
|
||||
return err_msg(player, "You are not in any town you can modify.")
|
||||
end
|
||||
|
||||
if p == nil then
|
||||
return err_msg(player, "There is no plot here.")
|
||||
end
|
||||
|
||||
local tdata = towny.towns[t]
|
||||
local pdata = tdata.plots[p]
|
||||
|
||||
if not pdata.members[player] then
|
||||
return err_msg(player, "You are not a member of this plot.")
|
||||
end
|
||||
|
||||
-- Update plot members
|
||||
local members = {}
|
||||
if pdata.owner == player then
|
||||
pdata.owner = nil
|
||||
if pdata.flags["greeting"] ~= nil then
|
||||
pdata.flags["greeting"] = nil
|
||||
end
|
||||
end
|
||||
|
||||
for mem,dat in pairs(pdata.members) do
|
||||
if mem ~= player then
|
||||
-- Transfer ownership to the first other member
|
||||
if pdata.owner == nil then
|
||||
pdata.owner = mem
|
||||
end
|
||||
members[mem] = dat
|
||||
end
|
||||
end
|
||||
pdata.members = members
|
||||
towny:mark_dirty(t, false)
|
||||
minetest.chat_send_player(player, "Successfully abandoned the plot!")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function towny:plot_member(pos,player,member,action)
|
||||
local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
|
||||
if not pos then
|
||||
pos = minetest.get_player_by_name(player):get_pos()
|
||||
end
|
||||
|
||||
local town = towny:get_player_town(player)
|
||||
if not town then
|
||||
return err_msg(player, "You're not currently in a town!")
|
||||
end
|
||||
|
||||
local t,p,c = towny.regions:get_town_at(pos)
|
||||
if not t or t ~= town then
|
||||
return err_msg(player, "You are not in any town you can modify.")
|
||||
end
|
||||
|
||||
if p == nil then
|
||||
return err_msg(player, "There is no plot here.")
|
||||
end
|
||||
|
||||
local tdata = towny.towns[t]
|
||||
local pdata = tdata.plots[p]
|
||||
|
||||
if pdata.owner ~= player and player ~= tdata.mayor and not towny_admin then
|
||||
return err_msg(player, "You do not have permission to modify this plot.")
|
||||
end
|
||||
|
||||
if not tdata.members[member] then
|
||||
return err_msg(player, "User '"..member.."' is not part of this town.")
|
||||
end
|
||||
|
||||
-- Update plot members
|
||||
local members = {}
|
||||
local action_desc = "add yourself to"
|
||||
if action == 0 then
|
||||
action_desc = "remove yourself from"
|
||||
end
|
||||
|
||||
if member == pdata.owner then
|
||||
return err_msg(player, "You cannot "..action_desc.." from this plot.")
|
||||
end
|
||||
|
||||
if action == 0 then
|
||||
action_desc = "removed "..member.." from"
|
||||
for mem,dat in pairs(pdata.members) do
|
||||
if mem ~= member then
|
||||
-- Transfer ownership to the first other member
|
||||
members[mem] = dat
|
||||
end
|
||||
end
|
||||
else
|
||||
action_desc = "added "..member.." to"
|
||||
members = pdata.members
|
||||
members[member] = {}
|
||||
end
|
||||
|
||||
pdata.members = members
|
||||
towny:mark_dirty(t, false)
|
||||
minetest.chat_send_player(player, "Successfully "..action_desc.." plot!")
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function flag_typeify(value,pos)
|
||||
if type(value) == "string" then
|
||||
if value == "true" then
|
||||
value = true
|
||||
elseif value == "false" then
|
||||
value = false
|
||||
elseif value == "here" then
|
||||
value = pos
|
||||
elseif value == "none" or value == "null" or value == "nil" then
|
||||
value = nil
|
||||
elseif tonumber(value) ~= nil then
|
||||
value = tonumber(value)
|
||||
elseif minetest.string_to_pos(value) ~= nil then
|
||||
@ -335,7 +526,10 @@ local function flag_typeify(value)
|
||||
return value
|
||||
end
|
||||
|
||||
-- Set flags
|
||||
|
||||
function towny:set_plot_flags(pos,player,flag,value)
|
||||
if not flag then return false end
|
||||
local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
|
||||
if not pos then
|
||||
pos = minetest.get_player_by_name(player):get_pos()
|
||||
@ -351,7 +545,7 @@ function towny:set_plot_flags(pos,player,flag,value)
|
||||
return err_msg(player, "You are not in any town you can modify.")
|
||||
end
|
||||
|
||||
if p ~= nil then
|
||||
if p == nil then
|
||||
return err_msg(player, "There is no plot here! Please stand in the plot you wish to modify.")
|
||||
end
|
||||
|
||||
@ -362,11 +556,50 @@ function towny:set_plot_flags(pos,player,flag,value)
|
||||
end
|
||||
|
||||
minetest.chat_send_player(player, "Successfully set the plot flag '" .. flag .."' to '" .. value .. "'!")
|
||||
plot_data.flags[flag] = flag_typeify(value,pos)
|
||||
towny:mark_dirty(t, false)
|
||||
end
|
||||
|
||||
function towny:set_plot_member_flags(pos,player,member,flag,value)
|
||||
if not member or not flag then return false end
|
||||
local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
|
||||
if not pos then
|
||||
pos = minetest.get_player_by_name(player):get_pos()
|
||||
end
|
||||
|
||||
local town = towny:get_player_town(player)
|
||||
if not town and not towny_admin then
|
||||
return err_msg(player, "You're not currently in a town!")
|
||||
end
|
||||
|
||||
local t,p,c = towny.regions:get_town_at(pos)
|
||||
if not t or (t ~= town and not towny_admin) then
|
||||
return err_msg(player, "You are not in any town you can modify.")
|
||||
end
|
||||
|
||||
if p == nil then
|
||||
return err_msg(player, "There is no plot here! Please stand in the plot you wish to modify.")
|
||||
end
|
||||
|
||||
local data = towny.towns[t]
|
||||
local plot_data = data.plots[p]
|
||||
if data.mayor ~= player and plot_data.owner ~= player and not towny_admin then
|
||||
return err_msg(player, "You do not have permission to modify this plot.")
|
||||
end
|
||||
|
||||
if not plot_data.members[member] then
|
||||
return err_msg(player, "There is no such member in this plot.")
|
||||
end
|
||||
|
||||
if flag == "build" then flag = "plot_build" end
|
||||
|
||||
minetest.chat_send_player(player, "Successfully set the plot member "..member.."'s flag '" .. flag .."' to '" .. value .. "'!")
|
||||
plot_data.members[member][flag] = flag_typeify(value,pos)
|
||||
towny:mark_dirty(t, false)
|
||||
plot_data.flags[flag] = flag_typeify(value)
|
||||
end
|
||||
|
||||
function towny:set_town_flags(pos,player,flag,value)
|
||||
if not flag then return false end
|
||||
local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
|
||||
if not pos then
|
||||
pos = minetest.get_player_by_name(player):get_pos()
|
||||
@ -392,8 +625,33 @@ function towny:set_town_flags(pos,player,flag,value)
|
||||
end
|
||||
|
||||
minetest.chat_send_player(player, "Successfully set the town flag '" .. flag .."' to '" .. value .. "'!")
|
||||
data.flags[flag] = flag_typeify(value,pos)
|
||||
towny:mark_dirty(t, false)
|
||||
data.flags[flag] = flag_typeify(value)
|
||||
end
|
||||
|
||||
-- Get flags
|
||||
|
||||
function towny:get_flags(town,plot)
|
||||
local tdata = towny.towns[town]
|
||||
if not tdata then return nil end
|
||||
if not plot then return tdata.flags end
|
||||
if not tdata.plots[plot] then return nil end
|
||||
return tdata.plots[plot].flags
|
||||
end
|
||||
|
||||
function towny:get_plot_flags(town,pos,player)
|
||||
local towny_admin = minetest.check_player_privs(player, { towny_admin = true })
|
||||
if not pos and player then
|
||||
pos = minetest.get_player_by_name(player):get_pos()
|
||||
end
|
||||
|
||||
local t,p,c = towny.regions:get_town_at(pos)
|
||||
if not t or (t ~= town and not towny_admin) then
|
||||
return err_msg(player, "You are not in any town you can access.")
|
||||
end
|
||||
|
||||
if not t or not p then return nil end
|
||||
return towny:get_flags(t,p)
|
||||
end
|
||||
|
||||
function towny:get_claims_total(town)
|
||||
|
Loading…
Reference in New Issue
Block a user