J3c: a land server stopping tells its players and is started afresh when they rejoin; the extra ports to forward on the Host page, the hosting message, the server log and HOSTING.md

This commit is contained in:
Paul Bailey
2026-11-07 00:08:05 +00:00
parent 86ebe07899
commit f9b138b304
9 changed files with 108 additions and 12 deletions

View File

@@ -65,6 +65,8 @@ func server_started(args: Dictionary) -> void:
if err != OK:
push_warning("[lands] couldn't open the private link on %d (error %d): no other lands this run" % [game_port() + LINK_PORT_OFFSET, err])
_link = null
elif not _order().is_empty():
print("[lands] other lands start on demand. Players over the internet need %s forwarded" % ports_text(home(), game_port()))
## Called as a server stops: stops every land server it started.
func server_stopped() -> void:
@@ -109,13 +111,39 @@ func home() -> String:
## Every land after home, in the order the journey reaches them.
func _order() -> Array:
return journey_from(home())
## The lands a server whose home is `home` and whose port is `base` may run,
## after home: [[land, port]] (24243 for the Cove when the server's 24242).
## Friends playing over the internet need these forwarded too.
static func extra_ports(home_land: String, base: int) -> Array:
var out: Array = []
var at := home()
var i := 1
for l in journey_from(home_land):
out.append([l, base + i])
i += 1
return out
## "UDP 24242 and 24243 (the Cove)": what to forward for a server on `base`.
static func ports_text(home_land: String, base: int) -> String:
var extra := extra_ports(home_land, base)
if extra.is_empty():
return "UDP %d" % base
var T: Script = load("res://scripts/world/terrain.gd")
var parts: Array[String] = []
for e in extra:
parts.append("%d (the %s)" % [int(e[1]), T.worldlet_name(String(e[0]))])
return "UDP %d and %s" % [base, ", ".join(parts)]
static func journey_from(home_land: String) -> Array:
var out: Array = []
var at := home_land
for _i in range(16):
var d: Dictionary = load("res://scripts/world/terrain.gd").load_worldlet(at)
var nxt := ""
for c in d.get("next", []):
if c is Dictionary and not String(c.get("to", "")) in out and String(c.get("to", "")) != home():
if c is Dictionary and not String(c.get("to", "")) in out and String(c.get("to", "")) != home_land \
and not load("res://scripts/world/terrain.gd").load_worldlet(String(c.get("to", ""))).is_empty():
nxt = String(c.to)
break
if nxt.is_empty():
@@ -148,6 +176,9 @@ func ensure(l: String, then: Callable) -> void:
if not hub:
then.call("this isn't the hub")
return
if servers.has(l) and int(servers[l].pid) != 0 and not OS.is_process_running(int(servers[l].pid)):
print("[lands] the %s's server has gone: starting it again" % l)
servers.erase(l) # (crashed, and not noticed yet: start afresh)
if servers.has(l) and bool(servers[l].ready):
servers[l].idle = 0.0
then.call("")