Skip to content

Instantly share code, notes, and snippets.

@levidavidmurray
Created June 7, 2024 02:33
Show Gist options
  • Save levidavidmurray/6e43a77edfbf3f82f7d4ae36f1fa04bb to your computer and use it in GitHub Desktop.
Save levidavidmurray/6e43a77edfbf3f82f7d4ae36f1fa04bb to your computer and use it in GitHub Desktop.
extends Node
signal server_hosted
signal connection_started
signal ping_updated(ping: int)
signal client_disconnecting
signal server_connected
signal server_disconnected
signal server_destroyed
signal player_connected(peer_id: int)
signal player_disconnected(peer_id: int)
signal connection_failed
const PORT = 10567
const MAX_PEERS = 4
const UPDATE_PING_FRAMES = 60
const DEBUG_FORCE_ENET = true
var STEAM_LOBBY_FAILURE_MESSAGE = {
2: "This lobby no longer exists.",
3: "You don't have permission to join this lobby.",
4: "The lobby is now full.",
5: "Uh... something unexpected happened!",
6: "You are banned from this lobby.",
7: "You cannot join due to having a limited account.",
8: "This lobby is locked or disabled.",
9: "This lobby is community locked.",
10: "A user in the lobby has blocked you from joining.",
11: "A user you have blocked is in the lobby."
}
var lobby_id: int = -1
var lobby_name: String = ""
var is_connected_to_server = false
var debug_peer_id: int # only used for debugging
# ping stuff
var ping = 0
var ping_send_time = 0
var frames_since_last_ping = 0
var peer: MultiplayerPeer
func _ready():
multiplayer.server_relay = false
Steam.lobby_created.connect(_on_lobby_created)
Steam.lobby_joined.connect(_on_lobby_joined)
Steam.join_requested.connect(_on_join_requested)
func _process(_delta):
if not is_connected_to_server or not peer:
return
if frames_since_last_ping >= UPDATE_PING_FRAMES:
send_ping()
frames_since_last_ping = 0
else:
frames_since_last_ping += 1
func enet_create_server():
peer = ENetMultiplayerPeer.new()
peer.create_server(PORT, MAX_PEERS)
_setup_server()
func enet_create_client(ip: String = "localhost"):
peer = ENetMultiplayerPeer.new()
peer.create_client(ip, PORT)
_setup_client()
## STEAM STUFF
func host_lobby(_lobby_name: String):
lobby_name = _lobby_name
Steam.createLobby(Steam.LOBBY_TYPE_PUBLIC, MAX_PEERS)
func join_lobby(_lobby_id, _new_player_name = ""):
Steam.joinLobby(int(_lobby_id))
func _create_socket():
peer = SteamMultiplayerPeer.new()
peer.create_host(0, [])
_setup_server()
func _connect_socket(steam_id: int):
peer = SteamMultiplayerPeer.new()
peer.create_client(steam_id, 0, [])
_setup_client()
## END STEAM STUFF
func disconnect_server():
client_disconnecting.emit()
if multiplayer.is_server():
close_server()
else:
peer.close()
Steam.leaveLobby(lobby_id)
func close_server():
server_destroyed.emit()
multiplayer.peer_connected.disconnect(_on_peer_connected)
multiplayer.peer_disconnected.disconnect(_on_peer_disconnected)
peer.close()
peer = null
multiplayer.multiplayer_peer = null
func send_ping():
ping_send_time = Time.get_ticks_msec()
receive_ping.rpc_id(1, ping_send_time)
@rpc("any_peer")
func receive_ping(timestamp: int):
receive_pong.rpc_id(multiplayer.get_remote_sender_id(), timestamp)
@rpc("any_peer")
func receive_pong(timestamp: int):
ping = Time.get_ticks_msec() - timestamp
ping_updated.emit(ping)
func _setup_server():
multiplayer.multiplayer_peer = peer
debug_peer_id = multiplayer.get_unique_id()
multiplayer.peer_connected.connect(_on_peer_connected)
multiplayer.peer_disconnected.connect(_on_peer_disconnected)
server_hosted.emit()
func _setup_client():
multiplayer.multiplayer_peer = peer
debug_peer_id = multiplayer.get_unique_id()
if not multiplayer.server_disconnected.is_connected(_on_server_disconnected):
print("Connecting signals")
multiplayer.connected_to_server.connect(_on_connected_to_server)
multiplayer.server_disconnected.connect(_on_server_disconnected)
multiplayer.connection_failed.connect(_on_connection_failed)
connection_started.emit()
func _on_lobby_created(_connect: int, _lobby_id: int):
print("PNet::_on_lobby_created ", _lobby_id)
if _connect == 1:
lobby_id = _lobby_id
Steam.setLobbyData(lobby_id, "name", lobby_name)
# Steam.allowP2PPacketRelay(true)
_create_socket()
else:
printerr("Failed to create lobby")
func _on_lobby_joined(_lobby_id: int, permissions: int, locked: bool, response: int):
print("PNet::_on_lobby_joined ", _lobby_id)
lobby_id = _lobby_id
if response == 1:
var id = Steam.getLobbyOwner(lobby_id)
if id != Steam.getSteamID():
_connect_socket(id)
else:
# Get the failure reason
var message = STEAM_LOBBY_FAILURE_MESSAGE[response]
printerr(message)
func _on_join_requested(_lobby_id: int, friend_id: int):
print("PNet::_on_join_requested ", _lobby_id)
join_lobby(_lobby_id)
func _on_connected_to_server():
print("PNet::_on_connected_to_server")
is_connected_to_server = true
server_connected.emit()
func _on_server_disconnected():
# TODO: Remove this variable?
print("PNet::_on_server_disconnected")
is_connected_to_server = false
Steam.leaveLobby(lobby_id)
peer = null
multiplayer.multiplayer_peer = null
server_disconnected.emit()
func _on_peer_connected(peer_id: int):
print("PNet::_on_peer_connected ", peer_id)
player_connected.emit(peer_id)
func _on_peer_disconnected(peer_id: int):
print("PNet::_on_peer_disconnected ", peer_id)
player_disconnected.emit(peer_id)
func _on_connection_failed():
print("PNet::_on_connection_failed")
connection_failed.emit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment