steam p2p test

This commit is contained in:
Chris Bell 2024-12-10 22:36:59 -06:00
parent cd66b6d910
commit 9b36da6cf4
4 changed files with 241 additions and 3 deletions

View File

@ -1,10 +1,17 @@
class_name NetworkManager class_name NetworkManager
extends Node extends Node
var steamId: int const PACKET_READ_LIMIT: int = 32
var steam_id: int
var username: String var username: String
var avatar_texture: ImageTexture var avatar_texture: ImageTexture
var is_host: bool = false
var lobby_id: int = 0
var lobby_members: Array = []
var lobby_members_max: int = 4
func _ready() -> void: func _ready() -> void:
var init_result = Steam.steamInit(true, 480) var init_result = Steam.steamInit(true, 480)
if init_result["status"] <= 1: if init_result["status"] <= 1:
@ -14,13 +21,23 @@ func _ready() -> void:
func _initialize() -> void: func _initialize() -> void:
steamId = Steam.getSteamID() steam_id = Steam.getSteamID()
username = Steam.getFriendPersonaName(steamId) username = Steam.getFriendPersonaName(steam_id)
GameConsole.print_line("Steam ID: " + username) GameConsole.print_line("Steam ID: " + username)
Steam.getPlayerAvatar() Steam.getPlayerAvatar()
Steam.avatar_loaded.connect(_on_avatar_loaded) Steam.avatar_loaded.connect(_on_avatar_loaded)
Steam.lobby_created.connect(_on_lobby_created)
Steam.lobby_joined.connect(_on_lobby_joined)
Steam.p2p_session_request.connect(_on_p2p_session_request)
func _process(_delta: float) -> void:
Steam.run_callbacks()
if lobby_id > 0:
read_all_p2p_packets()
func _on_avatar_loaded(_user_id: int, avatar_size: int, avatar_buffer: PackedByteArray) -> void: func _on_avatar_loaded(_user_id: int, avatar_size: int, avatar_buffer: PackedByteArray) -> void:
var avatar_image: Image = Image.create_from_data(avatar_size, avatar_size, false, Image.FORMAT_RGBA8, avatar_buffer) var avatar_image: Image = Image.create_from_data(avatar_size, avatar_size, false, Image.FORMAT_RGBA8, avatar_buffer)
@ -30,5 +47,98 @@ func _on_avatar_loaded(_user_id: int, avatar_size: int, avatar_buffer: PackedByt
if avatar_image != null: if avatar_image != null:
avatar_texture = ImageTexture.create_from_image(avatar_image) avatar_texture = ImageTexture.create_from_image(avatar_image)
GameConsole.print_line("Avatar loaded!")
else: else:
GameConsole.log_error("Failed to create avatar image!") GameConsole.log_error("Failed to create avatar image!")
func _on_lobby_created(connection_status: int, this_lobby_id: int) -> void:
if connection_status == 1:
lobby_id = this_lobby_id
Steam.setLobbyJoinable(lobby_id, true)
Steam.setLobbyData(lobby_id, "host", str(steam_id))
var set_relay: bool = Steam.allowP2PPacketRelay(true)
GameConsole.print_line("Lobby created: " + str(lobby_id))
func _on_lobby_joined(this_lobby_id: int, _permissions: int, _locked: bool, response: int) -> void:
if response == Steam.CHAT_ROOM_ENTER_RESPONSE_SUCCESS:
lobby_id = this_lobby_id
get_lobby_members()
make_p2p_handshake()
func read_all_p2p_packets(read_count: int = 0) -> void:
if read_count >= PACKET_READ_LIMIT:
return
if Steam.getAvailableP2PPacketSize(0) > 0:
read_p2p_packet()
read_all_p2p_packets(read_count + 1)
func _on_p2p_session_request(remote_id: int) -> void:
var this_requester: String = Steam.getFriendPersonaName(remote_id)
Steam.acceptP2PSessionWithUser(remote_id)
func make_p2p_handshake() -> void:
send_p2p_packet(0, {"message" : "handshake", "steam_id" : steam_id, "username" : username})
func create_lobby() -> void:
if lobby_id == 0:
is_host = true
Steam.createLobby(Steam.LOBBY_TYPE_PUBLIC, lobby_members_max)
func join_lobby(this_lobby_id: int) -> void:
Steam.joinLobby(lobby_id)
func get_lobby_members():
lobby_members.clear()
var member_count: int = Steam.getNumLobbyMembers(lobby_id)
for member in range(0,member_count):
var member_id: int = Steam.getLobbyMemberByIndex(lobby_id, member)
var member_username: String = Steam.getFriendPersonaName(member_id)
lobby_members.append({"steam_id": member_id, "username": member_username})
func send_p2p_packet(this_target: int, packet_data: Dictionary, send_type: int = 0) -> void:
var channel: int = 0
var this_data: PackedByteArray
this_data.append_array(var_to_bytes(packet_data))
if this_target == 0:
if lobby_members.size() > 1:
for member in lobby_members:
if member["steam_id"] != steam_id:
Steam.sendP2PPacket(member["steam_id"], this_data, send_type, channel)
else:
Steam.sendP2PPacket(this_target, this_data, send_type, channel)
func read_p2p_packet() -> void:
var packet_size: int = Steam.getAvailableP2PPacketSize()
if packet_size > 0:
var this_packet: Dictionary = Steam.readP2PPacket(packet_size, 0)
var packet_sender: int = this_packet["remote_steam_id"]
var packet_code: PackedByteArray = this_packet["data"]
var read_data: Dictionary = bytes_to_var(packet_code)
if read_data.has("message"):
match read_data["message"]:
"handshake":
GameConsole.print_line("Handshake from: " + read_data["username"])
get_lobby_members()
"chat":
GameConsole.print_line(read_data["username"] + ": " + read_data["message"])
_:
GameConsole.print_line("Unknown message: " + read_data["message"])

View File

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://bpmn7t87tfk7f"]
[ext_resource type="Script" path="res://assets/core/networking/NetworkManager.gd" id="1_6essl"]
[node name="NetworkManager" type="Node"]
script = ExtResource("1_6essl")

View File

@ -0,0 +1,41 @@
extends Control
@export var network_manager: NetworkManager
@export var host_button: Button
@export var join_button: Button
@export var lobby_id: LineEdit
@export var pfp: TextureRect
@export var username: Label
@export var hosted_lobby_id: Label
# Called when the node enters the scene tree for the first time.
func _ready() -> void:
host_button.button_down.connect(_on_host_button_pressed)
join_button.button_down.connect(_on_join_button_pressed)
username.text = network_manager.username
if network_manager.avatar_texture == null:
GameConsole.log_error("Avatar texture is null!")
get_tree().create_timer(0.005).timeout.connect(
func():
pfp.texture = network_manager.avatar_texture
)
else:
pfp.texture = network_manager.avatar_texture
func _on_host_button_pressed() -> void:
network_manager.create_lobby()
get_tree().create_timer(0.5).timeout.connect(
func():
hosted_lobby_id.text = ("Lobby hosted: " + str(network_manager.lobby_id))
)
hosted_lobby_id.visible = true
func _on_join_button_pressed() -> void:
network_manager.join_lobby(int(lobby_id.text))

View File

@ -0,0 +1,81 @@
[gd_scene load_steps=4 format=3 uid="uid://dfa8n5rw2qpfd"]
[ext_resource type="PackedScene" uid="uid://bpmn7t87tfk7f" path="res://assets/core/networking/network_manager.tscn" id="1_i1w5w"]
[ext_resource type="Script" path="res://assets/core/networking/network_test_ui.gd" id="2_rbs4r"]
[ext_resource type="Texture2D" uid="uid://fwub8fvl2u4i" path="res://addons/ingameconsole/ps1hagrid.png" id="3_co2ix"]
[node name="Test-lobby" type="CanvasLayer"]
[node name="NetworkManager" parent="." instance=ExtResource("1_i1w5w")]
[node name="UiRoot" type="Control" parent="." node_paths=PackedStringArray("network_manager", "host_button", "join_button", "lobby_id", "pfp", "username", "hosted_lobby_id")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("2_rbs4r")
network_manager = NodePath("../NetworkManager")
host_button = NodePath("Panel/HBoxContainer/VBoxContainer/Host")
join_button = NodePath("Panel/HBoxContainer/VBoxContainer/Join")
lobby_id = NodePath("Panel/HBoxContainer/VBoxContainer/LobbyID")
pfp = NodePath("Panel/HBoxContainer/VBoxContainer2/HBoxContainer/PFP")
username = NodePath("Panel/HBoxContainer/VBoxContainer2/HBoxContainer/Username")
hosted_lobby_id = NodePath("Panel/HBoxContainer/VBoxContainer/HostedLobbyID")
[node name="Panel" type="Panel" parent="UiRoot"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="HBoxContainer" type="HBoxContainer" parent="UiRoot/Panel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="UiRoot/Panel/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Host" type="Button" parent="UiRoot/Panel/HBoxContainer/VBoxContainer"]
layout_mode = 2
text = "Host"
[node name="Join" type="Button" parent="UiRoot/Panel/HBoxContainer/VBoxContainer"]
layout_mode = 2
text = "Join"
[node name="LobbyID" type="LineEdit" parent="UiRoot/Panel/HBoxContainer/VBoxContainer"]
layout_mode = 2
placeholder_text = "Lobby ID"
[node name="HostedLobbyID" type="Label" parent="UiRoot/Panel/HBoxContainer/VBoxContainer"]
visible = false
layout_mode = 2
text = "Lobby hosted: "
[node name="VBoxContainer2" type="VBoxContainer" parent="UiRoot/Panel/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="HBoxContainer" type="HBoxContainer" parent="UiRoot/Panel/HBoxContainer/VBoxContainer2"]
layout_mode = 2
[node name="PFP" type="TextureRect" parent="UiRoot/Panel/HBoxContainer/VBoxContainer2/HBoxContainer"]
custom_minimum_size = Vector2(128, 128)
layout_mode = 2
size_flags_horizontal = 4
texture = ExtResource("3_co2ix")
expand_mode = 1
[node name="Username" type="Label" parent="UiRoot/Panel/HBoxContainer/VBoxContainer2/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 8
text = "username"