Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
7
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
Evert Prants
towny
Commits
2853a8e3
Verified
Commit
2853a8e3
authored
Jan 12, 2019
by
Evert Prants
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Chat commands
parent
2539ece4
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
425 additions
and
15 deletions
+425
-15
chat.lua
chat.lua
+149
-1
init.lua
init.lua
+11
-7
town.lua
town.lua
+265
-7
No files found.
chat.lua
View file @
2853a8e3
...
...
@@ -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."
...
...
init.lua
View file @
2853a8e3
...
...
@@ -3,19 +3,23 @@
local
modpath
=
minetest
.
get_modpath
(
minetest
.
get_current_modname
())
towny
=
{
claimbonus
=
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
,
claimbonus
=
tonumber
(
minetest
.
settings
:
get
(
'towny_claim_bonus'
)
)
or
8
,
regions
=
{
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
=
{},
},
-- See "Town data structure"
flatfile
=
{},
towns
=
{},
chat
=
{},
towns
=
{},
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
,
...
...
town.lua
View file @
2853a8e3
...
...
@@ -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
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment