aboutsummaryrefslogtreecommitdiff
path: root/build/android/gradlew
blob: 91a7e269e19dfc62e27137a0b57ef3e430cee4fd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/env bash

##############################################################################
##
##  Gradle start up script for UN*X
##
##############################################################################

# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""

APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`

# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"

warn ( ) {
    echo "$*"
}

die ( ) {
    echo
    echo "$*"
    echo
    exit 1
}

# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
  CYGWIN* )
    cygwin=true
    ;;
  Darwin* )
    darwin=true
    ;;
  MINGW* )
    msys=true
    ;;
esac

# For Cygwin, ensure paths are in UNIX format before anything is touched.
if $cygwin ; then
    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi

# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
    ls=`ls -ld "$PRG"`
    link=`expr "$ls" : '.*-> \(.*\)$'`
    if expr "$link" : '/.*' > /dev/null; then
        PRG="$link"
    else
        PRG=`dirname "$PRG"`"/$link"
    fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >&-
APP_HOME="`pwd -P`"
cd "$SAVED" >&-

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar

# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
        # IBM's JDK on AIX uses strange locations for the executables
        JAVACMD="$JAVA_HOME/jre/sh/java"
    else
        JAVACMD="$JAVA_HOME/bin/java"
    fi
    if [ ! -x "$JAVACMD" ] ; then
        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
    fi
else
    JAVACMD="java"
    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi

# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
    MAX_FD_LIMIT=`ulimit -H -n`
    if [ $? -eq 0 ] ; then
        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
            MAX_FD="$MAX_FD_LIMIT"
        fi
        ulimit -n $MAX_FD
        if [ $? -ne 0 ] ; then
            warn "Could not set maximum file descriptor limit: $MAX_FD"
        fi
    else
        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
    fi
fi

# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi

# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`

    # We build the pattern for arguments to be converted via cygpath
    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
    SEP=""
    for dir in $ROOTDIRSRAW ; do
        ROOTDIRS="$ROOTDIRS$SEP$dir"
        SEP="|"
    done
    OURCYGPATTERN="(^($ROOTDIRS))"
    # Add a user-defined pattern to the cygpath arguments
    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
    fi
    # Now convert the arguments - kludge to limit ourselves to /bin/sh
    i=0
    for arg in "$@" ; do
        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option

        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
        else
            eval `echo args$i`="\"$arg\""
        fi
        i=$((i+1))
    done
    case $i in
        (0) set -- ;;
        (1) set -- "$args0" ;;
        (2) set -- "$args0" "$args1" ;;
        (3) set -- "$args0" "$args1" "$args2" ;;
        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
    esac
fi

# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
    JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"

exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
ref='#n362'>362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693
-- Minetest: builtin/chatcommands.lua

--
-- Chat command handler
--

minetest.chatcommands = {}
function minetest.register_chatcommand(cmd, def)
	def = def or {}
	def.params = def.params or ""
	def.description = def.description or ""
	def.privs = def.privs or {}
	minetest.chatcommands[cmd] = def
end

minetest.register_on_chat_message(function(name, message)
	local cmd, param = string.match(message, "^/([^ ]+) *(.*)")
	if not param then
		param = ""
	end
	local cmd_def = minetest.chatcommands[cmd]
	if cmd_def then
		local has_privs, missing_privs = minetest.check_player_privs(name, cmd_def.privs)
		if has_privs then
			cmd_def.func(name, param)
		else
			minetest.chat_send_player(name, "You don't have permission to run this command (missing privileges: "..table.concat(missing_privs, ", ")..")")
		end
		return true -- handled chat message
	end
	return false
end)

--
-- Chat commands
--
minetest.register_chatcommand("me", {
	params = "<action>",
	description = "chat action (eg. /me orders a pizza)",
	privs = {shout=true},
	func = function(name, param)
		minetest.chat_send_all("* " .. name .. " " .. param)
	end,
})

minetest.register_chatcommand("help", {
	privs = {},
	params = "(nothing)/all/privs/<cmd>",
	description = "Get help for commands or list privileges",
	func = function(name, param)
		local format_help_line = function(cmd, def)
			local msg = "/"..cmd
			if def.params and def.params ~= "" then msg = msg .. " " .. def.params end
			if def.description and def.description ~= "" then msg = msg .. ": " .. def.description end
			return msg
		end
		if param == "" then
			local msg = ""
			cmds = {}
			for cmd, def in pairs(minetest.chatcommands) do
				if minetest.check_player_privs(name, def.privs) then
					table.insert(cmds, cmd)
				end
			end
			minetest.chat_send_player(name, "Available commands: "..table.concat(cmds, " "))
			minetest.chat_send_player(name, "Use '/help <cmd>' to get more information, or '/help all' to list everything.")
		elseif param == "all" then
			minetest.chat_send_player(name, "Available commands:")
			for cmd, def in pairs(minetest.chatcommands) do
				if minetest.check_player_privs(name, def.privs) then
					minetest.chat_send_player(name, format_help_line(cmd, def))
				end
			end
		elseif param == "privs" then
			minetest.chat_send_player(name, "Available privileges:")
			for priv, def in pairs(minetest.registered_privileges) do
				minetest.chat_send_player(name, priv..": "..def.description)
			end
		else
			local cmd = param
			def = minetest.chatcommands[cmd]
			if not def then
				minetest.chat_send_player(name, "Command not available: "..cmd)
			else
				minetest.chat_send_player(name, format_help_line(cmd, def))
			end
		end
	end,
})
minetest.register_chatcommand("privs", {
	params = "<name>",
	description = "print out privileges of player",
	func = function(name, param)
		if param == "" then
			param = name
		else
			--[[if not minetest.check_player_privs(name, {privs=true}) then
				minetest.chat_send_player(name, "Privileges of "..param.." are hidden from you.")
				return
			end]]
		end
		minetest.chat_send_player(name, "Privileges of "..param..": "..minetest.privs_to_string(minetest.get_player_privs(param), ' '))
	end,
})
minetest.register_chatcommand("grant", {
	params = "<name> <privilege>|all",
	description = "Give privilege to player",
	privs = {},
	func = function(name, param)
		if not minetest.check_player_privs(name, {privs=true}) and 
				not minetest.check_player_privs(name, {basic_privs=true}) then
			minetest.chat_send_player(name, "Your privileges are insufficient.")
			return
		end
		local grantname, grantprivstr = string.match(param, "([^ ]+) (.+)")
		if not grantname or not grantprivstr then
			minetest.chat_send_player(name, "Invalid parameters (see /help grant)")
			return
		elseif not minetest.auth_table[grantname] then
			minetest.chat_send_player(name, "Player "..grantname.." does not exist.")
			return
		end
		local grantprivs = minetest.string_to_privs(grantprivstr)
		if grantprivstr == "all" then
			grantprivs = minetest.registered_privileges
		end
		local privs = minetest.get_player_privs(grantname)
		local privs_known = true
		for priv, _ in pairs(grantprivs) do
			if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and not minetest.check_player_privs(name, {privs=true}) then
				minetest.chat_send_player(name, "Your privileges are insufficient.")
				return
			end
			if not minetest.registered_privileges[priv] then
				minetest.chat_send_player(name, "Unknown privilege: "..priv)
				privs_known = false
			end
			privs[priv] = true
		end
		if not privs_known then
			return
		end
		minetest.set_player_privs(grantname, privs)
		minetest.log(name..' granted ('..minetest.privs_to_string(grantprivs, ', ')..') privileges to '..grantname)
		minetest.chat_send_player(name, "Privileges of "..grantname..": "..minetest.privs_to_string(minetest.get_player_privs(grantname), ' '))
		if grantname ~= name then
			minetest.chat_send_player(grantname, name.." granted you privileges: "..minetest.privs_to_string(grantprivs, ' '))
		end
	end,
})
minetest.register_chatcommand("revoke", {
	params = "<name> <privilege>|all",
	description = "Remove privilege from player",
	privs = {},
	func = function(name, param)
		if not minetest.check_player_privs(name, {privs=true}) and 
				not minetest.check_player_privs(name, {basic_privs=true}) then
			minetest.chat_send_player(name, "Your privileges are insufficient.")
			return
		end
		local revokename, revokeprivstr = string.match(param, "([^ ]+) (.+)")
		if not revokename or not revokeprivstr then
			minetest.chat_send_player(name, "Invalid parameters (see /help revoke)")
			return
		elseif not minetest.auth_table[revokename] then
			minetest.chat_send_player(name, "Player "..revokename.." does not exist.")
			return
		end
		local revokeprivs = minetest.string_to_privs(revokeprivstr)
		local privs = minetest.get_player_privs(revokename)
		for priv, _ in pairs(revokeprivs) do
			if priv ~= "interact" and priv ~= "shout" and priv ~= "interact_extra" and not minetest.check_player_privs(name, {privs=true}) then
				minetest.chat_send_player(name, "Your privileges are insufficient.")
				return
			end
		end
		if revokeprivstr == "all" then
			privs = {}
		else
			for priv, _ in pairs(revokeprivs) do
				privs[priv] = nil
			end
		end
		minetest.set_player_privs(revokename, privs)
		minetest.log(name..' revoked ('..minetest.privs_to_string(revokeprivs, ', ')..') privileges from '..revokename)
		minetest.chat_send_player(name, "Privileges of "..revokename..": "..minetest.privs_to_string(minetest.get_player_privs(revokename), ' '))
		if revokename ~= name then
			minetest.chat_send_player(revokename, name.." revoked privileges from you: "..minetest.privs_to_string(revokeprivs, ' '))
		end
	end,
})
minetest.register_chatcommand("setpassword", {
	params = "<name> <password>",
	description = "set given password",
	privs = {password=true},
	func = function(name, param)
		local toname, raw_password = string.match(param, "^([^ ]+) +(.+)$")
		if not toname then
			toname = string.match(param, "^([^ ]+) *$")
			raw_password = nil
		end
		if not toname then
			minetest.chat_send_player(name, "Name field required")
			return
		end
		local actstr = "?"
		if not raw_password then
			minetest.set_player_password(toname, "")
			actstr = "cleared"
		else
			minetest.set_player_password(toname, minetest.get_password_hash(toname, raw_password))
			actstr = "set"
		end
		minetest.chat_send_player(name, "Password of player \""..toname.."\" "..actstr)
		if toname ~= name then
			minetest.chat_send_player(toname, "Your password was "..actstr.." by "..name)
		end
	end,
})
minetest.register_chatcommand("clearpassword", {
	params = "<name>",
	description = "set empty password",
	privs = {password=true},
	func = function(name, param)
		toname = param
		if toname == "" then
			minetest.chat_send_player(name, "Name field required")
			return
		end
		minetest.set_player_password(toname, '')
		minetest.chat_send_player(name, "Password of player \""..toname.."\" cleared")
	end,
})

