added player connection
This commit is contained in:
7
project/scenes/player.gd
Normal file
7
project/scenes/player.gd
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
extends CharacterBody2D
|
||||||
|
class_name Player
|
||||||
|
|
||||||
|
var session_id: String
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
$NameTag.text = session_id
|
29
project/scenes/player.tscn
Normal file
29
project/scenes/player.tscn
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://co4dwle8qgvn4"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scenes/player.gd" id="1_0ulg3"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://brayuh2pw38ix" path="res://icon.svg" id="1_5um25"]
|
||||||
|
|
||||||
|
[sub_resource type="RectangleShape2D" id="RectangleShape2D_gcdh3"]
|
||||||
|
size = Vector2(128, 128)
|
||||||
|
|
||||||
|
[node name="Player" type="CharacterBody2D"]
|
||||||
|
script = ExtResource("1_0ulg3")
|
||||||
|
|
||||||
|
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||||
|
texture = ExtResource("1_5um25")
|
||||||
|
|
||||||
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||||
|
shape = SubResource("RectangleShape2D_gcdh3")
|
||||||
|
|
||||||
|
[node name="NameTag" type="Label" parent="."]
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = -11.5
|
||||||
|
offset_right = 20.0
|
||||||
|
offset_bottom = 11.5
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
12
project/scenes/worFF19.tmp
Normal file
12
project/scenes/worFF19.tmp
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://br61u82ldlrxe"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scenes/world.gd" id="1_r7dh1"]
|
||||||
|
|
||||||
|
[node name="World" type="Node2D"]
|
||||||
|
script = ExtResource("1_r7dh1")
|
||||||
|
|
||||||
|
[node name="Button" type="Button" parent="."]
|
||||||
|
offset_right = 8.0
|
||||||
|
offset_bottom = 8.0
|
||||||
|
|
||||||
|
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]
|
29
project/scenes/world.gd
Normal file
29
project/scenes/world.gd
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
extends Node2D
|
||||||
|
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
UdpClient.player_join.connect(_on_player_join)
|
||||||
|
UdpClient.player_disconnect.connect(_on_player_disconnect)
|
||||||
|
|
||||||
|
func _on_player_join(player_client: Dictionary, clients: Array) -> void:
|
||||||
|
add_player(player_client)
|
||||||
|
for client in clients:
|
||||||
|
add_player(client)
|
||||||
|
|
||||||
|
|
||||||
|
func add_player(client: Dictionary):
|
||||||
|
var player: Player = preload("res://scenes/player.tscn").instantiate()
|
||||||
|
player.session_id = client.session_id
|
||||||
|
player.position = Vector2(client.position.x, client.position.y)
|
||||||
|
add_child(player)
|
||||||
|
|
||||||
|
func _on_button_pressed():
|
||||||
|
var payload: Dictionary = {
|
||||||
|
"type": "init",
|
||||||
|
}
|
||||||
|
UdpClient.send_message("test")
|
||||||
|
|
||||||
|
func _on_player_disconnect(session_id: String):
|
||||||
|
for child: Node in get_children():
|
||||||
|
if child is Player && child.session_id == session_id:
|
||||||
|
child.queue_free()
|
12
project/scenes/world.tscn
Normal file
12
project/scenes/world.tscn
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://br61u82ldlrxe"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://scenes/world.gd" id="1_r7dh1"]
|
||||||
|
|
||||||
|
[node name="World" type="Node2D"]
|
||||||
|
script = ExtResource("1_r7dh1")
|
||||||
|
|
||||||
|
[node name="Button" type="Button" parent="."]
|
||||||
|
offset_right = 8.0
|
||||||
|
offset_bottom = 8.0
|
||||||
|
|
||||||
|
[connection signal="pressed" from="Button" to="." method="_on_button_pressed"]
|
@@ -1,14 +1,15 @@
|
|||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
|
signal player_move(session_id: String, position_mod: Vector2)
|
||||||
|
signal player_join(player_client: Dictionary, clients: Array)
|
||||||
|
signal player_disconnect(session_id: String)
|
||||||
|
|
||||||
var udp_peer: PacketPeerUDP = PacketPeerUDP.new()
|
var udp_peer: PacketPeerUDP = PacketPeerUDP.new()
|
||||||
var server_ip: String = "45.93.249.177" # Replace with your server's IP
|
var server_ip: String = "127.0.0.1" # Replace with your server's IP
|
||||||
var server_port: int = 4477 # Replace with your server's port
|
var server_port: int = 4477 # Replace with your server's port
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
var err = udp_peer.bind(server_port, "*")
|
udp_peer.bind(server_port, "*")
|
||||||
if err != OK:
|
|
||||||
print("Failed to bind to port: ", server_port)
|
|
||||||
return
|
|
||||||
print("Listening on port: ", server_port)
|
print("Listening on port: ", server_port)
|
||||||
# Send a message to the server to initiate session ID assignment
|
# Send a message to the server to initiate session ID assignment
|
||||||
var payload: Dictionary = {
|
var payload: Dictionary = {
|
||||||
@@ -19,8 +20,16 @@ func _ready():
|
|||||||
func _process(_delta):
|
func _process(_delta):
|
||||||
if udp_peer.get_available_packet_count() > 0:
|
if udp_peer.get_available_packet_count() > 0:
|
||||||
var packet = udp_peer.get_packet()
|
var packet = udp_peer.get_packet()
|
||||||
var message: String = packet.get_string_from_utf8()
|
var packet_json: Dictionary = JSON.parse_string(packet.get_string_from_utf8())
|
||||||
print("Received: ", message)
|
match packet_json.type:
|
||||||
|
"init_success":
|
||||||
|
player_join.emit(packet_json.player_client, Array(packet_json.clients))
|
||||||
|
"message":
|
||||||
|
print(packet_json.msg)
|
||||||
|
"move":
|
||||||
|
player_move.emit(packet_json.session_id, Vector2(packet_json.direction.x,packet_json.direction.y))
|
||||||
|
"disconnect":
|
||||||
|
player_disconnect.emit(packet_json.session_id)
|
||||||
|
|
||||||
func send_message(message: String) -> void:
|
func send_message(message: String) -> void:
|
||||||
var payload: Dictionary = {
|
var payload: Dictionary = {
|
||||||
@@ -34,12 +43,18 @@ func send_payload(payload: Dictionary):
|
|||||||
udp_peer.set_dest_address(server_ip, server_port)
|
udp_peer.set_dest_address(server_ip, server_port)
|
||||||
udp_peer.put_packet(packet)
|
udp_peer.put_packet(packet)
|
||||||
|
|
||||||
func move(vec: Vector2i):
|
func move(position_mod: Vector2):
|
||||||
var payload: Dictionary = {
|
var payload: Dictionary = {
|
||||||
"type": "move",
|
"type": "move",
|
||||||
"direction": {
|
"direction": {
|
||||||
"x": vec.x,
|
"x": position_mod.x,
|
||||||
"y": vec.y
|
"y": position_mod.y
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
send_payload(payload)
|
send_payload(payload)
|
||||||
|
|
||||||
|
func _exit_tree():
|
||||||
|
var payload: Dictionary = {
|
||||||
|
"type": "disconnect"
|
||||||
|
}
|
||||||
|
send_payload(payload)
|
||||||
|
@@ -6,6 +6,7 @@ import (
|
|||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
r "math/rand"
|
||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
@@ -14,13 +15,32 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type Payload struct {
|
type Payload struct {
|
||||||
|
SessionID string `json:"session_id,omitempty"`
|
||||||
|
Type string `json:"type"`
|
||||||
|
Message string `json:"msg,omitempty"`
|
||||||
|
Direction *Vector2 `json:"direction,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InitPayload struct {
|
||||||
|
Type string `json:"type"`
|
||||||
|
PlayerClient *Client `json:"player_client"`
|
||||||
|
Clients []*Client `json:"clients"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DisconnectPayload struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Message string `json:"msg,omitempty"`
|
SessionID string `json:"session_id"`
|
||||||
Direction *struct {
|
}
|
||||||
X int `json:"x,omitempty"`
|
|
||||||
Y int `json:"y,omitempty"`
|
type Client struct {
|
||||||
} `json:"direction,omitempty"`
|
SessionID string `json:"session_id"`
|
||||||
SessionID string `json:"session_id,omitempty"`
|
LastSeen time.Time `json:"last_seen"`
|
||||||
|
Positon *Vector2 `json:"position"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Vector2 struct {
|
||||||
|
X float64 `json:"x,omitempty"`
|
||||||
|
Y float64 `json:"y,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate a unique session ID
|
// Generate a unique session ID
|
||||||
@@ -55,8 +75,7 @@ func main() {
|
|||||||
fmt.Println("Server running on " + port)
|
fmt.Println("Server running on " + port)
|
||||||
|
|
||||||
buf := make([]byte, 1024)
|
buf := make([]byte, 1024)
|
||||||
clients := make(map[string]string) // Map to keep track of clients and their session IDs
|
clients := make(map[string]*Client) // Map to keep track of clients and their session IDs
|
||||||
clientLastSeen := make(map[string]time.Time) // Map to track the last seen time of each client
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
n, addr, err := conn.ReadFromUDP(buf)
|
n, addr, err := conn.ReadFromUDP(buf)
|
||||||
@@ -75,63 +94,65 @@ func main() {
|
|||||||
// Use the client's IP and port as the key to uniquely identify the connection
|
// Use the client's IP and port as the key to uniquely identify the connection
|
||||||
key := addr.String()
|
key := addr.String()
|
||||||
|
|
||||||
// Update the last seen time for the client
|
|
||||||
clientLastSeen[key] = time.Now()
|
|
||||||
|
|
||||||
// Check if the client's connection already has a session ID
|
// Check if the client's connection already has a session ID
|
||||||
if _, ok := clients[key]; !ok {
|
if _, ok := clients[key]; !ok {
|
||||||
// The client is new, generate a session ID
|
// The client is new, generate a session ID
|
||||||
sessionID := generateSessionID()
|
sessionID := generateSessionID()
|
||||||
clients[key] = sessionID
|
clients[key] = &Client{SessionID: sessionID, LastSeen: time.Now(), Positon: &Vector2{X: randomFloatInRange(300, 600), Y: randomFloatInRange(300, 600)}} // Initialize a new Client struct and store its pointer
|
||||||
// Send the session ID back to the client
|
// Send the session ID back to the client
|
||||||
responsePayload := Payload{Type: "init_success", SessionID: sessionID}
|
clientsSlice := make([]*Client, 0, len(clients))
|
||||||
response, _ := json.Marshal(responsePayload)
|
for _, client := range clients {
|
||||||
conn.WriteToUDP(response, addr)
|
clientsSlice = append(clientsSlice, client)
|
||||||
|
}
|
||||||
|
responsePayload := InitPayload{Type: "init_success", PlayerClient: clients[key], Clients: clientsSlice}
|
||||||
|
broadcastMessage(conn, clients, responsePayload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clients[key].LastSeen = time.Now()
|
||||||
|
|
||||||
switch payload.Type {
|
switch payload.Type {
|
||||||
case "init":
|
case "init":
|
||||||
fmt.Printf("Received initiation generated SessionID: %s\n", clients[key])
|
fmt.Printf("Received initiation generated SessionID: %s\n", clients[key].SessionID)
|
||||||
case "move":
|
case "move":
|
||||||
fmt.Printf("Received move message from Session ID: %s : X=%d, Y=%d\n", clients[key], payload.Direction.X, payload.Direction.Y)
|
fmt.Printf("Received move message from Session ID: %s : X=%f, Y=%f\n", clients[key].SessionID, payload.Direction.X, payload.Direction.Y)
|
||||||
// Handle movement logic here
|
broadcastMessage(conn, clients, payload)
|
||||||
|
|
||||||
case "disconnect":
|
case "disconnect":
|
||||||
// Disconnect the client
|
// Disconnect the client
|
||||||
|
fmt.Printf("Client %s disconnected\n", clients[key].SessionID)
|
||||||
|
broadcastMessage(conn, clients, DisconnectPayload{Type: "disconnect", SessionID: clients[key].SessionID})
|
||||||
delete(clients, key)
|
delete(clients, key)
|
||||||
delete(clientLastSeen, key)
|
|
||||||
fmt.Printf("Client %s disconnected\n", clients[key])
|
|
||||||
case "message":
|
case "message":
|
||||||
fmt.Printf("Received message from Session ID: %s : %s\n", clients[key], payload.Message)
|
fmt.Printf("Received message from Session ID: %s : %s\n", clients[key].SessionID, payload.Message)
|
||||||
broadcastMessage(conn, clients, payload.Message)
|
broadcastMessage(conn, clients, payload)
|
||||||
default:
|
default:
|
||||||
fmt.Printf("Received unknown message type Session ID: %s\n", clients[key])
|
fmt.Printf("Received unknown message type Session ID: %s\n", clients[key].SessionID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check for disconnected clients and reset their session ID
|
// Check for disconnected clients and reset their session ID
|
||||||
for clientKey, lastSeen := range clientLastSeen {
|
for clientKey, client := range clients {
|
||||||
if time.Since(lastSeen) > 5*time.Minute { // 5 minutes timeout
|
if time.Since(client.LastSeen) > 5*time.Minute { // 5 minutes timeout
|
||||||
delete(clients, clientKey)
|
delete(clients, clientKey)
|
||||||
delete(clientLastSeen, clientKey)
|
fmt.Printf("Client %s disconnected and session ID reset\n", clients[clientKey].SessionID)
|
||||||
fmt.Printf("Client %s disconnected and session ID reset\n", clients[clientKey])
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func broadcastMessage(conn *net.UDPConn, clients map[string]string, message string) {
|
func broadcastMessage(conn *net.UDPConn, clients map[string]*Client, payload interface{}) {
|
||||||
for clientKey, sessionID := range clients {
|
for clientKey := range clients {
|
||||||
// Parse the clientKey to get the *net.UDPAddr
|
|
||||||
clientAddr, err := net.ResolveUDPAddr("udp", clientKey)
|
clientAddr, err := net.ResolveUDPAddr("udp", clientKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println("Error resolving UDP address:", err)
|
fmt.Println("Error resolving UDP address:", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
payload := Payload{
|
|
||||||
Type: "message",
|
|
||||||
Message: message,
|
|
||||||
SessionID: sessionID,
|
|
||||||
}
|
|
||||||
response, _ := json.Marshal(payload)
|
response, _ := json.Marshal(payload)
|
||||||
conn.WriteToUDP(response, clientAddr)
|
conn.WriteToUDP(response, clientAddr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func randomFloatInRange(min, max float64) float64 {
|
||||||
|
seed := time.Now().UnixNano()
|
||||||
|
rf := r.New(r.NewSource(seed))
|
||||||
|
return min + rf.Float64()*(max-min)
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user