forked from unfa/liblast
Finished basic server-side player list implementation.
This commit is contained in:
parent
49f4e7c70f
commit
df861143a4
2 changed files with 96 additions and 67 deletions
|
@ -52,8 +52,8 @@ func _unhandled_input(_event) -> void:
|
|||
get_tree().get_root().set_input_as_handled()
|
||||
|
||||
# doesn't work over network due to missing RPC implementation in Godot 4
|
||||
@remotesync func chat_message(sender_id: int, recipient_team, message: String) -> void:
|
||||
var sender_info = main.player_list[sender_id]
|
||||
@remotesync func chat_message(sender_pid: int, recipient_team, message: String) -> void:
|
||||
var sender_info = main.player_list.get(sender_pid)
|
||||
chat_history.append_bbcode('\n' + '[b][color=' + sender_info.color.to_html() +']' + str(sender_info.name) + '[/color][/b] : [i]' + message + '[/i]')
|
||||
|
||||
func _on_Editor_text_submitted(new_text):
|
||||
|
|
159
Game/Main.gd
159
Game/Main.gd
|
@ -25,19 +25,22 @@ class PlayerInfo:
|
|||
var team: int
|
||||
var color: Color
|
||||
var focus: GameFocus
|
||||
|
||||
func _init():#name: String, team: int, color: Color):
|
||||
# self.name = name
|
||||
# self.team = team
|
||||
# self.color = color
|
||||
# self.focus = 0
|
||||
|
||||
var health: int
|
||||
|
||||
func _init():#name: String, team: int, color: Color):
|
||||
var player_name = ""
|
||||
for i in range(0, 4):
|
||||
player_name += ['a','b','c', 'd', 'e', 'f'][randi() % 5]
|
||||
self.name = player_name
|
||||
self.color = Color(randf(),randf(),randf())
|
||||
self.team = 0
|
||||
self.focus = 999
|
||||
self.health = 100
|
||||
# else:
|
||||
# self.name = name
|
||||
# self.team = team
|
||||
# self.color = color
|
||||
# self.focus = 0
|
||||
|
||||
func serialize():
|
||||
return {
|
||||
|
@ -45,52 +48,59 @@ class PlayerInfo:
|
|||
'team': str(self.team),
|
||||
'color': self.color.to_html(),
|
||||
'focus': self.focus,
|
||||
'health': self.health
|
||||
}
|
||||
func set(name: String, team: int, color: Color, focus: int):
|
||||
func set(name: String, team: int, color: Color, focus: int, health: int):
|
||||
self.name = name
|
||||
self.team = team
|
||||
self.color = color
|
||||
self.focus = focus
|
||||
self.health = health
|
||||
|
||||
func deserialize(info):
|
||||
#var info_parsed = info.parse_json(info)
|
||||
self.name = info['name']
|
||||
self.team = info['team'].to_int()
|
||||
self.color = Color.html(info['color'])
|
||||
self.focus = info['focus']
|
||||
|
||||
self.health = info['health']
|
||||
#func generate():
|
||||
|
||||
func _process(delta):
|
||||
$Label.text = "player_list: \n"
|
||||
for i in player_list.keys():
|
||||
$Label.text += str(i) + str(player_list[i].serialize()) + "\n"
|
||||
for i in player_list.players.keys():
|
||||
if player_list.players[i]:
|
||||
$Label.text += str(i) + " = " + str(player_list.get(i).serialize()) + "\n"
|
||||
else:
|
||||
$Label.text += str(i) + " = ???"
|
||||
|
||||
var local_player_info: PlayerInfo
|
||||
|
||||
#class PlayerList:
|
||||
# var items = {}
|
||||
class PlayerList:
|
||||
var players = {}
|
||||
#
|
||||
# func store(pid, item):
|
||||
# items[pid] = item
|
||||
#
|
||||
# func erase(pid):
|
||||
# items.erase(pid)
|
||||
#
|
||||
# func update(pid, item):
|
||||
# if items[pid]:
|
||||
# items[pid] = item
|
||||
#
|
||||
# func get():
|
||||
# return items
|
||||
|
||||
func erase(pid):
|
||||
players.erase(pid)
|
||||
|
||||
func set(pid: int, info: PlayerInfo):
|
||||
# if info is PlayerInfo:
|
||||
players[pid] = info
|
||||
# else:
|
||||
# var new_info = PlayerInfo.deserialize(info)
|
||||
# players[pid] = new_info
|
||||
|
||||
func get(pid: int) -> PlayerInfo:
|
||||
return players[pid]
|
||||
|
||||
var player_list = {}:
|
||||
set(player_list):
|
||||
if role in [NetworkRole.SERVER, NetworkRole.DEDICATED_SERVER]:
|
||||
for i in player_list:
|
||||
rpc(&'player_list_update', i.serialize())
|
||||
else:
|
||||
rpc_id(1, &'player_list_update', player_list.serialize())
|
||||
# func update():
|
||||
# if get_tree().network_peer.get_unique_id() == 1:
|
||||
# for i in players.keys:
|
||||
# rpc(&'player_list_update', i, players[i].serialize())
|
||||
# else:
|
||||
# rpc_id(1, &'player_list_update', players[get_tree().network_peer.get_unique_id()].serialize())
|
||||
|
||||
|
||||
@onready var player_list = PlayerList.new()
|
||||
|
||||
var focus = GameFocus.MENU :
|
||||
set(new_focus):
|
||||
|
@ -135,48 +145,65 @@ func _input(_event) -> void:
|
|||
#@remote func update_player_list(player_list):
|
||||
# self.player_list = player_list
|
||||
|
||||
@remotesync func player_list_update(info):
|
||||
var new_info = PlayerInfo.deserialize(info)
|
||||
var id = get_tree().get_rpc_sender_id()
|
||||
print("Updating player_list wit hnew info: ", new_info)
|
||||
player_list[id] = new_info
|
||||
print("Player list: ", player_list)
|
||||
print("Player list item for id ", id, ": ", player_list[id])
|
||||
@remote func player_list_update(info, pid = get_tree().get_rpc_sender_id()):
|
||||
if get_tree().network_peer.get_unique_id() == 1: # if we're server, we should store this
|
||||
pid = get_tree().get_rpc_sender_id() #disallow clients setting player_info for other players than themselves
|
||||
var new_info = PlayerInfo.new()
|
||||
new_info.deserialize(info)
|
||||
player_list.set(pid, new_info)
|
||||
rpc(&'player_list_update', info, pid) # broadcast the new entry to clients
|
||||
else: #we are client, so we're getting data relayed from the server
|
||||
var new_info = PlayerInfo.new()
|
||||
new_info.deserialize(info)
|
||||
player_list.set(pid, new_info) # server relays other PID's data
|
||||
|
||||
func create_player(id: int, is_local: bool) -> void:
|
||||
# if not id:
|
||||
# id = get_tree().get_rpc_sender_id()
|
||||
#
|
||||
# print_debug("player_list_update ", info)
|
||||
# if info is PlayerInfo:
|
||||
# player_list.set(id, info)
|
||||
# else:
|
||||
# var new_info = PlayerInfo.deserialize(info)
|
||||
# player_list.set(id, new_info)
|
||||
# print("Updating player_list wit hnew info: ", new_info)
|
||||
#
|
||||
# print("Player list: ", player_list)
|
||||
# print("Player list item for id ", id, ": ", player_list[id])
|
||||
|
||||
func create_player(pid: int, is_local: bool) -> void:
|
||||
var new_player
|
||||
|
||||
new_player = player_scene.instantiate()
|
||||
|
||||
var spawnpoint = $Map/SpawnPoints.get_children()[randi() % len($Map/SpawnPoints.get_children())]
|
||||
new_player.name = str(id)
|
||||
new_player.name = str(pid)
|
||||
new_player.global_transform = spawnpoint.global_transform
|
||||
new_player.set_network_master(id)
|
||||
new_player.set_network_master(pid)
|
||||
$Players.add_child(new_player)
|
||||
|
||||
if is_local:
|
||||
local_player = new_player #$Players.get_node(str(id))
|
||||
local_player.get_node("Head/Camera").current = true
|
||||
var new_info = PlayerInfo.new()
|
||||
#new_info.generate()
|
||||
local_player_info = new_info
|
||||
rpc_id(id, &'player_list_update', local_player_info.serialize()) # send player_info to others
|
||||
player_list[id] = local_player_info
|
||||
player_list.set(pid, new_info)
|
||||
|
||||
$NetworkTesting/TextEdit.text = local_player_info.name
|
||||
$NetworkTesting/ColorPickerButton.color = local_player_info.color
|
||||
if get_tree().network_peer.get_unique_id() != 1: #if we're not the server
|
||||
rpc_id(1, &'player_list_update', new_info.serialize()) # send local player info to the server
|
||||
|
||||
$NetworkTesting/TextEdit.text = new_info.name
|
||||
$NetworkTesting/ColorPickerButton.color = new_info.color
|
||||
else: # make sure we use the right camera
|
||||
new_player.get_node("Head/Camera").current = false
|
||||
if local_player:
|
||||
if local_player: #if there is a local player, use it's camera
|
||||
local_player.get_node("Head/Camera").current = true
|
||||
|
||||
func start_dedicated_server():
|
||||
func start_dedicated_server(): # start server without creating a local player
|
||||
role = NetworkRole.DEDICATED_SERVER
|
||||
peer.create_server(NET_PORT, 16)
|
||||
get_tree().network_peer = peer
|
||||
#create_player(1, true)
|
||||
|
||||
func _on_Host_pressed():
|
||||
func _on_Host_pressed(): # start server and create a local player
|
||||
role = NetworkRole.SERVER
|
||||
$NetworkTesting/Host.disabled = true
|
||||
$NetworkTesting/Connect.disabled = true
|
||||
|
@ -193,36 +220,38 @@ func _on_Connect_pressed():
|
|||
peer.create_client(NET_SERVER, NET_PORT)
|
||||
get_tree().network_peer = peer
|
||||
|
||||
func _player_connected(id) -> void:
|
||||
print("player connected, id: ", id)
|
||||
create_player(id, false)
|
||||
func _player_connected(pid) -> void:
|
||||
print("player connected, id: ", pid)
|
||||
create_player(pid, false)
|
||||
|
||||
if get_tree().network_peer.get_unique_id() == 1: # if we're the server
|
||||
for i in player_list.players.keys(): # send each player info entry to the newly connected client
|
||||
rpc_id(pid, &'player_list_update', player_list.get(i).serialize(), i) # send local player info to the server
|
||||
|
||||
# if local_player:
|
||||
# local_player.rpc(&"update_info")
|
||||
#
|
||||
# if role in [NetworkRole.SERVER, NetworkRole.DEDICATED_SERVER]:
|
||||
# rpc_id(id, "player_list_update", player_list)
|
||||
|
||||
func _player_disconnected(id) -> void:
|
||||
print("player disconnected, id: ", id)
|
||||
func _player_disconnected(pid) -> void:
|
||||
print("player disconnected, id: ", pid)
|
||||
|
||||
func _connected_ok() -> void:
|
||||
print("connected to server")
|
||||
var id = get_tree().get_network_unique_id()
|
||||
create_player(id, true)
|
||||
var pid = get_tree().get_network_unique_id()
|
||||
create_player(pid, true)
|
||||
focus = GameFocus.GAME
|
||||
role = NetworkRole.CLIENT
|
||||
# todo pull player list from server
|
||||
|
||||
func _connected_fail() -> void:
|
||||
print("connection to server failed")
|
||||
|
||||
func _server_disconnected() -> void:
|
||||
print("server disconnected")
|
||||
|
||||
role = NetworkRole.NONE
|
||||
|
||||
func _ready() -> void:
|
||||
|
||||
print("Commandline arguments: ", OS.get_cmdline_args())
|
||||
|
||||
get_tree().connect("network_peer_connected", self._player_connected)
|
||||
|
@ -233,7 +262,7 @@ func _ready() -> void:
|
|||
|
||||
|
||||
func _on_TextEdit_text_submitted(new_text):
|
||||
local_player_info.name = new_text
|
||||
player_list.players[get_tree().network_peer.get_unique_id()].name = new_text
|
||||
|
||||
func _on_ColorPickerButton_color_changed(color):
|
||||
local_player_info.color = color
|
||||
player_list.players[get_tree().network_peer.get_unique_id()].color = color
|
||||
|
|
Loading…
Reference in a new issue