minetest.register_chatcommand("auth_reload", {
	params = "",
	description = "reload authentication data",
	privs = {server=true},
	func = function(name, param)
		local done = minetest.auth_reload()
		if done then
			minetest.chat_send_player(name, "Done.")
		else
			minetest.chat_send_player(name, "Failed.")
		end
	end,
})

minetest.register_chatcommand("teleport", {
	params = "<X>,<Y>,<Z> | <to_name> | <name> <X>,<Y>,<Z> | <name> <to_name>",
	description = "teleport to given position",
	privs = {teleport=true},
	func = function(name, param)
		-- Returns (pos, true) if found, otherwise (pos, false)
		local function find_free_position_near(pos)
			local tries = {
				{x=1,y=0,z=0},
				{x=-1,y=0,z=0},
				{x=0,y=0,z=1},
				{x=0,y=0,z=-1},
			}
			for _, d in ipairs(tries) do
				local p = {x = pos.x+d.x, y = pos.y+d.y, z = pos.z+d.z}
				local n = minetest.get_node(p)
				if not minetest.registered_nodes[n.name].walkable then
					return p, true
				end
			end
			return pos, false
		end

		local teleportee = nil
		local p = {}
		p.x, p.y, p.z = string.match(param, "^([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
		p.x = tonumber(p.x)
		p.y = tonumber(p.y)
		p.z = tonumber(p.z)
		teleportee = minetest.get_player_by_name(name)
		if teleportee and p.x and p.y and p.z then
			minetest.chat_send_player(name, "Teleporting to ("..p.x..", "..p.y..", "..p.z..")")
			teleportee:setpos(p)
			return
		end
		
		local teleportee = nil
		local p = nil
		local target_name = nil
		target_name = string.match(param, "^([^ ]+)$")
		teleportee = minetest.get_player_by_name(name)
		if target_name then
			local target = minetest.get_player_by_name(target_name)
			if target then
				p = target:getpos()
			end
		end
		if teleportee and p then
			p = find_free_position_near(p)
			minetest.chat_send_player(name, "Teleporting to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")")
			teleportee:setpos(p)
			return
		end
		
		if minetest.check_player_privs(name, {bring=true}) then
			local teleportee = nil
			local p = {}
			local teleportee_name = nil
			teleportee_name, p.x, p.y, p.z = string.match(param, "^([^ ]+) +([%d.-]+)[, ] *([%d.-]+)[, ] *([%d.-]+)$")
			p.x = tonumber(p.x)
			p.y = tonumber(p.y)
			p.z = tonumber(p.z)
			if teleportee_name then
				teleportee = minetest.get_player_by_name(teleportee_name)
			end
			if teleportee and p.x and p.y and p.z then
				minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to ("..p.x..", "..p.y..", "..p.z..")")
				teleportee:setpos(p)
				return
			end
			
			local teleportee = nil
			local p = nil
			local teleportee_name = nil
			local target_name = nil
			teleportee_name, target_name = string.match(param, "^([^ ]+) +([^ ]+)$")
			if teleportee_name then
				teleportee = minetest.get_player_by_name(teleportee_name)
			end
			if target_name then
				local target = minetest.get_player_by_name(target_name)
				if target then
					p = target:getpos()
				end
			end
			if teleportee and p then
				p = find_free_position_near(p)
				minetest.chat_send_player(name, "Teleporting "..teleportee_name.." to "..target_name.." at ("..p.x..", "..p.y..", "..p.z..")")
				teleportee:setpos(p)
				return
			end
		end

		minetest.chat_send_player(name, "Invalid parameters (\""..param.."\") or player not found (see /help teleport)")
		return
	end,
})

minetest.register_chatcommand("set", {
	params = "[-n] <name> <value> | <name>",
	description = "set or read server configuration setting",
	privs = {server=true},
	func = function(name, param)
		local arg, setname, setvalue = string.match(param, "(-[n]) ([^ ]+) (.+)")
		if arg and arg == "-n" and setname and setvalue then
			minetest.setting_set(setname, setvalue)
			minetest.chat_send_player(name, setname.." = "..setvalue)
			return
		end
		local setname, setvalue = string.match(param, "([^ ]+) (.+)")
		if setname and setvalue then
			if not minetest.setting_get(setname) then
				minetest.chat_send_player(name, "Failed. Use '/set -n <name> <value>' to create a new setting.")
				return
			end
			minetest.setting_set(setname, setvalue)
			minetest.chat_send_player(name, setname.." = "..setvalue)
			return
		end
		local setname = string.match(param, "([^ ]+)")
		if setname then
			local setvalue = minetest.setting_get(setname)
			if not setvalue then
				setvalue = "<not set>"
			end
			minetest.chat_send_player(name, setname.." = "..setvalue)
			return
		end
		minetest.chat_send_player(name, "Invalid parameters (see /help set)")
	end,
})

minetest.register_chatcommand("mods", {
	params = "",
	description = "lists mods installed on the server",
	privs = {},
	func = function(name, param)
		local response = ""
		local modnames = minetest.get_modnames()
		for i, mod in ipairs(modnames) do
			response = response .. mod
			-- Add space if not at the end
			if i ~= #modnames then
				response = response .. " "
			end
		end
		minetest.chat_send_player(name, response)
	end,
})

local function handle_give_command(cmd, giver, receiver, stackstring)
	minetest.log("action", giver.." invoked "..cmd..', stackstring="'
			..stackstring..'"')
	minetest.log(cmd..' invoked, stackstring="'..stackstring..'"')
	local itemstack = ItemStack(stackstring)
	if itemstack:is_empty() then
		minetest.chat_send_player(giver, 'error: cannot give an empty item')
		return
	elseif not itemstack:is_known() then
		minetest.chat_send_player(giver, 'error: cannot give an unknown item')
		return
	end
	local receiverref = minetest.get_player_by_name(receiver)
	if receiverref == nil then
		minetest.chat_send_player(giver, receiver..' is not a known player')
		return
	end
	local leftover = receiverref:get_inventory():add_item("main", itemstack)
	if leftover:is_empty() then
		partiality = ""
	elseif leftover:get_count() == itemstack:get_count() then
		partiality = "could not be "
	else
		partiality = "partially "
	end
	-- The actual item stack string may be different from what the "giver"
	-- entered (e.g. big numbers are always interpreted as 2^16-1).
	stackstring = itemstack:to_string()
	if giver == receiver then
		minetest.chat_send_player(giver, '"'..stackstring
			..'" '..partiality..'added to inventory.');
	else
		minetest.chat_send_player(giver, '"'..stackstring
			..'" '..partiality..'added to '..receiver..'\'s inventory.');
		minetest.chat_send_player(receiver, '"'..stackstring
			..'" '..partiality..'added to inventory.');
	end
end

minetest.register_chatcommand("give", {
	params = "<name> <itemstring>",
	description = "give item to player",
	privs = {give=true},
	func = function(name, param)
		local toname, itemstring = string.match(param, "^([^ ]+) +(.+)$")
		if not toname or not itemstring then
			minetest.chat_send_player(name, "name and itemstring required")
			return
		end
		handle_give_command("/give", name, toname, itemstring)
	end,
})
minetest.register_chatcommand("giveme", {
	params = "<itemstring>",
	description = "give item to yourself",
	privs = {give=true},
	func = function(name, param)
		local itemstring = string.match(param, "(.+)$")
		if not itemstring then
			minetest.chat_send_player(name, "itemstring required")
			return
		end
		handle_give_command("/giveme", name, name, itemstring)
	end,
})
minetest.register_chatcommand("spawnentity", {
	params = "<entityname>",
	description = "spawn entity at your position",
	privs = {give=true, interact=true},
	func = function(name, param)
		local entityname = string.match(param, "(.+)$")
		if not entityname then
			minetest.chat_send_player(name, "entityname required")
			return
		end
		print('/spawnentity invoked, entityname="'..entityname..'"')
		local player = minetest.get_player_by_name(name)
		if player == nil then
			print("Unable to spawn entity, player is nil")
			return true -- Handled chat message
		end
		local p = player:getpos()
		p.y = p.y + 1
		minetest.add_entity(p, entityname)
		minetest.chat_send_player(name, '"'..entityname
				..'" spawned.');
	end,
})
minetest.register_chatcommand("pulverize", {
	params = "",
	description = "delete item in hand",
	privs = {},
	func = function(name, param)
		local player = minetest.get_player_by_name(name)
		if player == nil then
			print("Unable to pulverize, player is nil")
			return true -- Handled chat message
		end
		if player:get_wielded_item():is_empty() then
			minetest.chat_send_player(name, 'Unable to pulverize, no item in hand.')
		else
			player:set_wielded_item(nil)
			minetest.chat_send_player(name, 'An item was pulverized.')
		end
	end,
})

-- Key = player name
minetest.rollback_punch_callbacks = {}

minetest.register_on_punchnode(function(pos, node, puncher)
	local name = puncher:get_player_name()
	if minetest.rollback_punch_callbacks[name] then
		minetest.rollback_punch_callbacks[name](pos, node, puncher)
		minetest.rollback_punch_callbacks[name] = nil
	end
end)

minetest.register_chatcommand("rollback_check", {
	params = "[<range>] [<seconds>]",
	description = "check who has last touched a node or near it, "..
			"max. <seconds> ago (default range=0, seconds=86400=24h)",
	privs = {rollback=true},
	func = function(name, param)
		local range, seconds = string.match(param, "(%d+) *(%d*)")
		range = tonumber(range) or 0
		seconds = tonumber(seconds) or 86400
		minetest.chat_send_player(name, "Punch a node (limits set: range="..
				dump(range).." seconds="..dump(seconds).."s)")
		minetest.rollback_punch_callbacks[name] = function(pos, node, puncher)
			local name = puncher:get_player_name()
			minetest.chat_send_player(name, "Checking...")
			local actor, act_p, act_seconds =
					minetest.rollback_get_last_node_actor(pos, range, seconds)
			if actor == "" then
				minetest.chat_send_player(name, "Nobody has touched the "..
						"specified location in "..dump(seconds).." seconds")
				return
			end
			local nodedesc = "this node"
			if act_p.x ~= pos.x or act_p.y ~= pos.y or act_p.z ~= pos.z then
				nodedesc = minetest.pos_to_string(act_p)
			end
			local nodename = minetest.get_node(act_p).name
			minetest.chat_send_player(name, "Last actor on "..nodedesc..
					" was "..actor..", "..dump(act_seconds)..
					"s ago (node is now "..nodename..")")
		end
	end,
})

minetest.register_chatcommand("rollback", {
	params = "<player name> [<seconds>] | :<actor> [<seconds>]",
	description = "revert actions of a player; default for <seconds> is 60",
	privs = {rollback=true},
	func = function(name, param)
		local target_name, seconds = string.match(param, ":([^ ]+) *(%d*)")
		if not target_name then
			local player_name = nil;
			player_name, seconds = string.match(param, "([^ ]+) *(%d*)")
			if not player_name then
				minetest.chat_send_player(name, "Invalid parameters. See /help rollback and /help rollback_check")
				return
			end
			target_name = "player:"..player_name
		end
		seconds = tonumber(seconds) or 60
		minetest.chat_send_player(name, "Reverting actions of "..
				dump(target_name).." since "..dump(seconds).." seconds.")
		local success, log = minetest.rollback_revert_actions_by(
				target_name, seconds)
		if #log > 10 then
			minetest.chat_send_player(name, "(log is too long to show)")
		else
			for _,line in ipairs(log) do
				minetest.chat_send_player(name, line)
			end
		end
		if success then
			minetest.chat_send_player(name, "Reverting actions succeeded.")
		else
			minetest.chat_send_player(name, "Reverting actions FAILED.")
		end
	end,
})

minetest.register_chatcommand("status", {
	params = "",
	description = "print server status line",
	privs = {},
	func = function(name, param)
		minetest.chat_send_player(name, minetest.get_server_status())
	end,
})

minetest.register_chatcommand("time", {
	params = "<0...24000>",
	description = "set time of day",
	privs = {settime=true},
	func = function(name, param)
		if param == "" then
			minetest.chat_send_player(name, "Missing parameter")
			return
		end
		local newtime = tonumber(param)
		if newtime == nil then
			minetest.chat_send_player(name, "Invalid time")
		else
			minetest.set_timeofday((newtime % 24000) / 24000)
			minetest.chat_send_player(name, "Time of day changed.")
			minetest.log("action", name .. " sets time " .. newtime)
		end
	end,
})

minetest.register_chatcommand("shutdown", {
	params = "",
	description = "shutdown server",
	privs = {server=true},
	func = function(name, param)
		minetest.log("action", name .. " shuts down server")
		minetest.request_shutdown()
		minetest.chat_send_all("*** Server shutting down (operator request).")
	end,
})

minetest.register_chatcommand("ban", {
	params = "<name>",
	description = "ban IP of player",
	privs = {ban=true},
	func = function(name, param)
		if param == "" then
			minetest.chat_send_player(name, "Ban list: " .. minetest.get_ban_list())
			return
		end
		if not minetest.get_player_by_name(param) then
			minetest.chat_send_player(name, "No such player")
			return
		end
		if not minetest.ban_player(param) then
			minetest.chat_send_player(name, "Failed to ban player")
		else
			local desc = minetest.get_ban_description(param)