...
This commit is contained in:
parent
c9deb6b89a
commit
28c94acf1e
6 changed files with 149 additions and 0 deletions
68
weltenauge/01_core/systems/id_manager.gd
Normal file
68
weltenauge/01_core/systems/id_manager.gd
Normal file
|
|
@ -0,0 +1,68 @@
|
||||||
|
extends RefCounted
|
||||||
|
|
||||||
|
|
||||||
|
var assigned_ids = {}
|
||||||
|
const ID_STORAGE_PATH = "user://assigned_ids.json"
|
||||||
|
|
||||||
|
func _init():
|
||||||
|
load_assigned_ids()
|
||||||
|
|
||||||
|
func generate_unique_id(username):
|
||||||
|
for id in assigned_ids:
|
||||||
|
if assigned_ids[id] == username:
|
||||||
|
return id
|
||||||
|
|
||||||
|
var new_id = generate_uuid()
|
||||||
|
while assigned_ids.has(new_id):
|
||||||
|
new_id = generate_uuid()
|
||||||
|
assigned_ids[new_id] = username
|
||||||
|
print("Assigned new ID " + str(new_id) + " to user " + username)
|
||||||
|
return new_id
|
||||||
|
|
||||||
|
|
||||||
|
func generate_uuid():
|
||||||
|
var hasher = HASH.new()
|
||||||
|
hasher.hash(str(randf()).utf8)
|
||||||
|
return hasher.get_hex_string()
|
||||||
|
|
||||||
|
|
||||||
|
func release_id(id):
|
||||||
|
if assigned_ids.has(id):
|
||||||
|
var username = assigned_ids.pop(id)
|
||||||
|
print("Released ID " + str(id) + " from user " + username)
|
||||||
|
|
||||||
|
|
||||||
|
func get_username_from_id(id):
|
||||||
|
if assigned_ids.has(id):
|
||||||
|
return assigned_ids[id]
|
||||||
|
else:
|
||||||
|
return null
|
||||||
|
|
||||||
|
|
||||||
|
func save_assigned_ids():
|
||||||
|
var data = {}
|
||||||
|
for id in assigned_ids:
|
||||||
|
data[id] = assigned_ids[id]
|
||||||
|
var file = FileAccess.open(ID_STORAGE_PATH, FileAccess.WRITE)
|
||||||
|
if file:
|
||||||
|
file.store_string(JSON.stringify(data, "\t"))
|
||||||
|
file.close()
|
||||||
|
print("Saved assigned_ids to " + ID_STORAGE_PATH)
|
||||||
|
else:
|
||||||
|
printerr("Error saving assigned_ids to " + ID_STORAGE_PATH)
|
||||||
|
|
||||||
|
|
||||||
|
func load_assigned_ids():
|
||||||
|
var file = FileAccess.open(ID_STORAGE_PATH, FileAccess.READ)
|
||||||
|
if file:
|
||||||
|
var json_string = file.get_as_text()
|
||||||
|
file.close()
|
||||||
|
|
||||||
|
var data = JSON.parse_string(json_string)
|
||||||
|
if typeof(data) == TYPE_DICTIONARY:
|
||||||
|
assigned_ids = data
|
||||||
|
print("Loaded assigned_ids from " + ID_STORAGE_PATH + ": " + str(assigned_ids))
|
||||||
|
else:
|
||||||
|
printerr("Invalid data in " + ID_STORAGE_PATH)
|
||||||
|
else:
|
||||||
|
print("No assigned_ids file found. Starting with empty list.")
|
||||||
1
weltenauge/01_core/systems/id_manager.gd.uid
Normal file
1
weltenauge/01_core/systems/id_manager.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bollf1ei7xaia
|
||||||
|
|
@ -15,6 +15,16 @@ var area_paths = {
|
||||||
# Server-seitiges Tracking: peer_id -> SubViewportContainer
|
# Server-seitiges Tracking: peer_id -> SubViewportContainer
|
||||||
var player_worlds = {}
|
var player_worlds = {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Struktur: "username" -> { "password_hash": String, "chars": Array[CharacterData] }
|
||||||
|
var _accounts: Dictionary = {}
|
||||||
|
|
||||||
|
# Der Pfad, wo die Benutzerdaten liegen
|
||||||
|
const SAVE_PATH = "user://accounts/"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
GameEvents.ui_host_requested.connect(host_game)
|
GameEvents.ui_host_requested.connect(host_game)
|
||||||
GameEvents.ui_join_requested.connect(join_game)
|
GameEvents.ui_join_requested.connect(join_game)
|
||||||
|
|
@ -30,6 +40,56 @@ func host_game():
|
||||||
multiplayer.peer_connected.connect(_on_player_connected)
|
multiplayer.peer_connected.connect(_on_player_connected)
|
||||||
multiplayer.peer_disconnected.connect(_on_player_disconnected)
|
multiplayer.peer_disconnected.connect(_on_player_disconnected)
|
||||||
print("Server gestartet. id=" + str(multiplayer.get_unique_id()))
|
print("Server gestartet. id=" + str(multiplayer.get_unique_id()))
|
||||||
|
|
||||||
|
print("Server: Loading Characters")
|
||||||
|
# Ordner erstellen, falls nicht vorhanden
|
||||||
|
if not DirAccess.dir_exists_absolute(SAVE_PATH):
|
||||||
|
DirAccess.make_dir_recursive_absolute(SAVE_PATH)
|
||||||
|
_load_all_accounts_from_disk()
|
||||||
|
|
||||||
|
func save_character(username: String, char_data: Resource) -> void: # Die Resouce ist CharacterData
|
||||||
|
var account_path = SAVE_PATH + username + "/chars/"
|
||||||
|
if not DirAccess.dir_exists_absolute(account_path):
|
||||||
|
DirAccess.make_dir_recursive_absolute(account_path)
|
||||||
|
|
||||||
|
# Dateiname ist die UUID des Charakters
|
||||||
|
var file_path = account_path + char_data.guid + ".tres"
|
||||||
|
var error = ResourceSaver.save(char_data as Resource, file_path)
|
||||||
|
|
||||||
|
if error == OK:
|
||||||
|
print("Server: Charakter %s gespeichert." % char_data.character_name)
|
||||||
|
|
||||||
|
|
||||||
|
func _load_all_accounts_from_disk():
|
||||||
|
var dir = DirAccess.open(SAVE_PATH)
|
||||||
|
if dir:
|
||||||
|
dir.list_dir_begin()
|
||||||
|
var user_dir = dir.get_next()
|
||||||
|
while user_dir != "":
|
||||||
|
if dir.current_is_dir() and not user_dir.begin_with("."):
|
||||||
|
_load_account(user_dir)
|
||||||
|
user_dir = dir.get_next()
|
||||||
|
|
||||||
|
func _load_account(username: String):
|
||||||
|
var char_path = SAVE_PATH + username + "/chars/"
|
||||||
|
var characters: Array[CharacterData] = []
|
||||||
|
|
||||||
|
if DirAccess.dir_exists_absolute(char_path):
|
||||||
|
var dir = DirAccess.open(char_path)
|
||||||
|
dir.list_dir_begin()
|
||||||
|
var file_name = dir.get_next()
|
||||||
|
while file_name != "":
|
||||||
|
if file_name.ends_with(".tres"):
|
||||||
|
var res = ResourceLoader.load(char_path + file_name)
|
||||||
|
if res is CharacterData:
|
||||||
|
characters.append(res)
|
||||||
|
file_name = dir.get_next()
|
||||||
|
|
||||||
|
_accounts[username] = {
|
||||||
|
"password_hash": "...", # Hier würde man eine account_info.json laden
|
||||||
|
"characters": characters
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
func join_game(ip: String, username: String, password: String):
|
func join_game(ip: String, username: String, password: String):
|
||||||
print("NetworkManager.join_game(", ip, "/", username, "/", password)
|
print("NetworkManager.join_game(", ip, "/", username, "/", password)
|
||||||
|
|
|
||||||
18
weltenauge/01_core/systems/utils.gd
Normal file
18
weltenauge/01_core/systems/utils.gd
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
## Generiert eine kryptografisch sichere, zufällige ID.
|
||||||
|
## Länge 16 Bytes ergibt einen 32-Zeichen Hex-String.
|
||||||
|
func generate_uuid() -> String:
|
||||||
|
var crypto = Crypto.new()
|
||||||
|
return crypto.generate_random_hex(16)
|
||||||
|
|
||||||
|
## Falls du jemals eine formatierte UUID v4 brauchst (8-4-4-4-12):
|
||||||
|
func generate_uuid_v4_formatted() -> String:
|
||||||
|
var s = generate_uuid()
|
||||||
|
return "%s-%s-%s-%s-%s" % [
|
||||||
|
s.substr(0, 8),
|
||||||
|
s.substr(8, 4),
|
||||||
|
s.substr(12, 4),
|
||||||
|
s.substr(16, 4),
|
||||||
|
s.substr(20, 12)
|
||||||
|
]
|
||||||
1
weltenauge/01_core/systems/utils.gd.uid
Normal file
1
weltenauge/01_core/systems/utils.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://cn5ctk4o8qo6k
|
||||||
|
|
@ -20,6 +20,7 @@ boot_splash/minimum_display_time=1000
|
||||||
|
|
||||||
[autoload]
|
[autoload]
|
||||||
|
|
||||||
|
Utils="*uid://cn5ctk4o8qo6k"
|
||||||
GameEvents="*uid://4xof67e363t4"
|
GameEvents="*uid://4xof67e363t4"
|
||||||
ChatManager="*uid://c351ysuym2mdm"
|
ChatManager="*uid://c351ysuym2mdm"
|
||||||
NetworkManager="*uid://tniwwfk5703p"
|
NetworkManager="*uid://tniwwfk5703p"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue