diff --git a/.gitignore b/.gitignore index 5cfae44..2126236 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ .rust/ server/target/ +Godot_* +.current_version diff --git a/client/.gitignore b/client/.gitignore new file mode 100644 index 0000000..0b0ef26 --- /dev/null +++ b/client/.gitignore @@ -0,0 +1,4 @@ +# Godot 4+ specific ignores +.godot/ +assets/*.import +*.import diff --git a/client/assets/ground.jpg b/client/assets/ground.jpg new file mode 100644 index 0000000..dee2d4a Binary files /dev/null and b/client/assets/ground.jpg differ diff --git a/client/assets/player.glb b/client/assets/player.glb new file mode 100644 index 0000000..063fb8c Binary files /dev/null and b/client/assets/player.glb differ diff --git a/client/assets/root.glb b/client/assets/root.glb new file mode 100644 index 0000000..6799653 Binary files /dev/null and b/client/assets/root.glb differ diff --git a/client/assets/root.tscn b/client/assets/root.tscn new file mode 100644 index 0000000..53dc81c --- /dev/null +++ b/client/assets/root.tscn @@ -0,0 +1,13 @@ +[gd_scene load_steps=3 format=3 uid="uid://c688gu5xrshpg"] + +[ext_resource type="PackedScene" uid="uid://b5ej7nfagdlmf" path="res://assets/root.glb" id="1_s8vvr"] + +[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_rf26g"] +data = PackedVector3Array(20, -1, -20, -21, -1, 20, -21, -1, -20, 20, -1, -20, 20, -1, 20, -21, -1, 20, 20, -3, 20, -21, -1, 20, 20, -1, 20, 20, -3, 20, -21, -3, 20, -21, -1, 20, -21, -3, 20, -21, -1, -20, -21, -1, 20, -21, -3, 20, -21, -3, -20, -21, -1, -20, -21, -3, -20, 20, -3, 20, 20, -3, -20, -21, -3, -20, -21, -3, 20, 20, -3, 20, 20, -3, -20, 20, -1, 20, 20, -1, -20, 20, -3, -20, 20, -3, 20, 20, -1, 20, -21, -3, -20, 20, -1, -20, -21, -1, -20, -21, -3, -20, 20, -3, -20, 20, -1, -20) + +[node name="root" instance=ExtResource("1_s8vvr")] + +[node name="StaticBody3D" type="StaticBody3D" parent="Cube" index="0"] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="Cube/StaticBody3D" index="0"] +shape = SubResource("ConcavePolygonShape3D_rf26g") diff --git a/client/icon.svg b/client/icon.svg new file mode 100644 index 0000000..b370ceb --- /dev/null +++ b/client/icon.svg @@ -0,0 +1 @@ + diff --git a/client/project.godot b/client/project.godot new file mode 100644 index 0000000..6e4ed48 --- /dev/null +++ b/client/project.godot @@ -0,0 +1,60 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="Khaganat Short Client Server" +run/main_scene="res://scenes/main.tscn" +config/features=PackedStringArray("4.1", "Forward Plus") +config/icon="res://icon.svg" + +[input] + +ui_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":113,"echo":false,"script":null) +, null] +} +ui_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) +] +} +ui_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":122,"echo":false,"script":null) +] +} +ui_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) +] +} +ui_rotate_player={ +"deadzone": 0.5, +"events": [Object(InputEventMouseButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"button_mask":0,"position":Vector2(0, 0),"global_position":Vector2(0, 0),"factor":1.0,"button_index":1,"canceled":false,"pressed":false,"double_click":false,"script":null) +] +} + +[rendering] + +environment/defaults/default_clear_color=Color(0.682353, 0.678431, 0.631373, 1) diff --git a/client/scenes/Window.gd b/client/scenes/Window.gd new file mode 100644 index 0000000..1b80c98 --- /dev/null +++ b/client/scenes/Window.gd @@ -0,0 +1,58 @@ +extends Window + +var focus_ok:bool = false +var last_event = null + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(_delta): + pass + + +func _on_button_pressed(): + if $VBoxContainer/TextEdit.get_text() != "": + self.hide() + #get_parent().get_node("CharacterBody3D").set_enable_event(true) + get_parent().connect_enet($VBoxContainer/TextEdit.get_text()) + + +func _on_text_edit_text_changed(value:String): + if len(value) > 0: + $VBoxContainer/Button.disabled = false + else: + $VBoxContainer/Button.disabled = true + + +func _on_focus_entered(): + focus_ok = true + + +func _on_focus_exited(): + focus_ok = false + + +func _on_mouse_entered(): + focus_ok = true + self.get_parent().CharacterBody3D.disabled = true + + +func _on_mouse_exited(): + focus_ok = false + self.get_parent().CharacterBody3D.disabled = false + +func open_windows(): + focus_ok = false + get_parent().get_node("CharacterBody3D").set_enable_event(false) + self.show() + +#func _on_window_input(event): +# if event.is_pressed() == false: +# return +# if focus_ok: +# return +# if (event is InputEventKey) && (self.type_event == 1): +# last_event = event diff --git a/client/scenes/main.gd b/client/scenes/main.gd new file mode 100644 index 0000000..31d868e --- /dev/null +++ b/client/scenes/main.gd @@ -0,0 +1,299 @@ +extends Node3D + +# The player name. +var player_name: String +var connected:bool = false +var enet:ENetConnection +var dataEnet:ENetPacketPeer +var errorEnet:Error +var id = 0 +var maxplayer = 0 + +# Server confirm our account +var account_confirmed:bool = false + +const PLAYER = preload("res://scenes/player.tscn") + +const PORT = 33333 +const ADDR = "127.0.0.1" + +var dtls := PacketPeerDTLS.new() +var udp := PacketPeerUDP.new() + + +func test_cert(filename): + print("------", filename) + enet = ENetConnection.new() + print(enet) + #var cert: X509Certificate = X509Certificate.new() + #errorEnet = cert.load(filename) + #print("load cert:", errorEnet) + #print(cert) + #var client_tls_options = TLSOptions.client_unsafe(cert) + #print(client_tls_options) + errorEnet = enet.create_host(10) + if errorEnet != OK: + print("ERROR ENET.create_host: ", errorEnet) + return + #enet.connect_to_host(ADDR, PORT) + #errorEnet = enet.dtls_client_setup(ADDR, client_tls_options) + #print("dtls_client_setup:", errorEnet) + #if errorEnet != OK: + # print("ERROR ENET: ", errorEnet) + # return + dataEnet = enet.connect_to_host(ADDR, PORT, 10) + print(dataEnet) + if not dataEnet.is_active(): + print("ERROR enet.connect_to_host: ", dataEnet.is_active()) + return + + +func create_server_enet(): + print("------ create_server_enet") + test_cert("res://cert.crt") + + +# Called when the node enters the scene tree for the first time. +func _ready(): + #test_cert("res://cert.crt") + create_server_enet() + pass # Replace with function body. + + +func decode_msg(data:PackedByteArray): + print("==========================") + var cmd = data.decode_u8(0) + print("cmd:", cmd) + var taille = data.decode_u8(1) + print("taille:", taille) + var str:String = "" + var tmp = data.slice(2,taille+2) + print("tmp:", tmp) + + str = tmp.get_string_from_utf8() + + print("str:", str) + print("len str:", len(str)) + + print("==========================") + +func send_account(): + var data:PackedByteArray = PackedByteArray() + + #data.encode_u8(1,0) + data.append(1) + data.append(len(player_name)) + var packed_array = player_name.to_ascii_buffer() +# var str:PackedStringArray = PackedStringArray() +# str.push_back(player_name) + data += packed_array + #data.append_array(str.to_byte_array()) + +# print("-------------------------") +# print(len(packed_array)) +# print("player_name: ", player_name) +# print("packed_array: ", packed_array) +# print("str: ", str) +# print("str -> bytes: ", str.to_byte_array()) +# print("data: ", data) +# print("-------------------------") + + print(player_name, " -> size:", data.size(), " / " , len(player_name) ) + errorEnet = dataEnet.send(1, data, 1) + if errorEnet != OK: + print("ERROR ENET: ", errorEnet) + return + #decode_msg(data) + + +func set_player_position(pos: Vector3): + self.get_node("CharacterBody3D").set_global_position(pos) + + +func get_player_position(): + if not account_confirmed: + return + print("perso: ", id, " ", self.get_node("CharacterBody3D").get_position()) + var pos:PackedFloat64Array = PackedFloat64Array() + var posRaw:Vector3 = self.get_node("CharacterBody3D").get_position() + #posRaw.x = 123456789182729270e15 + #posRaw.y = 2.0 + #posRaw.z = 3.0 + pos.append(posRaw.x) + #print("x:", pos.to_byte_array()) + pos.append(posRaw.y) + #print("x+y:", pos.to_byte_array()) + pos.append(posRaw.z) + #print("x+y+z:", pos.to_byte_array()) + var data:PackedByteArray = PackedByteArray() + data += pos.to_byte_array() + #data.append(len(player_name)) + #var packed_array = player_name.to_ascii_buffer() + #data += packed_array + #print(player_name, " -> size:", data.size(), " / " , len(player_name) ) + errorEnet = dataEnet.send(2, data, 1) + if errorEnet != OK: + print("ERROR ENET: ", errorEnet) + return + + +func bad_acocunt(): + player_name = "" + self.get_node("Window").open_windows() + + +func get_event_received(): + var data = dataEnet.get_packet() + print("get: ", data) + if data[0] == 1: # Return connexion + if data[1] == 0: # OK + id = data.decode_u64(2) + var x = data.decode_double(2+8) + var y = data.decode_double(2+16) + var z = data.decode_double(2+24) + print("id:", id, " x:", x, " y:", y, " z:", z) + self.set_player_position(Vector3(x, y, z)) + account_confirmed = true + self.get_node("CharacterBody3D").set_enable_event(true) + else: # KO + bad_acocunt() + elif data[0] == 3: # Get position + if id == 0: + return + var nb = data[1] + var pos = 2 + for i in nb: + var mid = data.decode_u64(pos) + var mx = data.decode_double(pos+8) + var my = data.decode_double(pos+16) + var mz = data.decode_double(pos+24) + pos += 32 + if mid == id: + print("Me id:", mid, " x:", mx, " y:", my, " z:", mz) + continue + print("-- id:", mid, " x:", mx, " y:", my, " z:", mz) + var child = $Players.find_child(str(mid), false, false) + if child == null: + print("Not found") + if maxplayer > 3: + continue + var scene = preload("res://scenes/player.tscn") + var instance = scene.instantiate() + #var current_scene = scene.instance() + #var GrabbedInstance = PLAYER.instance() + instance.set_name(str(mid)) + $Players.add_child(instance) + #$Players.add_child(scene) + maxplayer += 1 + for child3 in $Players.get_children(): + print(" -> ", child3.get_name()) + var child2 = $Players.find_child(str(mid), false, false) + child2.set_global_position(Vector3(mx, my, mz)) + + else: + child.set_global_position(Vector3(mx, my, mz)) + print("Found:", $Players.get_child_count()) + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(_delta): + #print("state:", dataEnet.get_state()) + get_player_position() + if dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTED: + var event = enet.service() + if event[0] == ENetConnection.EVENT_RECEIVE: + #print("get: ", dataEnet.get_packet()) + get_event_received() + if player_name != "" and not account_confirmed: + send_account() + elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTING: + var event = enet.service() + if event[0] == ENetConnection.EVENT_RECEIVE: + pass + elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECTED: + var _event = enet.service() + elif dataEnet.get_state() == ENetPacketPeer.STATE_ACKNOWLEDGING_CONNECT: + var _event = enet.service() + elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTION_PENDING: + var _event = enet.service() + elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTION_SUCCEEDED: + var _event = enet.service() + elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECT_LATER: + var _event = enet.service() + elif dataEnet.get_state() == ENetPacketPeer.STATE_DISCONNECTING: + var _event = enet.service() + elif dataEnet.get_state() == ENetPacketPeer.STATE_ACKNOWLEDGING_DISCONNECT: + var _event = enet.service() + elif dataEnet.get_state() == ENetPacketPeer.STATE_ZOMBIE: + var _event = enet.service() + else: + var _event = enet.service() + + +func _process_ter(_delta): + var res = enet.service(1) + #print(res) + if res[0] == ENetConnection.EVENT_RECEIVE: + #print("EVENT_RECEIVE") + print(dataEnet.get_packet()) + #if res[1] + var data:PackedByteArray = PackedByteArray() + data.append(len(player_name)) + data.append(123) + errorEnet = dataEnet.send(1, data, 1) + if errorEnet != OK: + print("ERROR ENET: ", errorEnet) + return + + +func _process_bis(_delta): + if not dataEnet.is_active(): + create_server_enet() + elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTING: + var res = enet.service(1) + print(res) + elif dataEnet.get_state() == ENetPacketPeer.STATE_CONNECTED: + var res = enet.service(1) + print(res) + var data:PackedByteArray = PackedByteArray() + data.append(len(player_name)) + data.append(123) + errorEnet = dataEnet.send(1, data, 1) + if errorEnet != OK: + print("ERROR ENET: ", errorEnet) + return + #print("<> get_state: ", dataEnet.get_state()) + else: + print("get_state: ", dataEnet.get_state()) + return + + if not connected: + if player_name != "": + create_server_enet() + return + var res = enet.service(1) + print(res) + return + if not connected: + if player_name != "": + create_server_enet() + else: + var data:PackedByteArray = PackedByteArray() + data.append(len(player_name)) + data.append(123) + #print(len(data)) + print("active:", dataEnet.is_active()) + print("state:", dataEnet.get_state()) + print("address:", dataEnet.get_remote_address()) + print("port:", dataEnet.get_remote_port()) + errorEnet = dataEnet.send(1, data, 1) + if errorEnet != OK: + print("ERROR ENET: ", errorEnet) + return + #enet.socket_send(ADDR, PORT, data) + + +func connect_enet(_name:String): + player_name = _name + print("My name:" + player_name) + diff --git a/client/scenes/main.gdshader b/client/scenes/main.gdshader new file mode 100644 index 0000000..fc05ebc --- /dev/null +++ b/client/scenes/main.gdshader @@ -0,0 +1,21 @@ +shader_type spatial; + +void fragment() { + bool v = false; + bool w = false; + float b = 0.0; + float g = 0.2; + float r = 0.0; + if ( mod(UV.x,0.005) > 0.0025 ) { + v = true; + }; + if ( mod(UV.y,0.005) > 0.0025 ) { + w = true; + }; + if ( ( v && ! w ) || ( !v && w ) ) { + b = 0.0; + g = 0.0; + r = 0.2; + } + ALBEDO = vec3(r, g, b); +} \ No newline at end of file diff --git a/client/scenes/main.tscn b/client/scenes/main.tscn new file mode 100644 index 0000000..65db350 --- /dev/null +++ b/client/scenes/main.tscn @@ -0,0 +1,89 @@ +[gd_scene load_steps=11 format=3 uid="uid://bemavktwweaog"] + +[ext_resource type="Shader" path="res://scenes/main.gdshader" id="1_caff6"] +[ext_resource type="PackedScene" uid="uid://cg5uqqd4ibdem" path="res://scenes/player.tscn" id="1_nc7b3"] +[ext_resource type="Script" path="res://scenes/main.gd" id="1_ts8of"] +[ext_resource type="Script" path="res://scenes/Window.gd" id="3_uwnj8"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_5dcgs"] +size = Vector3(1000, 1, 1000) + +[sub_resource type="ShaderMaterial" id="ShaderMaterial_gypq5"] +render_priority = 0 +shader = ExtResource("1_caff6") + +[sub_resource type="BoxMesh" id="BoxMesh_fm2j6"] +material = SubResource("ShaderMaterial_gypq5") +size = Vector3(1000, 1, 1000) + +[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_0qg6h"] + +[sub_resource type="Sky" id="Sky_i4xvw"] +sky_material = SubResource("ProceduralSkyMaterial_0qg6h") + +[sub_resource type="Environment" id="Environment_12j7q"] +background_mode = 2 +background_color = Color(0.803922, 0.776471, 0.733333, 1) +sky = SubResource("Sky_i4xvw") +ambient_light_color = Color(0.968627, 0.933333, 0.596078, 1) +reflected_light_source = 2 + +[node name="main" type="Node3D"] +script = ExtResource("1_ts8of") + +[node name="ground" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0) + +[node name="CollisionShape3D" type="CollisionShape3D" parent="ground"] +shape = SubResource("BoxShape3D_5dcgs") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="ground"] +mesh = SubResource("BoxMesh_fm2j6") + +[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."] +transform = Transform3D(-0.866025, 0, -0.5, -0.25, 0.866025, 0.433013, 0.433013, 0.5, -0.75, 0, 50, 0) +shadow_enabled = true +shadow_opacity = 0.5 + +[node name="CharacterBody3D" parent="." instance=ExtResource("1_nc7b3")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 6, 0) + +[node name="Players" type="Node3D" parent="."] + +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_12j7q") + +[node name="Window" type="Window" parent="."] +title = "Connexion" +initial_position = 1 +size = Vector2i(300, 100) +script = ExtResource("3_uwnj8") + +[node name="VBoxContainer" type="VBoxContainer" parent="Window"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Label" type="Label" parent="Window/VBoxContainer"] +layout_mode = 2 +text = "Login" +horizontal_alignment = 1 + +[node name="TextEdit" type="LineEdit" parent="Window/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +placeholder_text = "Account" + +[node name="Button" type="Button" parent="Window/VBoxContainer"] +layout_mode = 2 +disabled = true +text = "OK" + +[connection signal="focus_entered" from="Window" to="Window" method="_on_focus_entered"] +[connection signal="focus_exited" from="Window" to="Window" method="_on_focus_exited"] +[connection signal="mouse_entered" from="Window" to="Window" method="_on_mouse_entered"] +[connection signal="mouse_exited" from="Window" to="Window" method="_on_mouse_exited"] +[connection signal="text_changed" from="Window/VBoxContainer/TextEdit" to="Window" method="_on_text_edit_text_changed"] +[connection signal="pressed" from="Window/VBoxContainer/Button" to="Window" method="_on_button_pressed"] diff --git a/client/scenes/player.gd b/client/scenes/player.gd new file mode 100644 index 0000000..e936823 --- /dev/null +++ b/client/scenes/player.gd @@ -0,0 +1,67 @@ +extends CharacterBody3D + + +const SPEED = 30.0 +const JUMP_VELOCITY = 14.5 + +# Get the gravity from the project settings to be synced with RigidBody nodes. +var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") +@export var event_disabled:bool = true + +# How fast the player moves in meters per second. +@export var speed = 14 +# The downward acceleration when in the air, in meters per second squared. +@export var fall_acceleration = 75 + +var target_velocity = Vector3.ZERO + +var direction = Vector3.FORWARD +var h_sensitivity:float = 0.1 +var v_sensitivity:float = 0.1 +var camrot_h:float = 0.0 +var camrot_v:float = 0.0 +var h_acceleration:float = 10.0 +var v_acceleration:float = 10.0 +var input_view_camera_move_player_follow_mouse:bool = false + +func _input(event): + if event_disabled: + return + if event is InputEventMouseButton: + if Input.is_action_pressed("ui_rotate_player"): + input_view_camera_move_player_follow_mouse = true + else: + input_view_camera_move_player_follow_mouse = false + + if event is InputEventMouseMotion and input_view_camera_move_player_follow_mouse: + camrot_h += -event.relative.x * h_sensitivity + camrot_v += -event.relative.y * v_sensitivity + +func _physics_process(delta:float): + if event_disabled: + return + var h_rot:float = $h.global_transform.basis.get_euler().y + # Add the gravity. + if not is_on_floor(): + velocity.y -= gravity * delta + + # Handle Jump. + if Input.is_action_just_pressed("ui_accept") and is_on_floor(): + velocity.y = JUMP_VELOCITY + + # Get the input direction and handle the movement/deceleration. + # As good practice, you should replace UI actions with custom gameplay actions. + var input_dir = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down").rotated(-h_rot) + direction = (transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized() + if direction: + velocity.x = direction.x * SPEED + velocity.z = direction.z * SPEED + else: + velocity.x = move_toward(velocity.x, 0, SPEED) + velocity.z = move_toward(velocity.z, 0, SPEED) + $h.rotation_degrees.y = lerp($h.rotation_degrees.y, camrot_h, delta * h_acceleration) + $h/v.rotation_degrees.x = lerp($h/v.rotation_degrees.x, camrot_v, delta * v_acceleration) + move_and_slide() + +func set_enable_event(state:bool): + event_disabled = ! state diff --git a/client/scenes/player.tscn b/client/scenes/player.tscn new file mode 100644 index 0000000..1d07649 --- /dev/null +++ b/client/scenes/player.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=4 format=3 uid="uid://cg5uqqd4ibdem"] + +[ext_resource type="PackedScene" uid="uid://bng6cjt7kq1hv" path="res://assets/player.glb" id="1_bpxp1"] +[ext_resource type="Script" path="res://scenes/player.gd" id="1_br7n0"] + +[sub_resource type="SphereShape3D" id="SphereShape3D_cjbav"] + +[node name="CharacterBody3D" type="CharacterBody3D"] +script = ExtResource("1_br7n0") + +[node name="Pivot" type="Node3D" parent="."] + +[node name="player" parent="Pivot" instance=ExtResource("1_bpxp1")] + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(2, 0, 0, 0, 2, 0, 0, 0, 2, 0, 1, 0) +shape = SubResource("SphereShape3D_cjbav") + +[node name="h" type="Node3D" parent="."] + +[node name="v" type="Node3D" parent="h"] + +[node name="Camera3D" type="Camera3D" parent="h/v"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 5) diff --git a/precheck.gd b/precheck.gd new file mode 100644 index 0000000..f720f16 --- /dev/null +++ b/precheck.gd @@ -0,0 +1,37 @@ +extends MainLoop +#extends Node + +# print("Example") + + +# Called when the node enters the scene tree for the first time. +#func _ready(): +# print("Example _ready") +# # print( get_user_data_dir() ) +# # print(Performance.get_monitor(Performance.TIME_FPS)) +# pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +#func _process(delta): +# print("Example _process") +# pass +func _process(delta): + return true + +func _init(): + var info:String = "" + #info = get_base_script() + var processName:String = OS.get_processor_name() + var modelName:String = OS.get_model_name() + var osName:String = OS.get_name() + var version:String = OS.get_version() + var detailCardGraphics: PackedStringArray = OS.get_video_adapter_driver_info() + var idHardware:String = OS.get_unique_id() + var idGodot:String = str(Engine.get_version_info()) + #for i in range(OS.get_screen_cound()): + # print(i) + var data = " - ".join(detailCardGraphics) + print( processName + "!" + modelName + "!" + osName + "!" + version + "!" + data + "!" + idHardware + "!" + idGodot) + + diff --git a/start-bazar-client.sh b/start-bazar-client.sh new file mode 100755 index 0000000..7b6de37 --- /dev/null +++ b/start-bazar-client.sh @@ -0,0 +1,181 @@ +#!/bin/bash + +declare DEBUG=0 +declare HELP=0 +declare EDITOR=0 +declare FORCE=0 +declare IMPORT=0 +declare ERASEIMPORT=0 +declare WORKDIR="$(dirname $(readlink -f $0))" +declare GODOT_SRC="https://downloads.tuxfamily.org/godotengine/4.1.2/Godot_v4.1.2-stable_linux.x86_64.zip" +declare OUTZIP="$WORKDIR/$(basename $GODOT_SRC)" +declare CLIENTDIR="$WORKDIR/client" +declare OPTION="" +declare NEWPRG=0 +declare DISABLEAUTODETECTCARD=0 + +function msg_debug() +{ + if [ $DEBUG -ne 0 ] + then + echo "### DEBUG : $*" >&2 + fi +} + +function msg_info() +{ + echo "--- INFO : $*" >&2 +} + +function msg_error() +{ + echo "*** ERROR : $*" >&2 +} + +function download() +{ + local package="$1" + local out="$2" + if [[ $FORCE -eq 0 && -f $2 ]] + then + return 0 + fi + which curl 1>/dev/null 2>/dev/null + if [ $? -eq 0 ] + then + curl -o $out $package + if [ $? -eq 0 ] + then + msg_info "Package GODOT downloaded" + return 0 + fi + fi + which wget 1>/dev/null 2>/dev/null + if [ $? -eq 0 ] + then + wget $package -O $out + if [ $? -eq 0 ] + then + msg_info "Package GODOT downloaded" + return 0 + fi + fi + msg_error "Impossible to download" + exit 2 +} + +function extract() +{ + local compressed_file="$1" + which unzip 1>/dev/null 2>/dev/null + if [ $? -eq 0 ] + then + fileout=$(unzip -Z1 $compressed_file) + if [[ $FORCE -eq 0 && -f $fileout ]] + then + echo $fileout + return 0 + fi + unzip -u $compressed_file -d $WORKDIR 1>&2 + if [ $? -eq 0 ] + then + msg_info "Uncompressed GODOT" + echo $fileout + NEWPRG=1 + return 0 + fi + fi + msg_error "Impossible to extract" + exit 2 +} + + +while getopts hdeo:s:fix flag +do + case "${flag}" in + h) HELP=1;; + d) DEBUG=1;; + e) EDITOR=1;; + o) OUTZIP=${OPTARG};; + s) GODOT_SRC=${OPTARG};; + f) FORCE=1;; + i) IMPORT=1;; + x) ERASEIMPORT=1;; + y) DISABLEAUTODETECTCARD=1;; + *) HELP=1;; + esac +done + +if [[ $HELP -ne 0 ]] +then + cat << EOF +$(basename $0) [Option] : Donwload Launch Godot + Option: + -h : Show help + -d : Show debug message + -e : Start Godot in editor mode + -f : force download & uncompress + -i : force import data + -x : erase import data + -y : Disable auto detect host (OS/CPU/GPU) + -o : target godot file (downloaded) + -s : Url to download a specific godot version +EOF + exit 1 +fi + +msg_info "Start" +msg_debug "WORKDIR:$WORKDIR OUTZIP:$OUTZIP GODOT_SRC:$GODOT_SRC" +download "$GODOT_SRC" "$OUTZIP" +EXE=$(extract "$OUTZIP") +msg_info "Prg:$EXE" + +if [ $NEWPRG -ne 0 ] +then + echo "--- New program detected" + ERASEIMPORT=1 + IMPORT=1 +elif [ $DISABLEAUTODETECTCARD -eq 0 ] +then + echo "--- Check host" + $WORKDIR/$EXE --script precheck.gd > $WORKDIR/.current_version.tmp + if [ -f $WORKDIR/.current_version ] + then + diff $WORKDIR/.current_version.tmp $WORKDIR/.current_version >/dev/null + if [ $? -ne 0 ] + then + ERASEIMPORT=1 + IMPORT=1 + mv $WORKDIR/.current_version.tmp $WORKDIR/.current_version + else + rm $WORKDIR/.current_version.tmp + fi + else + ERASEIMPORT=1 + IMPORT=1 + mv $WORKDIR/.current_version.tmp $WORKDIR/.current_version + fi +fi + +if [ $ERASEIMPORT -ne 0 ] +then + echo "--- Erase imported data" + rm -f $WORKDIR/.godot/imported/* +fi + +if [[ ($IMPORT -ne 0) || (! -d $WORKDIR/.godot) ]] +then + echo "--- Launch import (please wait)" + $WORKDIR/$EXE --editor --quit + echo "--- Import finished" +fi + +if [ $EDITOR -ne 0 ] +then + OPTION="$OPTION -e" +fi + +cd $CLIENTDIR +$WORKDIR/$EXE $OPTION + +msg_info "End"