diff options
-rw-r--r-- | Game/Client.gd | 56 | ||||
-rw-r--r-- | Game/Client.tscn | 3 | ||||
-rw-r--r-- | Game/Lobby/Server/index.php | 56 | ||||
-rw-r--r-- | Game/Lobby/game_lobby.gd | 89 | ||||
-rw-r--r-- | Game/Network.gd | 19 | ||||
-rw-r--r-- | UI/GameLobby/game_lobby.gd | 6 | ||||
-rw-r--r-- | UI/GameLobby/lobby_game.gd | 15 | ||||
-rw-r--r-- | UI/PlayerLobby/lobby.gd | 9 | ||||
-rw-r--r-- | UI/Start.gd | 13 | ||||
-rw-r--r-- | UI/Start.tscn | 2 | ||||
-rw-r--r-- | project.godot | 1 |
11 files changed, 171 insertions, 98 deletions
diff --git a/Game/Client.gd b/Game/Client.gd index fd24a07..6e08a58 100644 --- a/Game/Client.gd +++ b/Game/Client.gd @@ -11,10 +11,6 @@ signal multi_select_finished(nodes) var previous_scene: String -var game_lobby_url := "http://localhost:8910" -@onready var game_lobby_server: HTTPRequest = %GameLobbyServer -var current_game_id := "" - var state: State : set(value): state = value @@ -109,12 +105,26 @@ func update_unit(path: NodePath, data: Unit.NetworkData): func change_scene_to_instance(scene: Node): (func(): + previous_scene = get_tree().current_scene.get_path() + get_tree().current_scene.queue_free() get_tree().root.add_child(scene) get_tree().current_scene = scene ).call_deferred() +func get_config() -> ConfigFile: + var config := ConfigFile.new() + config.load("user://config") + + if not FileAccess.file_exists("user://config"): + config.set_value("general", "host_default_port", 1234) + config.set_value("general", "game_lobby_server_base_url", "http://localhost:8910") + config.save("user://config") + + return config + + func array_intersect(first, second): var compare = {} for value in first: @@ -125,41 +135,3 @@ func array_intersect(first, second): return true return false - - -class HTTPResponse extends Resource: - var result_code: HTTPRequest.Result - var response_code: int - var headers: PackedStringArray - var body: PackedByteArray - func parse_json() -> Dictionary: - return JSON.parse_string(body.get_string_from_utf8()) - -func request( - url: String, - custom_headers: PackedStringArray = PackedStringArray(), - method: HTTPClient.Method = HTTPClient.METHOD_GET, - request_data: String = "" -) -> HTTPResponse: - var response = HTTPResponse.new() - - %GameLobbyServer.request_completed.connect( - func ( - result_code: int, - response_code: int, - headers: PackedStringArray, - body: PackedByteArray - ): - response.result_code = result_code - response.response_code = response_code - response.headers = headers - response.body = body - ) - %GameLobbyServer.request(url, custom_headers, method, request_data) - - await %GameLobbyServer.request_completed - return response - -func check_game_lobby_available() -> bool: - var response = await Client.request("%s" % [Client.game_lobby_url], [], HTTPClient.METHOD_GET) - return response.result_code == HTTPRequest.RESULT_SUCCESS diff --git a/Game/Client.tscn b/Game/Client.tscn index ba9a1a8..db2a8b2 100644 --- a/Game/Client.tscn +++ b/Game/Client.tscn @@ -4,6 +4,3 @@ [node name="Client" type="Node"] script = ExtResource("1_kj0qy") - -[node name="GameLobbyServer" type="HTTPRequest" parent="."] -unique_name_in_owner = true diff --git a/Game/Lobby/Server/index.php b/Game/Lobby/Server/index.php index 16be3ef..ae734a6 100644 --- a/Game/Lobby/Server/index.php +++ b/Game/Lobby/Server/index.php @@ -2,9 +2,11 @@ /* * Routes: - * /host ?host&port=$port&name=$name - * /get-list ?get-list - * /join ?join=$id + * /host ?port=$port&name=$name + * /get-list ? + * /join ?id=$id + * /close ?id=$id + * /keep-alive ?id=$id */ $dbname = $_ENV['DB_NAME'] ?? 'db'; @@ -24,7 +26,8 @@ if (php_sapi_name() == 'cli') { port integer, creation_time integer, ping_time integer, - name text + name text, + secret text ); SQL) ->execute(); @@ -33,14 +36,19 @@ if (php_sapi_name() == 'cli') { return; } -$inputPost = json_decode(file_get_contents('php://input'), true); -if ($inputPost) { - $_POST = $inputPost + $_POST; +$url = parse_url("$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"); +$method = $_SERVER['REQUEST_METHOD']; + +if ($method == 'POST') { + $inputPost = json_decode(file_get_contents('php://input'), true); + if ($inputPost) { + $_POST = $inputPost + $_POST; + } } $response = []; -if (isset($_POST['host'])) { +if ($method == 'POST' && $url['path'] == '/host') { $ip = filter_var($_SERVER['REMOTE_ADDR'], FILTER_VALIDATE_IP); if ($ip === false) { @@ -54,9 +62,10 @@ if (isset($_POST['host'])) { $port = intval($_POST['port']); $name = $_POST['name']; $id = md5($name . time()); + $secret = md5($id . random_bytes($port)); $success = $db->prepare(<<<SQL - insert or replace into games (id, ip, port, creation_time, ping_time, name) values (:id, :ip, :port, :timestamp, :timestamp, :name) + insert or replace into games (id, ip, port, creation_time, ping_time, name, secret) values (:id, :ip, :port, :timestamp, :timestamp, :name, :secret) SQL) ->execute([ 'id' => $id, @@ -64,13 +73,16 @@ if (isset($_POST['host'])) { 'port' => $port, 'timestamp' => time(), 'name' => $name, + 'secret' => $secret, ]); - if ($success) { $response = [ 'success' => $success, - 'data' => $id, + 'data' => [ + 'id' => $id, + 'secret' => $secret, + ], ]; } else { $response = [ @@ -81,7 +93,7 @@ if (isset($_POST['host'])) { } } -else if (isset($_GET['get-list'])) { +else if ($method == 'GET' && $url['path'] == '/get-list') { $statement = $db->prepare(<<<SQL select id, name from games where ping_time > :comparison_time @@ -105,8 +117,8 @@ else if (isset($_GET['get-list'])) { ]; } -else if (isset($_GET['join'])) { - $id = $_GET['join']; +else if ($method == 'GET' && $url['path'] == '/join') { + $id = $_GET['id']; $statement = $db->prepare(<<<SQL select ip, port from games @@ -136,14 +148,16 @@ else if (isset($_GET['join'])) { } } -else if (isset($_POST['close'])) { - $id = $_POST['close']; +else if ($method == 'POST' && $url['path'] == '/close') { + $id = $_POST['id']; + $secret = $_POST['secret']; $success = $db->prepare(<<<SQL - delete from games where id = :id + delete from games where id = :id and secret = :secret SQL) ->execute([ 'id' => $id, + 'secret' => $secret, ]); $response = [ @@ -151,14 +165,16 @@ else if (isset($_POST['close'])) { ]; } -else if (isset($_POST['keep-alive'])) { - $id = $_POST['keep-alive']; +else if ($method == 'POST' && $url['path'] == '/keep-alive') { + $id = $_POST['id']; + $secret = $_POST['secret']; $success = $db->prepare(<<<SQL - update games set ping_time = :ping_time where id = :id + update games set ping_time = :ping_time where id = :id and secret = :secret SQL) ->execute([ 'id' => $id, + 'secret' => $secret, 'ping_time' => time(), ]); diff --git a/Game/Lobby/game_lobby.gd b/Game/Lobby/game_lobby.gd new file mode 100644 index 0000000..6bfa8be --- /dev/null +++ b/Game/Lobby/game_lobby.gd @@ -0,0 +1,89 @@ +extends Node + + +class HTTPRequestConfig extends Resource: + var headers: PackedStringArray + var method: HTTPClient.Method + var data: Dictionary + var node: HTTPRequest + + @warning_ignore("shadowed_variable") + func _init( + headers := PackedStringArray(), + method := HTTPClient.METHOD_GET, + data := {}, + node := HTTPRequest.new() + ) -> void: + self.headers = headers + self.method = method + self.data = data + self.node = node + + +class HTTPResponse extends Resource: + var result_code: HTTPRequest.Result + var response_code: int + var headers: PackedStringArray + var body: PackedByteArray + + func parse_json() -> Dictionary: + return JSON.parse_string(body.get_string_from_utf8()) + + +var server_base_url: String = Client.get_config().get_value("general", "game_lobby_server_base_url") +var current_game_id: String +var current_secret: String + + +func request( + url: String, + config: HTTPRequestConfig = HTTPRequestConfig.new() +) -> HTTPResponse: + get_tree().root.add_child(config.node) + + if config.method == HTTPClient.METHOD_POST: + config.set("id", current_game_id) + config.set("secret", current_secret) + + var response = HTTPResponse.new() + config.node.request_completed.connect( + func ( + result_code: int, + response_code: int, + headers: PackedStringArray, + body: PackedByteArray + ): + response.result_code = result_code + response.response_code = response_code + response.headers = headers + response.body = body + + get_tree().root.remove_child(config.node) + ) + config.node.request( + "%s%s" % [server_base_url, url], + config.headers, + config.method, + JSON.stringify(config.data) + ) + + await config.node.request_completed + return response + + +func request_get(url: String, headers := PackedStringArray()): + var config := HTTPRequestConfig.new(headers) + + return await request(url, config) + + +func request_post(url: String, data: Dictionary = {}, headers := PackedStringArray()): + var config := HTTPRequestConfig.new(headers, HTTPClient.METHOD_POST, data) + + return await request(url, config) + + +func check_available() -> bool: + var response = await GameLobby.request_get("") + + return response.result_code == HTTPRequest.RESULT_SUCCESS diff --git a/Game/Network.gd b/Game/Network.gd index 23542e2..2858d98 100644 --- a/Game/Network.gd +++ b/Game/Network.gd @@ -16,17 +16,25 @@ func _ready(): multiplayer.allow_object_decoding = true -func host_game(port): +func host_game(port) -> Error: var peer = ENetMultiplayerPeer.new() - peer.create_server(int(port)) + var error = peer.create_server(int(port)) + + if error != OK: + return error multiplayer.multiplayer_peer = peer Client.player.id = multiplayer.get_unique_id() + + return error func join_game(ip, port): var peer = ENetMultiplayerPeer.new() - peer.create_client(ip, int(port)) + var error = peer.create_client(ip, int(port)) + + if error != OK: + return error multiplayer.multiplayer_peer = peer @@ -37,8 +45,9 @@ func close_game(): multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new() reset_players() - await Client.request(Client.game_lobby_url, [], HTTPClient.METHOD_POST, JSON.stringify({"close": Client.current_game_id})) - Client.current_game_id = "" + await GameLobby.request_post("/close") + GameLobby.current_game_id = "" + GameLobby.current_secret = "" func _on_connected_to_server(): diff --git a/UI/GameLobby/game_lobby.gd b/UI/GameLobby/game_lobby.gd index 9f13882..85a8a91 100644 --- a/UI/GameLobby/game_lobby.gd +++ b/UI/GameLobby/game_lobby.gd @@ -16,11 +16,11 @@ func _ready() -> void: $RefreshTimer.wait_time = refresh_interval $RefreshTimer.start() else: - %ServerNotReachable.text = %ServerNotReachable.text.replace("%SERVER%", Client.game_lobby_url) + %ServerNotReachable.text = %ServerNotReachable.text.replace("%SERVER%", GameLobby.server_base_url) func check_game_lobby_available(): - var is_available = await Client.check_game_lobby_available() + var is_available = await GameLobby.check_available() %ServerNotReachable.visible = !is_available @@ -28,7 +28,7 @@ func check_game_lobby_available(): func get_server_list(): - var response = await Client.request("%s/?get-list" % [Client.game_lobby_url], [], HTTPClient.METHOD_GET) + var response = await GameLobby.request_get("/get-list") var result = response.parse_json() print(result) diff --git a/UI/GameLobby/lobby_game.gd b/UI/GameLobby/lobby_game.gd index 4736d44..2433dfd 100644 --- a/UI/GameLobby/lobby_game.gd +++ b/UI/GameLobby/lobby_game.gd @@ -11,9 +11,12 @@ func set_game_name(value): func _on_join_pressed() -> void: - var response = await Network.request("%s/?join=%s" % [Client.game_lobby_url, game_id]) - var result = response.parse_json() - var game_data = result["data"] - - Network.join_game(game_data["ip"], game_data["port"]) - get_tree().change_scene_to_file("res://UI/PlayerLobby/Lobby.tscn") + var response = await GameLobby.request_get("/join?id=%s" % [game_id]) + if response.response_code == 200: + var result = response.parse_json() + var game_data = result["data"] + + Network.join_game(game_data["ip"], game_data["port"]) + get_tree().change_scene_to_file("res://UI/PlayerLobby/Lobby.tscn") + else: + print(response.response_code) diff --git a/UI/PlayerLobby/lobby.gd b/UI/PlayerLobby/lobby.gd index 6506097..4169478 100644 --- a/UI/PlayerLobby/lobby.gd +++ b/UI/PlayerLobby/lobby.gd @@ -45,7 +45,7 @@ func _ready() -> void: if multiplayer.is_server(): $KeepAliveTimer.start() $KeepAliveTimer.timeout.connect(func(): - Client.request(Client.game_lobby_url, [], HTTPClient.METHOD_POST, JSON.stringify({"keep-alive": Client.current_game_id})) + GameLobby.request_post("/keep-alive") ) @@ -92,13 +92,6 @@ func _on_start_button_pressed() -> void: func _on_cancel_button_pressed() -> void: multiplayer.multiplayer_peer.close() - await Client.request( - "%s" % [Client.game_lobby_url], - [], - HTTPClient.METHOD_POST, - JSON.stringify({"close": Client.current_game_id}) - ) - # TODO: if was host => Start. if was joined and connected from list => List get_tree().change_scene_to_file("res://UI/Start.tscn") diff --git a/UI/Start.gd b/UI/Start.gd index b078d65..85a7946 100644 --- a/UI/Start.gd +++ b/UI/Start.gd @@ -22,7 +22,7 @@ func get_ip() -> String: func get_port() -> int: - var port := 1234 + var port: int = Client.get_config().get_value("general", "host_default_port") if %Port.text: port = int(%Port.text) @@ -38,17 +38,12 @@ func _on_peer_disconnected(id): func _on_host_pressed() -> void: Client.player.username = %Username.text - var response = await Client.request( - "%s" % [Client.game_lobby_url], - [], - HTTPClient.METHOD_POST, - JSON.stringify({"host": true, "port": get_port(), "name" : %GameName.text}) - ) - + var response = await GameLobby.request_post("/host", {"port": get_port(), "name" : %GameName.text}) if response.result_code == HTTPRequest.RESULT_SUCCESS: var result = response.parse_json() if result["success"]: - Client.current_game_id = result["data"] + GameLobby.current_game_id = result["data"]["id"] + GameLobby.current_secret = result["data"]["secret"] Network.host_game(get_port()) get_tree().change_scene_to_file("res://UI/PlayerLobby/Lobby.tscn") diff --git a/UI/Start.tscn b/UI/Start.tscn index efa061c..b0d4ac2 100644 --- a/UI/Start.tscn +++ b/UI/Start.tscn @@ -100,8 +100,6 @@ mouse_default_cursor_shape = 2 theme_override_font_sizes/font_size = 24 text = "Search" -[node name="ServerHost" type="HTTPRequest" parent="."] - [connection signal="pressed" from="CenterContainer/VBoxContainer/Host" to="." method="_on_host_pressed"] [connection signal="pressed" from="CenterContainer/VBoxContainer/Join" to="." method="_on_join_pressed"] [connection signal="pressed" from="CenterContainer/VBoxContainer/Search" to="." method="_on_search_pressed"] diff --git a/project.godot b/project.godot index f340872..26eeb2e 100644 --- a/project.godot +++ b/project.godot @@ -19,6 +19,7 @@ config/icon="res://icon.svg" Network="*res://Game/Network.tscn" Client="*res://Game/Client.tscn" +GameLobby="*res://Game/Lobby/game_lobby.gd" [display] |