feature/moving-platforms #6

Merged
gskeough merged 7 commits from feature/moving-platforms into develop 2024-12-14 03:44:59 +00:00
12 changed files with 534 additions and 38 deletions
Showing only changes of commit cfd59e5332 - Show all commits

View File

@ -6,6 +6,7 @@
[node name="GameConsole" type="Control"]
process_mode = 3
z_index = 4096
z_as_relative = false
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=11 format=3 uid="uid://ewovs6ns5y3k"]
[ext_resource type="Script" path="res://assets/core/networking/NetworkManager.gd" id="1_kki4t"]
[ext_resource type="Script" path="res://assets/core/networking/old/old_NetworkManager.gd" id="1_kki4t"]
[ext_resource type="Texture2D" uid="uid://gymb0tju4y67" path="res://addons/kennysprototypetextures/Dark/texture_black (1).png" id="1_l0osb"]
[ext_resource type="PackedScene" uid="uid://c6w0ivy4hetrl" path="res://assets/core/player-controller/scenes/player.tscn" id="2_q510b"]
[ext_resource type="PackedScene" uid="uid://c7mtmmke1anxp" path="res://assets/core/ships/test-ship/test-ship.tscn" id="4_feinw"]

View File

@ -1,34 +0,0 @@
class_name NetworkManager
extends Node
var steamId: int
var username: String
var avatar_texture: ImageTexture
func _ready() -> void:
var init_result = Steam.steamInit(true, 480)
if init_result["status"] <= 1:
_initialize()
else:
GameConsole.log_error("Steam failed to initialize: " + str(init_result))
func _initialize() -> void:
steamId = Steam.getSteamID()
username = Steam.getFriendPersonaName(steamId)
GameConsole.print_line("Steam ID: " + username)
Steam.getPlayerAvatar()
Steam.avatar_loaded.connect(_on_avatar_loaded)
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)
if avatar_size > 128:
avatar_image.resize(128, 128, Image.INTERPOLATE_LANCZOS)
if avatar_image != null:
avatar_texture = ImageTexture.create_from_image(avatar_image)
else:
GameConsole.log_error("Failed to create avatar image!")

View File

@ -0,0 +1,67 @@
[gd_scene load_steps=3 format=3 uid="uid://7t1x82gvrw8a"]
[ext_resource type="Script" path="res://assets/core/networking/scripts/lobby.gd" id="1_o4fbq"]
[ext_resource type="PackedScene" uid="uid://biryul3n6thlw" path="res://assets/core/networking/scenes/user_box_prefab.tscn" id="2_dpthk"]
[node name="Lobby" type="Control" node_paths=PackedStringArray("host_button", "join_button", "leave_button", "lobby_id_line_edit", "user_list_box")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_o4fbq")
host_button = NodePath("Panel/HBoxContainer/Buttons/Host")
join_button = NodePath("Panel/HBoxContainer/Buttons/HBoxContainer/Join")
leave_button = NodePath("Panel/HBoxContainer/Buttons/Leave")
lobby_id_line_edit = NodePath("Panel/HBoxContainer/Buttons/HBoxContainer/LineEdit")
user_list_box = NodePath("Panel/HBoxContainer/PlayerList")
user_box_prefab = ExtResource("2_dpthk")
[node name="Panel" type="Panel" parent="."]
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="Panel"]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Buttons" type="VBoxContainer" parent="Panel/HBoxContainer"]
custom_minimum_size = Vector2(500, 0)
layout_mode = 2
size_flags_horizontal = 6
size_flags_vertical = 4
[node name="Host" type="Button" parent="Panel/HBoxContainer/Buttons"]
layout_mode = 2
size_flags_vertical = 4
text = "Host Lobby"
[node name="HBoxContainer" type="HBoxContainer" parent="Panel/HBoxContainer/Buttons"]
layout_mode = 2
[node name="LineEdit" type="LineEdit" parent="Panel/HBoxContainer/Buttons/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Join" type="Button" parent="Panel/HBoxContainer/Buttons/HBoxContainer"]
custom_minimum_size = Vector2(90, 0)
layout_mode = 2
text = "Join"
[node name="Leave" type="Button" parent="Panel/HBoxContainer/Buttons"]
layout_mode = 2
disabled = true
text = "Leave Lobby"
[node name="PlayerList" type="VBoxContainer" parent="Panel/HBoxContainer"]
layout_mode = 2
size_flags_horizontal = 3

View File

@ -0,0 +1,20 @@
[gd_scene load_steps=2 format=3 uid="uid://biryul3n6thlw"]
[ext_resource type="Texture2D" uid="uid://fwub8fvl2u4i" path="res://addons/ingameconsole/ps1hagrid.png" id="1_gtutw"]
[node name="UserBox" type="HBoxContainer"]
offset_right = 610.0
offset_bottom = 128.0
[node name="PFP" type="TextureRect" parent="."]
custom_minimum_size = Vector2(128, 128)
layout_mode = 2
size_flags_horizontal = 4
texture = ExtResource("1_gtutw")
expand_mode = 1
[node name="Username" type="Label" parent="."]
layout_mode = 2
size_flags_horizontal = 3
text = "Hagrid 1"
horizontal_alignment = 1

View File

@ -0,0 +1,322 @@
extends Node
const STEAM_APP_ID: int = 480
const PACKET_READ_LIMIT: int = 32
var lobby_data
var lobby_id: int = 0
var lobby_members: Array = []
var lobby_members_max: int = 10
var lobby_vote_kick: bool = false
var lobby_type: int = Steam.LOBBY_TYPE_PUBLIC
var steam_id: int = 0
var steam_username: String = ""
var avatar_texture_cache: Dictionary = {}
var host_id: int = 0
signal lobby_created(lobby_id: int)
signal lobby_joined(lobby_id: int)
signal user_joined_lobby(user_id: int)
signal user_left_lobby(user_id: int)
signal host_left_lobby()
func _ready() -> void:
_init_steam()
func _process(_delta: float) -> void:
Steam.run_callbacks()
if lobby_id > 0:
read_all_p2p_packets()
func _init_steam() -> void:
var init_result = Steam.steamInitEx(true, STEAM_APP_ID)
print("Steam Init Result: " + str(init_result))
if init_result['status'] > 0:
printerr("Steam failed to initialize, shutting down: " + str(init_result))
#get_tree().quit()
steam_id = Steam.getSteamID()
steam_username = Steam.getFriendPersonaName(steam_id)
Steam.p2p_session_request.connect(_on_p2p_session_request)
Steam.p2p_session_connect_fail.connect(_on_p2p_session_connect_fail)
Steam.join_requested.connect(_on_lobby_join_requested)
Steam.lobby_chat_update.connect(_on_lobby_chat_update)
Steam.lobby_created.connect(_on_lobby_created)
#Steam.lobby_data_update.connect(_on_lobby_data_update)
#Steam.lobby_invite.connect(_on_lobby_invite)
Steam.lobby_joined.connect(_on_lobby_joined)
Steam.lobby_match_list.connect(_on_lobby_match_list)
Steam.lobby_message.connect(_on_lobby_message)
Steam.persona_state_change.connect(_on_persona_change)
func _on_lobby_join_requested(this_lobby_id: int, friend_id: int):
var owner_name: String = Steam.getFriendPersonaName(friend_id)
print("Trying to join " + owner_name + "'s lobby...")
join_lobby(this_lobby_id)
func _on_lobby_chat_update(this_lobby_id: int, change_id: int, making_change_id: int, chat_state: int) -> void:
var changer_name: String = Steam.getFriendPersonaName(change_id)
# If a player has joined the lobby
if chat_state == Steam.CHAT_MEMBER_STATE_CHANGE_ENTERED:
print("%s has joined the lobby." % changer_name)
elif chat_state == Steam.CHAT_MEMBER_STATE_CHANGE_LEFT:
user_left_lobby.emit(change_id)
print("%s has left the lobby." % changer_name)
elif chat_state == Steam.CHAT_MEMBER_STATE_CHANGE_KICKED:
print("%s has been kicked from the lobby." % changer_name)
elif chat_state == Steam.CHAT_MEMBER_STATE_CHANGE_BANNED:
print("%s has been banned from the lobby." % changer_name)
else:
print("%s did... something." % changer_name)
get_lobby_members()
func _on_lobby_created(connect: int, this_lobby_id: int) -> void:
if connect == 1:
lobby_id = this_lobby_id
lobby_created.emit(lobby_id)
print("Lobby created with ID: " + str(lobby_id))
host_id = steam_id
Steam.setLobbyJoinable(lobby_id, true)
Steam.setLobbyData(lobby_id, "name", str(steam_username) + "'s Lobby")
var set_relay: bool = Steam.allowP2PPacketRelay(true)
#func _on_lobby_data_update():
# pass
#func _on_lobby_invite():
# pass
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()
lobby_joined.emit(lobby_id)
else:
var fail_reason: String
match response:
Steam.CHAT_ROOM_ENTER_RESPONSE_DOESNT_EXIST: fail_reason = "This lobby no longer exists."
Steam.CHAT_ROOM_ENTER_RESPONSE_NOT_ALLOWED: fail_reason = "You don't have permission to join this lobby."
Steam.CHAT_ROOM_ENTER_RESPONSE_FULL: fail_reason = "The lobby is now full."
Steam.CHAT_ROOM_ENTER_RESPONSE_ERROR: fail_reason = "Uh... something unexpected happened!"
Steam.CHAT_ROOM_ENTER_RESPONSE_BANNED: fail_reason = "You are banned from this lobby."
Steam.CHAT_ROOM_ENTER_RESPONSE_LIMITED: fail_reason = "You cannot join due to having a limited account."
Steam.CHAT_ROOM_ENTER_RESPONSE_CLAN_DISABLED: fail_reason = "This lobby is locked or disabled."
Steam.CHAT_ROOM_ENTER_RESPONSE_COMMUNITY_BAN: fail_reason = "This lobby is community locked."
Steam.CHAT_ROOM_ENTER_RESPONSE_MEMBER_BLOCKED_YOU: fail_reason = "A user in the lobby has blocked you from joining."
Steam.CHAT_ROOM_ENTER_RESPONSE_YOU_BLOCKED_MEMBER: fail_reason = "A user you have blocked is in the lobby."
print("Failed to join this chat room: %s" % fail_reason)
func _on_lobby_match_list():
pass
func _on_lobby_message():
pass
func _on_persona_change(this_steam_id: int, _flags: int) -> void:
if lobby_id > 0 and lobby_members:
for member in lobby_members:
if member["steam_id"] == this_steam_id:
var user: String = str(this_steam_id) + ":" + Steam.getFriendPersonaName(this_steam_id)
print("User (%s) had information change, updating lobby list." % user)
get_lobby_members()
break
func _on_p2p_session_request(remote_id: int):
var this_requester: String = Steam.getFriendPersonaName(remote_id)
print("P2P session request from: " + this_requester)
Steam.acceptP2PSessionWithUser(remote_id)
make_p2p_handshake()
func _on_p2p_session_connect_fail(steam_id: int, session_error: int) -> void:
# If no error was given
if session_error == 0:
print("WARNING: Session failure with %s: no error given" % steam_id)
# Else if target user was not running the same game
elif session_error == 1:
print("WARNING: Session failure with %s: target user not running the same game" % steam_id)
# Else if local user doesn't own app / game
elif session_error == 2:
print("WARNING: Session failure with %s: local user doesn't own app / game" % steam_id)
# Else if target user isn't connected to Steam
elif session_error == 3:
print("WARNING: Session failure with %s: target user isn't connected to Steam" % steam_id)
# Else if connection timed out
elif session_error == 4:
print("WARNING: Session failure with %s: connection timed out" % steam_id)
# Else if unused
elif session_error == 5:
print("WARNING: Session failure with %s: unused" % steam_id)
# Else no known error
else:
print("WARNING: Session failure with %s: unknown error %s" % [steam_id, session_error])
func host_lobby():
if lobby_id == 0:
Steam.createLobby(lobby_type, lobby_members_max)
else:
printerr("Cannot host lobby, already in a lobby")
func join_lobby(this_lobby_id: int):
print("Attempting to join lobby: " + str(this_lobby_id))
lobby_members.clear()
Steam.joinLobby(this_lobby_id)
func leave_lobby():
if lobby_id != 0:
Steam.leaveLobby(lobby_id)
lobby_id = 0
for this_member in lobby_members:
if this_member["steam_id"] != steam_id:
Steam.closeP2PSessionWithUser(this_member["steam_id"])
lobby_members.clear()
print("Left lobby.")
func get_lobby_members():
lobby_members.clear()
var member_count: int = Steam.getNumLobbyMembers(lobby_id)
for this_member in range(0, member_count):
var member_steam_id: int = Steam.getLobbyMemberByIndex(lobby_id, this_member)
var member_steam_name: String = Steam.getFriendPersonaName(member_steam_id)
lobby_members.append({"steam_id":member_steam_id, "steam_name":member_steam_name})
user_joined_lobby.emit(member_steam_id)
await request_player_avatar(member_steam_id)
func make_p2p_handshake():
print("Sending p2p handshake to the lobby...")
send_p2p_packet(0, {"message":"handshake", "from":steam_id})
func send_p2p_packet(target: int, packet_data: Dictionary) -> void:
# Set the send_type and channel
var send_type: int = Steam.P2P_SEND_RELIABLE
var channel: int = 0
# Create a data array to send the data through
var this_data: PackedByteArray
# Compress the PackedByteArray we create from our dictionary using the GZIP compression method
var compressed_data: PackedByteArray = var_to_bytes(packet_data).compress(FileAccess.COMPRESSION_GZIP)
this_data.append_array(compressed_data)
# If sending a packet to everyone
if target == 0:
# If there is more than one user, send packets
if lobby_members.size() > 1:
# Loop through all members that aren't you
for this_member in lobby_members:
if this_member['steam_id'] != steam_id:
Steam.sendP2PPacket(this_member['steam_id'], this_data, send_type, channel)
# Else send it to someone specific
else:
Steam.sendP2PPacket(target, this_data, send_type, channel)
func read_all_p2p_packets(read_count: int = 0):
if read_count >= PACKET_READ_LIMIT:
return
if Steam.getAvailableP2PPacketSize(0) > 0:
read_p2p_packet()
read_all_p2p_packets(read_count + 1)
func read_p2p_packet() -> void:
var packet_size: int = Steam.getAvailableP2PPacketSize(0)
# There is a packet
if packet_size > 0:
var this_packet: Dictionary = Steam.readP2PPacket(packet_size, 0)
if this_packet.is_empty() or this_packet == null:
print("WARNING: read an empty packet with non-zero size!")
# Get the remote user's ID
var packet_sender: int = this_packet['remote_steam_id']
# Make the packet data readable
var packet_code: PackedByteArray = this_packet['data']
# Decompress the array before turning it into a useable dictionary
var readable_data: Dictionary = bytes_to_var(packet_code.decompress_dynamic(-1, FileAccess.COMPRESSION_GZIP))
# Print the packet to output
print("Packet: %s" % readable_data)
func request_player_avatar(user_id: int, size: int = 128) -> void:
var avatar_texture: ImageTexture = null
Steam.getPlayerAvatar(Steam.AVATAR_LARGE, user_id)
print("Attempting to get avatar for " + Steam.getFriendPersonaName(user_id) + ".....")
Steam.avatar_loaded.connect(func(loaded_user_id: int, avatar_size: int, avatar_buffer: PackedByteArray):
if loaded_user_id == user_id:
var avatar_image: Image = Image.create_from_data(avatar_size, avatar_size, false, Image.FORMAT_RGBA8, avatar_buffer)
if avatar_size != size:
avatar_image.resize(size, size, Image.INTERPOLATE_LANCZOS)
avatar_texture = ImageTexture.create_from_image(avatar_image)
avatar_texture_cache[user_id] = avatar_texture
)
while not avatar_texture_cache.has(user_id):
await get_tree().process_frame
func get_player_avatar(user_id: int) -> ImageTexture:
if avatar_texture_cache.has(user_id):
return avatar_texture_cache[user_id]
else:
await request_player_avatar(user_id)
return avatar_texture_cache[user_id]

View File

@ -0,0 +1,80 @@
extends Control
@export var host_button: Button
@export var join_button: Button
@export var leave_button: Button
@export var lobby_id_line_edit: LineEdit
@export var user_list_box: VBoxContainer
@export var user_box_prefab: PackedScene
var added_users = []
func _ready() -> void:
host_button.pressed.connect(_on_host)
join_button.pressed.connect(_on_join)
leave_button.pressed.connect(_on_leave)
NetworkManager.lobby_created.connect(_on_lobby_created)
NetworkManager.lobby_joined.connect(_on_lobby_joined)
NetworkManager.user_joined_lobby.connect(_on_user_joined_lobby)
NetworkManager.user_left_lobby.connect(_on_user_left_lobby)
GameConsole.register_command(Command.new("update", update, [], "Updates the lobby UI"))
func _on_host():
NetworkManager.host_lobby()
func _on_join():
NetworkManager.join_lobby(int(lobby_id_line_edit.text))
func _on_leave():
NetworkManager.leave_lobby()
added_users.clear()
for child in user_list_box.get_children():
child.queue_free()
func _on_lobby_created(lobby_id: int):
print("Lobby created")
lobby_id_line_edit.text = str(NetworkManager.lobby_id)
host_button.disabled = true
join_button.disabled = true
leave_button.disabled = false
lobby_id_line_edit.editable = false
func _on_lobby_joined(lobby_id: int):
host_button.disabled = true
join_button.disabled = true
leave_button.disabled = false
lobby_id_line_edit.editable = false
func _on_user_joined_lobby(user_id: int):
if user_id in added_users:
return # User already added, skip
added_users.append(user_id)
update()
func _on_user_left_lobby(user_id: int):
added_users.erase(user_id)
update()
func update() -> void:
for child in user_list_box.get_children():
child.queue_free()
for user_id in added_users:
var user_box = user_box_prefab.instantiate()
user_box.get_node("Username").text = str(Steam.getFriendPersonaName(user_id))
user_list_box.add_child(user_box)
var avatar_texture = await NetworkManager.get_player_avatar(user_id)
user_box.get_node("PFP").texture = avatar_texture

