first commit
This commit is contained in:
136
scripts/net.gd
Normal file
136
scripts/net.gd
Normal file
@@ -0,0 +1,136 @@
|
||||
extends Node
|
||||
## Netzwerk-Verwaltung: Host/Client via ENet, Lobby und Spielstart.
|
||||
|
||||
signal lobby_changed
|
||||
signal game_started(config: Dictionary)
|
||||
signal connection_failed(reason: String)
|
||||
signal server_closed
|
||||
|
||||
const PORT := 8910
|
||||
const MAX_HUMANS := 8
|
||||
|
||||
var player_name := "Spieler"
|
||||
## peer_id -> name (enthält auch den Host mit id 1)
|
||||
var lobby: Dictionary = {}
|
||||
var is_host := false
|
||||
var in_game := false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
multiplayer.peer_connected.connect(_on_peer_connected)
|
||||
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
|
||||
multiplayer.connected_to_server.connect(_on_connected)
|
||||
multiplayer.connection_failed.connect(_on_connect_fail)
|
||||
multiplayer.server_disconnected.connect(_on_server_disconnected)
|
||||
|
||||
|
||||
func host_game(pname: String, port: int = PORT) -> bool:
|
||||
player_name = pname
|
||||
var peer := ENetMultiplayerPeer.new()
|
||||
var err := peer.create_server(port, MAX_HUMANS - 1)
|
||||
if err != OK:
|
||||
connection_failed.emit("Server konnte nicht gestartet werden (Port %d belegt?)" % port)
|
||||
return false
|
||||
multiplayer.multiplayer_peer = peer
|
||||
is_host = true
|
||||
lobby = {1: pname}
|
||||
lobby_changed.emit()
|
||||
return true
|
||||
|
||||
|
||||
func join_game(ip: String, pname: String, port: int = PORT) -> bool:
|
||||
player_name = pname
|
||||
var peer := ENetMultiplayerPeer.new()
|
||||
var err := peer.create_client(ip, port)
|
||||
if err != OK:
|
||||
connection_failed.emit("Verbindung zu %s:%d fehlgeschlagen" % [ip, port])
|
||||
return false
|
||||
multiplayer.multiplayer_peer = peer
|
||||
is_host = false
|
||||
return true
|
||||
|
||||
|
||||
func leave() -> void:
|
||||
if multiplayer.multiplayer_peer != null:
|
||||
multiplayer.multiplayer_peer.close()
|
||||
multiplayer.multiplayer_peer = null
|
||||
lobby.clear()
|
||||
is_host = false
|
||||
in_game = false
|
||||
lobby_changed.emit()
|
||||
|
||||
|
||||
func is_online() -> bool:
|
||||
var peer := multiplayer.multiplayer_peer
|
||||
return peer is ENetMultiplayerPeer \
|
||||
and peer.get_connection_status() != MultiplayerPeer.CONNECTION_DISCONNECTED
|
||||
|
||||
|
||||
func _on_peer_connected(id: int) -> void:
|
||||
if is_host:
|
||||
_push_lobby.rpc_id(id, lobby)
|
||||
|
||||
|
||||
func _on_peer_disconnected(id: int) -> void:
|
||||
if is_host:
|
||||
lobby.erase(id)
|
||||
_push_lobby.rpc(lobby)
|
||||
lobby_changed.emit()
|
||||
|
||||
|
||||
func _on_connected() -> void:
|
||||
_register.rpc_id(1, player_name)
|
||||
|
||||
|
||||
func _on_connect_fail() -> void:
|
||||
multiplayer.multiplayer_peer = null
|
||||
connection_failed.emit("Server nicht erreichbar.")
|
||||
|
||||
|
||||
func _on_server_disconnected() -> void:
|
||||
multiplayer.multiplayer_peer = null
|
||||
lobby.clear()
|
||||
in_game = false
|
||||
server_closed.emit()
|
||||
|
||||
|
||||
@rpc("any_peer", "reliable")
|
||||
func _register(pname: String) -> void:
|
||||
if not is_host:
|
||||
return
|
||||
var id := multiplayer.get_remote_sender_id()
|
||||
lobby[id] = pname.substr(0, 16)
|
||||
_push_lobby.rpc(lobby)
|
||||
lobby_changed.emit()
|
||||
|
||||
|
||||
@rpc("authority", "reliable")
|
||||
func _push_lobby(data: Dictionary) -> void:
|
||||
lobby = data
|
||||
lobby_changed.emit()
|
||||
|
||||
|
||||
## Einzelspieler: kein Netzwerk, nur der lokale Spieler und Bots.
|
||||
func start_singleplayer(pname: String, ai_count: int) -> void:
|
||||
player_name = pname
|
||||
multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new()
|
||||
is_host = true
|
||||
lobby = {1: pname}
|
||||
lobby_changed.emit()
|
||||
_begin({"peers": [1], "names": lobby.duplicate(), "ai": ai_count})
|
||||
|
||||
|
||||
## Nur der Host ruft das auf.
|
||||
func start_game(ai_count: int) -> void:
|
||||
if not is_host:
|
||||
return
|
||||
var order: Array = lobby.keys()
|
||||
order.sort()
|
||||
var cfg := {"peers": order, "names": lobby.duplicate(), "ai": ai_count}
|
||||
_begin.rpc(cfg)
|
||||
|
||||
|
||||
@rpc("authority", "call_local", "reliable")
|
||||
func _begin(cfg: Dictionary) -> void:
|
||||
in_game = true
|
||||
game_started.emit(cfg)
|
||||
Reference in New Issue
Block a user