M2.6: server rules (PvP, raiding, locks and friends, death penalty, difficulty, wolf grace), chat, admin commands, server console
This commit is contained in:
@@ -54,6 +54,7 @@ static func open(p: String = DEFAULT_PATH) -> RefCounted:
|
||||
if FileAccess.file_exists(c.names_path()) else null
|
||||
if n is Dictionary:
|
||||
c.names = n
|
||||
c.load_friends()
|
||||
return c
|
||||
|
||||
func names_path() -> String:
|
||||
@@ -104,3 +105,104 @@ func add_admin(id: String) -> void:
|
||||
if not id in data.admins:
|
||||
data.admins.append(id)
|
||||
save()
|
||||
|
||||
func ban(id: String) -> void:
|
||||
if not id in data.banned:
|
||||
data.banned.append(id)
|
||||
save()
|
||||
|
||||
func unban(id: String) -> bool:
|
||||
if not id in data.banned:
|
||||
return false
|
||||
data.banned.erase(id)
|
||||
save()
|
||||
return true
|
||||
|
||||
## A reserved name back up for grabs (the player who had it keeps their
|
||||
## character, and picks another name next time they join).
|
||||
func release_name(n: String) -> bool:
|
||||
if not names.has(n.to_lower()):
|
||||
return false
|
||||
names.erase(n.to_lower())
|
||||
save_names()
|
||||
return true
|
||||
|
||||
## The name a player id goes by here ("" if none).
|
||||
func name_of(id: String) -> String:
|
||||
for k in names:
|
||||
if names[k].id == id:
|
||||
return String(names[k].name)
|
||||
return ""
|
||||
|
||||
# --- rules that can change while the server runs (/set) --------------------------
|
||||
|
||||
## What each can be set to. The others in DEFAULTS are fixed at start-up.
|
||||
const SETTABLE := {
|
||||
"pvp": ["false", "true"],
|
||||
"raiding": ["false", "true"],
|
||||
"locks": ["off", "owner", "owner_and_friends"],
|
||||
"death_penalty": ["grave", "keep", "drop_all"],
|
||||
"sleep": ["all_online", "half", "anyone", "off"],
|
||||
"pause_when_empty": ["false", "true"],
|
||||
"difficulty": ["easy", "normal", "hard"],
|
||||
"wolf_grace_days": "0-10",
|
||||
"motd": "text",
|
||||
"server_name": "text",
|
||||
}
|
||||
|
||||
## Changes a rule and saves server.json. Returns "" or what's wrong.
|
||||
func set_rule(k: String, value: String) -> String:
|
||||
if not SETTABLE.has(k):
|
||||
return "Can't set '%s'. These can be set: %s" % [k, ", ".join(PackedStringArray(SETTABLE.keys()))]
|
||||
var allowed: Variant = SETTABLE[k]
|
||||
var val: Variant
|
||||
if allowed is Array:
|
||||
if not value in allowed:
|
||||
return "%s can be: %s" % [k, " / ".join(PackedStringArray(allowed))]
|
||||
val = (value == "true") if value in ["true", "false"] else value
|
||||
elif allowed == "0-10":
|
||||
if not value.is_valid_int() or int(value) < 0 or int(value) > 10:
|
||||
return "%s is a number from 0 to 10" % k
|
||||
val = int(value)
|
||||
else:
|
||||
if value.strip_edges().is_empty() or value.length() > 80:
|
||||
return "%s needs some text (up to 80 characters)" % k
|
||||
val = value.strip_edges()
|
||||
data[k] = val
|
||||
overrides.erase(k) # (a flag no longer wins over what the admin just set)
|
||||
save()
|
||||
return ""
|
||||
|
||||
# --- friends (docs/MULTIPLAYER_PLAN.md §4) ----------------------------------------
|
||||
# Per player: whose doors and chests they share. Stored as owner id -> [ids],
|
||||
# in friends.json next to server.json.
|
||||
|
||||
var friends: Dictionary = {}
|
||||
|
||||
func friends_path() -> String:
|
||||
return path.get_base_dir().path_join("friends.json")
|
||||
|
||||
func load_friends() -> void:
|
||||
var f: Variant = JSON.parse_string(FileAccess.get_file_as_string(friends_path())) \
|
||||
if FileAccess.file_exists(friends_path()) else null
|
||||
friends = f if f is Dictionary else {}
|
||||
|
||||
## `owner` lets `friend` use their things.
|
||||
func add_friend(owner: String, friend: String) -> void:
|
||||
var l: Array = friends.get(owner, [])
|
||||
if not friend in l:
|
||||
l.append(friend)
|
||||
friends[owner] = l
|
||||
_write(friends_path(), friends)
|
||||
|
||||
func remove_friend(owner: String, friend: String) -> bool:
|
||||
var l: Array = friends.get(owner, [])
|
||||
if not friend in l:
|
||||
return false
|
||||
l.erase(friend)
|
||||
friends[owner] = l
|
||||
_write(friends_path(), friends)
|
||||
return true
|
||||
|
||||
func is_friend(owner: String, friend: String) -> bool:
|
||||
return friend in friends.get(owner, [])
|
||||
|
||||
Reference in New Issue
Block a user