View File

@ -1,6 +1,6 @@
class_name Player extends CharacterBody3D
var network_manager: NetworkManager
var network_manager: OldnetworkManager
var player_tag: Label3D
var username: String = ""
var is_piloting: bool = false
@ -36,7 +36,7 @@ func _ready() -> void:
func init_network_manager() -> void:
network_manager = %NetworkManager
if network_manager != null:
username = network_manager.username
username = network_manager.my_username
player_tag.text = username
else:
player_tag.text = "Player"

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://huq7dxk5yvjk"]
[ext_resource type="Script" path="res://assets/core/networking/NetworkManager.gd" id="1_dcack"]
[ext_resource type="Script" path="res://assets/core/networking/old/old_NetworkManager.gd" id="1_dcack"]
[node name="Main" type="Node"]

39
export_presets.cfg Normal file
View File

@ -0,0 +1,39 @@
[preset.0]
name="Linux"
platform="Linux"
runnable=true
advanced_options=false
dedicated_server=false
custom_features=""
export_filter="all_resources"
include_filter=""
exclude_filter=""
export_path="../build/linux/debug/Steamforged Skies.x86_64"
encryption_include_filters=""
encryption_exclude_filters=""
encrypt_pck=false
encrypt_directory=false
script_export_mode=2
[preset.0.options]
custom_template/debug=""
custom_template/release=""
debug/export_console_wrapper=1
binary_format/embed_pck=false
texture_format/s3tc_bptc=true
texture_format/etc2_astc=false
binary_format/architecture="x86_64"
ssh_remote_deploy/enabled=false
ssh_remote_deploy/host="user@host_ip"
ssh_remote_deploy/port="22"
ssh_remote_deploy/extra_args_ssh=""
ssh_remote_deploy/extra_args_scp=""
ssh_remote_deploy/run_script="#!/usr/bin/env bash
export DISPLAY=:0
unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\"
\"{temp_dir}/{exe_name}\" {cmd_args}"
ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash
kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\")
rm -rf \"{temp_dir}\""

View File

@ -18,6 +18,7 @@ config/icon="res://assets/icon.png"
[autoload]
GameConsole="*res://addons/ingameconsole/GameConsole.tscn"
NetworkManager="*res://assets/core/networking/scripts/NetworkManager.gd"
[debug]