184 lines
4.8 KiB
GDScript
184 lines
4.8 KiB
GDScript
extends Node
|
|
|
|
signal player_registered(peer_id: int, player_info: Dictionary)
|
|
signal network_error(message: String)
|
|
|
|
const DEFAULT_PORT: int = 10567
|
|
const MAX_PEERS: int = 20
|
|
|
|
var players := {}
|
|
var is_dedicated: bool = false
|
|
|
|
var _peer: ENetMultiplayerPeer
|
|
var _local_player_info := {"name": ""}
|
|
|
|
var _title_scene := preload("res://scenes/title.tscn")
|
|
var _main_scene := preload("res://scenes/main.tscn")
|
|
var _player_scene := preload("res://scenes/player.tscn")
|
|
|
|
|
|
func _ready() -> void:
|
|
multiplayer.peer_connected.connect(_on_multiplayer_peer_connected)
|
|
multiplayer.peer_disconnected.connect(_on_multiplayer_peer_disconnected)
|
|
multiplayer.connected_to_server.connect(_on_multiplayer_connected_to_server)
|
|
multiplayer.connection_failed.connect(_on_multiplayer_connection_failed)
|
|
multiplayer.server_disconnected.connect(_on_multiplayer_server_disconnected)
|
|
|
|
|
|
func _process(_delta: float) -> void:
|
|
Debugger.text("_local_player_info", _local_player_info)
|
|
Debugger.text("players", players)
|
|
|
|
|
|
func set_local_player_info(username: String) -> void:
|
|
_local_player_info["name"] = username
|
|
|
|
|
|
func host_game(dedicated: bool = false) -> void:
|
|
print("Hosting...")
|
|
is_dedicated = dedicated
|
|
_peer = ENetMultiplayerPeer.new()
|
|
var error := _peer.create_server(DEFAULT_PORT, MAX_PEERS)
|
|
|
|
if error:
|
|
match error:
|
|
ERR_ALREADY_IN_USE:
|
|
var message := "Already in use"
|
|
printerr(message)
|
|
network_error.emit(message)
|
|
ERR_CANT_CREATE:
|
|
var message := "Cannot create server"
|
|
printerr(message)
|
|
network_error.emit(message)
|
|
return
|
|
|
|
multiplayer.set_multiplayer_peer(_peer)
|
|
|
|
_load_main()
|
|
|
|
if not dedicated:
|
|
players[1] = _local_player_info
|
|
print("Registered player ", 1, " ", _local_player_info)
|
|
_add_player(multiplayer.get_unique_id(), _local_player_info)
|
|
|
|
|
|
func join_game(address: String) -> void:
|
|
print("Joining " + address + "...")
|
|
_peer = ENetMultiplayerPeer.new()
|
|
var error := _peer.create_client(address, DEFAULT_PORT)
|
|
|
|
if error:
|
|
match error:
|
|
ERR_ALREADY_IN_USE:
|
|
var message := "Already in use"
|
|
printerr(message)
|
|
network_error.emit(message)
|
|
ERR_CANT_CREATE:
|
|
var message := "Cannot create client"
|
|
printerr(message)
|
|
network_error.emit(message)
|
|
return
|
|
|
|
multiplayer.set_multiplayer_peer(_peer)
|
|
|
|
_load_main()
|
|
|
|
|
|
func is_active() -> bool:
|
|
return (
|
|
multiplayer.multiplayer_peer.get_connection_status()
|
|
== MultiplayerPeer.CONNECTION_CONNECTED
|
|
)
|
|
|
|
|
|
func is_dedicated_server() -> bool:
|
|
return OS.has_feature("dedicated_server") or DisplayServer.get_name() == "headless"
|
|
|
|
|
|
func player_name(peer_id: int) -> String:
|
|
if peer_id in players:
|
|
return str(peer_id) + " (" + players[peer_id]["name"] + ")"
|
|
|
|
return str(peer_id)
|
|
|
|
|
|
func _switch_scene(to: PackedScene, from: Node) -> void:
|
|
if from:
|
|
from.queue_free()
|
|
|
|
var new_scene := to.instantiate()
|
|
get_tree().get_root().add_child(new_scene)
|
|
print("Scene loaded")
|
|
|
|
|
|
func _load_main() -> void:
|
|
print("Loading Main...")
|
|
_switch_scene(_main_scene, $/root/Title)
|
|
|
|
|
|
func _add_player(peer_id: int, player_info: Dictionary) -> void:
|
|
if not multiplayer.is_server():
|
|
return
|
|
|
|
print("Adding player ", player_name(peer_id))
|
|
var player := _player_scene.instantiate() as Player
|
|
player.name = str(peer_id)
|
|
|
|
Referencer.main.player_holder.add_child(player, true)
|
|
player.set_info(player_info)
|
|
|
|
|
|
func _remove_player(peer_id: int) -> void:
|
|
if not multiplayer.is_server():
|
|
return
|
|
|
|
print("Removing player ", player_name(peer_id))
|
|
var player := Referencer.main.player_holder.get_node_or_null(str(peer_id))
|
|
if player:
|
|
player.queue_free()
|
|
|
|
|
|
@rpc("any_peer", "reliable")
|
|
func _register_player(player_info: Dictionary) -> void:
|
|
var peer_id := multiplayer.get_remote_sender_id()
|
|
print("Registering player ", peer_id, " ", player_info)
|
|
if peer_id == 1 and !player_info["name"]:
|
|
print("Skipping registering the host")
|
|
return
|
|
players[peer_id] = player_info
|
|
player_registered.emit(peer_id, player_info)
|
|
|
|
|
|
func _on_multiplayer_peer_connected(peer_id: int) -> void:
|
|
print("Peer connected ", peer_id)
|
|
_register_player.rpc_id(peer_id, _local_player_info)
|
|
_add_player(peer_id, _local_player_info)
|
|
|
|
|
|
func _on_multiplayer_peer_disconnected(peer_id: int) -> void:
|
|
print("Peer disconnected ", player_name(peer_id))
|
|
_remove_player(peer_id)
|
|
players.erase(peer_id)
|
|
|
|
|
|
func _on_multiplayer_connected_to_server() -> void:
|
|
var peer_id := multiplayer.get_unique_id()
|
|
print("Connected to server as ", peer_id)
|
|
players[peer_id] = _local_player_info
|
|
print("Registered player ", peer_id, " ", _local_player_info)
|
|
|
|
|
|
func _on_multiplayer_connection_failed() -> void:
|
|
multiplayer.set_multiplayer_peer(null)
|
|
var message := "Connection failed"
|
|
printerr(message)
|
|
network_error.emit(message)
|
|
|
|
|
|
func _on_multiplayer_server_disconnected() -> void:
|
|
var message := "Server disconnected"
|
|
printerr(message)
|
|
players.clear()
|
|
_switch_scene(_title_scene, $/root/Main)
|
|
network_error.emit(message)
|