Improved network code
This commit is contained in:
parent
9b47e374c7
commit
b885d70625
@ -5,6 +5,23 @@ var udp := PacketPeerUDP.new()
|
||||
|
||||
func _ready():
|
||||
udp.connect_to_host("127.0.0.1", 4242)
|
||||
send_login()
|
||||
|
||||
func _process(_delta):
|
||||
if Client.udp.get_available_packet_count() <= 0:
|
||||
return
|
||||
|
||||
var packet := Client.udp.get_packet()
|
||||
var type := packet.decode_u8(0)
|
||||
print("Packet type %d data size %d" % [type, packet.size()-1])
|
||||
|
||||
func send_login():
|
||||
var login_data = PackedByteArray()
|
||||
login_data.push_back(2)
|
||||
udp.put_packet(login_data)
|
||||
print("Connecting...")
|
||||
|
||||
func spawn_player():
|
||||
var player = PLAYER.instantiate()
|
||||
add_child(player)
|
||||
print("Ready.")
|
||||
|
||||
|
@ -3,5 +3,5 @@ extends Node3D
|
||||
func _ready():
|
||||
pass
|
||||
|
||||
func _process(delta):
|
||||
rotate_y(delta)
|
||||
func _process(_delta):
|
||||
pass
|
||||
|
@ -11,7 +11,7 @@ config_version=5
|
||||
[application]
|
||||
|
||||
config/name="Battle of Mages"
|
||||
run/main_scene="res://world/World.tscn"
|
||||
run/main_scene="res://world/Game.tscn"
|
||||
config/features=PackedStringArray("4.2", "Forward Plus")
|
||||
config/icon="res://ui/icon.svg"
|
||||
|
||||
|
@ -3,6 +3,8 @@ package core
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"time"
|
||||
)
|
||||
|
||||
@ -12,15 +14,38 @@ type Handler func([]byte, *Client)
|
||||
// Server represents a UDP server.
|
||||
type Server struct {
|
||||
socket *net.UDPConn
|
||||
clients map[string]*Client
|
||||
handlers [256]Handler
|
||||
clients sync.Map
|
||||
count atomic.Int64
|
||||
}
|
||||
|
||||
// New creates a new server.
|
||||
func New() *Server {
|
||||
return &Server{
|
||||
clients: make(map[string]*Client),
|
||||
}
|
||||
timeout := 3 * time.Second
|
||||
interval := time.Second
|
||||
server := &Server{}
|
||||
|
||||
go func() {
|
||||
ticker := time.NewTicker(interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for range ticker.C {
|
||||
now := time.Now()
|
||||
|
||||
server.clients.Range(func(key, value interface{}) bool {
|
||||
item := value.(*Client)
|
||||
|
||||
if !item.lastPacket.IsZero() && now.After(item.lastPacket.Add(timeout)) {
|
||||
server.clients.Delete(key)
|
||||
server.count.Add(-1)
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
}
|
||||
}()
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
// AddHandler adds the handler for the given byte code.
|
||||
@ -28,8 +53,14 @@ func (s *Server) AddHandler(code byte, handler Handler) {
|
||||
s.handlers[code] = handler
|
||||
}
|
||||
|
||||
// SendTo sends the data to a client.
|
||||
func (s *Server) SendTo(data []byte, client *Client) {
|
||||
// Count returns the number of connected clients.
|
||||
func (s *Server) Count() int {
|
||||
return int(s.count.Load())
|
||||
}
|
||||
|
||||
// Send sends the data prefixed with the byte code to the client.
|
||||
func (s *Server) Send(code byte, data []byte, client *Client) {
|
||||
data = append([]byte{code}, data...)
|
||||
_, err := s.socket.WriteToUDP(data, client.address)
|
||||
|
||||
if err != nil {
|
||||
@ -91,25 +122,26 @@ func (s *Server) handle(data []byte, addr *net.UDPAddr) {
|
||||
handler := s.handlers[data[0]]
|
||||
|
||||
if handler == nil {
|
||||
fmt.Println("Unknown packet type.")
|
||||
fmt.Printf("No callback registered for packet type %d\n", data[0])
|
||||
return
|
||||
}
|
||||
|
||||
handler(data, c)
|
||||
handler(data[1:], c)
|
||||
}
|
||||
|
||||
// getClient either returns a new or existing client for the requested address.
|
||||
func (s *Server) getClient(addr *net.UDPAddr) *Client {
|
||||
c, exists := s.clients[addr.String()]
|
||||
obj, exists := s.clients.Load(addr.String())
|
||||
|
||||
if exists {
|
||||
return c
|
||||
return obj.(*Client)
|
||||
}
|
||||
|
||||
c = &Client{
|
||||
client := &Client{
|
||||
address: addr,
|
||||
}
|
||||
|
||||
s.clients[addr.String()] = c
|
||||
return c
|
||||
s.clients.Store(addr.String(), client)
|
||||
s.count.Add(1)
|
||||
return client
|
||||
}
|
||||
|
13
server/login.go
Normal file
13
server/login.go
Normal file
@ -0,0 +1,13 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"server/core"
|
||||
"server/packet"
|
||||
)
|
||||
|
||||
// login checks the account credentials and gives a network peer access to an account.
|
||||
func login(data []byte, client *core.Client) {
|
||||
fmt.Println("2 - login!")
|
||||
server.Send(packet.LOGIN, nil, client)
|
||||
}
|
@ -2,16 +2,13 @@ package main
|
||||
|
||||
import (
|
||||
"server/core"
|
||||
"server/packet"
|
||||
)
|
||||
|
||||
var server = core.New()
|
||||
|
||||
func main() {
|
||||
server := core.New()
|
||||
|
||||
server.AddHandler(0, func(data []byte, client *core.Client) {
|
||||
// count := data[1]
|
||||
// fmt.Println(count)
|
||||
server.SendTo(data, client)
|
||||
})
|
||||
|
||||
server.AddHandler(packet.PING, ping)
|
||||
server.AddHandler(packet.LOGIN, login)
|
||||
server.Run(4242)
|
||||
}
|
||||
|
8
server/packet/types.go
Normal file
8
server/packet/types.go
Normal file
@ -0,0 +1,8 @@
|
||||
package packet
|
||||
|
||||
const (
|
||||
PING = 1
|
||||
LOGIN = 2
|
||||
LOGOUT = 3
|
||||
MOVE = 10
|
||||
)
|
14
server/ping.go
Normal file
14
server/ping.go
Normal file
@ -0,0 +1,14 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"server/core"
|
||||
"server/packet"
|
||||
)
|
||||
|
||||
// ping is used as a heartbeat and latency check.
|
||||
func ping(data []byte, client *core.Client) {
|
||||
fmt.Println("1 - ping!")
|
||||
server.Send(packet.PING, data, client)
|
||||
fmt.Println(server.Count(), "clients")
|
||||
}
|
19
ui/Ping.gd
19
ui/Ping.gd
@ -8,7 +8,6 @@ var pingSent: Array[float] = []
|
||||
func _ready():
|
||||
var timer := Timer.new()
|
||||
add_child(timer)
|
||||
timer.autostart = true
|
||||
timer.wait_time = 1
|
||||
timer.connect("timeout", self._ping)
|
||||
timer.start()
|
||||
@ -16,18 +15,18 @@ func _ready():
|
||||
pingSent.resize(HISTORY_SIZE)
|
||||
|
||||
func _process(_delta):
|
||||
if Client.udp.get_available_packet_count() > 0:
|
||||
#print("Received: %s" % udp.get_packet().get_string_from_utf8())
|
||||
var bytes := Client.udp.get_packet()
|
||||
var count := bytes.decode_u8(1)
|
||||
var timeSent := pingSent[count]
|
||||
var duration := Time.get_unix_time_from_system() - timeSent
|
||||
var ping := duration * 1000
|
||||
text = str(snapped(ping, 0.01))
|
||||
pass
|
||||
#if Client.udp.get_available_packet_count() > 0:
|
||||
#var bytes := Client.udp.get_packet()
|
||||
#var count := bytes.decode_u8(1)
|
||||
#var timeSent := pingSent[count]
|
||||
#var duration := Time.get_unix_time_from_system() - timeSent
|
||||
#var ping := duration * 1000
|
||||
#text = str(snapped(ping, 0.01))
|
||||
|
||||
func _ping():
|
||||
var buffer := StreamPeerBuffer.new()
|
||||
buffer.put_8(0)
|
||||
buffer.put_8(1)
|
||||
buffer.put_8(pingCount)
|
||||
Client.udp.put_packet(buffer.data_array)
|
||||
|
||||
|
@ -1,8 +1,10 @@
|
||||
[gd_resource type="Environment" load_steps=2 format=3 uid="uid://dixa0yso2s1u3"]
|
||||
|
||||
[ext_resource type="Sky" uid="uid://b0q75qnaj0r5h" path="res://world/Sky.tres" id="1_utnj1"]
|
||||
[gd_resource type="Environment" format=3 uid="uid://dixa0yso2s1u3"]
|
||||
|
||||
[resource]
|
||||
sky = ExtResource("1_utnj1")
|
||||
background_mode = 1
|
||||
background_color = Color(0.317647, 0.541176, 0.713726, 1)
|
||||
ambient_light_source = 3
|
||||
reflected_light_source = 2
|
||||
ambient_light_color = Color(0.607843, 0.756863, 0.92549, 1)
|
||||
ambient_light_sky_contribution = 0.17
|
||||
tonemap_mode = 2
|
||||
adjustment_saturation = 0.01
|
||||
|
108
world/Game.tscn
Normal file
108
world/Game.tscn
Normal file
@ -0,0 +1,108 @@
|
||||
[gd_scene load_steps=16 format=3 uid="uid://b40y7iuskv1ar"]
|
||||
|
||||
[ext_resource type="Script" path="res://world/Game.gd" id="1_xmqq4"]
|
||||
[ext_resource type="PackedScene" uid="uid://bxotvk73tbgw0" path="res://ui/UI.tscn" id="2_x1l7l"]
|
||||
[ext_resource type="Script" path="res://world/RotateY.gd" id="3_4gn6n"]
|
||||
[ext_resource type="Shader" path="res://world/shader/Outline.gdshader" id="4_gweie"]
|
||||
[ext_resource type="Environment" uid="uid://dixa0yso2s1u3" path="res://world/Environment.tres" id="5_bll74"]
|
||||
[ext_resource type="Script" path="res://world/Sun.gd" id="5_pf5uw"]
|
||||
[ext_resource type="CameraAttributesPractical" uid="uid://b835orxyqq6w5" path="res://world/CameraAttributes.tres" id="6_8wfwf"]
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_r8n03"]
|
||||
diffuse_mode = 3
|
||||
albedo_color = Color(0.482353, 0.470588, 0.47451, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_0bujj"]
|
||||
material = SubResource("StandardMaterial3D_r8n03")
|
||||
size = Vector3(20, 0.5, 20)
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4w7ln"]
|
||||
diffuse_mode = 3
|
||||
albedo_color = Color(0.294118, 0.356863, 0.439216, 1)
|
||||
|
||||
[sub_resource type="BoxMesh" id="BoxMesh_hf021"]
|
||||
material = SubResource("StandardMaterial3D_4w7ln")
|
||||
|
||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ahmjh"]
|
||||
diffuse_mode = 3
|
||||
albedo_color = Color(0.14902, 0.517647, 1, 1)
|
||||
roughness = 0.08
|
||||
|
||||
[sub_resource type="TorusMesh" id="TorusMesh_mu45b"]
|
||||
material = SubResource("StandardMaterial3D_ahmjh")
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_qm56v"]
|
||||
render_priority = 0
|
||||
shader = ExtResource("4_gweie")
|
||||
shader_parameter/depth_threshold = 0.05
|
||||
shader_parameter/reverse_depth_threshold = 0.25
|
||||
shader_parameter/normal_threshold = 0.6
|
||||
shader_parameter/darken_amount = 0.3
|
||||
shader_parameter/lighten_amount = 1.5
|
||||
shader_parameter/light_direction = Vector3(0.122788, -0.707107, -0.696364)
|
||||
|
||||
[sub_resource type="QuadMesh" id="QuadMesh_7yiqd"]
|
||||
material = SubResource("ShaderMaterial_qm56v")
|
||||
flip_faces = true
|
||||
size = Vector2(2, 2)
|
||||
|
||||
[node name="Game" type="Node"]
|
||||
script = ExtResource("1_xmqq4")
|
||||
|
||||
[node name="World" type="Node3D" parent="."]
|
||||
|
||||
[node name="Ground" type="MeshInstance3D" parent="World"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.25, 0)
|
||||
mesh = SubResource("BoxMesh_0bujj")
|
||||
skeleton = NodePath("../..")
|
||||
|
||||
[node name="Box" type="MeshInstance3D" parent="World"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, -4)
|
||||
mesh = SubResource("BoxMesh_hf021")
|
||||
skeleton = NodePath("../../SubViewportContainer/SubViewport")
|
||||
|
||||
[node name="Torus" type="MeshInstance3D" parent="World"]
|
||||
transform = Transform3D(0.7, 0, 0, 0, -3.0598e-08, -0.7, 0, 0.7, -3.0598e-08, 0, 1.79933, -4)
|
||||
mesh = SubResource("TorusMesh_mu45b")
|
||||
skeleton = NodePath("../../SubViewportContainer/SubViewport")
|
||||
script = ExtResource("3_4gn6n")
|
||||
|
||||
[node name="UI" parent="." instance=ExtResource("2_x1l7l")]
|
||||
|
||||
[node name="SubViewportContainer" type="SubViewportContainer" parent="."]
|
||||
texture_filter = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
stretch = true
|
||||
stretch_shrink = 3
|
||||
|
||||
[node name="SubViewport" type="SubViewport" parent="SubViewportContainer"]
|
||||
handle_input_locally = false
|
||||
size = Vector2i(384, 216)
|
||||
render_target_update_mode = 4
|
||||
|
||||
[node name="Camera" type="Camera3D" parent="SubViewportContainer/SubViewport"]
|
||||
transform = Transform3D(0.707107, 0.331966, -0.624338, 0, 0.882947, 0.469472, 0.707107, -0.331966, 0.624338, -5, 5, 5)
|
||||
projection = 1
|
||||
current = true
|
||||
fov = 90.0
|
||||
size = 9.6
|
||||
near = 0.001
|
||||
|
||||
[node name="PostProcessing" type="MeshInstance3D" parent="SubViewportContainer/SubViewport/Camera"]
|
||||
unique_name_in_owner = true
|
||||
extra_cull_margin = 16384.0
|
||||
mesh = SubResource("QuadMesh_7yiqd")
|
||||
|
||||
[node name="Sun" type="DirectionalLight3D" parent="SubViewportContainer/SubViewport"]
|
||||
transform = Transform3D(0.984808, 0.122788, -0.122788, 0, 0.707107, 0.707107, 0.173648, -0.696364, 0.696364, 0, 5, 0)
|
||||
shadow_enabled = true
|
||||
directional_shadow_split_1 = 0.028
|
||||
script = ExtResource("5_pf5uw")
|
||||
|
||||
[node name="Environment" type="WorldEnvironment" parent="SubViewportContainer/SubViewport"]
|
||||
environment = ExtResource("5_bll74")
|
||||
camera_attributes = ExtResource("6_8wfwf")
|
@ -1,4 +0,0 @@
|
||||
[gd_resource type="ProceduralSkyMaterial" format=3 uid="uid://b7q6crweeh3jv"]
|
||||
|
||||
[resource]
|
||||
ground_bottom_color = Color(0.0313726, 0.0470588, 0.160784, 1)
|
6
world/RotateY.gd
Normal file
6
world/RotateY.gd
Normal file
@ -0,0 +1,6 @@
|
||||
extends Node3D
|
||||
|
||||
@export var speed: float = 1.0
|
||||
|
||||
func _process(delta):
|
||||
rotate_y(speed * delta)
|
@ -1,6 +0,0 @@
|
||||
[gd_resource type="Sky" load_steps=2 format=3 uid="uid://b0q75qnaj0r5h"]
|
||||
|
||||
[ext_resource type="Material" uid="uid://b7q6crweeh3jv" path="res://world/ProceduralSky.tres" id="1_7mt7h"]
|
||||
|
||||
[resource]
|
||||
sky_material = ExtResource("1_7mt7h")
|
5
world/Sun.gd
Normal file
5
world/Sun.gd
Normal file
@ -0,0 +1,5 @@
|
||||
@tool
|
||||
extends DirectionalLight3D
|
||||
|
||||
func _process(_delta):
|
||||
(%PostProcessing as MeshInstance3D).mesh.surface_get_material(0).set_shader_parameter("light_direction", -global_basis.z)
|
@ -1,22 +0,0 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://b40y7iuskv1ar"]
|
||||
|
||||
[ext_resource type="Script" path="res://world/World.gd" id="1_2lci4"]
|
||||
[ext_resource type="Environment" uid="uid://dixa0yso2s1u3" path="res://world/Environment.tres" id="1_qb8w4"]
|
||||
[ext_resource type="CameraAttributesPractical" uid="uid://b835orxyqq6w5" path="res://world/CameraAttributes.tres" id="2_1nt3m"]
|
||||
[ext_resource type="PackedScene" uid="uid://bxotvk73tbgw0" path="res://ui/UI.tscn" id="4_c6x8y"]
|
||||
|
||||
[node name="World" type="Node"]
|
||||
script = ExtResource("1_2lci4")
|
||||
|
||||
[node name="UI" parent="." instance=ExtResource("4_c6x8y")]
|
||||
|
||||
[node name="Camera" type="Camera3D" parent="."]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 5)
|
||||
fov = 90.0
|
||||
|
||||
[node name="Sun" type="DirectionalLight3D" parent="."]
|
||||
transform = Transform3D(0.904299, 0.26004, -0.33856, 0, 0.793066, 0.609135, 0.4269, -0.55084, 0.717169, 0, 0, 0)
|
||||
|
||||
[node name="Environment" type="WorldEnvironment" parent="."]
|
||||
environment = ExtResource("1_qb8w4")
|
||||
camera_attributes = ExtResource("2_1nt3m")
|
Loading…
Reference in New Issue
Block a user