Inital project
This commit is contained in:
17
2d_mp_base/scripts/GameManager.gd
Normal file
17
2d_mp_base/scripts/GameManager.gd
Normal file
@@ -0,0 +1,17 @@
|
||||
extends Node
|
||||
|
||||
const BALL = preload("uid://dpcnrigmslqkt")
|
||||
var current_level: Node
|
||||
var chat_node: Chat
|
||||
|
||||
@rpc("any_peer", "call_remote", "reliable")
|
||||
func request_spawn_ball(pos: Vector3):
|
||||
if is_multiplayer_authority():
|
||||
_spawn_ball(pos, multiplayer.get_remote_sender_id())
|
||||
|
||||
|
||||
func _spawn_ball(pos: Vector3, sender_id: int):
|
||||
var new_ball: Node3D = BALL.instantiate()
|
||||
new_ball.name = "Ball_%d_%d" % [sender_id, randi()]
|
||||
current_level.add_child(new_ball, true)
|
||||
new_ball.global_position = pos
|
||||
1
2d_mp_base/scripts/GameManager.gd.uid
Normal file
1
2d_mp_base/scripts/GameManager.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://qvw0khflh6bq
|
||||
178
2d_mp_base/scripts/NetworkManager.gd
Normal file
178
2d_mp_base/scripts/NetworkManager.gd
Normal file
@@ -0,0 +1,178 @@
|
||||
extends Node
|
||||
|
||||
const PLAYER = preload("uid://coomlq1nbp7aw")
|
||||
const LOADING_SCREEN = preload("uid://38t27mxycd35")
|
||||
|
||||
var enet_peer := ENetMultiplayerPeer.new()
|
||||
var port = 9999
|
||||
|
||||
var is_steam_lobby: bool = false
|
||||
var steam_lobby_id: int = 0
|
||||
var steam_peer := SteamMultiplayerPeer.new()
|
||||
var is_host_steam: bool = false
|
||||
var is_joining_steam: bool = false
|
||||
|
||||
var loading_screen: LoadingScreen
|
||||
var player_list: Dictionary[int, Player]
|
||||
|
||||
var ip_username: String = "Username"
|
||||
var ip_avatar: ImageTexture
|
||||
|
||||
|
||||
func create_loading_screen(label_text: String = "Joining server..."):
|
||||
loading_screen = LOADING_SCREEN.instantiate()
|
||||
get_tree().current_scene.add_child.call_deferred(loading_screen, true)
|
||||
loading_screen.cancel_pressed.connect(func(): leave_server())
|
||||
loading_screen.loading_label.text = label_text
|
||||
loading_screen.show()
|
||||
|
||||
|
||||
func _connect_multiplayer_signals(is_server: bool):
|
||||
multiplayer.peer_connected.connect(add_player)
|
||||
multiplayer.peer_disconnected.connect(remove_player)
|
||||
if not is_server:
|
||||
multiplayer.connected_to_server.connect(_on_connected_to_server)
|
||||
|
||||
|
||||
func start_steam_lobby():
|
||||
create_loading_screen("Creating lobby...")
|
||||
Steam.lobby_created.connect(_on_steam_lobby_created)
|
||||
Steam.createLobby(Steam.LOBBY_TYPE_PUBLIC, 10)
|
||||
is_host_steam = true
|
||||
|
||||
|
||||
func _on_steam_lobby_created(result: int, lobby_id: int) -> void:
|
||||
if result != Steam.Result.RESULT_OK:
|
||||
push_error("Could not create lobby: " + str(result))
|
||||
return
|
||||
|
||||
steam_lobby_id = lobby_id
|
||||
steam_peer.server_relay = true
|
||||
steam_peer.create_host()
|
||||
multiplayer.multiplayer_peer = steam_peer
|
||||
_connect_multiplayer_signals(true)
|
||||
is_steam_lobby = true
|
||||
add_player(1)
|
||||
print("Lobby created. ID: " + str(lobby_id))
|
||||
loading_screen.queue_free()
|
||||
|
||||
|
||||
func join_steam_lobby(lobby_id: int):
|
||||
Steam.lobby_joined.connect(_on_join_steam_lobby)
|
||||
is_joining_steam = true
|
||||
Steam.joinLobby(lobby_id)
|
||||
create_loading_screen("Joining steam lobby...")
|
||||
|
||||
|
||||
func _on_join_steam_lobby(lobby_id: int, permission: int, locked: bool, response: int) -> void:
|
||||
if not is_joining_steam:
|
||||
return
|
||||
|
||||
steam_lobby_id = lobby_id
|
||||
steam_peer.server_relay = true
|
||||
var result := steam_peer.create_client(Steam.getLobbyOwner(lobby_id))
|
||||
if result != 0:
|
||||
push_error("Could not join lobby: " + str(result))
|
||||
return
|
||||
|
||||
multiplayer.multiplayer_peer = steam_peer
|
||||
_connect_multiplayer_signals(false)
|
||||
is_joining_steam = false
|
||||
is_steam_lobby = true
|
||||
|
||||
|
||||
func _on_connected_to_server():
|
||||
add_player(multiplayer.get_unique_id())
|
||||
|
||||
if is_steam_lobby:
|
||||
set_player_details_steam.rpc(multiplayer.get_unique_id(), Steamworks.steam_id)
|
||||
else:
|
||||
set_player_details_ip.rpc(multiplayer.get_unique_id(), ip_username, ip_avatar.get_image().save_png_to_buffer())
|
||||
|
||||
loading_screen.queue_free()
|
||||
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func set_player_details_steam(peer_id: int, steam_id: int):
|
||||
if player_list.has(peer_id):
|
||||
await player_list[peer_id].set_player_info_steam(steam_id)
|
||||
|
||||
|
||||
func add_player(peer_id: int):
|
||||
var new_player: Player = PLAYER.instantiate()
|
||||
new_player.name = str(peer_id)
|
||||
get_tree().current_scene.add_child(new_player, true)
|
||||
player_list[peer_id] = new_player
|
||||
|
||||
if is_steam_lobby and player_list.has(multiplayer.get_unique_id()):
|
||||
set_player_details_steam.rpc(multiplayer.get_unique_id(), Steamworks.steam_id)
|
||||
elif !is_steam_lobby and player_list.has(multiplayer.get_unique_id()):
|
||||
set_player_details_ip.rpc(multiplayer.get_unique_id(), ip_username, ip_avatar.get_image().save_png_to_buffer())
|
||||
|
||||
|
||||
func remove_player(peer_id: int):
|
||||
if peer_id == 1:
|
||||
leave_server()
|
||||
return
|
||||
|
||||
if player_list.has(peer_id):
|
||||
player_list[peer_id].queue_free()
|
||||
player_list.erase(peer_id)
|
||||
|
||||
|
||||
func leave_server():
|
||||
if is_steam_lobby:
|
||||
_cleanup_steam_signals()
|
||||
|
||||
_cleanup_multiplayer_signals()
|
||||
|
||||
multiplayer.multiplayer_peer.close()
|
||||
multiplayer.multiplayer_peer = null
|
||||
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||
player_list.clear()
|
||||
get_tree().reload_current_scene()
|
||||
|
||||
|
||||
func _cleanup_multiplayer_signals():
|
||||
if multiplayer.peer_connected.is_connected(add_player):
|
||||
multiplayer.peer_connected.disconnect(add_player)
|
||||
if multiplayer.peer_disconnected.is_connected(remove_player):
|
||||
multiplayer.peer_disconnected.disconnect(remove_player)
|
||||
if multiplayer.connected_to_server.is_connected(_on_connected_to_server):
|
||||
multiplayer.connected_to_server.disconnect(_on_connected_to_server)
|
||||
|
||||
|
||||
func _cleanup_steam_signals():
|
||||
if Steam.lobby_created.is_connected(_on_steam_lobby_created):
|
||||
Steam.lobby_created.disconnect(_on_steam_lobby_created)
|
||||
if Steam.lobby_joined.is_connected(_on_join_steam_lobby):
|
||||
Steam.lobby_joined.disconnect(_on_join_steam_lobby)
|
||||
|
||||
|
||||
#region Non-steam
|
||||
func start_server(username: String, avatar: ImageTexture):
|
||||
is_steam_lobby = false
|
||||
ip_username = username
|
||||
ip_avatar = avatar
|
||||
enet_peer.create_server(port)
|
||||
multiplayer.multiplayer_peer = enet_peer
|
||||
_connect_multiplayer_signals(true)
|
||||
add_player(1)
|
||||
|
||||
|
||||
func join_server(ip: String, username: String, avatar: ImageTexture):
|
||||
is_steam_lobby = false
|
||||
ip_username = username
|
||||
ip_avatar = avatar
|
||||
enet_peer.create_client(ip, port)
|
||||
multiplayer.multiplayer_peer = enet_peer
|
||||
_connect_multiplayer_signals(false)
|
||||
create_loading_screen()
|
||||
|
||||
|
||||
@rpc("any_peer", "call_local")
|
||||
func set_player_details_ip(peer_id: int, username: String, avatar_bytes: PackedByteArray):
|
||||
if player_list.has(peer_id):
|
||||
await player_list[peer_id].set_player_info_ip(username, avatar_bytes)
|
||||
|
||||
#endregion
|
||||
1
2d_mp_base/scripts/NetworkManager.gd.uid
Normal file
1
2d_mp_base/scripts/NetworkManager.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://ff235q5xbiie
|
||||
48
2d_mp_base/scripts/Steamworks.gd
Normal file
48
2d_mp_base/scripts/Steamworks.gd
Normal file
@@ -0,0 +1,48 @@
|
||||
extends Node
|
||||
|
||||
var use_steam := true
|
||||
var is_initalized: bool = false
|
||||
var steam_id: int = 0
|
||||
var steam_username: String = "None"
|
||||
var steam_avatar: ImageTexture
|
||||
var tmp_avatar_image_texture: ImageTexture
|
||||
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
if is_initalized: return
|
||||
if OS.has_feature("nosteam"):
|
||||
print("[Steamworks] Window has flag 'nosteam', skipping steam initalization")
|
||||
use_steam = false
|
||||
return
|
||||
|
||||
var response := Steam.steamInitEx()
|
||||
if response["status"] != 0:
|
||||
push_error("Steam failed to initalize: " + str(response))
|
||||
print("Steam failed to initalize. Error code: " + str(response))
|
||||
await get_tree().create_timer(1).timeout
|
||||
get_tree().quit()
|
||||
return
|
||||
|
||||
print("Steam initalized successfully")
|
||||
is_initalized = true
|
||||
|
||||
steam_id = Steam.getSteamID()
|
||||
steam_username = Steam.getPersonaName()
|
||||
steam_avatar = await get_player_avatar(steam_id)
|
||||
|
||||
|
||||
func get_player_avatar(steam_id: int) -> ImageTexture:
|
||||
if !is_initalized or !use_steam: return
|
||||
Steam.getPlayerAvatar(Steam.AVATAR_LARGE, steam_id)
|
||||
var result = await Steam.avatar_loaded # returns (avatar_id, width, avatar_data)
|
||||
|
||||
while result[0] != steam_id:
|
||||
result = await Steam.avatar_loaded
|
||||
|
||||
var width: int = result[1]
|
||||
var avatar_data: PackedByteArray = result[2]
|
||||
var image := Image.create_from_data(width, width, false, Image.FORMAT_RGBA8, avatar_data)
|
||||
if width > 128:
|
||||
image.resize(128, 128, Image.INTERPOLATE_LANCZOS)
|
||||
return ImageTexture.create_from_image(image)
|
||||
1
2d_mp_base/scripts/Steamworks.gd.uid
Normal file
1
2d_mp_base/scripts/Steamworks.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://6im158hn15uv
|
||||
58
2d_mp_base/scripts/player_info.gd
Normal file
58
2d_mp_base/scripts/player_info.gd
Normal file
@@ -0,0 +1,58 @@
|
||||
class_name PlayerInfoResource
|
||||
extends Resource
|
||||
|
||||
var peer_id: int = 0
|
||||
var username: String = "None"
|
||||
var avatar: ImageTexture
|
||||
var avatar_modulated_color: Color
|
||||
|
||||
var is_steam: bool = false
|
||||
var steam_id: int = 0
|
||||
|
||||
|
||||
func init_enet(peer_id: int, username: String, avatar_bytes: PackedByteArray):
|
||||
is_steam = false
|
||||
self.peer_id = peer_id
|
||||
self.username = username
|
||||
var avatar_image := Image.new()
|
||||
var err := avatar_image.load_png_from_buffer(avatar_bytes)
|
||||
if err != 0:
|
||||
push_error("Could not load avatar image for peer: %s, Error: %s" % [peer_id, err])
|
||||
return
|
||||
avatar_image.resize(128, 128, Image.INTERPOLATE_LANCZOS)
|
||||
self.avatar = ImageTexture.create_from_image(avatar_image)
|
||||
self.avatar_modulated_color = get_modulated_avatar_color(avatar)
|
||||
|
||||
|
||||
func init_steam(peer_id: int, username: String, avatar: ImageTexture, steam_id: int):
|
||||
is_steam = true
|
||||
self.peer_id = peer_id
|
||||
self.username = username
|
||||
self.avatar = avatar
|
||||
self.avatar_modulated_color = get_modulated_avatar_color(avatar)
|
||||
self.steam_id = steam_id
|
||||
|
||||
|
||||
func to_str() -> String:
|
||||
var fmt_string := "Peer ID: %s\nUsername: %s\nIs Steam?: %s\nSteam ID: %s"
|
||||
var final_string := fmt_string % [peer_id, username, is_steam, steam_id]
|
||||
return final_string
|
||||
|
||||
|
||||
func get_modulated_avatar_color(avatar: ImageTexture) -> Color:
|
||||
var avatar_image: Image = avatar.get_image()
|
||||
if avatar_image.get_width() > 128:
|
||||
avatar_image.resize(128, 128, Image.INTERPOLATE_LANCZOS)
|
||||
var new_avatar_texture = ImageTexture.create_from_image(avatar_image)
|
||||
|
||||
# modulate steam profile picture to use for username color in chat
|
||||
var avatar_modulated_color := Vector3.ZERO
|
||||
var texture_size := avatar.get_size()
|
||||
var image := avatar.get_image()
|
||||
for y in range(0, texture_size.y):
|
||||
for x in range(0, texture_size.x):
|
||||
var pixel := image.get_pixel(x, y)
|
||||
avatar_modulated_color += Vector3(pixel.r, pixel.g, pixel.b)
|
||||
avatar_modulated_color /= texture_size.x * texture_size.y
|
||||
print(Color(avatar_modulated_color.x, avatar_modulated_color.y, avatar_modulated_color.z))
|
||||
return Color(avatar_modulated_color.x, avatar_modulated_color.y, avatar_modulated_color.z)
|
||||
1
2d_mp_base/scripts/player_info.gd.uid
Normal file
1
2d_mp_base/scripts/player_info.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dmix4x4jyc4xt
|
||||
Reference in New Issue
Block a user