commit 452f61934c823c8b719035310c0313ba3d237c6a Author: Sebastian Benjamin Date: Tue Jan 28 17:10:26 2025 -0800 Initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5f7dea9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +*.swp +*.import +test_suite/addons +test_suite/addons/* +test_suite/.import/* diff --git a/.godot/.gdignore b/.godot/.gdignore new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/.godot/.gdignore @@ -0,0 +1 @@ + diff --git a/.godot/editor/editor_layout.cfg b/.godot/editor/editor_layout.cfg new file mode 100644 index 0000000..25d2228 --- /dev/null +++ b/.godot/editor/editor_layout.cfg @@ -0,0 +1,49 @@ +[docks] + +dock_3_selected_tab_idx=0 +dock_4_selected_tab_idx=0 +dock_5_selected_tab_idx=0 +dock_floating={} +dock_bottom=[] +dock_closed=[] +dock_split_2=0 +dock_split_3=0 +dock_hsplit_1=0 +dock_hsplit_2=270 +dock_hsplit_3=-270 +dock_hsplit_4=0 +dock_filesystem_h_split_offset=240 +dock_filesystem_v_split_offset=0 +dock_filesystem_display_mode=0 +dock_filesystem_file_sort=0 +dock_filesystem_file_list_display_mode=1 +dock_filesystem_selected_paths=PackedStringArray("res://danmaku!/player.tscn") +dock_filesystem_uncollapsed_paths=PackedStringArray("Favorites", "res://", "res://danmaku!/") +dock_3="Scene,Import" +dock_4="FileSystem" +dock_5="Inspector,Node,History" + +[EditorNode] + +open_scenes=PackedStringArray("res://danmaku!/player.tscn", "res://danmaku!/testworld.tscn") +current_scene="res://danmaku!/testworld.tscn" +center_split_offset=0 +selected_default_debugger_tab_idx=0 +selected_main_editor_idx=2 +selected_bottom_panel_item=0 + +[ScriptEditor] + +open_scripts=["res://danmaku!/player.gd"] +selected_script="res://danmaku!/player.gd" +open_help=[] +script_split_offset=70 +list_split_offset=0 +zoom_factor=1.0 + +[ShaderEditor] + +open_shaders=[] +split_offset=0 +selected_shader="" +text_shader_zoom_factor=1.0 diff --git a/.godot/editor/filesystem_cache8 b/.godot/editor/filesystem_cache8 new file mode 100644 index 0000000..206b85a --- /dev/null +++ b/.godot/editor/filesystem_cache8 @@ -0,0 +1,35 @@ +ea4bc82a6ad023ab7ee23ee620429895 +::res://::1738111850 +CHANGELOG.md::TextFile::-1::1737676442::0::1::::<><>:: +icon.svg::CompressedTexture2D::3707950262073026637::1737417699::1737417720::1::::<><>:: +README.md::TextFile::-1::1737676442::0::1::::<><>:: +::res://addons/::1737676442 +::res://addons/com.heroiclabs.nakama/::1737676442 +Nakama.gd::GDScript::-1::1737676442::0::1::::<>Node<>:: +::res://addons/com.heroiclabs.nakama/api/::1737676442 +NakamaAPI.gd::GDScript::-1::1737676442::0::1::::NakamaAPI<>RefCounted<>:: +NakamaRTAPI.gd::GDScript::-1::1737676442::0::1::::NakamaRTAPI<>NakamaAsyncResult<>:: +NakamaRTMessage.gd::GDScript::-1::1737676442::0::1::::NakamaRTMessage<>RefCounted<>:: +NakamaSession.gd::GDScript::-1::1737676442::0::1::::NakamaSession<>NakamaAsyncResult<>:: +NakamaStorageObjectId.gd::GDScript::-1::1737676442::0::1::::NakamaStorageObjectId<>RefCounted<>:: +NakamaWriteStorageObject.gd::GDScript::-1::1737676442::0::1::::NakamaWriteStorageObject<>RefCounted<>:: +::res://addons/com.heroiclabs.nakama/client/::1737676442 +NakamaClient.gd::GDScript::-1::1737676442::0::1::::NakamaClient<>RefCounted<>:: +NakamaHTTPAdapter.gd::GDScript::-1::1737676442::0::1::::NakamaHTTPAdapter<>Node<>:: +::res://addons/com.heroiclabs.nakama/dotnet-utils/::1737676442 +::res://addons/com.heroiclabs.nakama/socket/::1737676442 +NakamaSocket.gd::GDScript::-1::1737676442::0::1::::NakamaSocket<>RefCounted<>:: +NakamaSocketAdapter.gd::GDScript::-1::1737676442::0::1::::NakamaSocketAdapter<>Node<>:: +::res://addons/com.heroiclabs.nakama/utils/::1737676442 +NakamaAsyncResult.gd::GDScript::-1::1737676442::0::1::::NakamaAsyncResult<>RefCounted<>:: +NakamaException.gd::GDScript::-1::1737676442::0::1::::NakamaException<>RefCounted<>:: +NakamaLogger.gd::GDScript::-1::1737676442::0::1::::NakamaLogger<>RefCounted<>:: +NakamaMultiplayerBridge.gd::GDScript::-1::1737676442::0::1::::NakamaMultiplayerBridge<>RefCounted<>:: +NakamaMultiplayerPeer.gd::GDScript::-1::1737676442::0::1::::NakamaMultiplayerPeer<>MultiplayerPeerExtension<>:: +NakamaSerializer.gd::GDScript::-1::1737676442::0::1::::NakamaSerializer<>RefCounted<>:: +::res://codegen/::1737676442 +README.md::TextFile::-1::1737676442::0::1::::<><>:: +::res://danmaku!/::1737683594 +player.gd::GDScript::-1::1737682905::0::1::::<>Node2D<>:: +player.tscn::PackedScene::5042393718698370894::1737683594::0::1::::<><>::res://danmaku!/player.gd +testworld.tscn::PackedScene::4237769419146379699::1737683594::0::1::::<><>::uid://cd3tqt7hr5pqs::::res://danmaku!/player.tscn diff --git a/.godot/editor/player.gd-folding-08e5b31c929bae6461782ae25245b0e8.cfg b/.godot/editor/player.gd-folding-08e5b31c929bae6461782ae25245b0e8.cfg new file mode 100644 index 0000000..e860dd4 --- /dev/null +++ b/.godot/editor/player.gd-folding-08e5b31c929bae6461782ae25245b0e8.cfg @@ -0,0 +1,3 @@ +[folding] + +sections_unfolded=PackedStringArray() diff --git a/.godot/editor/player.tscn-editstate-bb18e8d3779d0936229b342e50ccb558.cfg b/.godot/editor/player.tscn-editstate-bb18e8d3779d0936229b342e50ccb558.cfg new file mode 100644 index 0000000..2f44b6a --- /dev/null +++ b/.godot/editor/player.tscn-editstate-bb18e8d3779d0936229b342e50ccb558.cfg @@ -0,0 +1,178 @@ +[editor_states] + +Anim={ +"visible": false +} +2D={ +"grid_offset": Vector2(0, 0), +"grid_snap_active": false, +"grid_step": Vector2(8, 8), +"grid_visibility": 1, +"ofs": Vector2(-165, -110), +"primary_grid_step": Vector2i(8, 8), +"show_group_gizmos": true, +"show_guides": true, +"show_helpers": false, +"show_lock_gizmos": true, +"show_origin": true, +"show_position_gizmos": true, +"show_rulers": true, +"show_transformation_gizmos": true, +"show_viewport": true, +"show_zoom_control": true, +"smart_snap_active": false, +"snap_guides": true, +"snap_node_anchors": true, +"snap_node_center": true, +"snap_node_parent": true, +"snap_node_sides": true, +"snap_other_nodes": true, +"snap_pixel": true, +"snap_relative": false, +"snap_rotation": false, +"snap_rotation_offset": 0.0, +"snap_rotation_step": 0.261799, +"snap_scale": false, +"snap_scale_step": 0.1, +"zoom": 1.0 +} +3D={ +"fov": 70.01, +"gizmos_status": { +"AudioListener3D": 0, +"AudioStreamPlayer3D": 0, +"CPUParticles3D": 0, +"CSGShape3D": 0, +"Camera3D": 0, +"CollisionObject3D": 0, +"CollisionPolygon3D": 0, +"CollisionShape3D": 0, +"Decal": 0, +"FogVolume": 0, +"GPUParticles3D": 0, +"GPUParticlesCollision3D": 0, +"Joint3D": 0, +"Light3D": 0, +"LightmapGI": 0, +"LightmapProbe": 0, +"Marker3D": 0, +"MeshInstance3DCustomAABB": 0, +"NavigationLink3D": 0, +"NavigationRegion3D": 0, +"OccluderInstance3D": 0, +"Path3D": 0, +"PhysicalBone3D": 0, +"RayCast3D": 0, +"ReflectionProbe": 0, +"ShapeCast3D": 0, +"Skeleton3D": 0, +"SoftBody3D": 0, +"SpringArm3D": 0, +"VehicleWheel3D": 0, +"VisibleOnScreenNotifier3D": 0, +"VoxelGI": 0 +}, +"local_coords": false, +"preview_sun_env": { +"environ_ao_enabled": false, +"environ_enabled": true, +"environ_energy": 1.0, +"environ_gi_enabled": false, +"environ_glow_enabled": true, +"environ_ground_color": Color(0.2, 0.169, 0.133, 1), +"environ_sky_color": Color(0.385, 0.454, 0.55, 1), +"environ_tonemap_enabled": true, +"sun_color": Color(1, 1, 1, 1), +"sun_enabled": true, +"sun_energy": 1.0, +"sun_max_distance": 100.0, +"sun_rotation": Vector2(-1.0472, 2.61799) +}, +"rotate_snap": 15.0, +"scale_snap": 10.0, +"show_grid": true, +"show_origin": true, +"snap_enabled": false, +"translate_snap": 1.0, +"viewport_mode": 1, +"viewports": [{ +"auto_orthogonal": false, +"auto_orthogonal_enabled": true, +"cinematic_preview": false, +"display_mode": 21, +"distance": 4.0, +"doppler": false, +"frame_time": false, +"gizmos": true, +"half_res": false, +"information": false, +"listener": true, +"lock_rotation": false, +"orthogonal": false, +"position": Vector3(0, 0, 0), +"use_environment": false, +"view_type": 0, +"x_rotation": 0.5, +"y_rotation": -0.5 +}, { +"auto_orthogonal": false, +"auto_orthogonal_enabled": true, +"cinematic_preview": false, +"display_mode": 21, +"distance": 4.0, +"doppler": false, +"frame_time": false, +"gizmos": true, +"half_res": false, +"information": false, +"listener": false, +"lock_rotation": false, +"orthogonal": false, +"position": Vector3(0, 0, 0), +"use_environment": false, +"view_type": 0, +"x_rotation": 0.5, +"y_rotation": -0.5 +}, { +"auto_orthogonal": false, +"auto_orthogonal_enabled": true, +"cinematic_preview": false, +"display_mode": 21, +"distance": 4.0, +"doppler": false, +"frame_time": false, +"gizmos": true, +"half_res": false, +"information": false, +"listener": false, +"lock_rotation": false, +"orthogonal": false, +"position": Vector3(0, 0, 0), +"use_environment": false, +"view_type": 0, +"x_rotation": 0.5, +"y_rotation": -0.5 +}, { +"auto_orthogonal": false, +"auto_orthogonal_enabled": true, +"cinematic_preview": false, +"display_mode": 21, +"distance": 4.0, +"doppler": false, +"frame_time": false, +"gizmos": true, +"half_res": false, +"information": false, +"listener": false, +"lock_rotation": false, +"orthogonal": false, +"position": Vector3(0, 0, 0), +"use_environment": false, +"view_type": 0, +"x_rotation": 0.5, +"y_rotation": -0.5 +}], +"zfar": 4000.01, +"znear": 0.05 +} +selected_nodes=Array[NodePath]([NodePath("/root/@EditorNode@16886/@Panel@13/@VBoxContainer@14/DockHSplitLeftL/DockHSplitLeftR/DockHSplitMain/@VBoxContainer@25/DockVSplitCenter/@VSplitContainer@52/@VBoxContainer@53/@PanelContainer@98/MainScreen/@CanvasItemEditor@9272/@VSplitContainer@9094/@HSplitContainer@9096/@HSplitContainer@9098/@Control@9099/@SubViewportContainer@9100/@SubViewport@9101/Testworld/Player")]) diff --git a/.godot/editor/player.tscn-folding-bb18e8d3779d0936229b342e50ccb558.cfg b/.godot/editor/player.tscn-folding-bb18e8d3779d0936229b342e50ccb558.cfg new file mode 100644 index 0000000..1d019fa --- /dev/null +++ b/.godot/editor/player.tscn-folding-bb18e8d3779d0936229b342e50ccb558.cfg @@ -0,0 +1,5 @@ +[folding] + +node_unfolds=[] +resource_unfolds=[] +nodes_folded=[] diff --git a/.godot/editor/project_metadata.cfg b/.godot/editor/project_metadata.cfg new file mode 100644 index 0000000..4924e7a --- /dev/null +++ b/.godot/editor/project_metadata.cfg @@ -0,0 +1,20 @@ +[editor_metadata] + +executable_path="E:/Games/steamapps/common/Godot Engine/godot.windows.opt.tools.64.exe" + +[dialog_bounds] + +project_settings=Rect2(4120, 370, 1200, 700) + +[recent_files] + +scripts=["res://danmaku!/player.gd", "res://codegen/README.md", "res://README.md"] +scenes=["res://danmaku!/testworld.tscn", "res://danmaku!/player.tscn"] + +[project_settings] + +advanced_mode=true + +[script_setup] + +last_selected_language="GDScript" diff --git a/.godot/editor/recent_dirs b/.godot/editor/recent_dirs new file mode 100644 index 0000000..e1accf0 --- /dev/null +++ b/.godot/editor/recent_dirs @@ -0,0 +1,2 @@ +res://danmaku! +res://addons/com.heroiclabs.nakama diff --git a/.godot/editor/script_editor_cache.cfg b/.godot/editor/script_editor_cache.cfg new file mode 100644 index 0000000..78dd569 --- /dev/null +++ b/.godot/editor/script_editor_cache.cfg @@ -0,0 +1,41 @@ +[res://README.md] + +state={ +"bookmarks": PackedInt32Array(), +"breakpoints": PackedInt32Array(), +"column": 0, +"folded_lines": Array[int]([]), +"h_scroll_position": 0, +"row": 0, +"scroll_position": 3.0, +"selection": false, +"syntax_highlighter": "Plain Text" +} + +[res://codegen/README.md] + +state={ +"bookmarks": PackedInt32Array(), +"breakpoints": PackedInt32Array(), +"column": 0, +"folded_lines": Array[int]([]), +"h_scroll_position": 0, +"row": 0, +"scroll_position": 0.0, +"selection": false, +"syntax_highlighter": "Plain Text" +} + +[res://danmaku!/player.gd] + +state={ +"bookmarks": PackedInt32Array(), +"breakpoints": PackedInt32Array(), +"column": 0, +"folded_lines": Array[int]([]), +"h_scroll_position": 0, +"row": 16, +"scroll_position": 0.0, +"selection": false, +"syntax_highlighter": "GDScript" +} diff --git a/.godot/editor/testworld.tscn-editstate-5a67704a94a9c767c34f85516be02ce8.cfg b/.godot/editor/testworld.tscn-editstate-5a67704a94a9c767c34f85516be02ce8.cfg new file mode 100644 index 0000000..2f44b6a --- /dev/null +++ b/.godot/editor/testworld.tscn-editstate-5a67704a94a9c767c34f85516be02ce8.cfg @@ -0,0 +1,178 @@ +[editor_states] + +Anim={ +"visible": false +} +2D={ +"grid_offset": Vector2(0, 0), +"grid_snap_active": false, +"grid_step": Vector2(8, 8), +"grid_visibility": 1, +"ofs": Vector2(-165, -110), +"primary_grid_step": Vector2i(8, 8), +"show_group_gizmos": true, +"show_guides": true, +"show_helpers": false, +"show_lock_gizmos": true, +"show_origin": true, +"show_position_gizmos": true, +"show_rulers": true, +"show_transformation_gizmos": true, +"show_viewport": true, +"show_zoom_control": true, +"smart_snap_active": false, +"snap_guides": true, +"snap_node_anchors": true, +"snap_node_center": true, +"snap_node_parent": true, +"snap_node_sides": true, +"snap_other_nodes": true, +"snap_pixel": true, +"snap_relative": false, +"snap_rotation": false, +"snap_rotation_offset": 0.0, +"snap_rotation_step": 0.261799, +"snap_scale": false, +"snap_scale_step": 0.1, +"zoom": 1.0 +} +3D={ +"fov": 70.01, +"gizmos_status": { +"AudioListener3D": 0, +"AudioStreamPlayer3D": 0, +"CPUParticles3D": 0, +"CSGShape3D": 0, +"Camera3D": 0, +"CollisionObject3D": 0, +"CollisionPolygon3D": 0, +"CollisionShape3D": 0, +"Decal": 0, +"FogVolume": 0, +"GPUParticles3D": 0, +"GPUParticlesCollision3D": 0, +"Joint3D": 0, +"Light3D": 0, +"LightmapGI": 0, +"LightmapProbe": 0, +"Marker3D": 0, +"MeshInstance3DCustomAABB": 0, +"NavigationLink3D": 0, +"NavigationRegion3D": 0, +"OccluderInstance3D": 0, +"Path3D": 0, +"PhysicalBone3D": 0, +"RayCast3D": 0, +"ReflectionProbe": 0, +"ShapeCast3D": 0, +"Skeleton3D": 0, +"SoftBody3D": 0, +"SpringArm3D": 0, +"VehicleWheel3D": 0, +"VisibleOnScreenNotifier3D": 0, +"VoxelGI": 0 +}, +"local_coords": false, +"preview_sun_env": { +"environ_ao_enabled": false, +"environ_enabled": true, +"environ_energy": 1.0, +"environ_gi_enabled": false, +"environ_glow_enabled": true, +"environ_ground_color": Color(0.2, 0.169, 0.133, 1), +"environ_sky_color": Color(0.385, 0.454, 0.55, 1), +"environ_tonemap_enabled": true, +"sun_color": Color(1, 1, 1, 1), +"sun_enabled": true, +"sun_energy": 1.0, +"sun_max_distance": 100.0, +"sun_rotation": Vector2(-1.0472, 2.61799) +}, +"rotate_snap": 15.0, +"scale_snap": 10.0, +"show_grid": true, +"show_origin": true, +"snap_enabled": false, +"translate_snap": 1.0, +"viewport_mode": 1, +"viewports": [{ +"auto_orthogonal": false, +"auto_orthogonal_enabled": true, +"cinematic_preview": false, +"display_mode": 21, +"distance": 4.0, +"doppler": false, +"frame_time": false, +"gizmos": true, +"half_res": false, +"information": false, +"listener": true, +"lock_rotation": false, +"orthogonal": false, +"position": Vector3(0, 0, 0), +"use_environment": false, +"view_type": 0, +"x_rotation": 0.5, +"y_rotation": -0.5 +}, { +"auto_orthogonal": false, +"auto_orthogonal_enabled": true, +"cinematic_preview": false, +"display_mode": 21, +"distance": 4.0, +"doppler": false, +"frame_time": false, +"gizmos": true, +"half_res": false, +"information": false, +"listener": false, +"lock_rotation": false, +"orthogonal": false, +"position": Vector3(0, 0, 0), +"use_environment": false, +"view_type": 0, +"x_rotation": 0.5, +"y_rotation": -0.5 +}, { +"auto_orthogonal": false, +"auto_orthogonal_enabled": true, +"cinematic_preview": false, +"display_mode": 21, +"distance": 4.0, +"doppler": false, +"frame_time": false, +"gizmos": true, +"half_res": false, +"information": false, +"listener": false, +"lock_rotation": false, +"orthogonal": false, +"position": Vector3(0, 0, 0), +"use_environment": false, +"view_type": 0, +"x_rotation": 0.5, +"y_rotation": -0.5 +}, { +"auto_orthogonal": false, +"auto_orthogonal_enabled": true, +"cinematic_preview": false, +"display_mode": 21, +"distance": 4.0, +"doppler": false, +"frame_time": false, +"gizmos": true, +"half_res": false, +"information": false, +"listener": false, +"lock_rotation": false, +"orthogonal": false, +"position": Vector3(0, 0, 0), +"use_environment": false, +"view_type": 0, +"x_rotation": 0.5, +"y_rotation": -0.5 +}], +"zfar": 4000.01, +"znear": 0.05 +} +selected_nodes=Array[NodePath]([NodePath("/root/@EditorNode@16886/@Panel@13/@VBoxContainer@14/DockHSplitLeftL/DockHSplitLeftR/DockHSplitMain/@VBoxContainer@25/DockVSplitCenter/@VSplitContainer@52/@VBoxContainer@53/@PanelContainer@98/MainScreen/@CanvasItemEditor@9272/@VSplitContainer@9094/@HSplitContainer@9096/@HSplitContainer@9098/@Control@9099/@SubViewportContainer@9100/@SubViewport@9101/Testworld/Player")]) diff --git a/.godot/editor/testworld.tscn-folding-5a67704a94a9c767c34f85516be02ce8.cfg b/.godot/editor/testworld.tscn-folding-5a67704a94a9c767c34f85516be02ce8.cfg new file mode 100644 index 0000000..1d019fa --- /dev/null +++ b/.godot/editor/testworld.tscn-folding-5a67704a94a9c767c34f85516be02ce8.cfg @@ -0,0 +1,5 @@ +[folding] + +node_unfolds=[] +resource_unfolds=[] +nodes_folded=[] diff --git a/.godot/global_script_class_cache.cfg b/.godot/global_script_class_cache.cfg new file mode 100644 index 0000000..f22204d --- /dev/null +++ b/.godot/global_script_class_cache.cfg @@ -0,0 +1,97 @@ +list=Array[Dictionary]([{ +"base": &"RefCounted", +"class": &"NakamaAPI", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/api/NakamaAPI.gd" +}, { +"base": &"RefCounted", +"class": &"NakamaAsyncResult", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/utils/NakamaAsyncResult.gd" +}, { +"base": &"RefCounted", +"class": &"NakamaClient", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/client/NakamaClient.gd" +}, { +"base": &"RefCounted", +"class": &"NakamaException", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/utils/NakamaException.gd" +}, { +"base": &"Node", +"class": &"NakamaHTTPAdapter", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/client/NakamaHTTPAdapter.gd" +}, { +"base": &"RefCounted", +"class": &"NakamaLogger", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/utils/NakamaLogger.gd" +}, { +"base": &"RefCounted", +"class": &"NakamaMultiplayerBridge", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/utils/NakamaMultiplayerBridge.gd" +}, { +"base": &"MultiplayerPeerExtension", +"class": &"NakamaMultiplayerPeer", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/utils/NakamaMultiplayerPeer.gd" +}, { +"base": &"NakamaAsyncResult", +"class": &"NakamaRTAPI", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd" +}, { +"base": &"RefCounted", +"class": &"NakamaRTMessage", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/api/NakamaRTMessage.gd" +}, { +"base": &"RefCounted", +"class": &"NakamaSerializer", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/utils/NakamaSerializer.gd" +}, { +"base": &"NakamaAsyncResult", +"class": &"NakamaSession", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/api/NakamaSession.gd" +}, { +"base": &"RefCounted", +"class": &"NakamaSocket", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/socket/NakamaSocket.gd" +}, { +"base": &"Node", +"class": &"NakamaSocketAdapter", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/socket/NakamaSocketAdapter.gd" +}, { +"base": &"RefCounted", +"class": &"NakamaStorageObjectId", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/api/NakamaStorageObjectId.gd" +}, { +"base": &"RefCounted", +"class": &"NakamaWriteStorageObject", +"icon": "", +"language": &"GDScript", +"path": "res://addons/com.heroiclabs.nakama/api/NakamaWriteStorageObject.gd" +}]) diff --git a/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex b/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex new file mode 100644 index 0000000..b212427 Binary files /dev/null and b/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.ctex differ diff --git a/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.md5 b/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.md5 new file mode 100644 index 0000000..6c5ce64 --- /dev/null +++ b/.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.md5 @@ -0,0 +1,3 @@ +source_md5="0eed98577cbbf02f0bdc0f5c9f70465b" +dest_md5="411b5d2fe36e6f2e5e4c615f024ce43b" + diff --git a/.godot/scene_groups_cache.cfg b/.godot/scene_groups_cache.cfg new file mode 100644 index 0000000..e69de29 diff --git a/.godot/shader_cache/BestFitNormalShaderRD/da50b1ee325fa09e8a9d2278e44bfbc4e716c11aa4475ca5323315d9d3e84d70/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/BestFitNormalShaderRD/da50b1ee325fa09e8a9d2278e44bfbc4e716c11aa4475ca5323315d9d3e84d70/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..eb33be5 Binary files /dev/null and b/.godot/shader_cache/BestFitNormalShaderRD/da50b1ee325fa09e8a9d2278e44bfbc4e716c11aa4475ca5323315d9d3e84d70/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/BlitShaderRD/09b63e5347ccb6779fd79e54b093cfc915ec80510efa1f613c9ada9ff2e0f70d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/BlitShaderRD/09b63e5347ccb6779fd79e54b093cfc915ec80510efa1f613c9ada9ff2e0f70d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..017d7cc Binary files /dev/null and b/.godot/shader_cache/BlitShaderRD/09b63e5347ccb6779fd79e54b093cfc915ec80510efa1f613c9ada9ff2e0f70d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/BokehDofShaderRD/39f32133b5111c9c24ab7cd9b202ca96bb3aeb73e0c73ebd7b7a5dae08cb759f/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/BokehDofShaderRD/39f32133b5111c9c24ab7cd9b202ca96bb3aeb73e0c73ebd7b7a5dae08cb759f/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..7bd3747 Binary files /dev/null and b/.godot/shader_cache/BokehDofShaderRD/39f32133b5111c9c24ab7cd9b202ca96bb3aeb73e0c73ebd7b7a5dae08cb759f/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasOcclusionShaderRD/42f2245b35206bcace1cda9e39e9282519e9967978ba6d5956472809525b1150/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/CanvasOcclusionShaderRD/42f2245b35206bcace1cda9e39e9282519e9967978ba6d5956472809525b1150/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..5df6628 Binary files /dev/null and b/.godot/shader_cache/CanvasOcclusionShaderRD/42f2245b35206bcace1cda9e39e9282519e9967978ba6d5956472809525b1150/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasSdfShaderRD/f65579ae334cdfb6901aee2527afd18ed626d1067a35c91f12fb632b45ce7f21/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/CanvasSdfShaderRD/f65579ae334cdfb6901aee2527afd18ed626d1067a35c91f12fb632b45ce7f21/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..9249df7 Binary files /dev/null and b/.godot/shader_cache/CanvasSdfShaderRD/f65579ae334cdfb6901aee2527afd18ed626d1067a35c91f12fb632b45ce7f21/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..31ce1bf Binary files /dev/null and b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/45fb1ddc6499e56682916a355ce2839e61f42dfe.vulkan.cache b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/45fb1ddc6499e56682916a355ce2839e61f42dfe.vulkan.cache new file mode 100644 index 0000000..e052521 Binary files /dev/null and b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/45fb1ddc6499e56682916a355ce2839e61f42dfe.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/6b3b870743b828dcd054fdf31e0034e036dad94f.vulkan.cache b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/6b3b870743b828dcd054fdf31e0034e036dad94f.vulkan.cache new file mode 100644 index 0000000..a5cfa1f Binary files /dev/null and b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/6b3b870743b828dcd054fdf31e0034e036dad94f.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/7d18bd726a158f1a35b723c8e73e7de5ebb3d37c.vulkan.cache b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/7d18bd726a158f1a35b723c8e73e7de5ebb3d37c.vulkan.cache new file mode 100644 index 0000000..86a38c8 Binary files /dev/null and b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/7d18bd726a158f1a35b723c8e73e7de5ebb3d37c.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/8a7277c8d3ac029b087c3fa9c55de85560be5119.vulkan.cache b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/8a7277c8d3ac029b087c3fa9c55de85560be5119.vulkan.cache new file mode 100644 index 0000000..f403ea6 Binary files /dev/null and b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/8a7277c8d3ac029b087c3fa9c55de85560be5119.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/c0a681ae42aa3e0b5abba232ccae0b036be455e4.vulkan.cache b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/c0a681ae42aa3e0b5abba232ccae0b036be455e4.vulkan.cache new file mode 100644 index 0000000..087533f Binary files /dev/null and b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/c0a681ae42aa3e0b5abba232ccae0b036be455e4.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/c58570947be7f76937b1582424c0fd3d81be0352.vulkan.cache b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/c58570947be7f76937b1582424c0fd3d81be0352.vulkan.cache new file mode 100644 index 0000000..c71b7dc Binary files /dev/null and b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/c58570947be7f76937b1582424c0fd3d81be0352.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/ddbe30d4d1be5d69b00075293fd27da8decd4af2.vulkan.cache b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/ddbe30d4d1be5d69b00075293fd27da8decd4af2.vulkan.cache new file mode 100644 index 0000000..82738a8 Binary files /dev/null and b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/ddbe30d4d1be5d69b00075293fd27da8decd4af2.vulkan.cache differ diff --git a/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/f3e258e8f7ec2e7e740b62f3bc48ecf5c99fb0db.vulkan.cache b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/f3e258e8f7ec2e7e740b62f3bc48ecf5c99fb0db.vulkan.cache new file mode 100644 index 0000000..4e8cb9b Binary files /dev/null and b/.godot/shader_cache/CanvasShaderRD/165f6964cfc63fea91c4221f04e7b8a54b5dc39d76b5a57aed5f99b20050b148/f3e258e8f7ec2e7e740b62f3bc48ecf5c99fb0db.vulkan.cache differ diff --git a/.godot/shader_cache/ClusterDebugShaderRD/2546937b6acfcec18164bde1022dd572463c5dc6a8dfb2db860e93b1f8cb6cf1/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/ClusterDebugShaderRD/2546937b6acfcec18164bde1022dd572463c5dc6a8dfb2db860e93b1f8cb6cf1/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..e4e7e19 Binary files /dev/null and b/.godot/shader_cache/ClusterDebugShaderRD/2546937b6acfcec18164bde1022dd572463c5dc6a8dfb2db860e93b1f8cb6cf1/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/ClusterRenderShaderRD/e138dfa55627ca222eda3daa0739d50014770edfb2a8fbab0fa51e2130af04e8/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/ClusterRenderShaderRD/e138dfa55627ca222eda3daa0739d50014770edfb2a8fbab0fa51e2130af04e8/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..778270f Binary files /dev/null and b/.godot/shader_cache/ClusterRenderShaderRD/e138dfa55627ca222eda3daa0739d50014770edfb2a8fbab0fa51e2130af04e8/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/ClusterStoreShaderRD/44efe54fdfa0811178ad2a7a0207ebc98532c6ae316489503cdc7c5c843a564e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/ClusterStoreShaderRD/44efe54fdfa0811178ad2a7a0207ebc98532c6ae316489503cdc7c5c843a564e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..857b40c Binary files /dev/null and b/.godot/shader_cache/ClusterStoreShaderRD/44efe54fdfa0811178ad2a7a0207ebc98532c6ae316489503cdc7c5c843a564e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/CopyShaderRD/4a43f34799f84bc5a387aff816d36330149d91299172af9be2d3ab05cc0c4e9d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/CopyShaderRD/4a43f34799f84bc5a387aff816d36330149d91299172af9be2d3ab05cc0c4e9d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..5835465 Binary files /dev/null and b/.godot/shader_cache/CopyShaderRD/4a43f34799f84bc5a387aff816d36330149d91299172af9be2d3ab05cc0c4e9d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/CopyToFbShaderRD/8668028c5ceed89276611359329de4a0f5d40702546caecc31456f63f6f9ffe8/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/CopyToFbShaderRD/8668028c5ceed89276611359329de4a0f5d40702546caecc31456f63f6f9ffe8/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..123bb3e Binary files /dev/null and b/.godot/shader_cache/CopyToFbShaderRD/8668028c5ceed89276611359329de4a0f5d40702546caecc31456f63f6f9ffe8/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/CubeToDpShaderRD/e3db5adc31b15e80112f4d7497dc8563c39b7d64675a53dcce7f9511c5ca9f80/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/CubeToDpShaderRD/e3db5adc31b15e80112f4d7497dc8563c39b7d64675a53dcce7f9511c5ca9f80/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..f5533eb Binary files /dev/null and b/.godot/shader_cache/CubeToDpShaderRD/e3db5adc31b15e80112f4d7497dc8563c39b7d64675a53dcce7f9511c5ca9f80/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/CubemapDownsamplerShaderRD/6376d8aae8d25aa5fed14d9e78a76a69c5566f021773d2b38defa77a573b20f1/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/CubemapDownsamplerShaderRD/6376d8aae8d25aa5fed14d9e78a76a69c5566f021773d2b38defa77a573b20f1/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..875ac99 Binary files /dev/null and b/.godot/shader_cache/CubemapDownsamplerShaderRD/6376d8aae8d25aa5fed14d9e78a76a69c5566f021773d2b38defa77a573b20f1/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/CubemapFilterShaderRD/96fd6d20ed52761601cf4665fa909c5a27f13aeaa25940cf720f4e331158ef8e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/CubemapFilterShaderRD/96fd6d20ed52761601cf4665fa909c5a27f13aeaa25940cf720f4e331158ef8e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..5405da8 Binary files /dev/null and b/.godot/shader_cache/CubemapFilterShaderRD/96fd6d20ed52761601cf4665fa909c5a27f13aeaa25940cf720f4e331158ef8e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/CubemapRoughnessShaderRD/1d72ea29a087908b2262137858ecb047ac60acf75d2e625661f01be4ce0d3ce2/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/CubemapRoughnessShaderRD/1d72ea29a087908b2262137858ecb047ac60acf75d2e625661f01be4ce0d3ce2/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..23736a2 Binary files /dev/null and b/.godot/shader_cache/CubemapRoughnessShaderRD/1d72ea29a087908b2262137858ecb047ac60acf75d2e625661f01be4ce0d3ce2/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/FsrUpscaleShaderRD/362fc0b19d06cf68dc6f6f2d99e1f9ccfd8afaef2a65e38a931df5dd9e183d7d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/FsrUpscaleShaderRD/362fc0b19d06cf68dc6f6f2d99e1f9ccfd8afaef2a65e38a931df5dd9e183d7d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..225d236 Binary files /dev/null and b/.godot/shader_cache/FsrUpscaleShaderRD/362fc0b19d06cf68dc6f6f2d99e1f9ccfd8afaef2a65e38a931df5dd9e183d7d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/GiShaderRD/2b51ba5b3e4e6be7fc223f7517a8a8b80c61234f3fbd4ffa229da05d747f020a/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/GiShaderRD/2b51ba5b3e4e6be7fc223f7517a8a8b80c61234f3fbd4ffa229da05d747f020a/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..8002a07 Binary files /dev/null and b/.godot/shader_cache/GiShaderRD/2b51ba5b3e4e6be7fc223f7517a8a8b80c61234f3fbd4ffa229da05d747f020a/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/LuminanceReduceShaderRD/2687da76c0ac04fe197e7093fd065958200b5a2e8e378e0f61c445212a1a0ac4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/LuminanceReduceShaderRD/2687da76c0ac04fe197e7093fd065958200b5a2e8e378e0f61c445212a1a0ac4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..99a9238 Binary files /dev/null and b/.godot/shader_cache/LuminanceReduceShaderRD/2687da76c0ac04fe197e7093fd065958200b5a2e8e378e0f61c445212a1a0ac4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/MotionVectorsShaderRD/cbf3cbdcba0d0a2026c9fbf248556f1acd11beacc38a2e8c5ce7009ee49a1560/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/MotionVectorsShaderRD/cbf3cbdcba0d0a2026c9fbf248556f1acd11beacc38a2e8c5ce7009ee49a1560/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..c5d19a0 Binary files /dev/null and b/.godot/shader_cache/MotionVectorsShaderRD/cbf3cbdcba0d0a2026c9fbf248556f1acd11beacc38a2e8c5ce7009ee49a1560/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/ParticlesCopyShaderRD/69566a7b0235d75ec40f504cd5555856aace22b5273899269166fde57287d26e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/ParticlesCopyShaderRD/69566a7b0235d75ec40f504cd5555856aace22b5273899269166fde57287d26e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..b32d7d5 Binary files /dev/null and b/.godot/shader_cache/ParticlesCopyShaderRD/69566a7b0235d75ec40f504cd5555856aace22b5273899269166fde57287d26e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/ParticlesShaderRD/47fcf57848349fdf54197e5c1f64750a69c8d54787d3509ade4781c9faa31654/f128cab0b22fb7e0d9f023d6cdb81309be392d95.vulkan.cache b/.godot/shader_cache/ParticlesShaderRD/47fcf57848349fdf54197e5c1f64750a69c8d54787d3509ade4781c9faa31654/f128cab0b22fb7e0d9f023d6cdb81309be392d95.vulkan.cache new file mode 100644 index 0000000..410d67a Binary files /dev/null and b/.godot/shader_cache/ParticlesShaderRD/47fcf57848349fdf54197e5c1f64750a69c8d54787d3509ade4781c9faa31654/f128cab0b22fb7e0d9f023d6cdb81309be392d95.vulkan.cache differ diff --git a/.godot/shader_cache/ResolveShaderRD/4eed9a584e94b3db5e08b3dd178112267127e5cb55e97790e3791fff9eb617f7/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/ResolveShaderRD/4eed9a584e94b3db5e08b3dd178112267127e5cb55e97790e3791fff9eb617f7/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..d5b29c4 Binary files /dev/null and b/.godot/shader_cache/ResolveShaderRD/4eed9a584e94b3db5e08b3dd178112267127e5cb55e97790e3791fff9eb617f7/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/048236defb6bf03aff4593ae5e1ee179e6446005.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/048236defb6bf03aff4593ae5e1ee179e6446005.vulkan.cache new file mode 100644 index 0000000..5c9feec Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/048236defb6bf03aff4593ae5e1ee179e6446005.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/0f1bcf11b9f7757773a7866f1cd2e297cb2acf5f.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/0f1bcf11b9f7757773a7866f1cd2e297cb2acf5f.vulkan.cache new file mode 100644 index 0000000..6903a4b Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/0f1bcf11b9f7757773a7866f1cd2e297cb2acf5f.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/1d94d7653c04fb7febbe6df8d6c0f471ee8df8ed.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/1d94d7653c04fb7febbe6df8d6c0f471ee8df8ed.vulkan.cache new file mode 100644 index 0000000..cb1ecfe Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/1d94d7653c04fb7febbe6df8d6c0f471ee8df8ed.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/2b83ada958e476cf26531ce107fe1c0d75fac7be.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/2b83ada958e476cf26531ce107fe1c0d75fac7be.vulkan.cache new file mode 100644 index 0000000..434614d Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/2b83ada958e476cf26531ce107fe1c0d75fac7be.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/3ee92779f31d8b7471ea1440cef676bd33f29c3b.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/3ee92779f31d8b7471ea1440cef676bd33f29c3b.vulkan.cache new file mode 100644 index 0000000..3225d52 Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/3ee92779f31d8b7471ea1440cef676bd33f29c3b.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/484574d6966da5fa625415ab5c4d35d8a9fde9f7.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/484574d6966da5fa625415ab5c4d35d8a9fde9f7.vulkan.cache new file mode 100644 index 0000000..65ae503 Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/484574d6966da5fa625415ab5c4d35d8a9fde9f7.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/7fb66440f65dac23b75016fc52fb82ae26e9393f.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/7fb66440f65dac23b75016fc52fb82ae26e9393f.vulkan.cache new file mode 100644 index 0000000..8e2877d Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/7fb66440f65dac23b75016fc52fb82ae26e9393f.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/8c4a6577a4ef29bb59d10356dbe5e400d812d8bb.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/8c4a6577a4ef29bb59d10356dbe5e400d812d8bb.vulkan.cache new file mode 100644 index 0000000..ecbc741 Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/8c4a6577a4ef29bb59d10356dbe5e400d812d8bb.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/8eb7aeac3861680a0202f049c0bfdcf05b99b274.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/8eb7aeac3861680a0202f049c0bfdcf05b99b274.vulkan.cache new file mode 100644 index 0000000..0c0e1ef Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/8eb7aeac3861680a0202f049c0bfdcf05b99b274.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/a6d99b637dfee75712ae57f13dc63ae39e299a45.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/a6d99b637dfee75712ae57f13dc63ae39e299a45.vulkan.cache new file mode 100644 index 0000000..5e9f90d Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/a6d99b637dfee75712ae57f13dc63ae39e299a45.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/a8d4cef55e3ab1332d431b88da8465c79f0e608a.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/a8d4cef55e3ab1332d431b88da8465c79f0e608a.vulkan.cache new file mode 100644 index 0000000..d5f8666 Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/a8d4cef55e3ab1332d431b88da8465c79f0e608a.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/aa0086cc160e9e167e95546ad5eb0423d596c5b3.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/aa0086cc160e9e167e95546ad5eb0423d596c5b3.vulkan.cache new file mode 100644 index 0000000..a147885 Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/aa0086cc160e9e167e95546ad5eb0423d596c5b3.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/ab60f8b228c0dad11d9d882c2ab4f61eb6ca2f20.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/ab60f8b228c0dad11d9d882c2ab4f61eb6ca2f20.vulkan.cache new file mode 100644 index 0000000..0130bb5 Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/ab60f8b228c0dad11d9d882c2ab4f61eb6ca2f20.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/afe1c0449d843047874ee4b0dda3f797decb0436.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/afe1c0449d843047874ee4b0dda3f797decb0436.vulkan.cache new file mode 100644 index 0000000..8a75142 Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/afe1c0449d843047874ee4b0dda3f797decb0436.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/b7b2f398c116e26c751517dd8d44535f700f825f.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/b7b2f398c116e26c751517dd8d44535f700f825f.vulkan.cache new file mode 100644 index 0000000..227abf6 Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/b7b2f398c116e26c751517dd8d44535f700f825f.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/c4c828897f8a3fe72e3713d35b4ba452d7ed9acf.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/c4c828897f8a3fe72e3713d35b4ba452d7ed9acf.vulkan.cache new file mode 100644 index 0000000..7d99e5e Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/c4c828897f8a3fe72e3713d35b4ba452d7ed9acf.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/c911b2eb203b7525047b1fc26929407fb3d4191d.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/c911b2eb203b7525047b1fc26929407fb3d4191d.vulkan.cache new file mode 100644 index 0000000..e9b0f31 Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/c911b2eb203b7525047b1fc26929407fb3d4191d.vulkan.cache differ diff --git a/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/fe8dec228868b5370e5ab7c53602014f601705fc.vulkan.cache b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/fe8dec228868b5370e5ab7c53602014f601705fc.vulkan.cache new file mode 100644 index 0000000..da84af9 Binary files /dev/null and b/.godot/shader_cache/SceneForwardClusteredShaderRD/29edc2f36233c2e08b9662507bec9ae15ecd3ff18670dd6a9d9e3c22bb80d2b9/fe8dec228868b5370e5ab7c53602014f601705fc.vulkan.cache differ diff --git a/.godot/shader_cache/ScreenSpaceReflectionFilterShaderRD/dbd56507c7ba6e4548ad94d4267e97184ea703036185204db88001c82b622120/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/ScreenSpaceReflectionFilterShaderRD/dbd56507c7ba6e4548ad94d4267e97184ea703036185204db88001c82b622120/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..0afdc7a Binary files /dev/null and b/.godot/shader_cache/ScreenSpaceReflectionFilterShaderRD/dbd56507c7ba6e4548ad94d4267e97184ea703036185204db88001c82b622120/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/ScreenSpaceReflectionScaleShaderRD/e5b92b2248f95dfc9534e9d5ec71a9d1fedfe58dd8fbbb2e903d8606c1ed8e0c/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/ScreenSpaceReflectionScaleShaderRD/e5b92b2248f95dfc9534e9d5ec71a9d1fedfe58dd8fbbb2e903d8606c1ed8e0c/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..3b869a2 Binary files /dev/null and b/.godot/shader_cache/ScreenSpaceReflectionScaleShaderRD/e5b92b2248f95dfc9534e9d5ec71a9d1fedfe58dd8fbbb2e903d8606c1ed8e0c/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/ScreenSpaceReflectionShaderRD/722d4571bebbe24c59b13360d89825ac27099da739a27f42e20a004e5e92da73/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/ScreenSpaceReflectionShaderRD/722d4571bebbe24c59b13360d89825ac27099da739a27f42e20a004e5e92da73/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..9b2ca2b Binary files /dev/null and b/.godot/shader_cache/ScreenSpaceReflectionShaderRD/722d4571bebbe24c59b13360d89825ac27099da739a27f42e20a004e5e92da73/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SdfgiDebugProbesShaderRD/41af92f24cfffd1d870ed50e96e7ae1bfd6c2cc11f728d520ef0a827972a1438/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SdfgiDebugProbesShaderRD/41af92f24cfffd1d870ed50e96e7ae1bfd6c2cc11f728d520ef0a827972a1438/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..e505c1d Binary files /dev/null and b/.godot/shader_cache/SdfgiDebugProbesShaderRD/41af92f24cfffd1d870ed50e96e7ae1bfd6c2cc11f728d520ef0a827972a1438/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SdfgiDebugShaderRD/372719c6eef32a8635d4db9b69f2f8b01b907642dbac0cc26f37ea2a76eeb95d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SdfgiDebugShaderRD/372719c6eef32a8635d4db9b69f2f8b01b907642dbac0cc26f37ea2a76eeb95d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..c4cabde Binary files /dev/null and b/.godot/shader_cache/SdfgiDebugShaderRD/372719c6eef32a8635d4db9b69f2f8b01b907642dbac0cc26f37ea2a76eeb95d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SdfgiDirectLightShaderRD/803c48e266e0d9c1590d25424071a668b88abc76bcda6fdde74b8524f298683c/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SdfgiDirectLightShaderRD/803c48e266e0d9c1590d25424071a668b88abc76bcda6fdde74b8524f298683c/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..48d7628 Binary files /dev/null and b/.godot/shader_cache/SdfgiDirectLightShaderRD/803c48e266e0d9c1590d25424071a668b88abc76bcda6fdde74b8524f298683c/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SdfgiIntegrateShaderRD/4647045d5ae8023ab209178c191d003ce94a58384c2bf158dfd5d1b256a1feb2/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SdfgiIntegrateShaderRD/4647045d5ae8023ab209178c191d003ce94a58384c2bf158dfd5d1b256a1feb2/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..986346f Binary files /dev/null and b/.godot/shader_cache/SdfgiIntegrateShaderRD/4647045d5ae8023ab209178c191d003ce94a58384c2bf158dfd5d1b256a1feb2/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SdfgiPreprocessShaderRD/42b3acb8f8f580e0ad8624239eada43680eb33d7a90e0279cf34b99bad80ffc9/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SdfgiPreprocessShaderRD/42b3acb8f8f580e0ad8624239eada43680eb33d7a90e0279cf34b99bad80ffc9/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..1450ab0 Binary files /dev/null and b/.godot/shader_cache/SdfgiPreprocessShaderRD/42b3acb8f8f580e0ad8624239eada43680eb33d7a90e0279cf34b99bad80ffc9/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/ShadowFrustumShaderRD/c9c1b6421f8f6625effc9ddfa4bb2c09cafda0942b62fb8e1414e90820e18fa0/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/ShadowFrustumShaderRD/c9c1b6421f8f6625effc9ddfa4bb2c09cafda0942b62fb8e1414e90820e18fa0/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..c396356 Binary files /dev/null and b/.godot/shader_cache/ShadowFrustumShaderRD/c9c1b6421f8f6625effc9ddfa4bb2c09cafda0942b62fb8e1414e90820e18fa0/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SkeletonShaderRD/4964fd59acf4406110ae7bca4b716f23ae52cc19864e21a8a35aee53e141e17e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SkeletonShaderRD/4964fd59acf4406110ae7bca4b716f23ae52cc19864e21a8a35aee53e141e17e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..027255e Binary files /dev/null and b/.godot/shader_cache/SkeletonShaderRD/4964fd59acf4406110ae7bca4b716f23ae52cc19864e21a8a35aee53e141e17e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/03e3b11c69e24394b2d955a8c0ba85587bb70839.vulkan.cache b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/03e3b11c69e24394b2d955a8c0ba85587bb70839.vulkan.cache new file mode 100644 index 0000000..a4f02a5 Binary files /dev/null and b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/03e3b11c69e24394b2d955a8c0ba85587bb70839.vulkan.cache differ diff --git a/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/0a0fb987bd6ede673a5edeb59834f887758ae2a6.vulkan.cache b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/0a0fb987bd6ede673a5edeb59834f887758ae2a6.vulkan.cache new file mode 100644 index 0000000..e7b1c49 Binary files /dev/null and b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/0a0fb987bd6ede673a5edeb59834f887758ae2a6.vulkan.cache differ diff --git a/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/1ec4b939427d7d13a35915081fffc339985e7d72.vulkan.cache b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/1ec4b939427d7d13a35915081fffc339985e7d72.vulkan.cache new file mode 100644 index 0000000..b515f1e Binary files /dev/null and b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/1ec4b939427d7d13a35915081fffc339985e7d72.vulkan.cache differ diff --git a/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/301c34f080b0d9fb9ff1c17636ea175173a43e1c.vulkan.cache b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/301c34f080b0d9fb9ff1c17636ea175173a43e1c.vulkan.cache new file mode 100644 index 0000000..82e2245 Binary files /dev/null and b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/301c34f080b0d9fb9ff1c17636ea175173a43e1c.vulkan.cache differ diff --git a/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/b5b8e4ba80a00c01ba3057eaf7b6778733fb4cd6.vulkan.cache b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/b5b8e4ba80a00c01ba3057eaf7b6778733fb4cd6.vulkan.cache new file mode 100644 index 0000000..e3f6996 Binary files /dev/null and b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/b5b8e4ba80a00c01ba3057eaf7b6778733fb4cd6.vulkan.cache differ diff --git a/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/de678811d1bad3cad4892a8db7b6ea0be197d51d.vulkan.cache b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/de678811d1bad3cad4892a8db7b6ea0be197d51d.vulkan.cache new file mode 100644 index 0000000..4a10b42 Binary files /dev/null and b/.godot/shader_cache/SkyShaderRD/4bc541bfde1c30032df77bb4c98974909ad0368d22557f44e6cf095b26c0490a/de678811d1bad3cad4892a8db7b6ea0be197d51d.vulkan.cache differ diff --git a/.godot/shader_cache/SortShaderRD/0b1e36114ab5330dc340cc740b0b946ed2dbf43098119b8d29cfa0222da18b7a/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SortShaderRD/0b1e36114ab5330dc340cc740b0b946ed2dbf43098119b8d29cfa0222da18b7a/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..159e5e4 Binary files /dev/null and b/.godot/shader_cache/SortShaderRD/0b1e36114ab5330dc340cc740b0b946ed2dbf43098119b8d29cfa0222da18b7a/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SpecularMergeShaderRD/a119881bb41d0ec2f36a7f060866ec38b88afa6d0e484a431c65b35b5a2e820b/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SpecularMergeShaderRD/a119881bb41d0ec2f36a7f060866ec38b88afa6d0e484a431c65b35b5a2e820b/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..a4e3a3a Binary files /dev/null and b/.godot/shader_cache/SpecularMergeShaderRD/a119881bb41d0ec2f36a7f060866ec38b88afa6d0e484a431c65b35b5a2e820b/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SsEffectsDownsampleShaderRD/d85ba7758123b2364d96690db4594bb43feabce176805e46abc91aa54c5874d4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SsEffectsDownsampleShaderRD/d85ba7758123b2364d96690db4594bb43feabce176805e46abc91aa54c5874d4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..ca0d247 Binary files /dev/null and b/.godot/shader_cache/SsEffectsDownsampleShaderRD/d85ba7758123b2364d96690db4594bb43feabce176805e46abc91aa54c5874d4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SsaoBlurShaderRD/32baf23e3ccb90d5c6840258a705d953d950a779d125df3b5bb979bd1309f4d4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SsaoBlurShaderRD/32baf23e3ccb90d5c6840258a705d953d950a779d125df3b5bb979bd1309f4d4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..558a022 Binary files /dev/null and b/.godot/shader_cache/SsaoBlurShaderRD/32baf23e3ccb90d5c6840258a705d953d950a779d125df3b5bb979bd1309f4d4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SsaoImportanceMapShaderRD/6d680b1500cda48a2de67225a98a208373d657c0f128c9e34a1528b50b3c2c5b/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SsaoImportanceMapShaderRD/6d680b1500cda48a2de67225a98a208373d657c0f128c9e34a1528b50b3c2c5b/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..8ac0d4b Binary files /dev/null and b/.godot/shader_cache/SsaoImportanceMapShaderRD/6d680b1500cda48a2de67225a98a208373d657c0f128c9e34a1528b50b3c2c5b/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SsaoInterleaveShaderRD/d3d5b300acaef6d08dcd3d033f393c424ad653c5ab554883703c29ee6eedf528/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SsaoInterleaveShaderRD/d3d5b300acaef6d08dcd3d033f393c424ad653c5ab554883703c29ee6eedf528/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..d20494e Binary files /dev/null and b/.godot/shader_cache/SsaoInterleaveShaderRD/d3d5b300acaef6d08dcd3d033f393c424ad653c5ab554883703c29ee6eedf528/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SsaoShaderRD/10348af53d51e568e9a1574f4be3c4bc66eb9b2b464c8e4f061d051e1a6c4de9/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SsaoShaderRD/10348af53d51e568e9a1574f4be3c4bc66eb9b2b464c8e4f061d051e1a6c4de9/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..9ac6c06 Binary files /dev/null and b/.godot/shader_cache/SsaoShaderRD/10348af53d51e568e9a1574f4be3c4bc66eb9b2b464c8e4f061d051e1a6c4de9/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SsilBlurShaderRD/dc4c027d65e080b2b5b1af257e3733c6bc35899ce02c3f333249db264836bd41/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SsilBlurShaderRD/dc4c027d65e080b2b5b1af257e3733c6bc35899ce02c3f333249db264836bd41/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..1a8bce4 Binary files /dev/null and b/.godot/shader_cache/SsilBlurShaderRD/dc4c027d65e080b2b5b1af257e3733c6bc35899ce02c3f333249db264836bd41/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SsilImportanceMapShaderRD/abbec59f40ae844d9bbca6d058972ef757a0baf48cdf91ef5836a8960f11569e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SsilImportanceMapShaderRD/abbec59f40ae844d9bbca6d058972ef757a0baf48cdf91ef5836a8960f11569e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..4639667 Binary files /dev/null and b/.godot/shader_cache/SsilImportanceMapShaderRD/abbec59f40ae844d9bbca6d058972ef757a0baf48cdf91ef5836a8960f11569e/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SsilInterleaveShaderRD/76868dec9e116ecbddcf9a480d808d2509e42cf65d5f7182e4f4cad2e24c9c70/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SsilInterleaveShaderRD/76868dec9e116ecbddcf9a480d808d2509e42cf65d5f7182e4f4cad2e24c9c70/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..462a00f Binary files /dev/null and b/.godot/shader_cache/SsilInterleaveShaderRD/76868dec9e116ecbddcf9a480d808d2509e42cf65d5f7182e4f4cad2e24c9c70/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SsilShaderRD/20c3a95a7a0528ebb5844939feeb8fe446ac0dcde9d011e24c2fc54af67e6c6d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SsilShaderRD/20c3a95a7a0528ebb5844939feeb8fe446ac0dcde9d011e24c2fc54af67e6c6d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..eb127b6 Binary files /dev/null and b/.godot/shader_cache/SsilShaderRD/20c3a95a7a0528ebb5844939feeb8fe446ac0dcde9d011e24c2fc54af67e6c6d/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/SubsurfaceScatteringShaderRD/43df2517be4d76d26d345b88762bb6d272983e54f79d503331a085ec082a97da/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/SubsurfaceScatteringShaderRD/43df2517be4d76d26d345b88762bb6d272983e54f79d503331a085ec082a97da/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..bd28536 Binary files /dev/null and b/.godot/shader_cache/SubsurfaceScatteringShaderRD/43df2517be4d76d26d345b88762bb6d272983e54f79d503331a085ec082a97da/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/TaaResolveShaderRD/66482a84ae3398a2cbd07e92185df239a902d24d388424e0dff9fe998af3c0b4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/TaaResolveShaderRD/66482a84ae3398a2cbd07e92185df239a902d24d388424e0dff9fe998af3c0b4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..a2577ab Binary files /dev/null and b/.godot/shader_cache/TaaResolveShaderRD/66482a84ae3398a2cbd07e92185df239a902d24d388424e0dff9fe998af3c0b4/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/TonemapShaderRD/1c4748b3de350503048a1f9eca4f1dc2b308086460692ea0a81bababfd80542a/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/TonemapShaderRD/1c4748b3de350503048a1f9eca4f1dc2b308086460692ea0a81bababfd80542a/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..df8c8ad Binary files /dev/null and b/.godot/shader_cache/TonemapShaderRD/1c4748b3de350503048a1f9eca4f1dc2b308086460692ea0a81bababfd80542a/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/VolumetricFogProcessShaderRD/2c2d7b3b51e66f06069290afb842fc1ee9ee4f60f06a5168b0cee5bd380366bc/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/VolumetricFogProcessShaderRD/2c2d7b3b51e66f06069290afb842fc1ee9ee4f60f06a5168b0cee5bd380366bc/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..50b9908 Binary files /dev/null and b/.godot/shader_cache/VolumetricFogProcessShaderRD/2c2d7b3b51e66f06069290afb842fc1ee9ee4f60f06a5168b0cee5bd380366bc/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/VolumetricFogShaderRD/22de546a38a6b3caaa1d02360e0e62d85133e560e5667f2f3f5e34e3145679af/9a227745af2d65830f930370a9fbba551fbd6f60.vulkan.cache b/.godot/shader_cache/VolumetricFogShaderRD/22de546a38a6b3caaa1d02360e0e62d85133e560e5667f2f3f5e34e3145679af/9a227745af2d65830f930370a9fbba551fbd6f60.vulkan.cache new file mode 100644 index 0000000..563015d Binary files /dev/null and b/.godot/shader_cache/VolumetricFogShaderRD/22de546a38a6b3caaa1d02360e0e62d85133e560e5667f2f3f5e34e3145679af/9a227745af2d65830f930370a9fbba551fbd6f60.vulkan.cache differ diff --git a/.godot/shader_cache/VoxelGiDebugShaderRD/83ec08f78c119345f086a6cbcb0da5d67f664d19fd7ba3259c4948638b76fb8c/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/VoxelGiDebugShaderRD/83ec08f78c119345f086a6cbcb0da5d67f664d19fd7ba3259c4948638b76fb8c/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..4dfc758 Binary files /dev/null and b/.godot/shader_cache/VoxelGiDebugShaderRD/83ec08f78c119345f086a6cbcb0da5d67f664d19fd7ba3259c4948638b76fb8c/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/VoxelGiShaderRD/8bfb40cf41510d02f432927249e4d6d6708843a0953b4faf61a2f2e3786d4fd0/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/VoxelGiShaderRD/8bfb40cf41510d02f432927249e4d6d6708843a0953b4faf61a2f2e3786d4fd0/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..ecc698f Binary files /dev/null and b/.godot/shader_cache/VoxelGiShaderRD/8bfb40cf41510d02f432927249e4d6d6708843a0953b4faf61a2f2e3786d4fd0/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/shader_cache/VrsShaderRD/def705023965d273a669c1ac6acfd7494138bde25b3e3bde0969c3c7a32c3aae/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache b/.godot/shader_cache/VrsShaderRD/def705023965d273a669c1ac6acfd7494138bde25b3e3bde0969c3c7a32c3aae/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache new file mode 100644 index 0000000..d03fb39 Binary files /dev/null and b/.godot/shader_cache/VrsShaderRD/def705023965d273a669c1ac6acfd7494138bde25b3e3bde0969c3c7a32c3aae/087916079fba7c625e62b0c2cca570e0fb87c99a.vulkan.cache differ diff --git a/.godot/uid_cache.bin b/.godot/uid_cache.bin new file mode 100644 index 0000000..0b5f9fc Binary files /dev/null and b/.godot/uid_cache.bin differ diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..cf6c0f4 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,130 @@ +# Change Log +All notable changes to this project are documented below. + +The format is based on [keep a changelog](http://keepachangelog.com/) and this project uses [semantic versioning](http://semver.org/). + +## [3.3.1] - 2023-04-17 + +### Fixed + +- Fix arguments for HTTPRequest.request() for beta17 +- Fix typehints for enums in Godot 4.0-rc1 +- Fix type check and typehint for Godot 4.0-rc3 +- Fix null byte array error in GodotHttpAdapter for C# + +## [3.3.0] - 2023-01-30 + +### Added + +- Add support for subscription validation APIs that were added in Nakama v3.13.0 +- Add support for sending events +- Allow disabling threads for making HTTP requests +- Add support for delete_account_sync() and other API changes that were added in Nakama v3.15.0 + +## [3.2.0] - 2022-08-30 + +### Fixed + +- Fix NakamaSocket.add_matchmaker_party_async() and the tests for it +- Fix MatchData.op_code type in schema to TYPE_INT +- Fix circular reference in Nakama singleton to itself + +### Added + +- Add support for receiving binary data in "NakamaRTAPI.MatchState" +- Add support for sending and receiving binary data in "NakamaRTAPI.PartyData" +- Add NakamaMultiplayerBridge to integrate with Godot's High-Level Multiplayer API + +## [3.1.0] - 2022-04-28 + +### Added + +- Expose the "seen_before" property on "NakamaAPI.ApiValidatedPurchase" +- Add support for creating match by name +- Add support for "count_multple" on "NakamaSocket.add_matchmaker_async()" and "NakamaSocket.add_matchmaker_party_async()" +- Add C# support classes to better integrate the .NET client with the Mono version of Godot, allowing HTML5 exports to work + +### Fixed + +- Fix receiving "NakamaRTAPI.PartyClose" message +- Fix sending and receiving of PartyData + +## [3.0.0] - 2022-03-28 + +### Added + +- Add realtime party support. +- Add purchase validation functions. +- Add Apple authentication functions. +- Add "demote_group_users_async" function. +- A session can be refreshed on demand with "session_refresh_async" method. +- Session and/or refresh tokens can now be invalidated with a client logout. +- The client now supports session auto-refresh using refresh tokens. This is enabled by default. +- The client now supports auto-retrying failed request due to network error. This is enabled by defulut. +- The client now support cancelling requests in-flight via "client.cancel_request". + +### Fixed + +- Fix Dictionary serialization (e.g. "NakamaSocket.add_matchmaker_async" "p_string_props" and "p_numeric_props"). +- Pass join metadata onwards into match join message. +- Don't stop processing messages when the game is paused. +- Fix "rpc_async", "rpc_async_with_key". Now uses GET request only if no payload is passed. +- Fix client errors parsing in Nakama 3.x +- Make it possible to omit the label and query on NakamaClient.list_matches_async(). + +### Backwards incompatible changes + +- The "received_error" signal on "NakamaSocket" is now emited with an "NakamaRTAPI.Error" object received from the server. + Previously, it was emitted with an integer error code when the socket failed to connect. + If you have old code using the "received_error" signal, you can switch to the new "connection_error" signal, which was added to replace it. + +## [2.1.0] - 2020-08-01 + +### Added + +- Add an optional log level parameter to "Nakama.create_client". + +### Changed + +- Update variable definitions to new gdscript variable controls. + +### Fixed + +- Fix "add_friends_async" should have its "id" field input as optional. +- Fix "add_matchmaker_async" and "MatchmakerAdd" parameter assignment. +- Fix missing "presence" property in NakamaRTAPI.MatchData. +- Fix NakamaSocket not emitting "received_error" correctly. +- Fix "DEFAULT_LOG_LEVEL" in Nakama.gd not doing anything. + +## [2.0.0] - 2020-04-02 + +### Added + +- Decode base64 data in "MatchData". (breaks compat) +- Add "FacebookInstantGame" endpoints (link/unlink/authenticate). +- GDScript-style comments (removing all XML tags). +- Add "list_storage_objects_async" "p_user_id" parameter to allow listing user(s) objects. + +### Fixed + +- Fix encoding of "op_code" in "MatchDataSend" and marshalling of "NakamaSocket.send_match_state_[raw_]async". +- Fix parsing of "MatchmakerMatched" messages when no token is specified. +- Disable "HTTPRequest.use_threads" in HTML5 exports. +- "NakamaSession.is_expired" returned reversed result. +- Fix "NakamaClient.update_account_async" to allow updating account without username change. +- Fix "NakamaClient.update_group_async" to allow updating group without name change. +- Fix "HTTPAdapter._send_async" error catching for some edge cases. +- Fix "NakamaClient.send_rpc_async" with empty payload (will send empty string now). +- Fix "NakamaRTAPI.Status" parsing. +- Fix "NakamaClient" "list_leaderboard_records_around_owner_async" and "list_leaderboard_records_async" parameter order. (breaks compat) +- Rename "NakamaClient.JoinTournamentAsync" to "join_tournament_async" for consistent naming. +- Update all "p_limit" parameters default in "NakamaClient" to "10". +- Fix "NakamaRTAPI.Stream" parsing. + +## [1.0.0] - 2020-01-28 +### Added +- Initial public release. +- Client API implementation. +- Realtime Socket implementation. +- Helper singleton. +- Setup instructions. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..6b0b127 --- /dev/null +++ b/LICENSE @@ -0,0 +1,203 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + diff --git a/README.md b/README.md new file mode 100644 index 0000000..ff0a26f --- /dev/null +++ b/README.md @@ -0,0 +1,320 @@ +Nakama Godot +=========== + +> Godot client for Nakama server written in GDScript. + +[Nakama](https://github.com/heroiclabs/nakama) is an open-source server designed to power modern games and apps. Features include user accounts, chat, social, matchmaker, realtime multiplayer, and much [more](https://heroiclabs.com). + +This client implements the full API and socket options with the server. It's written in GDScript to support Godot Engine `4.0+`. + +Full documentation is online - https://heroiclabs.com/docs + +## Godot 3 & 4 + +You're currently looking at the Godot 4 version of the Nakama client for Godot. + +If you are using Godot 3, you need to use the ['master' +branch](https://github.com/heroiclabs/nakama-godot/tree/godot-4) on GitHub. + +## Getting Started + +You'll need to setup the server and database before you can connect with the client. The simplest way is to use Docker but have a look at the [server documentation](https://github.com/heroiclabs/nakama#getting-started) for other options. + +1. Install and run the servers. Follow these [instructions](https://heroiclabs.com/docs/install-docker-quickstart). + +2. Download the client from the [releases page](https://github.com/heroiclabs/nakama-godot/releases) and import it into your project. You can also [download it from the asset repository](#asset-repository). + +3. Add the `Nakama.gd` singleton (in `addons/com.heroiclabs.nakama/`) as an [autoload in Godot](https://docs.godotengine.org/en/stable/getting_started/step_by_step/singletons_autoload.html). + +4. Use the connection credentials to build a client object using the singleton. + + ```gdscript + extends Node + + func _ready(): + var scheme = "http" + var host = "127.0.0.1" + var port = 7350 + var server_key = "defaultkey" + var client := Nakama.create_client(server_key, host, port, scheme) + ``` + +## Usage + +The client object has many methods to execute various features in the server or open realtime socket connections with the server. + +### Authenticate + +There's a variety of ways to [authenticate](https://heroiclabs.com/docs/authentication) with the server. Authentication can create a user if they don't already exist with those credentials. It's also easy to authenticate with a social profile from Google Play Games, Facebook, Game Center, etc. + +```gdscript + var email = "super@heroes.com" + var password = "batsignal" + # Use 'await' to wait for the request to complete. + var session : NakamaSession = await client.authenticate_email_async(email, password) + print(session) +``` + +### Sessions + +When authenticated the server responds with an auth token (JWT) which contains useful properties and gets deserialized into a `NakamaSession` object. + +```gdscript + print(session.token) # raw JWT token + print(session.user_id) + print(session.username) + print("Session has expired: %s" % session.expired) + print("Session expires at: %s" % session.expire_time) +``` + +It is recommended to store the auth token from the session and check at startup if it has expired. If the token has expired you must reauthenticate. The expiry time of the token can be changed as a setting in the server. + +```gdscript + var authtoken = "restored from somewhere" + var session2 = NakamaClient.restore_session(authtoken) + if session2.expired: + print("Session has expired. Must reauthenticate!") +``` + +NOTE: The length of the lifetime of a session can be changed on the server with the `--session.token_expiry_sec` command flag argument. + +### Requests + +The client includes lots of builtin APIs for various features of the game server. These can be accessed with the async methods. It can also call custom logic in RPC functions on the server. These can also be executed with a socket object. + +All requests are sent with a session object which authorizes the client. + +```gdscript + var account = await client.get_account_async(session) + print(account.user.id) + print(account.user.username) + print(account.wallet) +``` + +### Exceptions + +Since Godot Engine does not support exceptions, whenever you make an async request via the client or socket, you can check if an error occurred via the `is_exception()` method. + +```gdscript + var an_invalid_session = NakamaSession.new() # An empty session, which will cause and error when we use it. + var account2 = await client.get_account_async(an_invalid_session) + print(account2) # This will print the exception + if account2.is_exception(): + print("We got an exception") +``` + +### Socket + +The client can create one or more sockets with the server. Each socket can have it's own event listeners registered for responses received from the server. + +```gdscript + var socket = Nakama.create_socket_from(client) + socket.connected.connect(self._on_socket_connected) + socket.closed.connect(self._on_socket_closed) + socket.received_error.connect(self._on_socket_error) + await socket.connect_async(session) + print("Done") + +func _on_socket_connected(): + print("Socket connected.") + +func _on_socket_closed(): + print("Socket closed.") + +func _on_socket_error(err): + printerr("Socket error %s" % err) +``` + +## Integration with Godot's High-level Multiplayer API + +Godot provides a [High-level Multiplayer +API](https://docs.godotengine.org/en/latest/tutorials/networking/high_level_multiplayer.html), +allowing developers to make RPCs, calling functions that run on other peers in +a multiplayer match. + +For example: + +```gdscript +func _process(delta): + if not is_multiplayer_authority(): + return + + var input_vector = get_input_vector() + + # Move the player locally. + velocity = input_vector * SPEED + move_and_slide() + + # Then update the player's position on all other connected clients. + update_remote_position.rpc(position) + +@rpc(any_peer) +func update_remote_position(new_position): + position = new_position +``` + +Godot provides a number of built-in backends for sending the RPCs, including: +ENet, WebSockets, and WebRTC. + +However, you can also use the Nakama client as a backend! This can allow you to +continue using Godot's familiar High-level Multiplayer API, but with the RPCs +transparently sent over a realtime Nakama match. + +To do that, you need to use the `NakamaMultiplayerBridge` class: + +```gdscript +var multiplayer_bridge + +func _ready(): + # [...] + # You must have a working 'socket', created as described above. + + multiplayer_bridge = NakamaMultiplayerBridge.new(socket) + multiplayer_bridge.match_join_error.connect(self._on_match_join_error) + multiplayer_bridge.match_joined.connect(self._on_match_joined) + get_tree().get_multiplayer().set_multiplayer_peer(multiplayer_bridge.multiplayer_peer) + +func _on_match_join_error(error): + print ("Unable to join match: ", error.message) + +func _on_match_join() -> void: + print ("Joined match with id: ", multiplayer_bridge.match_id) +``` + +You can also connect to any of the usual signals on `MultiplayerAPI`, for +example: + +```gdscript + get_tree().get_multiplayer().peer_connected.connect(self._on_peer_connected) + get_tree().get_multiplayer().peer_disconnected.connect(self._on_peer_disconnected) + +func _on_peer_connected(peer_id): + print ("Peer joined match: ", peer_id) + +func _on_peer_disconnected(peer_id): + print ("Peer left match: ", peer_id) +``` + +Then you need to join a match, using one of the following methods: + +- Create a new private match, with your client as the host. + ```gdscript + multiplayer_bridge.create_match() + ``` + +- Join a private match. + ```gdscript + multiplayer_bridge.join_match(match_id) + ``` + +- Create or join a private match with the given name. + ```gdscript + multiplayer_bridge.join_named_match(match_name) + ``` + +- Use the matchmaker to find and join a public match. + ```gdscript + var ticket = await socket.add_matchmaker_async() + if ticket.is_exception(): + print ("Error joining matchmaking pool: ", ticket.get_exception().message) + return + + multiplayer_bridge.start_matchmaking(ticket) + ``` + +After the the "match_joined" signal is emitted, you can start sending RPCs as +usual with the `rpc()` function, and calling any other functions associated with +the High-level Multiplayer API, such as `get_tree().get_multiplayer().get_unique_id()` +and `node.set_network_authority(peer_id)` and `node.is_network_authority()`. + +## .NET / C# + +If you're using the .NET version of Godot with C# support, you can use the +[Nakama .NET client](https://github.com/heroiclabs/nakama-dotnet/), which can be +installed via NuGet: + +``` +dotnet add package NakamaClient +``` + +This addon includes some C# classes for use with the .NET client, to provide deeper +integration with Godot: + +- `GodotLogger`: A logger which prints to the Godot console. +- `GodotHttpAdapter`: An HTTP adapter which uses Godot's HTTPRequest node. +- `GodotWebSocketAdapter`: A socket adapter which uses Godot's WebSocketClient. + +Here's an example of how to use them: + +```csharp + var http_adapter = new GodotHttpAdapter(); + // It's a Node, so it needs to be added to the scene tree. + // Consider putting this in an autoload singleton so it won't go away unexpectedly. + AddChild(http_adapter); + + const string scheme = "http"; + const string host = "127.0.0.1"; + const int port = 7350; + const string serverKey = "defaultkey"; + + // Pass in the 'http_adapter' as the last argument. + var client = new Client(scheme, host, port, serverKey, http_adapter); + + // To log DEBUG messages to the Godot console. + client.Logger = new GodotLogger("Nakama", GodotLogger.LogLevel.DEBUG); + + ISession session; + try { + session = await client.AuthenticateDeviceAsync(OS.GetUniqueId(), "TestUser", true); + } + catch (ApiResponseException e) { + GD.PrintErr(e.ToString()); + return; + } + + var websocket_adapter = new GodotWebSocketAdapter(); + // Like the HTTP adapter, it's a Node, so it needs to be added to the scene tree. + // Consider putting this in an autoload singleton so it won't go away unexpectedly. + AddChild(websocket_adapter); + + // Pass in the 'websocket_adapter' as the last argument. + var socket = Socket.From(client, websocket_adapter); +``` + +**Note:** _The out-of-the-box Nakama .NET client will work fine with desktop builds of your game! However, it won't work with HTML5 builds, unless you use the `GodotHttpAdapter` and `GodotWebSocketAdapter` classes._ + +## Contribute + +The development roadmap is managed as GitHub issues and pull requests are welcome. If you're interested to improve the code please open an issue to discuss the changes or drop in and discuss it in the [community forum](https://forum.heroiclabs.com). + +### Run Tests + +To run tests you will need to run the server and database. Most tests are written as integration tests which execute against the server. A quick approach we use with our test workflow is to use the Docker compose file described in the [documentation](https://heroiclabs.com/docs/install-docker-quickstart). + +Additionally, you will need to copy (or symlink) the `addons` folder inside the `test_suite` folder. You can now run the `test_suite` project from the Godot Editor. + +To run the tests on a headless machine (without a GPU) you can download a copy of [Godot Headless](https://godotengine.org/download/server) and run it from the command line. + +To automate this procedure, move the headless binary to `test_suite/bin/godot.elf`, and run the tests via the `test_suite/run_tests.sh` shell script (exit code will report test failure/success). + +```shell +cd nakama +docker-compose -f ./docker-compose-postgres.yml up +cd .. +cd nakama-godot +sh test_suite/run_tests.sh +``` + +### Make a new release + +To make a new release ready for distribution, simply zip the addons folder recursively (possibly adding `CHANGELOG`, `LICENSE`, and `README.md` too). + +On unix systems, you can run the following command (replacing `$VERSION` with the desired version number). Remember to update the `CHANGELOG` file first. + +```shell +zip -r nakama-$VERSION.zip addons/ LICENSE CHANGELOG.md README.md +``` + +### License + +This project is licensed under the [Apache-2 License](https://github.com/heroiclabs/nakama-godot/blob/master/LICENSE). diff --git a/addons/com.heroiclabs.nakama/Nakama.gd b/addons/com.heroiclabs.nakama/Nakama.gd new file mode 100644 index 0000000..37781d4 --- /dev/null +++ b/addons/com.heroiclabs.nakama/Nakama.gd @@ -0,0 +1,61 @@ +@tool +extends Node + +# The default host address of the server. +const DEFAULT_HOST : String = "127.0.0.1" + +# The default port number of the server. +const DEFAULT_PORT : int = 7350 + +# The default timeout for the connections. +const DEFAULT_TIMEOUT = 3 + +# The default protocol scheme for the client connection. +const DEFAULT_CLIENT_SCHEME : String = "http" + +# The default protocol scheme for the socket connection. +const DEFAULT_SOCKET_SCHEME : String = "ws" + +# The default log level for the Nakama logger. +const DEFAULT_LOG_LEVEL = NakamaLogger.LOG_LEVEL.DEBUG + +var _http_adapter = null +var logger = NakamaLogger.new() + +func _ready() -> void: + process_mode = Node.PROCESS_MODE_ALWAYS + +func get_client_adapter() -> NakamaHTTPAdapter: + if _http_adapter == null: + _http_adapter = NakamaHTTPAdapter.new() + _http_adapter.logger = logger + _http_adapter.name = "NakamaHTTPAdapter" + add_child(_http_adapter) + return _http_adapter + +func create_socket_adapter() -> NakamaSocketAdapter: + var adapter = NakamaSocketAdapter.new() + adapter.name = "NakamaWebSocketAdapter" + adapter.logger = logger + add_child(adapter) + return adapter + +func create_client(p_server_key : String, + p_host : String = DEFAULT_HOST, + p_port : int = DEFAULT_PORT, + p_scheme : String = DEFAULT_CLIENT_SCHEME, + p_timeout : int = DEFAULT_TIMEOUT, + p_log_level : int = DEFAULT_LOG_LEVEL) -> NakamaClient: + logger._level = p_log_level + return NakamaClient.new(get_client_adapter(), p_server_key, p_scheme, p_host, p_port, p_timeout) + +func create_socket(p_host : String = DEFAULT_HOST, + p_port : int = DEFAULT_PORT, + p_scheme : String = DEFAULT_SOCKET_SCHEME) -> NakamaSocket: + return NakamaSocket.new(create_socket_adapter(), p_host, p_port, p_scheme, true) + +func create_socket_from(p_client : NakamaClient) -> NakamaSocket: + var scheme = "ws" + if p_client.scheme == "https": + scheme = "wss" + return NakamaSocket.new(create_socket_adapter(), p_client.host, p_client.port, scheme, true) diff --git a/addons/com.heroiclabs.nakama/api/NakamaAPI.gd b/addons/com.heroiclabs.nakama/api/NakamaAPI.gd new file mode 100644 index 0000000..fc680bd --- /dev/null +++ b/addons/com.heroiclabs.nakama/api/NakamaAPI.gd @@ -0,0 +1,6120 @@ +### Code generated by codegen/main.go. DO NOT EDIT. ### + +extends RefCounted +class_name NakamaAPI + +# A single user-role pair. +class GroupUserListGroupUser extends NakamaAsyncResult: + + const _SCHEMA = { + "state": {"name": "_state", "type": TYPE_INT, "required": false}, + "user": {"name": "_user", "type": "ApiUser", "required": false}, + } + + # Their relationship to the group. + var _state + var state : int: + get: + return 0 if not _state is int else int(_state) + + # User. + var _user + var user : ApiUser: + get: + return _user as ApiUser + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> GroupUserListGroupUser: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "GroupUserListGroupUser", p_dict), GroupUserListGroupUser) as GroupUserListGroupUser + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "state: %s, " % _state + output += "user: %s, " % _user + return output + +# A single group-role pair. +class UserGroupListUserGroup extends NakamaAsyncResult: + + const _SCHEMA = { + "group": {"name": "_group", "type": "ApiGroup", "required": false}, + "state": {"name": "_state", "type": TYPE_INT, "required": false}, + } + + # Group. + var _group + var group : ApiGroup: + get: + return _group as ApiGroup + + # The user's relationship to the group. + var _state + var state : int: + get: + return 0 if not _state is int else int(_state) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> UserGroupListUserGroup: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "UserGroupListUserGroup", p_dict), UserGroupListUserGroup) as UserGroupListUserGroup + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "group: %s, " % _group + output += "state: %s, " % _state + return output + +# Record values to write. +class WriteLeaderboardRecordRequestLeaderboardRecordWrite extends NakamaAsyncResult: + + const _SCHEMA = { + "metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false}, + "operator": {"name": "_operator", "type": TYPE_INT, "required": false}, + "score": {"name": "_score", "type": TYPE_STRING, "required": false}, + "subscore": {"name": "_subscore", "type": TYPE_STRING, "required": false}, + } + + # Optional record metadata. + var _metadata + var metadata : String: + get: + return "" if not _metadata is String else String(_metadata) + + # Operator override. + var _operator + var operator : int: + get: + return ApiOperator.values()[0] if not ApiOperator.values().has(_operator) else _operator + + # The score value to submit. + var _score + var score : String: + get: + return "" if not _score is String else String(_score) + + # An optional secondary value. + var _subscore + var subscore : String: + get: + return "" if not _subscore is String else String(_subscore) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> WriteLeaderboardRecordRequestLeaderboardRecordWrite: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "WriteLeaderboardRecordRequestLeaderboardRecordWrite", p_dict), WriteLeaderboardRecordRequestLeaderboardRecordWrite) as WriteLeaderboardRecordRequestLeaderboardRecordWrite + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "metadata: %s, " % _metadata + output += "operator: %s, " % _operator + output += "score: %s, " % _score + output += "subscore: %s, " % _subscore + return output + +# Record values to write. +class WriteTournamentRecordRequestTournamentRecordWrite extends NakamaAsyncResult: + + const _SCHEMA = { + "metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false}, + "operator": {"name": "_operator", "type": TYPE_INT, "required": false}, + "score": {"name": "_score", "type": TYPE_STRING, "required": false}, + "subscore": {"name": "_subscore", "type": TYPE_STRING, "required": false}, + } + + # A JSON object of additional properties (optional). + var _metadata + var metadata : String: + get: + return "" if not _metadata is String else String(_metadata) + + # Operator override. + var _operator + var operator : int: + get: + return ApiOperator.values()[0] if not ApiOperator.values().has(_operator) else _operator + + # The score value to submit. + var _score + var score : String: + get: + return "" if not _score is String else String(_score) + + # An optional secondary value. + var _subscore + var subscore : String: + get: + return "" if not _subscore is String else String(_subscore) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> WriteTournamentRecordRequestTournamentRecordWrite: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "WriteTournamentRecordRequestTournamentRecordWrite", p_dict), WriteTournamentRecordRequestTournamentRecordWrite) as WriteTournamentRecordRequestTournamentRecordWrite + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "metadata: %s, " % _metadata + output += "operator: %s, " % _operator + output += "score: %s, " % _score + output += "subscore: %s, " % _subscore + return output + +# A user with additional account details. Always the current user. +class ApiAccount extends NakamaAsyncResult: + + const _SCHEMA = { + "custom_id": {"name": "_custom_id", "type": TYPE_STRING, "required": false}, + "devices": {"name": "_devices", "type": TYPE_ARRAY, "required": false, "content": "ApiAccountDevice"}, + "disable_time": {"name": "_disable_time", "type": TYPE_STRING, "required": false}, + "email": {"name": "_email", "type": TYPE_STRING, "required": false}, + "user": {"name": "_user", "type": "ApiUser", "required": false}, + "verify_time": {"name": "_verify_time", "type": TYPE_STRING, "required": false}, + "wallet": {"name": "_wallet", "type": TYPE_STRING, "required": false}, + } + + # The custom id in the user's account. + var _custom_id + var custom_id : String: + get: + return "" if not _custom_id is String else String(_custom_id) + + # The devices which belong to the user's account. + var _devices + var devices : Array: + get: + return Array() if not _devices is Array else Array(_devices) + + # The UNIX time when the user's account was disabled/banned. + var _disable_time + var disable_time : String: + get: + return "" if not _disable_time is String else String(_disable_time) + + # The email address of the user. + var _email + var email : String: + get: + return "" if not _email is String else String(_email) + + # The user object. + var _user + var user : ApiUser: + get: + return _user as ApiUser + + # The UNIX time when the user's email was verified. + var _verify_time + var verify_time : String: + get: + return "" if not _verify_time is String else String(_verify_time) + + # The user's wallet data. + var _wallet + var wallet : String: + get: + return "" if not _wallet is String else String(_wallet) + + var _wallet_dict = null + var wallet_dict : Dictionary: + get: + if _wallet_dict == null: + if _wallet == null: + return {} + var json = JSON.new() + if json.parse(_wallet) != OK: + return {} + _wallet_dict = json.get_data() + return _wallet_dict as Dictionary + + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccount: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccount", p_dict), ApiAccount) as ApiAccount + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "custom_id: %s, " % _custom_id + output += "devices: %s, " % [_devices] + output += "disable_time: %s, " % _disable_time + output += "email: %s, " % _email + output += "user: %s, " % _user + output += "verify_time: %s, " % _verify_time + output += "wallet: %s, " % _wallet + return output + +# Send a Apple Sign In token to the server. Used with authenticate/link/unlink. +class ApiAccountApple extends NakamaAsyncResult: + + const _SCHEMA = { + "token": {"name": "_token", "type": TYPE_STRING, "required": false}, + "vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # The ID token received from Apple to validate. + var _token + var token : String: + get: + return "" if not _token is String else String(_token) + + # Extra information that will be bundled in the session token. + var _vars + var vars : Dictionary: + get: + return Dictionary() if not _vars is Dictionary else _vars.duplicate() + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountApple: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountApple", p_dict), ApiAccountApple) as ApiAccountApple + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "token: %s, " % _token + var map_string : String = "" + if typeof(_vars) == TYPE_DICTIONARY: + for k in _vars: + map_string += "{%s=%s}, " % [k, _vars[k]] + output += "vars: [%s], " % map_string + return output + +# Send a custom ID to the server. Used with authenticate/link/unlink. +class ApiAccountCustom extends NakamaAsyncResult: + + const _SCHEMA = { + "id": {"name": "_id", "type": TYPE_STRING, "required": false}, + "vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # A custom identifier. + var _id + var id : String: + get: + return "" if not _id is String else String(_id) + + # Extra information that will be bundled in the session token. + var _vars + var vars : Dictionary: + get: + return Dictionary() if not _vars is Dictionary else _vars.duplicate() + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountCustom: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountCustom", p_dict), ApiAccountCustom) as ApiAccountCustom + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "id: %s, " % _id + var map_string : String = "" + if typeof(_vars) == TYPE_DICTIONARY: + for k in _vars: + map_string += "{%s=%s}, " % [k, _vars[k]] + output += "vars: [%s], " % map_string + return output + +# Send a device to the server. Used with authenticate/link/unlink and user. +class ApiAccountDevice extends NakamaAsyncResult: + + const _SCHEMA = { + "id": {"name": "_id", "type": TYPE_STRING, "required": false}, + "vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # A device identifier. Should be obtained by a platform-specific device API. + var _id + var id : String: + get: + return "" if not _id is String else String(_id) + + # Extra information that will be bundled in the session token. + var _vars + var vars : Dictionary: + get: + return Dictionary() if not _vars is Dictionary else _vars.duplicate() + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountDevice: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountDevice", p_dict), ApiAccountDevice) as ApiAccountDevice + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "id: %s, " % _id + var map_string : String = "" + if typeof(_vars) == TYPE_DICTIONARY: + for k in _vars: + map_string += "{%s=%s}, " % [k, _vars[k]] + output += "vars: [%s], " % map_string + return output + +# Send an email with password to the server. Used with authenticate/link/unlink. +class ApiAccountEmail extends NakamaAsyncResult: + + const _SCHEMA = { + "email": {"name": "_email", "type": TYPE_STRING, "required": false}, + "password": {"name": "_password", "type": TYPE_STRING, "required": false}, + "vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # A valid RFC-5322 email address. + var _email + var email : String: + get: + return "" if not _email is String else String(_email) + + # A password for the user account. + var _password + var password : String: + get: + return "" if not _password is String else String(_password) + + # Extra information that will be bundled in the session token. + var _vars + var vars : Dictionary: + get: + return Dictionary() if not _vars is Dictionary else _vars.duplicate() + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountEmail: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountEmail", p_dict), ApiAccountEmail) as ApiAccountEmail + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "email: %s, " % _email + output += "password: %s, " % _password + var map_string : String = "" + if typeof(_vars) == TYPE_DICTIONARY: + for k in _vars: + map_string += "{%s=%s}, " % [k, _vars[k]] + output += "vars: [%s], " % map_string + return output + +# Send a Facebook token to the server. Used with authenticate/link/unlink. +class ApiAccountFacebook extends NakamaAsyncResult: + + const _SCHEMA = { + "token": {"name": "_token", "type": TYPE_STRING, "required": false}, + "vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # The OAuth token received from Facebook to access their profile API. + var _token + var token : String: + get: + return "" if not _token is String else String(_token) + + # Extra information that will be bundled in the session token. + var _vars + var vars : Dictionary: + get: + return Dictionary() if not _vars is Dictionary else _vars.duplicate() + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountFacebook: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountFacebook", p_dict), ApiAccountFacebook) as ApiAccountFacebook + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "token: %s, " % _token + var map_string : String = "" + if typeof(_vars) == TYPE_DICTIONARY: + for k in _vars: + map_string += "{%s=%s}, " % [k, _vars[k]] + output += "vars: [%s], " % map_string + return output + +# Send a Facebook Instant Game token to the server. Used with authenticate/link/unlink. +class ApiAccountFacebookInstantGame extends NakamaAsyncResult: + + const _SCHEMA = { + "signed_player_info": {"name": "_signed_player_info", "type": TYPE_STRING, "required": false}, + "vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # + var _signed_player_info + var signed_player_info : String: + get: + return "" if not _signed_player_info is String else String(_signed_player_info) + + # Extra information that will be bundled in the session token. + var _vars + var vars : Dictionary: + get: + return Dictionary() if not _vars is Dictionary else _vars.duplicate() + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountFacebookInstantGame: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountFacebookInstantGame", p_dict), ApiAccountFacebookInstantGame) as ApiAccountFacebookInstantGame + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "signed_player_info: %s, " % _signed_player_info + var map_string : String = "" + if typeof(_vars) == TYPE_DICTIONARY: + for k in _vars: + map_string += "{%s=%s}, " % [k, _vars[k]] + output += "vars: [%s], " % map_string + return output + +# Send Apple's Game Center account credentials to the server. Used with authenticate/link/unlink. +class ApiAccountGameCenter extends NakamaAsyncResult: + + const _SCHEMA = { + "bundle_id": {"name": "_bundle_id", "type": TYPE_STRING, "required": false}, + "player_id": {"name": "_player_id", "type": TYPE_STRING, "required": false}, + "public_key_url": {"name": "_public_key_url", "type": TYPE_STRING, "required": false}, + "salt": {"name": "_salt", "type": TYPE_STRING, "required": false}, + "signature": {"name": "_signature", "type": TYPE_STRING, "required": false}, + "timestamp_seconds": {"name": "_timestamp_seconds", "type": TYPE_STRING, "required": false}, + "vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # Bundle ID (generated by GameCenter). + var _bundle_id + var bundle_id : String: + get: + return "" if not _bundle_id is String else String(_bundle_id) + + # Player ID (generated by GameCenter). + var _player_id + var player_id : String: + get: + return "" if not _player_id is String else String(_player_id) + + # The URL for the public encryption key. + var _public_key_url + var public_key_url : String: + get: + return "" if not _public_key_url is String else String(_public_key_url) + + # A random "NSString" used to compute the hash and keep it randomized. + var _salt + var salt : String: + get: + return "" if not _salt is String else String(_salt) + + # The verification signature data generated. + var _signature + var signature : String: + get: + return "" if not _signature is String else String(_signature) + + # Time since UNIX epoch when the signature was created. + var _timestamp_seconds + var timestamp_seconds : String: + get: + return "" if not _timestamp_seconds is String else String(_timestamp_seconds) + + # Extra information that will be bundled in the session token. + var _vars + var vars : Dictionary: + get: + return Dictionary() if not _vars is Dictionary else _vars.duplicate() + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountGameCenter: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountGameCenter", p_dict), ApiAccountGameCenter) as ApiAccountGameCenter + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "bundle_id: %s, " % _bundle_id + output += "player_id: %s, " % _player_id + output += "public_key_url: %s, " % _public_key_url + output += "salt: %s, " % _salt + output += "signature: %s, " % _signature + output += "timestamp_seconds: %s, " % _timestamp_seconds + var map_string : String = "" + if typeof(_vars) == TYPE_DICTIONARY: + for k in _vars: + map_string += "{%s=%s}, " % [k, _vars[k]] + output += "vars: [%s], " % map_string + return output + +# Send a Google token to the server. Used with authenticate/link/unlink. +class ApiAccountGoogle extends NakamaAsyncResult: + + const _SCHEMA = { + "token": {"name": "_token", "type": TYPE_STRING, "required": false}, + "vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # The OAuth token received from Google to access their profile API. + var _token + var token : String: + get: + return "" if not _token is String else String(_token) + + # Extra information that will be bundled in the session token. + var _vars + var vars : Dictionary: + get: + return Dictionary() if not _vars is Dictionary else _vars.duplicate() + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountGoogle: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountGoogle", p_dict), ApiAccountGoogle) as ApiAccountGoogle + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "token: %s, " % _token + var map_string : String = "" + if typeof(_vars) == TYPE_DICTIONARY: + for k in _vars: + map_string += "{%s=%s}, " % [k, _vars[k]] + output += "vars: [%s], " % map_string + return output + +# Send a Steam token to the server. Used with authenticate/link/unlink. +class ApiAccountSteam extends NakamaAsyncResult: + + const _SCHEMA = { + "token": {"name": "_token", "type": TYPE_STRING, "required": false}, + "vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # The account token received from Steam to access their profile API. + var _token + var token : String: + get: + return "" if not _token is String else String(_token) + + # Extra information that will be bundled in the session token. + var _vars + var vars : Dictionary: + get: + return Dictionary() if not _vars is Dictionary else _vars.duplicate() + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiAccountSteam: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiAccountSteam", p_dict), ApiAccountSteam) as ApiAccountSteam + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "token: %s, " % _token + var map_string : String = "" + if typeof(_vars) == TYPE_DICTIONARY: + for k in _vars: + map_string += "{%s=%s}, " % [k, _vars[k]] + output += "vars: [%s], " % map_string + return output + +# A message sent on a channel. +class ApiChannelMessage extends NakamaAsyncResult: + + const _SCHEMA = { + "channel_id": {"name": "_channel_id", "type": TYPE_STRING, "required": false}, + "code": {"name": "_code", "type": TYPE_INT, "required": false}, + "content": {"name": "_content", "type": TYPE_STRING, "required": false}, + "create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false}, + "group_id": {"name": "_group_id", "type": TYPE_STRING, "required": false}, + "message_id": {"name": "_message_id", "type": TYPE_STRING, "required": false}, + "persistent": {"name": "_persistent", "type": TYPE_BOOL, "required": false}, + "room_name": {"name": "_room_name", "type": TYPE_STRING, "required": false}, + "sender_id": {"name": "_sender_id", "type": TYPE_STRING, "required": false}, + "update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false}, + "user_id_one": {"name": "_user_id_one", "type": TYPE_STRING, "required": false}, + "user_id_two": {"name": "_user_id_two", "type": TYPE_STRING, "required": false}, + "username": {"name": "_username", "type": TYPE_STRING, "required": false}, + } + + # The channel this message belongs to. + var _channel_id + var channel_id : String: + get: + return "" if not _channel_id is String else String(_channel_id) + + # The code representing a message type or category. + var _code + var code : int: + get: + return 0 if not _code is int else int(_code) + + # The content payload. + var _content + var content : String: + get: + return "" if not _content is String else String(_content) + + # The UNIX time when the message was created. + var _create_time + var create_time : String: + get: + return "" if not _create_time is String else String(_create_time) + + # The ID of the group, or an empty string if this message was not sent through a group channel. + var _group_id + var group_id : String: + get: + return "" if not _group_id is String else String(_group_id) + + # The unique ID of this message. + var _message_id + var message_id : String: + get: + return "" if not _message_id is String else String(_message_id) + + # True if the message was persisted to the channel's history, false otherwise. + var _persistent + var persistent : bool: + get: + return false if not _persistent is bool else bool(_persistent) + + # The name of the chat room, or an empty string if this message was not sent through a chat room. + var _room_name + var room_name : String: + get: + return "" if not _room_name is String else String(_room_name) + + # Message sender, usually a user ID. + var _sender_id + var sender_id : String: + get: + return "" if not _sender_id is String else String(_sender_id) + + # The UNIX time when the message was last updated. + var _update_time + var update_time : String: + get: + return "" if not _update_time is String else String(_update_time) + + # The ID of the first DM user, or an empty string if this message was not sent through a DM chat. + var _user_id_one + var user_id_one : String: + get: + return "" if not _user_id_one is String else String(_user_id_one) + + # The ID of the second DM user, or an empty string if this message was not sent through a DM chat. + var _user_id_two + var user_id_two : String: + get: + return "" if not _user_id_two is String else String(_user_id_two) + + # The username of the message sender, if any. + var _username + var username : String: + get: + return "" if not _username is String else String(_username) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiChannelMessage: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiChannelMessage", p_dict), ApiChannelMessage) as ApiChannelMessage + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "channel_id: %s, " % _channel_id + output += "code: %s, " % _code + output += "content: %s, " % _content + output += "create_time: %s, " % _create_time + output += "group_id: %s, " % _group_id + output += "message_id: %s, " % _message_id + output += "persistent: %s, " % _persistent + output += "room_name: %s, " % _room_name + output += "sender_id: %s, " % _sender_id + output += "update_time: %s, " % _update_time + output += "user_id_one: %s, " % _user_id_one + output += "user_id_two: %s, " % _user_id_two + output += "username: %s, " % _username + return output + +# A list of channel messages, usually a result of a list operation. +class ApiChannelMessageList extends NakamaAsyncResult: + + const _SCHEMA = { + "cacheable_cursor": {"name": "_cacheable_cursor", "type": TYPE_STRING, "required": false}, + "messages": {"name": "_messages", "type": TYPE_ARRAY, "required": false, "content": "ApiChannelMessage"}, + "next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false}, + "prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false}, + } + + # Cacheable cursor to list newer messages. Durable and designed to be stored, unlike next/prev cursors. + var _cacheable_cursor + var cacheable_cursor : String: + get: + return "" if not _cacheable_cursor is String else String(_cacheable_cursor) + + # A list of messages. + var _messages + var messages : Array: + get: + return Array() if not _messages is Array else Array(_messages) + + # The cursor to send when retrieving the next page, if any. + var _next_cursor + var next_cursor : String: + get: + return "" if not _next_cursor is String else String(_next_cursor) + + # The cursor to send when retrieving the previous page, if any. + var _prev_cursor + var prev_cursor : String: + get: + return "" if not _prev_cursor is String else String(_prev_cursor) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiChannelMessageList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiChannelMessageList", p_dict), ApiChannelMessageList) as ApiChannelMessageList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "cacheable_cursor: %s, " % _cacheable_cursor + output += "messages: %s, " % [_messages] + output += "next_cursor: %s, " % _next_cursor + output += "prev_cursor: %s, " % _prev_cursor + return output + +# Create a group with the current user as owner. +class ApiCreateGroupRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false}, + "description": {"name": "_description", "type": TYPE_STRING, "required": false}, + "lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false}, + "max_count": {"name": "_max_count", "type": TYPE_INT, "required": false}, + "name": {"name": "_name", "type": TYPE_STRING, "required": false}, + "open": {"name": "_open", "type": TYPE_BOOL, "required": false}, + } + + # A URL for an avatar image. + var _avatar_url + var avatar_url : String: + get: + return "" if not _avatar_url is String else String(_avatar_url) + + # A description for the group. + var _description + var description : String: + get: + return "" if not _description is String else String(_description) + + # The language expected to be a tag which follows the BCP-47 spec. + var _lang_tag + var lang_tag : String: + get: + return "" if not _lang_tag is String else String(_lang_tag) + + # Maximum number of group members. + var _max_count + var max_count : int: + get: + return 0 if not _max_count is int else int(_max_count) + + # A unique name for the group. + var _name + var name : String: + get: + return "" if not _name is String else String(_name) + + # Mark a group as open or not where only admins can accept members. + var _open + var open : bool: + get: + return false if not _open is bool else bool(_open) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiCreateGroupRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiCreateGroupRequest", p_dict), ApiCreateGroupRequest) as ApiCreateGroupRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "avatar_url: %s, " % _avatar_url + output += "description: %s, " % _description + output += "lang_tag: %s, " % _lang_tag + output += "max_count: %s, " % _max_count + output += "name: %s, " % _name + output += "open: %s, " % _open + return output + +# Storage objects to delete. +class ApiDeleteStorageObjectId extends NakamaAsyncResult: + + const _SCHEMA = { + "collection": {"name": "_collection", "type": TYPE_STRING, "required": false}, + "key": {"name": "_key", "type": TYPE_STRING, "required": false}, + "version": {"name": "_version", "type": TYPE_STRING, "required": false}, + } + + # The collection which stores the object. + var _collection + var collection : String: + get: + return "" if not _collection is String else String(_collection) + + # The key of the object within the collection. + var _key + var key : String: + get: + return "" if not _key is String else String(_key) + + # The version hash of the object. + var _version + var version : String: + get: + return "" if not _version is String else String(_version) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiDeleteStorageObjectId: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiDeleteStorageObjectId", p_dict), ApiDeleteStorageObjectId) as ApiDeleteStorageObjectId + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "collection: %s, " % _collection + output += "key: %s, " % _key + output += "version: %s, " % _version + return output + +# Batch delete storage objects. +class ApiDeleteStorageObjectsRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "object_ids": {"name": "_object_ids", "type": TYPE_ARRAY, "required": false, "content": "ApiDeleteStorageObjectId"}, + } + + # Batch of storage objects. + var _object_ids + var object_ids : Array: + get: + return Array() if not _object_ids is Array else Array(_object_ids) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiDeleteStorageObjectsRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiDeleteStorageObjectsRequest", p_dict), ApiDeleteStorageObjectsRequest) as ApiDeleteStorageObjectsRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "object_ids: %s, " % [_object_ids] + return output + +# Represents an event to be passed through the server to registered event handlers. +class ApiEvent extends NakamaAsyncResult: + + const _SCHEMA = { + "external": {"name": "_external", "type": TYPE_BOOL, "required": false}, + "name": {"name": "_name", "type": TYPE_STRING, "required": false}, + "properties": {"name": "_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + "timestamp": {"name": "_timestamp", "type": TYPE_STRING, "required": false}, + } + + # True if the event came directly from a client call, false otherwise. + var _external + var external : bool: + get: + return false if not _external is bool else bool(_external) + + # An event name, type, category, or identifier. + var _name + var name : String: + get: + return "" if not _name is String else String(_name) + + # Arbitrary event property values. + var _properties + var properties : Dictionary: + get: + return Dictionary() if not _properties is Dictionary else _properties.duplicate() + + # The time when the event was triggered. + var _timestamp + var timestamp : String: + get: + return "" if not _timestamp is String else String(_timestamp) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiEvent: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiEvent", p_dict), ApiEvent) as ApiEvent + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "external: %s, " % _external + output += "name: %s, " % _name + var map_string : String = "" + if typeof(_properties) == TYPE_DICTIONARY: + for k in _properties: + map_string += "{%s=%s}, " % [k, _properties[k]] + output += "properties: [%s], " % map_string + output += "timestamp: %s, " % _timestamp + return output + +# A friend of a user. +class ApiFriend extends NakamaAsyncResult: + + const _SCHEMA = { + "state": {"name": "_state", "type": TYPE_INT, "required": false}, + "update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false}, + "user": {"name": "_user", "type": "ApiUser", "required": false}, + } + + # The friend status. + var _state + var state : int: + get: + return 0 if not _state is int else int(_state) + + # Time of the latest relationship update. + var _update_time + var update_time : String: + get: + return "" if not _update_time is String else String(_update_time) + + # The user object. + var _user + var user : ApiUser: + get: + return _user as ApiUser + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFriend: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiFriend", p_dict), ApiFriend) as ApiFriend + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "state: %s, " % _state + output += "update_time: %s, " % _update_time + output += "user: %s, " % _user + return output + +# A collection of zero or more friends of the user. +class ApiFriendList extends NakamaAsyncResult: + + const _SCHEMA = { + "cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false}, + "friends": {"name": "_friends", "type": TYPE_ARRAY, "required": false, "content": "ApiFriend"}, + } + + # Cursor for the next page of results, if any. + var _cursor + var cursor : String: + get: + return "" if not _cursor is String else String(_cursor) + + # The Friend objects. + var _friends + var friends : Array: + get: + return Array() if not _friends is Array else Array(_friends) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiFriendList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiFriendList", p_dict), ApiFriendList) as ApiFriendList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "cursor: %s, " % _cursor + output += "friends: %s, " % [_friends] + return output + +# A group in the server. +class ApiGroup extends NakamaAsyncResult: + + const _SCHEMA = { + "avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false}, + "create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false}, + "creator_id": {"name": "_creator_id", "type": TYPE_STRING, "required": false}, + "description": {"name": "_description", "type": TYPE_STRING, "required": false}, + "edge_count": {"name": "_edge_count", "type": TYPE_INT, "required": false}, + "id": {"name": "_id", "type": TYPE_STRING, "required": false}, + "lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false}, + "max_count": {"name": "_max_count", "type": TYPE_INT, "required": false}, + "metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false}, + "name": {"name": "_name", "type": TYPE_STRING, "required": false}, + "open": {"name": "_open", "type": TYPE_BOOL, "required": false}, + "update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false}, + } + + # A URL for an avatar image. + var _avatar_url + var avatar_url : String: + get: + return "" if not _avatar_url is String else String(_avatar_url) + + # The UNIX time when the group was created. + var _create_time + var create_time : String: + get: + return "" if not _create_time is String else String(_create_time) + + # The id of the user who created the group. + var _creator_id + var creator_id : String: + get: + return "" if not _creator_id is String else String(_creator_id) + + # A description for the group. + var _description + var description : String: + get: + return "" if not _description is String else String(_description) + + # The current count of all members in the group. + var _edge_count + var edge_count : int: + get: + return 0 if not _edge_count is int else int(_edge_count) + + # The id of a group. + var _id + var id : String: + get: + return "" if not _id is String else String(_id) + + # The language expected to be a tag which follows the BCP-47 spec. + var _lang_tag + var lang_tag : String: + get: + return "" if not _lang_tag is String else String(_lang_tag) + + # The maximum number of members allowed. + var _max_count + var max_count : int: + get: + return 0 if not _max_count is int else int(_max_count) + + # Additional information stored as a JSON object. + var _metadata + var metadata : String: + get: + return "" if not _metadata is String else String(_metadata) + + # The unique name of the group. + var _name + var name : String: + get: + return "" if not _name is String else String(_name) + + # Anyone can join open groups, otherwise only admins can accept members. + var _open + var open : bool: + get: + return false if not _open is bool else bool(_open) + + # The UNIX time when the group was last updated. + var _update_time + var update_time : String: + get: + return "" if not _update_time is String else String(_update_time) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGroup: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiGroup", p_dict), ApiGroup) as ApiGroup + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "avatar_url: %s, " % _avatar_url + output += "create_time: %s, " % _create_time + output += "creator_id: %s, " % _creator_id + output += "description: %s, " % _description + output += "edge_count: %s, " % _edge_count + output += "id: %s, " % _id + output += "lang_tag: %s, " % _lang_tag + output += "max_count: %s, " % _max_count + output += "metadata: %s, " % _metadata + output += "name: %s, " % _name + output += "open: %s, " % _open + output += "update_time: %s, " % _update_time + return output + +# One or more groups returned from a listing operation. +class ApiGroupList extends NakamaAsyncResult: + + const _SCHEMA = { + "cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false}, + "groups": {"name": "_groups", "type": TYPE_ARRAY, "required": false, "content": "ApiGroup"}, + } + + # A cursor used to get the next page. + var _cursor + var cursor : String: + get: + return "" if not _cursor is String else String(_cursor) + + # One or more groups. + var _groups + var groups : Array: + get: + return Array() if not _groups is Array else Array(_groups) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGroupList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiGroupList", p_dict), ApiGroupList) as ApiGroupList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "cursor: %s, " % _cursor + output += "groups: %s, " % [_groups] + return output + +# A list of users belonging to a group, along with their role. +class ApiGroupUserList extends NakamaAsyncResult: + + const _SCHEMA = { + "cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false}, + "group_users": {"name": "_group_users", "type": TYPE_ARRAY, "required": false, "content": "GroupUserListGroupUser"}, + } + + # Cursor for the next page of results, if any. + var _cursor + var cursor : String: + get: + return "" if not _cursor is String else String(_cursor) + + # User-role pairs for a group. + var _group_users + var group_users : Array: + get: + return Array() if not _group_users is Array else Array(_group_users) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiGroupUserList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiGroupUserList", p_dict), ApiGroupUserList) as ApiGroupUserList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "cursor: %s, " % _cursor + output += "group_users: %s, " % [_group_users] + return output + +# Represents a complete leaderboard record with all scores and associated metadata. +class ApiLeaderboardRecord extends NakamaAsyncResult: + + const _SCHEMA = { + "create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false}, + "expiry_time": {"name": "_expiry_time", "type": TYPE_STRING, "required": false}, + "leaderboard_id": {"name": "_leaderboard_id", "type": TYPE_STRING, "required": false}, + "max_num_score": {"name": "_max_num_score", "type": TYPE_INT, "required": false}, + "metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false}, + "num_score": {"name": "_num_score", "type": TYPE_INT, "required": false}, + "owner_id": {"name": "_owner_id", "type": TYPE_STRING, "required": false}, + "rank": {"name": "_rank", "type": TYPE_STRING, "required": false}, + "score": {"name": "_score", "type": TYPE_STRING, "required": false}, + "subscore": {"name": "_subscore", "type": TYPE_STRING, "required": false}, + "update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false}, + "username": {"name": "_username", "type": TYPE_STRING, "required": false}, + } + + # The UNIX time when the leaderboard record was created. + var _create_time + var create_time : String: + get: + return "" if not _create_time is String else String(_create_time) + + # The UNIX time when the leaderboard record expires. + var _expiry_time + var expiry_time : String: + get: + return "" if not _expiry_time is String else String(_expiry_time) + + # The ID of the leaderboard this score belongs to. + var _leaderboard_id + var leaderboard_id : String: + get: + return "" if not _leaderboard_id is String else String(_leaderboard_id) + + # The maximum number of score updates allowed by the owner. + var _max_num_score + var max_num_score : int: + get: + return 0 if not _max_num_score is int else int(_max_num_score) + + # Metadata. + var _metadata + var metadata : String: + get: + return "" if not _metadata is String else String(_metadata) + + # The number of submissions to this score record. + var _num_score + var num_score : int: + get: + return 0 if not _num_score is int else int(_num_score) + + # The ID of the score owner, usually a user or group. + var _owner_id + var owner_id : String: + get: + return "" if not _owner_id is String else String(_owner_id) + + # The rank of this record. + var _rank + var rank : String: + get: + return "" if not _rank is String else String(_rank) + + # The score value. + var _score + var score : String: + get: + return "" if not _score is String else String(_score) + + # An optional subscore value. + var _subscore + var subscore : String: + get: + return "" if not _subscore is String else String(_subscore) + + # The UNIX time when the leaderboard record was updated. + var _update_time + var update_time : String: + get: + return "" if not _update_time is String else String(_update_time) + + # The username of the score owner, if the owner is a user. + var _username + var username : String: + get: + return "" if not _username is String else String(_username) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLeaderboardRecord: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiLeaderboardRecord", p_dict), ApiLeaderboardRecord) as ApiLeaderboardRecord + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "create_time: %s, " % _create_time + output += "expiry_time: %s, " % _expiry_time + output += "leaderboard_id: %s, " % _leaderboard_id + output += "max_num_score: %s, " % _max_num_score + output += "metadata: %s, " % _metadata + output += "num_score: %s, " % _num_score + output += "owner_id: %s, " % _owner_id + output += "rank: %s, " % _rank + output += "score: %s, " % _score + output += "subscore: %s, " % _subscore + output += "update_time: %s, " % _update_time + output += "username: %s, " % _username + return output + +# A set of leaderboard records, may be part of a leaderboard records page or a batch of individual records. +class ApiLeaderboardRecordList extends NakamaAsyncResult: + + const _SCHEMA = { + "next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false}, + "owner_records": {"name": "_owner_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"}, + "prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false}, + "records": {"name": "_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"}, + } + + # The cursor to send when retrieving the next page, if any. + var _next_cursor + var next_cursor : String: + get: + return "" if not _next_cursor is String else String(_next_cursor) + + # A batched set of leaderboard records belonging to specified owners. + var _owner_records + var owner_records : Array: + get: + return Array() if not _owner_records is Array else Array(_owner_records) + + # The cursor to send when retrieving the previous page, if any. + var _prev_cursor + var prev_cursor : String: + get: + return "" if not _prev_cursor is String else String(_prev_cursor) + + # A list of leaderboard records. + var _records + var records : Array: + get: + return Array() if not _records is Array else Array(_records) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLeaderboardRecordList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiLeaderboardRecordList", p_dict), ApiLeaderboardRecordList) as ApiLeaderboardRecordList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "next_cursor: %s, " % _next_cursor + output += "owner_records: %s, " % [_owner_records] + output += "prev_cursor: %s, " % _prev_cursor + output += "records: %s, " % [_records] + return output + +# Link Steam to the current user's account. +class ApiLinkSteamRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "account": {"name": "_account", "type": "ApiAccountSteam", "required": false}, + "sync": {"name": "_sync", "type": TYPE_BOOL, "required": false}, + } + + # The Facebook account details. + var _account + var account : ApiAccountSteam: + get: + return _account as ApiAccountSteam + + # Import Steam friends for the user. + var _sync + var sync : bool: + get: + return false if not _sync is bool else bool(_sync) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiLinkSteamRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiLinkSteamRequest", p_dict), ApiLinkSteamRequest) as ApiLinkSteamRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "account: %s, " % _account + output += "sync: %s, " % _sync + return output + +# List user subscriptions. +class ApiListSubscriptionsRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false}, + "limit": {"name": "_limit", "type": TYPE_INT, "required": false}, + } + + # + var _cursor + var cursor : String: + get: + return "" if not _cursor is String else String(_cursor) + + # + var _limit + var limit : int: + get: + return 0 if not _limit is int else int(_limit) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiListSubscriptionsRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiListSubscriptionsRequest", p_dict), ApiListSubscriptionsRequest) as ApiListSubscriptionsRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "cursor: %s, " % _cursor + output += "limit: %s, " % _limit + return output + +# Represents a realtime match. +class ApiMatch extends NakamaAsyncResult: + + const _SCHEMA = { + "authoritative": {"name": "_authoritative", "type": TYPE_BOOL, "required": false}, + "handler_name": {"name": "_handler_name", "type": TYPE_STRING, "required": false}, + "label": {"name": "_label", "type": TYPE_STRING, "required": false}, + "match_id": {"name": "_match_id", "type": TYPE_STRING, "required": false}, + "size": {"name": "_size", "type": TYPE_INT, "required": false}, + "tick_rate": {"name": "_tick_rate", "type": TYPE_INT, "required": false}, + } + + # True if it's an server-managed authoritative match, false otherwise. + var _authoritative + var authoritative : bool: + get: + return false if not _authoritative is bool else bool(_authoritative) + + # + var _handler_name + var handler_name : String: + get: + return "" if not _handler_name is String else String(_handler_name) + + # Match label, if any. + var _label + var label : String: + get: + return "" if not _label is String else String(_label) + + # The ID of the match, can be used to join. + var _match_id + var match_id : String: + get: + return "" if not _match_id is String else String(_match_id) + + # Current number of users in the match. + var _size + var size : int: + get: + return 0 if not _size is int else int(_size) + + # + var _tick_rate + var tick_rate : int: + get: + return 0 if not _tick_rate is int else int(_tick_rate) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiMatch: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiMatch", p_dict), ApiMatch) as ApiMatch + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "authoritative: %s, " % _authoritative + output += "handler_name: %s, " % _handler_name + output += "label: %s, " % _label + output += "match_id: %s, " % _match_id + output += "size: %s, " % _size + output += "tick_rate: %s, " % _tick_rate + return output + +# A list of realtime matches. +class ApiMatchList extends NakamaAsyncResult: + + const _SCHEMA = { + "matches": {"name": "_matches", "type": TYPE_ARRAY, "required": false, "content": "ApiMatch"}, + } + + # A number of matches corresponding to a list operation. + var _matches + var matches : Array: + get: + return Array() if not _matches is Array else Array(_matches) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiMatchList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiMatchList", p_dict), ApiMatchList) as ApiMatchList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "matches: %s, " % [_matches] + return output + +# A notification in the server. +class ApiNotification extends NakamaAsyncResult: + + const _SCHEMA = { + "code": {"name": "_code", "type": TYPE_INT, "required": false}, + "content": {"name": "_content", "type": TYPE_STRING, "required": false}, + "create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false}, + "id": {"name": "_id", "type": TYPE_STRING, "required": false}, + "persistent": {"name": "_persistent", "type": TYPE_BOOL, "required": false}, + "sender_id": {"name": "_sender_id", "type": TYPE_STRING, "required": false}, + "subject": {"name": "_subject", "type": TYPE_STRING, "required": false}, + } + + # Category code for this notification. + var _code + var code : int: + get: + return 0 if not _code is int else int(_code) + + # Content of the notification in JSON. + var _content + var content : String: + get: + return "" if not _content is String else String(_content) + + # The UNIX time when the notification was created. + var _create_time + var create_time : String: + get: + return "" if not _create_time is String else String(_create_time) + + # ID of the Notification. + var _id + var id : String: + get: + return "" if not _id is String else String(_id) + + # True if this notification was persisted to the database. + var _persistent + var persistent : bool: + get: + return false if not _persistent is bool else bool(_persistent) + + # ID of the sender, if a user. Otherwise 'null'. + var _sender_id + var sender_id : String: + get: + return "" if not _sender_id is String else String(_sender_id) + + # Subject of the notification. + var _subject + var subject : String: + get: + return "" if not _subject is String else String(_subject) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiNotification: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiNotification", p_dict), ApiNotification) as ApiNotification + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "code: %s, " % _code + output += "content: %s, " % _content + output += "create_time: %s, " % _create_time + output += "id: %s, " % _id + output += "persistent: %s, " % _persistent + output += "sender_id: %s, " % _sender_id + output += "subject: %s, " % _subject + return output + +# A collection of zero or more notifications. +class ApiNotificationList extends NakamaAsyncResult: + + const _SCHEMA = { + "cacheable_cursor": {"name": "_cacheable_cursor", "type": TYPE_STRING, "required": false}, + "notifications": {"name": "_notifications", "type": TYPE_ARRAY, "required": false, "content": "ApiNotification"}, + } + + # Use this cursor to paginate notifications. Cache this to catch up to new notifications. + var _cacheable_cursor + var cacheable_cursor : String: + get: + return "" if not _cacheable_cursor is String else String(_cacheable_cursor) + + # Collection of notifications. + var _notifications + var notifications : Array: + get: + return Array() if not _notifications is Array else Array(_notifications) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiNotificationList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiNotificationList", p_dict), ApiNotificationList) as ApiNotificationList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "cacheable_cursor: %s, " % _cacheable_cursor + output += "notifications: %s, " % [_notifications] + return output + +# Operator that can be used to override the one set in the leaderboard. +# - NO_OVERRIDE: Do not override the leaderboard operator. +# - BEST: Override the leaderboard operator with BEST. +# - SET: Override the leaderboard operator with SET. +# - INCREMENT: Override the leaderboard operator with INCREMENT. +# - DECREMENT: Override the leaderboard operator with DECREMENT.# [ - NO_OVERRIDE: Do not override the leaderboard operator. - BEST: Override the leaderboard operator with BEST. - SET: Override the leaderboard operator with SET. - INCREMENT: Override the leaderboard operator with INCREMENT. - DECREMENT: Override the leaderboard operator with DECREMENT.] +enum ApiOperator {NO_OVERRIDE = 0,BEST = 1,SET = 2,INCREMENT = 3,DECREMENT = 4,} + +# Storage objects to get. +class ApiReadStorageObjectId extends NakamaAsyncResult: + + const _SCHEMA = { + "collection": {"name": "_collection", "type": TYPE_STRING, "required": false}, + "key": {"name": "_key", "type": TYPE_STRING, "required": false}, + "user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false}, + } + + # The collection which stores the object. + var _collection + var collection : String: + get: + return "" if not _collection is String else String(_collection) + + # The key of the object within the collection. + var _key + var key : String: + get: + return "" if not _key is String else String(_key) + + # The user owner of the object. + var _user_id + var user_id : String: + get: + return "" if not _user_id is String else String(_user_id) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiReadStorageObjectId: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiReadStorageObjectId", p_dict), ApiReadStorageObjectId) as ApiReadStorageObjectId + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "collection: %s, " % _collection + output += "key: %s, " % _key + output += "user_id: %s, " % _user_id + return output + +# Batch get storage objects. +class ApiReadStorageObjectsRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "object_ids": {"name": "_object_ids", "type": TYPE_ARRAY, "required": false, "content": "ApiReadStorageObjectId"}, + } + + # Batch of storage objects. + var _object_ids + var object_ids : Array: + get: + return Array() if not _object_ids is Array else Array(_object_ids) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiReadStorageObjectsRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiReadStorageObjectsRequest", p_dict), ApiReadStorageObjectsRequest) as ApiReadStorageObjectsRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "object_ids: %s, " % [_object_ids] + return output + +# Execute an Lua function on the server. +class ApiRpc extends NakamaAsyncResult: + + const _SCHEMA = { + "http_key": {"name": "_http_key", "type": TYPE_STRING, "required": false}, + "id": {"name": "_id", "type": TYPE_STRING, "required": false}, + "payload": {"name": "_payload", "type": TYPE_STRING, "required": false}, + } + + # The authentication key used when executed as a non-client HTTP request. + var _http_key + var http_key : String: + get: + return "" if not _http_key is String else String(_http_key) + + # The identifier of the function. + var _id + var id : String: + get: + return "" if not _id is String else String(_id) + + # The payload of the function which must be a JSON object. + var _payload + var payload : String: + get: + return "" if not _payload is String else String(_payload) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiRpc: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiRpc", p_dict), ApiRpc) as ApiRpc + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "http_key: %s, " % _http_key + output += "id: %s, " % _id + output += "payload: %s, " % _payload + return output + +# A user's session used to authenticate messages. +class ApiSession extends NakamaAsyncResult: + + const _SCHEMA = { + "created": {"name": "_created", "type": TYPE_BOOL, "required": false}, + "refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false}, + "token": {"name": "_token", "type": TYPE_STRING, "required": false}, + } + + # True if the corresponding account was just created, false otherwise. + var _created + var created : bool: + get: + return false if not _created is bool else bool(_created) + + # Refresh token that can be used for session token renewal. + var _refresh_token + var refresh_token : String: + get: + return "" if not _refresh_token is String else String(_refresh_token) + + # Authentication credentials. + var _token + var token : String: + get: + return "" if not _token is String else String(_token) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSession: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSession", p_dict), ApiSession) as ApiSession + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "created: %s, " % _created + output += "refresh_token: %s, " % _refresh_token + output += "token: %s, " % _token + return output + +# Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user. +class ApiSessionLogoutRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "refresh_token": {"name": "_refresh_token", "type": TYPE_STRING, "required": false}, + "token": {"name": "_token", "type": TYPE_STRING, "required": false}, + } + + # Refresh token to invalidate. + var _refresh_token + var refresh_token : String: + get: + return "" if not _refresh_token is String else String(_refresh_token) + + # Session token to log out. + var _token + var token : String: + get: + return "" if not _token is String else String(_token) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSessionLogoutRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSessionLogoutRequest", p_dict), ApiSessionLogoutRequest) as ApiSessionLogoutRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "refresh_token: %s, " % _refresh_token + output += "token: %s, " % _token + return output + +# Authenticate against the server with a refresh token. +class ApiSessionRefreshRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "token": {"name": "_token", "type": TYPE_STRING, "required": false}, + "vars": {"name": "_vars", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # Refresh token. + var _token + var token : String: + get: + return "" if not _token is String else String(_token) + + # Extra information that will be bundled in the session token. + var _vars + var vars : Dictionary: + get: + return Dictionary() if not _vars is Dictionary else _vars.duplicate() + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSessionRefreshRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSessionRefreshRequest", p_dict), ApiSessionRefreshRequest) as ApiSessionRefreshRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "token: %s, " % _token + var map_string : String = "" + if typeof(_vars) == TYPE_DICTIONARY: + for k in _vars: + map_string += "{%s=%s}, " % [k, _vars[k]] + output += "vars: [%s], " % map_string + return output + +# An object within the storage engine. +class ApiStorageObject extends NakamaAsyncResult: + + const _SCHEMA = { + "collection": {"name": "_collection", "type": TYPE_STRING, "required": false}, + "create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false}, + "key": {"name": "_key", "type": TYPE_STRING, "required": false}, + "permission_read": {"name": "_permission_read", "type": TYPE_INT, "required": false}, + "permission_write": {"name": "_permission_write", "type": TYPE_INT, "required": false}, + "update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false}, + "user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false}, + "value": {"name": "_value", "type": TYPE_STRING, "required": false}, + "version": {"name": "_version", "type": TYPE_STRING, "required": false}, + } + + # The collection which stores the object. + var _collection + var collection : String: + get: + return "" if not _collection is String else String(_collection) + + # The UNIX time when the object was created. + var _create_time + var create_time : String: + get: + return "" if not _create_time is String else String(_create_time) + + # The key of the object within the collection. + var _key + var key : String: + get: + return "" if not _key is String else String(_key) + + # The read access permissions for the object. + var _permission_read + var permission_read : int: + get: + return 0 if not _permission_read is int else int(_permission_read) + + # The write access permissions for the object. + var _permission_write + var permission_write : int: + get: + return 0 if not _permission_write is int else int(_permission_write) + + # The UNIX time when the object was last updated. + var _update_time + var update_time : String: + get: + return "" if not _update_time is String else String(_update_time) + + # The user owner of the object. + var _user_id + var user_id : String: + get: + return "" if not _user_id is String else String(_user_id) + + # The value of the object. + var _value + var value : String: + get: + return "" if not _value is String else String(_value) + + # The version hash of the object. + var _version + var version : String: + get: + return "" if not _version is String else String(_version) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObject: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObject", p_dict), ApiStorageObject) as ApiStorageObject + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "collection: %s, " % _collection + output += "create_time: %s, " % _create_time + output += "key: %s, " % _key + output += "permission_read: %s, " % _permission_read + output += "permission_write: %s, " % _permission_write + output += "update_time: %s, " % _update_time + output += "user_id: %s, " % _user_id + output += "value: %s, " % _value + output += "version: %s, " % _version + return output + +# A storage acknowledgement. +class ApiStorageObjectAck extends NakamaAsyncResult: + + const _SCHEMA = { + "collection": {"name": "_collection", "type": TYPE_STRING, "required": false}, + "key": {"name": "_key", "type": TYPE_STRING, "required": false}, + "user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false}, + "version": {"name": "_version", "type": TYPE_STRING, "required": false}, + } + + # The collection which stores the object. + var _collection + var collection : String: + get: + return "" if not _collection is String else String(_collection) + + # The key of the object within the collection. + var _key + var key : String: + get: + return "" if not _key is String else String(_key) + + # The owner of the object. + var _user_id + var user_id : String: + get: + return "" if not _user_id is String else String(_user_id) + + # The version hash of the object. + var _version + var version : String: + get: + return "" if not _version is String else String(_version) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjectAck: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjectAck", p_dict), ApiStorageObjectAck) as ApiStorageObjectAck + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "collection: %s, " % _collection + output += "key: %s, " % _key + output += "user_id: %s, " % _user_id + output += "version: %s, " % _version + return output + +# Batch of acknowledgements for the storage object write. +class ApiStorageObjectAcks extends NakamaAsyncResult: + + const _SCHEMA = { + "acks": {"name": "_acks", "type": TYPE_ARRAY, "required": false, "content": "ApiStorageObjectAck"}, + } + + # Batch of storage write acknowledgements. + var _acks + var acks : Array: + get: + return Array() if not _acks is Array else Array(_acks) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjectAcks: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjectAcks", p_dict), ApiStorageObjectAcks) as ApiStorageObjectAcks + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "acks: %s, " % [_acks] + return output + +# List of storage objects. +class ApiStorageObjectList extends NakamaAsyncResult: + + const _SCHEMA = { + "cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false}, + "objects": {"name": "_objects", "type": TYPE_ARRAY, "required": false, "content": "ApiStorageObject"}, + } + + # The cursor for the next page of results, if any. + var _cursor + var cursor : String: + get: + return "" if not _cursor is String else String(_cursor) + + # The list of storage objects. + var _objects + var objects : Array: + get: + return Array() if not _objects is Array else Array(_objects) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjectList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjectList", p_dict), ApiStorageObjectList) as ApiStorageObjectList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "cursor: %s, " % _cursor + output += "objects: %s, " % [_objects] + return output + +# Batch of storage objects. +class ApiStorageObjects extends NakamaAsyncResult: + + const _SCHEMA = { + "objects": {"name": "_objects", "type": TYPE_ARRAY, "required": false, "content": "ApiStorageObject"}, + } + + # The batch of storage objects. + var _objects + var objects : Array: + get: + return Array() if not _objects is Array else Array(_objects) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiStorageObjects: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiStorageObjects", p_dict), ApiStorageObjects) as ApiStorageObjects + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "objects: %s, " % [_objects] + return output + +# Environment where a purchase/subscription took place, +# - UNKNOWN: Unknown environment. +# - SANDBOX: Sandbox/test environment. +# - PRODUCTION: Production environment.# [- UNKNOWN: Unknown environment. - SANDBOX: Sandbox/test environment. - PRODUCTION: Production environment.] +enum ApiStoreEnvironment {UNKNOWN = 0,SANDBOX = 1,PRODUCTION = 2,} + +# Validation Provider, +# - APPLE_APP_STORE: Apple App Store +# - GOOGLE_PLAY_STORE: Google Play Store +# - HUAWEI_APP_GALLERY: Huawei App Gallery# [- APPLE_APP_STORE: Apple App Store - GOOGLE_PLAY_STORE: Google Play Store - HUAWEI_APP_GALLERY: Huawei App Gallery] +enum ApiStoreProvider {APPLE_APP_STORE = 0,GOOGLE_PLAY_STORE = 1,HUAWEI_APP_GALLERY = 2,} + +# A list of validated subscriptions stored by Nakama. +class ApiSubscriptionList extends NakamaAsyncResult: + + const _SCHEMA = { + "cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false}, + "prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false}, + "validated_subscriptions": {"name": "_validated_subscriptions", "type": TYPE_ARRAY, "required": false, "content": "ApiValidatedSubscription"}, + } + + # The cursor to send when retrieving the next page, if any. + var _cursor + var cursor : String: + get: + return "" if not _cursor is String else String(_cursor) + + # The cursor to send when retrieving the previous page, if any. + var _prev_cursor + var prev_cursor : String: + get: + return "" if not _prev_cursor is String else String(_prev_cursor) + + # Stored validated subscriptions. + var _validated_subscriptions + var validated_subscriptions : Array: + get: + return Array() if not _validated_subscriptions is Array else Array(_validated_subscriptions) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiSubscriptionList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiSubscriptionList", p_dict), ApiSubscriptionList) as ApiSubscriptionList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "cursor: %s, " % _cursor + output += "prev_cursor: %s, " % _prev_cursor + output += "validated_subscriptions: %s, " % [_validated_subscriptions] + return output + +# A tournament on the server. +class ApiTournament extends NakamaAsyncResult: + + const _SCHEMA = { + "authoritative": {"name": "_authoritative", "type": TYPE_BOOL, "required": false}, + "can_enter": {"name": "_can_enter", "type": TYPE_BOOL, "required": false}, + "category": {"name": "_category", "type": TYPE_INT, "required": false}, + "create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false}, + "description": {"name": "_description", "type": TYPE_STRING, "required": false}, + "duration": {"name": "_duration", "type": TYPE_INT, "required": false}, + "end_active": {"name": "_end_active", "type": TYPE_INT, "required": false}, + "end_time": {"name": "_end_time", "type": TYPE_STRING, "required": false}, + "id": {"name": "_id", "type": TYPE_STRING, "required": false}, + "max_num_score": {"name": "_max_num_score", "type": TYPE_INT, "required": false}, + "max_size": {"name": "_max_size", "type": TYPE_INT, "required": false}, + "metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false}, + "next_reset": {"name": "_next_reset", "type": TYPE_INT, "required": false}, + "operator": {"name": "_operator", "type": TYPE_INT, "required": false}, + "prev_reset": {"name": "_prev_reset", "type": TYPE_INT, "required": false}, + "size": {"name": "_size", "type": TYPE_INT, "required": false}, + "sort_order": {"name": "_sort_order", "type": TYPE_INT, "required": false}, + "start_active": {"name": "_start_active", "type": TYPE_INT, "required": false}, + "start_time": {"name": "_start_time", "type": TYPE_STRING, "required": false}, + "title": {"name": "_title", "type": TYPE_STRING, "required": false}, + } + + # Whether the leaderboard was created authoritatively or not. + var _authoritative + var authoritative : bool: + get: + return false if not _authoritative is bool else bool(_authoritative) + + # True if the tournament is active and can enter. A computed value. + var _can_enter + var can_enter : bool: + get: + return false if not _can_enter is bool else bool(_can_enter) + + # The category of the tournament. e.g. "vip" could be category 1. + var _category + var category : int: + get: + return 0 if not _category is int else int(_category) + + # The UNIX time when the tournament was created. + var _create_time + var create_time : String: + get: + return "" if not _create_time is String else String(_create_time) + + # The description of the tournament. May be blank. + var _description + var description : String: + get: + return "" if not _description is String else String(_description) + + # Duration of the tournament in seconds. + var _duration + var duration : int: + get: + return 0 if not _duration is int else int(_duration) + + # The UNIX time when the tournament stops being active until next reset. A computed value. + var _end_active + var end_active : int: + get: + return 0 if not _end_active is int else int(_end_active) + + # The UNIX time when the tournament will be stopped. + var _end_time + var end_time : String: + get: + return "" if not _end_time is String else String(_end_time) + + # The ID of the tournament. + var _id + var id : String: + get: + return "" if not _id is String else String(_id) + + # The maximum score updates allowed per player for the current tournament. + var _max_num_score + var max_num_score : int: + get: + return 0 if not _max_num_score is int else int(_max_num_score) + + # The maximum number of players for the tournament. + var _max_size + var max_size : int: + get: + return 0 if not _max_size is int else int(_max_size) + + # Additional information stored as a JSON object. + var _metadata + var metadata : String: + get: + return "" if not _metadata is String else String(_metadata) + + # The UNIX time when the tournament is next playable. A computed value. + var _next_reset + var next_reset : int: + get: + return 0 if not _next_reset is int else int(_next_reset) + + # Operator. + var _operator + var operator : int: + get: + return ApiOperator.values()[0] if not ApiOperator.values().has(_operator) else _operator + + # The UNIX time when the tournament was last reset. A computed value. + var _prev_reset + var prev_reset : int: + get: + return 0 if not _prev_reset is int else int(_prev_reset) + + # The current number of players in the tournament. + var _size + var size : int: + get: + return 0 if not _size is int else int(_size) + + # ASC (0) or DESC (1) sort mode of scores in the tournament. + var _sort_order + var sort_order : int: + get: + return 0 if not _sort_order is int else int(_sort_order) + + # The UNIX time when the tournament start being active. A computed value. + var _start_active + var start_active : int: + get: + return 0 if not _start_active is int else int(_start_active) + + # The UNIX time when the tournament will start. + var _start_time + var start_time : String: + get: + return "" if not _start_time is String else String(_start_time) + + # The title for the tournament. + var _title + var title : String: + get: + return "" if not _title is String else String(_title) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiTournament: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiTournament", p_dict), ApiTournament) as ApiTournament + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "authoritative: %s, " % _authoritative + output += "can_enter: %s, " % _can_enter + output += "category: %s, " % _category + output += "create_time: %s, " % _create_time + output += "description: %s, " % _description + output += "duration: %s, " % _duration + output += "end_active: %s, " % _end_active + output += "end_time: %s, " % _end_time + output += "id: %s, " % _id + output += "max_num_score: %s, " % _max_num_score + output += "max_size: %s, " % _max_size + output += "metadata: %s, " % _metadata + output += "next_reset: %s, " % _next_reset + output += "operator: %s, " % _operator + output += "prev_reset: %s, " % _prev_reset + output += "size: %s, " % _size + output += "sort_order: %s, " % _sort_order + output += "start_active: %s, " % _start_active + output += "start_time: %s, " % _start_time + output += "title: %s, " % _title + return output + +# A list of tournaments. +class ApiTournamentList extends NakamaAsyncResult: + + const _SCHEMA = { + "cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false}, + "tournaments": {"name": "_tournaments", "type": TYPE_ARRAY, "required": false, "content": "ApiTournament"}, + } + + # A pagination cursor (optional). + var _cursor + var cursor : String: + get: + return "" if not _cursor is String else String(_cursor) + + # The list of tournaments returned. + var _tournaments + var tournaments : Array: + get: + return Array() if not _tournaments is Array else Array(_tournaments) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiTournamentList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiTournamentList", p_dict), ApiTournamentList) as ApiTournamentList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "cursor: %s, " % _cursor + output += "tournaments: %s, " % [_tournaments] + return output + +# A set of tournament records which may be part of a tournament records page or a batch of individual records. +class ApiTournamentRecordList extends NakamaAsyncResult: + + const _SCHEMA = { + "next_cursor": {"name": "_next_cursor", "type": TYPE_STRING, "required": false}, + "owner_records": {"name": "_owner_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"}, + "prev_cursor": {"name": "_prev_cursor", "type": TYPE_STRING, "required": false}, + "records": {"name": "_records", "type": TYPE_ARRAY, "required": false, "content": "ApiLeaderboardRecord"}, + } + + # The cursor to send when retireving the next page (optional). + var _next_cursor + var next_cursor : String: + get: + return "" if not _next_cursor is String else String(_next_cursor) + + # A batched set of tournament records belonging to specified owners. + var _owner_records + var owner_records : Array: + get: + return Array() if not _owner_records is Array else Array(_owner_records) + + # The cursor to send when retrieving the previous page (optional). + var _prev_cursor + var prev_cursor : String: + get: + return "" if not _prev_cursor is String else String(_prev_cursor) + + # A list of tournament records. + var _records + var records : Array: + get: + return Array() if not _records is Array else Array(_records) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiTournamentRecordList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiTournamentRecordList", p_dict), ApiTournamentRecordList) as ApiTournamentRecordList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "next_cursor: %s, " % _next_cursor + output += "owner_records: %s, " % [_owner_records] + output += "prev_cursor: %s, " % _prev_cursor + output += "records: %s, " % [_records] + return output + +# Update a user's account details. +class ApiUpdateAccountRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false}, + "display_name": {"name": "_display_name", "type": TYPE_STRING, "required": false}, + "lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false}, + "location": {"name": "_location", "type": TYPE_STRING, "required": false}, + "timezone": {"name": "_timezone", "type": TYPE_STRING, "required": false}, + "username": {"name": "_username", "type": TYPE_STRING, "required": false}, + } + + # A URL for an avatar image. + var _avatar_url + var avatar_url : String: + get: + return "" if not _avatar_url is String else String(_avatar_url) + + # The display name of the user. + var _display_name + var display_name : String: + get: + return "" if not _display_name is String else String(_display_name) + + # The language expected to be a tag which follows the BCP-47 spec. + var _lang_tag + var lang_tag : String: + get: + return "" if not _lang_tag is String else String(_lang_tag) + + # The location set by the user. + var _location + var location : String: + get: + return "" if not _location is String else String(_location) + + # The timezone set by the user. + var _timezone + var timezone : String: + get: + return "" if not _timezone is String else String(_timezone) + + # The username of the user's account. + var _username + var username : String: + get: + return "" if not _username is String else String(_username) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUpdateAccountRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUpdateAccountRequest", p_dict), ApiUpdateAccountRequest) as ApiUpdateAccountRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "avatar_url: %s, " % _avatar_url + output += "display_name: %s, " % _display_name + output += "lang_tag: %s, " % _lang_tag + output += "location: %s, " % _location + output += "timezone: %s, " % _timezone + output += "username: %s, " % _username + return output + +# Update fields in a given group. +class ApiUpdateGroupRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false}, + "description": {"name": "_description", "type": TYPE_STRING, "required": false}, + "group_id": {"name": "_group_id", "type": TYPE_STRING, "required": false}, + "lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false}, + "name": {"name": "_name", "type": TYPE_STRING, "required": false}, + "open": {"name": "_open", "type": TYPE_BOOL, "required": false}, + } + + # Avatar URL. + var _avatar_url + var avatar_url : String: + get: + return "" if not _avatar_url is String else String(_avatar_url) + + # Description string. + var _description + var description : String: + get: + return "" if not _description is String else String(_description) + + # The ID of the group to update. + var _group_id + var group_id : String: + get: + return "" if not _group_id is String else String(_group_id) + + # Lang tag. + var _lang_tag + var lang_tag : String: + get: + return "" if not _lang_tag is String else String(_lang_tag) + + # Name. + var _name + var name : String: + get: + return "" if not _name is String else String(_name) + + # Open is true if anyone should be allowed to join, or false if joins must be approved by a group admin. + var _open + var open : bool: + get: + return false if not _open is bool else bool(_open) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUpdateGroupRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUpdateGroupRequest", p_dict), ApiUpdateGroupRequest) as ApiUpdateGroupRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "avatar_url: %s, " % _avatar_url + output += "description: %s, " % _description + output += "group_id: %s, " % _group_id + output += "lang_tag: %s, " % _lang_tag + output += "name: %s, " % _name + output += "open: %s, " % _open + return output + +# A user in the server. +class ApiUser extends NakamaAsyncResult: + + const _SCHEMA = { + "apple_id": {"name": "_apple_id", "type": TYPE_STRING, "required": false}, + "avatar_url": {"name": "_avatar_url", "type": TYPE_STRING, "required": false}, + "create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false}, + "display_name": {"name": "_display_name", "type": TYPE_STRING, "required": false}, + "edge_count": {"name": "_edge_count", "type": TYPE_INT, "required": false}, + "facebook_id": {"name": "_facebook_id", "type": TYPE_STRING, "required": false}, + "facebook_instant_game_id": {"name": "_facebook_instant_game_id", "type": TYPE_STRING, "required": false}, + "gamecenter_id": {"name": "_gamecenter_id", "type": TYPE_STRING, "required": false}, + "google_id": {"name": "_google_id", "type": TYPE_STRING, "required": false}, + "id": {"name": "_id", "type": TYPE_STRING, "required": false}, + "lang_tag": {"name": "_lang_tag", "type": TYPE_STRING, "required": false}, + "location": {"name": "_location", "type": TYPE_STRING, "required": false}, + "metadata": {"name": "_metadata", "type": TYPE_STRING, "required": false}, + "online": {"name": "_online", "type": TYPE_BOOL, "required": false}, + "steam_id": {"name": "_steam_id", "type": TYPE_STRING, "required": false}, + "timezone": {"name": "_timezone", "type": TYPE_STRING, "required": false}, + "update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false}, + "username": {"name": "_username", "type": TYPE_STRING, "required": false}, + } + + # The Apple Sign In ID in the user's account. + var _apple_id + var apple_id : String: + get: + return "" if not _apple_id is String else String(_apple_id) + + # A URL for an avatar image. + var _avatar_url + var avatar_url : String: + get: + return "" if not _avatar_url is String else String(_avatar_url) + + # The UNIX time when the user was created. + var _create_time + var create_time : String: + get: + return "" if not _create_time is String else String(_create_time) + + # The display name of the user. + var _display_name + var display_name : String: + get: + return "" if not _display_name is String else String(_display_name) + + # Number of related edges to this user. + var _edge_count + var edge_count : int: + get: + return 0 if not _edge_count is int else int(_edge_count) + + # The Facebook id in the user's account. + var _facebook_id + var facebook_id : String: + get: + return "" if not _facebook_id is String else String(_facebook_id) + + # The Facebook Instant Game ID in the user's account. + var _facebook_instant_game_id + var facebook_instant_game_id : String: + get: + return "" if not _facebook_instant_game_id is String else String(_facebook_instant_game_id) + + # The Apple Game Center in of the user's account. + var _gamecenter_id + var gamecenter_id : String: + get: + return "" if not _gamecenter_id is String else String(_gamecenter_id) + + # The Google id in the user's account. + var _google_id + var google_id : String: + get: + return "" if not _google_id is String else String(_google_id) + + # The id of the user's account. + var _id + var id : String: + get: + return "" if not _id is String else String(_id) + + # The language expected to be a tag which follows the BCP-47 spec. + var _lang_tag + var lang_tag : String: + get: + return "" if not _lang_tag is String else String(_lang_tag) + + # The location set by the user. + var _location + var location : String: + get: + return "" if not _location is String else String(_location) + + # Additional information stored as a JSON object. + var _metadata + var metadata : String: + get: + return "" if not _metadata is String else String(_metadata) + + # Indicates whether the user is currently online. + var _online + var online : bool: + get: + return false if not _online is bool else bool(_online) + + # The Steam id in the user's account. + var _steam_id + var steam_id : String: + get: + return "" if not _steam_id is String else String(_steam_id) + + # The timezone set by the user. + var _timezone + var timezone : String: + get: + return "" if not _timezone is String else String(_timezone) + + # The UNIX time when the user was last updated. + var _update_time + var update_time : String: + get: + return "" if not _update_time is String else String(_update_time) + + # The username of the user's account. + var _username + var username : String: + get: + return "" if not _username is String else String(_username) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUser: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUser", p_dict), ApiUser) as ApiUser + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "apple_id: %s, " % _apple_id + output += "avatar_url: %s, " % _avatar_url + output += "create_time: %s, " % _create_time + output += "display_name: %s, " % _display_name + output += "edge_count: %s, " % _edge_count + output += "facebook_id: %s, " % _facebook_id + output += "facebook_instant_game_id: %s, " % _facebook_instant_game_id + output += "gamecenter_id: %s, " % _gamecenter_id + output += "google_id: %s, " % _google_id + output += "id: %s, " % _id + output += "lang_tag: %s, " % _lang_tag + output += "location: %s, " % _location + output += "metadata: %s, " % _metadata + output += "online: %s, " % _online + output += "steam_id: %s, " % _steam_id + output += "timezone: %s, " % _timezone + output += "update_time: %s, " % _update_time + output += "username: %s, " % _username + return output + +# A list of groups belonging to a user, along with the user's role in each group. +class ApiUserGroupList extends NakamaAsyncResult: + + const _SCHEMA = { + "cursor": {"name": "_cursor", "type": TYPE_STRING, "required": false}, + "user_groups": {"name": "_user_groups", "type": TYPE_ARRAY, "required": false, "content": "UserGroupListUserGroup"}, + } + + # Cursor for the next page of results, if any. + var _cursor + var cursor : String: + get: + return "" if not _cursor is String else String(_cursor) + + # Group-role pairs for a user. + var _user_groups + var user_groups : Array: + get: + return Array() if not _user_groups is Array else Array(_user_groups) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUserGroupList: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUserGroupList", p_dict), ApiUserGroupList) as ApiUserGroupList + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "cursor: %s, " % _cursor + output += "user_groups: %s, " % [_user_groups] + return output + +# A collection of zero or more users. +class ApiUsers extends NakamaAsyncResult: + + const _SCHEMA = { + "users": {"name": "_users", "type": TYPE_ARRAY, "required": false, "content": "ApiUser"}, + } + + # The User objects. + var _users + var users : Array: + get: + return Array() if not _users is Array else Array(_users) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiUsers: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiUsers", p_dict), ApiUsers) as ApiUsers + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "users: %s, " % [_users] + return output + +# +class ApiValidatePurchaseAppleRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "persist": {"name": "_persist", "type": TYPE_BOOL, "required": false}, + "receipt": {"name": "_receipt", "type": TYPE_STRING, "required": false}, + } + + # + var _persist + var persist : bool: + get: + return false if not _persist is bool else bool(_persist) + + # Base64 encoded Apple receipt data payload. + var _receipt + var receipt : String: + get: + return "" if not _receipt is String else String(_receipt) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatePurchaseAppleRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatePurchaseAppleRequest", p_dict), ApiValidatePurchaseAppleRequest) as ApiValidatePurchaseAppleRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "persist: %s, " % _persist + output += "receipt: %s, " % _receipt + return output + +# +class ApiValidatePurchaseGoogleRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "persist": {"name": "_persist", "type": TYPE_BOOL, "required": false}, + "purchase": {"name": "_purchase", "type": TYPE_STRING, "required": false}, + } + + # + var _persist + var persist : bool: + get: + return false if not _persist is bool else bool(_persist) + + # JSON encoded Google purchase payload. + var _purchase + var purchase : String: + get: + return "" if not _purchase is String else String(_purchase) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatePurchaseGoogleRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatePurchaseGoogleRequest", p_dict), ApiValidatePurchaseGoogleRequest) as ApiValidatePurchaseGoogleRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "persist: %s, " % _persist + output += "purchase: %s, " % _purchase + return output + +# +class ApiValidatePurchaseHuaweiRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "persist": {"name": "_persist", "type": TYPE_BOOL, "required": false}, + "purchase": {"name": "_purchase", "type": TYPE_STRING, "required": false}, + "signature": {"name": "_signature", "type": TYPE_STRING, "required": false}, + } + + # + var _persist + var persist : bool: + get: + return false if not _persist is bool else bool(_persist) + + # JSON encoded Huawei InAppPurchaseData. + var _purchase + var purchase : String: + get: + return "" if not _purchase is String else String(_purchase) + + # InAppPurchaseData signature. + var _signature + var signature : String: + get: + return "" if not _signature is String else String(_signature) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatePurchaseHuaweiRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatePurchaseHuaweiRequest", p_dict), ApiValidatePurchaseHuaweiRequest) as ApiValidatePurchaseHuaweiRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "persist: %s, " % _persist + output += "purchase: %s, " % _purchase + output += "signature: %s, " % _signature + return output + +# Validate IAP response. +class ApiValidatePurchaseResponse extends NakamaAsyncResult: + + const _SCHEMA = { + "validated_purchases": {"name": "_validated_purchases", "type": TYPE_ARRAY, "required": false, "content": "ApiValidatedPurchase"}, + } + + # Newly seen validated purchases. + var _validated_purchases + var validated_purchases : Array: + get: + return Array() if not _validated_purchases is Array else Array(_validated_purchases) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatePurchaseResponse: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatePurchaseResponse", p_dict), ApiValidatePurchaseResponse) as ApiValidatePurchaseResponse + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "validated_purchases: %s, " % [_validated_purchases] + return output + +# +class ApiValidateSubscriptionAppleRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "persist": {"name": "_persist", "type": TYPE_BOOL, "required": false}, + "receipt": {"name": "_receipt", "type": TYPE_STRING, "required": false}, + } + + # Persist the subscription. + var _persist + var persist : bool: + get: + return false if not _persist is bool else bool(_persist) + + # Base64 encoded Apple receipt data payload. + var _receipt + var receipt : String: + get: + return "" if not _receipt is String else String(_receipt) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidateSubscriptionAppleRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidateSubscriptionAppleRequest", p_dict), ApiValidateSubscriptionAppleRequest) as ApiValidateSubscriptionAppleRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "persist: %s, " % _persist + output += "receipt: %s, " % _receipt + return output + +# +class ApiValidateSubscriptionGoogleRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "persist": {"name": "_persist", "type": TYPE_BOOL, "required": false}, + "receipt": {"name": "_receipt", "type": TYPE_STRING, "required": false}, + } + + # Persist the subscription. + var _persist + var persist : bool: + get: + return false if not _persist is bool else bool(_persist) + + # JSON encoded Google purchase payload. + var _receipt + var receipt : String: + get: + return "" if not _receipt is String else String(_receipt) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidateSubscriptionGoogleRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidateSubscriptionGoogleRequest", p_dict), ApiValidateSubscriptionGoogleRequest) as ApiValidateSubscriptionGoogleRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "persist: %s, " % _persist + output += "receipt: %s, " % _receipt + return output + +# Validate Subscription response. +class ApiValidateSubscriptionResponse extends NakamaAsyncResult: + + const _SCHEMA = { + "validated_subscription": {"name": "_validated_subscription", "type": "ApiValidatedSubscription", "required": false}, + } + + # + var _validated_subscription + var validated_subscription : ApiValidatedSubscription: + get: + return _validated_subscription as ApiValidatedSubscription + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidateSubscriptionResponse: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidateSubscriptionResponse", p_dict), ApiValidateSubscriptionResponse) as ApiValidateSubscriptionResponse + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "validated_subscription: %s, " % _validated_subscription + return output + +# Validated Purchase stored by Nakama. +class ApiValidatedPurchase extends NakamaAsyncResult: + + const _SCHEMA = { + "create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false}, + "environment": {"name": "_environment", "type": TYPE_INT, "required": false}, + "product_id": {"name": "_product_id", "type": TYPE_STRING, "required": false}, + "provider_response": {"name": "_provider_response", "type": TYPE_STRING, "required": false}, + "purchase_time": {"name": "_purchase_time", "type": TYPE_STRING, "required": false}, + "refund_time": {"name": "_refund_time", "type": TYPE_STRING, "required": false}, + "seen_before": {"name": "_seen_before", "type": TYPE_BOOL, "required": false}, + "store": {"name": "_store", "type": TYPE_INT, "required": false}, + "transaction_id": {"name": "_transaction_id", "type": TYPE_STRING, "required": false}, + "update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false}, + "user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false}, + } + + # Timestamp when the receipt validation was stored in DB. + var _create_time + var create_time : String: + get: + return "" if not _create_time is String else String(_create_time) + + # Whether the purchase was done in production or sandbox environment. + var _environment + var environment : int: + get: + return ApiStoreEnvironment.values()[0] if not ApiStoreEnvironment.values().has(_environment) else _environment + + # Purchase Product ID. + var _product_id + var product_id : String: + get: + return "" if not _product_id is String else String(_product_id) + + # Raw provider validation response. + var _provider_response + var provider_response : String: + get: + return "" if not _provider_response is String else String(_provider_response) + + # Timestamp when the purchase was done. + var _purchase_time + var purchase_time : String: + get: + return "" if not _purchase_time is String else String(_purchase_time) + + # + var _refund_time + var refund_time : String: + get: + return "" if not _refund_time is String else String(_refund_time) + + # Whether the purchase had already been validated by Nakama before. + var _seen_before + var seen_before : bool: + get: + return false if not _seen_before is bool else bool(_seen_before) + + # + var _store + var store : int: + get: + return ApiStoreProvider.values()[0] if not ApiStoreProvider.values().has(_store) else _store + + # Purchase Transaction ID. + var _transaction_id + var transaction_id : String: + get: + return "" if not _transaction_id is String else String(_transaction_id) + + # Timestamp when the receipt validation was updated in DB. + var _update_time + var update_time : String: + get: + return "" if not _update_time is String else String(_update_time) + + # Purchase User ID. + var _user_id + var user_id : String: + get: + return "" if not _user_id is String else String(_user_id) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatedPurchase: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatedPurchase", p_dict), ApiValidatedPurchase) as ApiValidatedPurchase + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "create_time: %s, " % _create_time + output += "environment: %s, " % _environment + output += "product_id: %s, " % _product_id + output += "provider_response: %s, " % _provider_response + output += "purchase_time: %s, " % _purchase_time + output += "refund_time: %s, " % _refund_time + output += "seen_before: %s, " % _seen_before + output += "store: %s, " % _store + output += "transaction_id: %s, " % _transaction_id + output += "update_time: %s, " % _update_time + output += "user_id: %s, " % _user_id + return output + +# +class ApiValidatedSubscription extends NakamaAsyncResult: + + const _SCHEMA = { + "active": {"name": "_active", "type": TYPE_BOOL, "required": false}, + "create_time": {"name": "_create_time", "type": TYPE_STRING, "required": false}, + "environment": {"name": "_environment", "type": TYPE_INT, "required": false}, + "expiry_time": {"name": "_expiry_time", "type": TYPE_STRING, "required": false}, + "original_transaction_id": {"name": "_original_transaction_id", "type": TYPE_STRING, "required": false}, + "product_id": {"name": "_product_id", "type": TYPE_STRING, "required": false}, + "provider_notification": {"name": "_provider_notification", "type": TYPE_STRING, "required": false}, + "provider_response": {"name": "_provider_response", "type": TYPE_STRING, "required": false}, + "purchase_time": {"name": "_purchase_time", "type": TYPE_STRING, "required": false}, + "refund_time": {"name": "_refund_time", "type": TYPE_STRING, "required": false}, + "store": {"name": "_store", "type": TYPE_INT, "required": false}, + "update_time": {"name": "_update_time", "type": TYPE_STRING, "required": false}, + "user_id": {"name": "_user_id", "type": TYPE_STRING, "required": false}, + } + + # Whether the subscription is currently active or not. + var _active + var active : bool: + get: + return false if not _active is bool else bool(_active) + + # UNIX Timestamp when the receipt validation was stored in DB. + var _create_time + var create_time : String: + get: + return "" if not _create_time is String else String(_create_time) + + # Whether the purchase was done in production or sandbox environment. + var _environment + var environment : int: + get: + return ApiStoreEnvironment.values()[0] if not ApiStoreEnvironment.values().has(_environment) else _environment + + # Subscription expiration time. The subscription can still be auto-renewed to extend the expiration time further. + var _expiry_time + var expiry_time : String: + get: + return "" if not _expiry_time is String else String(_expiry_time) + + # Purchase Original transaction ID (we only keep track of the original subscription, not subsequent renewals). + var _original_transaction_id + var original_transaction_id : String: + get: + return "" if not _original_transaction_id is String else String(_original_transaction_id) + + # Purchase Product ID. + var _product_id + var product_id : String: + get: + return "" if not _product_id is String else String(_product_id) + + # Raw provider notification body. + var _provider_notification + var provider_notification : String: + get: + return "" if not _provider_notification is String else String(_provider_notification) + + # Raw provider validation response body. + var _provider_response + var provider_response : String: + get: + return "" if not _provider_response is String else String(_provider_response) + + # UNIX Timestamp when the purchase was done. + var _purchase_time + var purchase_time : String: + get: + return "" if not _purchase_time is String else String(_purchase_time) + + # Subscription refund time. If this time is set, the subscription was refunded. + var _refund_time + var refund_time : String: + get: + return "" if not _refund_time is String else String(_refund_time) + + # + var _store + var store : int: + get: + return ApiStoreProvider.values()[0] if not ApiStoreProvider.values().has(_store) else _store + + # UNIX Timestamp when the receipt validation was updated in DB. + var _update_time + var update_time : String: + get: + return "" if not _update_time is String else String(_update_time) + + # Subscription User ID. + var _user_id + var user_id : String: + get: + return "" if not _user_id is String else String(_user_id) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiValidatedSubscription: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiValidatedSubscription", p_dict), ApiValidatedSubscription) as ApiValidatedSubscription + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "active: %s, " % _active + output += "create_time: %s, " % _create_time + output += "environment: %s, " % _environment + output += "expiry_time: %s, " % _expiry_time + output += "original_transaction_id: %s, " % _original_transaction_id + output += "product_id: %s, " % _product_id + output += "provider_notification: %s, " % _provider_notification + output += "provider_response: %s, " % _provider_response + output += "purchase_time: %s, " % _purchase_time + output += "refund_time: %s, " % _refund_time + output += "store: %s, " % _store + output += "update_time: %s, " % _update_time + output += "user_id: %s, " % _user_id + return output + +# The object to store. +class ApiWriteStorageObject extends NakamaAsyncResult: + + const _SCHEMA = { + "collection": {"name": "_collection", "type": TYPE_STRING, "required": false}, + "key": {"name": "_key", "type": TYPE_STRING, "required": false}, + "permission_read": {"name": "_permission_read", "type": TYPE_INT, "required": false}, + "permission_write": {"name": "_permission_write", "type": TYPE_INT, "required": false}, + "value": {"name": "_value", "type": TYPE_STRING, "required": false}, + "version": {"name": "_version", "type": TYPE_STRING, "required": false}, + } + + # The collection to store the object. + var _collection + var collection : String: + get: + return "" if not _collection is String else String(_collection) + + # The key for the object within the collection. + var _key + var key : String: + get: + return "" if not _key is String else String(_key) + + # The read access permissions for the object. + var _permission_read + var permission_read : int: + get: + return 0 if not _permission_read is int else int(_permission_read) + + # The write access permissions for the object. + var _permission_write + var permission_write : int: + get: + return 0 if not _permission_write is int else int(_permission_write) + + # The value of the object. + var _value + var value : String: + get: + return "" if not _value is String else String(_value) + + # The version hash of the object to check. Possible values are: ["", "*", "#hash#"]. + var _version + var version : String: + get: + return "" if not _version is String else String(_version) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiWriteStorageObject: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiWriteStorageObject", p_dict), ApiWriteStorageObject) as ApiWriteStorageObject + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "collection: %s, " % _collection + output += "key: %s, " % _key + output += "permission_read: %s, " % _permission_read + output += "permission_write: %s, " % _permission_write + output += "value: %s, " % _value + output += "version: %s, " % _version + return output + +# Write objects to the storage engine. +class ApiWriteStorageObjectsRequest extends NakamaAsyncResult: + + const _SCHEMA = { + "objects": {"name": "_objects", "type": TYPE_ARRAY, "required": false, "content": "ApiWriteStorageObject"}, + } + + # The objects to store on the server. + var _objects + var objects : Array: + get: + return Array() if not _objects is Array else Array(_objects) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ApiWriteStorageObjectsRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ApiWriteStorageObjectsRequest", p_dict), ApiWriteStorageObjectsRequest) as ApiWriteStorageObjectsRequest + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "objects: %s, " % [_objects] + return output + +# +class ProtobufAny extends NakamaAsyncResult: + + const _SCHEMA = { + "type_url": {"name": "_type_url", "type": TYPE_STRING, "required": false}, + "value": {"name": "_value", "type": TYPE_STRING, "required": false}, + } + + # + var _type_url + var type_url : String: + get: + return "" if not _type_url is String else String(_type_url) + + # + var _value + var value : String: + get: + return "" if not _value is String else String(_value) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ProtobufAny: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ProtobufAny", p_dict), ProtobufAny) as ProtobufAny + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "type_url: %s, " % _type_url + output += "value: %s, " % _value + return output + +# +class RpcStatus extends NakamaAsyncResult: + + const _SCHEMA = { + "code": {"name": "_code", "type": TYPE_INT, "required": false}, + "details": {"name": "_details", "type": TYPE_ARRAY, "required": false, "content": "ProtobufAny"}, + "message": {"name": "_message", "type": TYPE_STRING, "required": false}, + } + + # + var _code + var code : int: + get: + return 0 if not _code is int else int(_code) + + # + var _details + var details : Array: + get: + return Array() if not _details is Array else Array(_details) + + # + var _message + var message : String: + get: + return "" if not _message is String else String(_message) + + func _init(p_exception = null): + super(p_exception) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> RpcStatus: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "RpcStatus", p_dict), RpcStatus) as RpcStatus + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string() -> String: + if is_exception(): + return get_exception()._to_string() + var output : String = "" + output += "code: %s, " % _code + output += "details: %s, " % [_details] + output += "message: %s, " % _message + return output + +# The low level client for the Nakama API. +class ApiClient extends RefCounted: + + var _base_uri : String + + var _http_adapter + var _namespace : GDScript + var _server_key : String + var auto_refresh := true + var auto_refresh_time := 300 + + var auto_retry : bool: + set(p_value): + _http_adapter.auto_retry = p_value + get: + return _http_adapter.auto_retry + + var auto_retry_count : int: + set(p_value): + _http_adapter.auto_retry_count = p_value + get: + return _http_adapter.auto_retry_count + + var auto_retry_backoff_base : int: + set(p_value): + _http_adapter.auto_retry_backoff_base = p_value + get: + return _http_adapter.auto_retry_backoff_base + + var last_cancel_token: + get: + return _http_adapter.get_last_token() + + func _init(p_base_uri : String, p_http_adapter, p_namespace : GDScript, p_server_key : String, p_timeout : int = 10): + _base_uri = p_base_uri + _http_adapter = p_http_adapter + _http_adapter.timeout = p_timeout + _namespace = p_namespace + _server_key = p_server_key + + func _refresh_session(p_session : NakamaSession): + if auto_refresh and p_session.is_valid() and p_session.refresh_token and not p_session.is_refresh_expired() and p_session.would_expire_in(auto_refresh_time): + var request = ApiSessionRefreshRequest.new() + request._token = p_session.refresh_token + return await session_refresh_async(_server_key, "", request) + return null + + func cancel_request(p_token): + if p_token: + _http_adapter.cancel_request(p_token) + + # A healthcheck which load balancers can use to check the service. + func healthcheck_async( + p_session : NakamaSession + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/healthcheck" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Delete the current user's account. + func delete_account_async( + p_session : NakamaSession + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "DELETE" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Fetch the current user's account. + func get_account_async( + p_session : NakamaSession + ) -> ApiAccount: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiAccount.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiAccount.new(result) + var out : ApiAccount = NakamaSerializer.deserialize(_namespace, "ApiAccount", result) + return out + + # Update fields in the current user's account. + func update_account_async( + p_session : NakamaSession + , p_body : ApiUpdateAccountRequest + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "PUT" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Authenticate a user with an Apple ID against the server. + func authenticate_apple_async( + p_basic_auth_username : String + , p_basic_auth_password : String + , p_account : ApiAccountApple + , p_create = null # : boolean + , p_username = null # : string + ) -> ApiSession: + var urlpath : String = "/v2/account/authenticate/apple" + var query_params = "" + if p_create != null: + query_params += "create=%s&" % str(bool(p_create)).to_lower() + if p_username != null: + query_params += "username=%s&" % NakamaSerializer.escape_http(p_username) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password) + var header = "Basic %s" % credentials + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSession.new(result) + var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result) + return out + + # Authenticate a user with a custom id against the server. + func authenticate_custom_async( + p_basic_auth_username : String + , p_basic_auth_password : String + , p_account : ApiAccountCustom + , p_create = null # : boolean + , p_username = null # : string + ) -> ApiSession: + var urlpath : String = "/v2/account/authenticate/custom" + var query_params = "" + if p_create != null: + query_params += "create=%s&" % str(bool(p_create)).to_lower() + if p_username != null: + query_params += "username=%s&" % NakamaSerializer.escape_http(p_username) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password) + var header = "Basic %s" % credentials + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSession.new(result) + var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result) + return out + + # Authenticate a user with a device id against the server. + func authenticate_device_async( + p_basic_auth_username : String + , p_basic_auth_password : String + , p_account : ApiAccountDevice + , p_create = null # : boolean + , p_username = null # : string + ) -> ApiSession: + var urlpath : String = "/v2/account/authenticate/device" + var query_params = "" + if p_create != null: + query_params += "create=%s&" % str(bool(p_create)).to_lower() + if p_username != null: + query_params += "username=%s&" % NakamaSerializer.escape_http(p_username) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password) + var header = "Basic %s" % credentials + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSession.new(result) + var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result) + return out + + # Authenticate a user with an email+password against the server. + func authenticate_email_async( + p_basic_auth_username : String + , p_basic_auth_password : String + , p_account : ApiAccountEmail + , p_create = null # : boolean + , p_username = null # : string + ) -> ApiSession: + var urlpath : String = "/v2/account/authenticate/email" + var query_params = "" + if p_create != null: + query_params += "create=%s&" % str(bool(p_create)).to_lower() + if p_username != null: + query_params += "username=%s&" % NakamaSerializer.escape_http(p_username) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password) + var header = "Basic %s" % credentials + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSession.new(result) + var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result) + return out + + # Authenticate a user with a Facebook OAuth token against the server. + func authenticate_facebook_async( + p_basic_auth_username : String + , p_basic_auth_password : String + , p_account : ApiAccountFacebook + , p_create = null # : boolean + , p_username = null # : string + , p_sync = null # : boolean + ) -> ApiSession: + var urlpath : String = "/v2/account/authenticate/facebook" + var query_params = "" + if p_create != null: + query_params += "create=%s&" % str(bool(p_create)).to_lower() + if p_username != null: + query_params += "username=%s&" % NakamaSerializer.escape_http(p_username) + if p_sync != null: + query_params += "sync=%s&" % str(bool(p_sync)).to_lower() + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password) + var header = "Basic %s" % credentials + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSession.new(result) + var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result) + return out + + # Authenticate a user with a Facebook Instant Game token against the server. + func authenticate_facebook_instant_game_async( + p_basic_auth_username : String + , p_basic_auth_password : String + , p_account : ApiAccountFacebookInstantGame + , p_create = null # : boolean + , p_username = null # : string + ) -> ApiSession: + var urlpath : String = "/v2/account/authenticate/facebookinstantgame" + var query_params = "" + if p_create != null: + query_params += "create=%s&" % str(bool(p_create)).to_lower() + if p_username != null: + query_params += "username=%s&" % NakamaSerializer.escape_http(p_username) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password) + var header = "Basic %s" % credentials + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSession.new(result) + var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result) + return out + + # Authenticate a user with Apple's GameCenter against the server. + func authenticate_game_center_async( + p_basic_auth_username : String + , p_basic_auth_password : String + , p_account : ApiAccountGameCenter + , p_create = null # : boolean + , p_username = null # : string + ) -> ApiSession: + var urlpath : String = "/v2/account/authenticate/gamecenter" + var query_params = "" + if p_create != null: + query_params += "create=%s&" % str(bool(p_create)).to_lower() + if p_username != null: + query_params += "username=%s&" % NakamaSerializer.escape_http(p_username) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password) + var header = "Basic %s" % credentials + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSession.new(result) + var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result) + return out + + # Authenticate a user with Google against the server. + func authenticate_google_async( + p_basic_auth_username : String + , p_basic_auth_password : String + , p_account : ApiAccountGoogle + , p_create = null # : boolean + , p_username = null # : string + ) -> ApiSession: + var urlpath : String = "/v2/account/authenticate/google" + var query_params = "" + if p_create != null: + query_params += "create=%s&" % str(bool(p_create)).to_lower() + if p_username != null: + query_params += "username=%s&" % NakamaSerializer.escape_http(p_username) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password) + var header = "Basic %s" % credentials + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSession.new(result) + var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result) + return out + + # Authenticate a user with Steam against the server. + func authenticate_steam_async( + p_basic_auth_username : String + , p_basic_auth_password : String + , p_account : ApiAccountSteam + , p_create = null # : boolean + , p_username = null # : string + , p_sync = null # : boolean + ) -> ApiSession: + var urlpath : String = "/v2/account/authenticate/steam" + var query_params = "" + if p_create != null: + query_params += "create=%s&" % str(bool(p_create)).to_lower() + if p_username != null: + query_params += "username=%s&" % NakamaSerializer.escape_http(p_username) + if p_sync != null: + query_params += "sync=%s&" % str(bool(p_sync)).to_lower() + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password) + var header = "Basic %s" % credentials + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSession.new(result) + var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result) + return out + + # Add an Apple ID to the social profiles on the current user's account. + func link_apple_async( + p_session : NakamaSession + , p_body : ApiAccountApple + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/link/apple" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Add a custom ID to the social profiles on the current user's account. + func link_custom_async( + p_session : NakamaSession + , p_body : ApiAccountCustom + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/link/custom" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Add a device ID to the social profiles on the current user's account. + func link_device_async( + p_session : NakamaSession + , p_body : ApiAccountDevice + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/link/device" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Add an email+password to the social profiles on the current user's account. + func link_email_async( + p_session : NakamaSession + , p_body : ApiAccountEmail + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/link/email" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Add Facebook to the social profiles on the current user's account. + func link_facebook_async( + p_session : NakamaSession + , p_account : ApiAccountFacebook + , p_sync = null # : boolean + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/link/facebook" + var query_params = "" + if p_sync != null: + query_params += "sync=%s&" % str(bool(p_sync)).to_lower() + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Add Facebook Instant Game to the social profiles on the current user's account. + func link_facebook_instant_game_async( + p_session : NakamaSession + , p_body : ApiAccountFacebookInstantGame + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/link/facebookinstantgame" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Add Apple's GameCenter to the social profiles on the current user's account. + func link_game_center_async( + p_session : NakamaSession + , p_body : ApiAccountGameCenter + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/link/gamecenter" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Add Google to the social profiles on the current user's account. + func link_google_async( + p_session : NakamaSession + , p_body : ApiAccountGoogle + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/link/google" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Add Steam to the social profiles on the current user's account. + func link_steam_async( + p_session : NakamaSession + , p_body : ApiLinkSteamRequest + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/link/steam" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Refresh a user's session using a refresh token retrieved from a previous authentication request. + func session_refresh_async( + p_basic_auth_username : String + , p_basic_auth_password : String + , p_body : ApiSessionRefreshRequest + ) -> ApiSession: + var urlpath : String = "/v2/account/session/refresh" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var credentials = Marshalls.utf8_to_base64(p_basic_auth_username + ":" + p_basic_auth_password) + var header = "Basic %s" % credentials + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSession.new(result) + var out : ApiSession = NakamaSerializer.deserialize(_namespace, "ApiSession", result) + return out + + # Remove the Apple ID from the social profiles on the current user's account. + func unlink_apple_async( + p_session : NakamaSession + , p_body : ApiAccountApple + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/unlink/apple" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Remove the custom ID from the social profiles on the current user's account. + func unlink_custom_async( + p_session : NakamaSession + , p_body : ApiAccountCustom + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/unlink/custom" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Remove the device ID from the social profiles on the current user's account. + func unlink_device_async( + p_session : NakamaSession + , p_body : ApiAccountDevice + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/unlink/device" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Remove the email+password from the social profiles on the current user's account. + func unlink_email_async( + p_session : NakamaSession + , p_body : ApiAccountEmail + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/unlink/email" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Remove Facebook from the social profiles on the current user's account. + func unlink_facebook_async( + p_session : NakamaSession + , p_body : ApiAccountFacebook + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/unlink/facebook" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Remove Facebook Instant Game profile from the social profiles on the current user's account. + func unlink_facebook_instant_game_async( + p_session : NakamaSession + , p_body : ApiAccountFacebookInstantGame + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/unlink/facebookinstantgame" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Remove Apple's GameCenter from the social profiles on the current user's account. + func unlink_game_center_async( + p_session : NakamaSession + , p_body : ApiAccountGameCenter + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/unlink/gamecenter" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Remove Google from the social profiles on the current user's account. + func unlink_google_async( + p_session : NakamaSession + , p_body : ApiAccountGoogle + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/unlink/google" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Remove Steam from the social profiles on the current user's account. + func unlink_steam_async( + p_session : NakamaSession + , p_body : ApiAccountSteam + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/account/unlink/steam" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # List a channel's message history. + func list_channel_messages_async( + p_session : NakamaSession + , p_channel_id : String + , p_limit = null # : integer + , p_forward = null # : boolean + , p_cursor = null # : string + ) -> ApiChannelMessageList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiChannelMessageList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/channel/{channelId}" + urlpath = urlpath.replace("{channelId}", NakamaSerializer.escape_http(p_channel_id)) + var query_params = "" + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_forward != null: + query_params += "forward=%s&" % str(bool(p_forward)).to_lower() + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiChannelMessageList.new(result) + var out : ApiChannelMessageList = NakamaSerializer.deserialize(_namespace, "ApiChannelMessageList", result) + return out + + # Submit an event for processing in the server's registered runtime custom events handler. + func event_async( + p_session : NakamaSession + , p_body : ApiEvent + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/event" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Delete one or more users by ID or username. + func delete_friends_async( + p_session : NakamaSession + , p_ids = null # : array + , p_usernames = null # : array + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/friend" + var query_params = "" + if p_ids != null: + for elem in p_ids: + query_params += "ids=%s&" % elem + if p_usernames != null: + for elem in p_usernames: + query_params += "usernames=%s&" % elem + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "DELETE" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # List all friends for the current user. + func list_friends_async( + p_session : NakamaSession + , p_limit = null # : integer + , p_state = null # : integer + , p_cursor = null # : string + ) -> ApiFriendList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiFriendList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/friend" + var query_params = "" + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_state != null: + query_params += "state=%d&" % p_state + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiFriendList.new(result) + var out : ApiFriendList = NakamaSerializer.deserialize(_namespace, "ApiFriendList", result) + return out + + # Add friends by ID or username to a user's account. + func add_friends_async( + p_session : NakamaSession + , p_ids = null # : array + , p_usernames = null # : array + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/friend" + var query_params = "" + if p_ids != null: + for elem in p_ids: + query_params += "ids=%s&" % elem + if p_usernames != null: + for elem in p_usernames: + query_params += "usernames=%s&" % elem + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Block one or more users by ID or username. + func block_friends_async( + p_session : NakamaSession + , p_ids = null # : array + , p_usernames = null # : array + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/friend/block" + var query_params = "" + if p_ids != null: + for elem in p_ids: + query_params += "ids=%s&" % elem + if p_usernames != null: + for elem in p_usernames: + query_params += "usernames=%s&" % elem + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Import Facebook friends and add them to a user's account. + func import_facebook_friends_async( + p_session : NakamaSession + , p_account : ApiAccountFacebook + , p_reset = null # : boolean + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/friend/facebook" + var query_params = "" + if p_reset != null: + query_params += "reset=%s&" % str(bool(p_reset)).to_lower() + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Import Steam friends and add them to a user's account. + func import_steam_friends_async( + p_session : NakamaSession + , p_account : ApiAccountSteam + , p_reset = null # : boolean + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/friend/steam" + var query_params = "" + if p_reset != null: + query_params += "reset=%s&" % str(bool(p_reset)).to_lower() + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_account.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # List groups based on given filters. + func list_groups_async( + p_session : NakamaSession + , p_name = null # : string + , p_cursor = null # : string + , p_limit = null # : integer + , p_lang_tag = null # : string + , p_members = null # : integer + , p_open = null # : boolean + ) -> ApiGroupList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiGroupList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group" + var query_params = "" + if p_name != null: + query_params += "name=%s&" % NakamaSerializer.escape_http(p_name) + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_lang_tag != null: + query_params += "lang_tag=%s&" % NakamaSerializer.escape_http(p_lang_tag) + if p_members != null: + query_params += "members=%d&" % p_members + if p_open != null: + query_params += "open=%s&" % str(bool(p_open)).to_lower() + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiGroupList.new(result) + var out : ApiGroupList = NakamaSerializer.deserialize(_namespace, "ApiGroupList", result) + return out + + # Create a new group with the current user as the owner. + func create_group_async( + p_session : NakamaSession + , p_body : ApiCreateGroupRequest + ) -> ApiGroup: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiGroup.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiGroup.new(result) + var out : ApiGroup = NakamaSerializer.deserialize(_namespace, "ApiGroup", result) + return out + + # Delete a group by ID. + func delete_group_async( + p_session : NakamaSession + , p_group_id : String + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group/{groupId}" + urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id)) + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "DELETE" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Update fields in a given group. + func update_group_async( + p_session : NakamaSession + , p_group_id : String + , p_body : ApiUpdateGroupRequest + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group/{groupId}" + urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id)) + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "PUT" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Add users to a group. + func add_group_users_async( + p_session : NakamaSession + , p_group_id : String + , p_user_ids = null # : array + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group/{groupId}/add" + urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id)) + var query_params = "" + if p_user_ids != null: + for elem in p_user_ids: + query_params += "user_ids=%s&" % elem + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Ban a set of users from a group. + func ban_group_users_async( + p_session : NakamaSession + , p_group_id : String + , p_user_ids = null # : array + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group/{groupId}/ban" + urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id)) + var query_params = "" + if p_user_ids != null: + for elem in p_user_ids: + query_params += "user_ids=%s&" % elem + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Demote a set of users in a group to the next role down. + func demote_group_users_async( + p_session : NakamaSession + , p_group_id : String + , p_user_ids = null # : array + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group/{groupId}/demote" + urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id)) + var query_params = "" + if p_user_ids != null: + for elem in p_user_ids: + query_params += "user_ids=%s&" % elem + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Immediately join an open group, or request to join a closed one. + func join_group_async( + p_session : NakamaSession + , p_group_id : String + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group/{groupId}/join" + urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id)) + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Kick a set of users from a group. + func kick_group_users_async( + p_session : NakamaSession + , p_group_id : String + , p_user_ids = null # : array + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group/{groupId}/kick" + urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id)) + var query_params = "" + if p_user_ids != null: + for elem in p_user_ids: + query_params += "user_ids=%s&" % elem + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Leave a group the user is a member of. + func leave_group_async( + p_session : NakamaSession + , p_group_id : String + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group/{groupId}/leave" + urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id)) + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Promote a set of users in a group to the next role up. + func promote_group_users_async( + p_session : NakamaSession + , p_group_id : String + , p_user_ids = null # : array + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group/{groupId}/promote" + urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id)) + var query_params = "" + if p_user_ids != null: + for elem in p_user_ids: + query_params += "user_ids=%s&" % elem + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # List all users that are part of a group. + func list_group_users_async( + p_session : NakamaSession + , p_group_id : String + , p_limit = null # : integer + , p_state = null # : integer + , p_cursor = null # : string + ) -> ApiGroupUserList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiGroupUserList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/group/{groupId}/user" + urlpath = urlpath.replace("{groupId}", NakamaSerializer.escape_http(p_group_id)) + var query_params = "" + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_state != null: + query_params += "state=%d&" % p_state + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiGroupUserList.new(result) + var out : ApiGroupUserList = NakamaSerializer.deserialize(_namespace, "ApiGroupUserList", result) + return out + + # Validate Apple IAP Receipt + func validate_purchase_apple_async( + p_session : NakamaSession + , p_body : ApiValidatePurchaseAppleRequest + ) -> ApiValidatePurchaseResponse: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiValidatePurchaseResponse.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/iap/purchase/apple" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiValidatePurchaseResponse.new(result) + var out : ApiValidatePurchaseResponse = NakamaSerializer.deserialize(_namespace, "ApiValidatePurchaseResponse", result) + return out + + # Validate Google IAP Receipt + func validate_purchase_google_async( + p_session : NakamaSession + , p_body : ApiValidatePurchaseGoogleRequest + ) -> ApiValidatePurchaseResponse: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiValidatePurchaseResponse.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/iap/purchase/google" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiValidatePurchaseResponse.new(result) + var out : ApiValidatePurchaseResponse = NakamaSerializer.deserialize(_namespace, "ApiValidatePurchaseResponse", result) + return out + + # Validate Huawei IAP Receipt + func validate_purchase_huawei_async( + p_session : NakamaSession + , p_body : ApiValidatePurchaseHuaweiRequest + ) -> ApiValidatePurchaseResponse: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiValidatePurchaseResponse.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/iap/purchase/huawei" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiValidatePurchaseResponse.new(result) + var out : ApiValidatePurchaseResponse = NakamaSerializer.deserialize(_namespace, "ApiValidatePurchaseResponse", result) + return out + + # List user's subscriptions. + func list_subscriptions_async( + p_session : NakamaSession + , p_body : ApiListSubscriptionsRequest + ) -> ApiSubscriptionList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiSubscriptionList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/iap/subscription" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiSubscriptionList.new(result) + var out : ApiSubscriptionList = NakamaSerializer.deserialize(_namespace, "ApiSubscriptionList", result) + return out + + # Validate Apple Subscription Receipt + func validate_subscription_apple_async( + p_session : NakamaSession + , p_body : ApiValidateSubscriptionAppleRequest + ) -> ApiValidateSubscriptionResponse: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiValidateSubscriptionResponse.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/iap/subscription/apple" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiValidateSubscriptionResponse.new(result) + var out : ApiValidateSubscriptionResponse = NakamaSerializer.deserialize(_namespace, "ApiValidateSubscriptionResponse", result) + return out + + # Validate Google Subscription Receipt + func validate_subscription_google_async( + p_session : NakamaSession + , p_body : ApiValidateSubscriptionGoogleRequest + ) -> ApiValidateSubscriptionResponse: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiValidateSubscriptionResponse.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/iap/subscription/google" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiValidateSubscriptionResponse.new(result) + var out : ApiValidateSubscriptionResponse = NakamaSerializer.deserialize(_namespace, "ApiValidateSubscriptionResponse", result) + return out + + # Get subscription by product id. + func get_subscription_async( + p_session : NakamaSession + , p_product_id : String + ) -> ApiValidatedSubscription: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiValidatedSubscription.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/iap/subscription/{productId}" + urlpath = urlpath.replace("{productId}", NakamaSerializer.escape_http(p_product_id)) + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiValidatedSubscription.new(result) + var out : ApiValidatedSubscription = NakamaSerializer.deserialize(_namespace, "ApiValidatedSubscription", result) + return out + + # Delete a leaderboard record. + func delete_leaderboard_record_async( + p_session : NakamaSession + , p_leaderboard_id : String + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/leaderboard/{leaderboardId}" + urlpath = urlpath.replace("{leaderboardId}", NakamaSerializer.escape_http(p_leaderboard_id)) + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "DELETE" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # List leaderboard records. + func list_leaderboard_records_async( + p_session : NakamaSession + , p_leaderboard_id : String + , p_owner_ids = null # : array + , p_limit = null # : integer + , p_cursor = null # : string + , p_expiry = null # : string + ) -> ApiLeaderboardRecordList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiLeaderboardRecordList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/leaderboard/{leaderboardId}" + urlpath = urlpath.replace("{leaderboardId}", NakamaSerializer.escape_http(p_leaderboard_id)) + var query_params = "" + if p_owner_ids != null: + for elem in p_owner_ids: + query_params += "owner_ids=%s&" % elem + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + if p_expiry != null: + query_params += "expiry=%s&" % NakamaSerializer.escape_http(p_expiry) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiLeaderboardRecordList.new(result) + var out : ApiLeaderboardRecordList = NakamaSerializer.deserialize(_namespace, "ApiLeaderboardRecordList", result) + return out + + # Write a record to a leaderboard. + func write_leaderboard_record_async( + p_session : NakamaSession + , p_leaderboard_id : String + , p_record : WriteLeaderboardRecordRequestLeaderboardRecordWrite + ) -> ApiLeaderboardRecord: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiLeaderboardRecord.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/leaderboard/{leaderboardId}" + urlpath = urlpath.replace("{leaderboardId}", NakamaSerializer.escape_http(p_leaderboard_id)) + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_record.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiLeaderboardRecord.new(result) + var out : ApiLeaderboardRecord = NakamaSerializer.deserialize(_namespace, "ApiLeaderboardRecord", result) + return out + + # List leaderboard records that belong to a user. + func list_leaderboard_records_around_owner_async( + p_session : NakamaSession + , p_leaderboard_id : String + , p_owner_id : String + , p_limit = null # : integer + , p_expiry = null # : string + , p_cursor = null # : string + ) -> ApiLeaderboardRecordList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiLeaderboardRecordList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/leaderboard/{leaderboardId}/owner/{ownerId}" + urlpath = urlpath.replace("{leaderboardId}", NakamaSerializer.escape_http(p_leaderboard_id)) + urlpath = urlpath.replace("{ownerId}", NakamaSerializer.escape_http(p_owner_id)) + var query_params = "" + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_expiry != null: + query_params += "expiry=%s&" % NakamaSerializer.escape_http(p_expiry) + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiLeaderboardRecordList.new(result) + var out : ApiLeaderboardRecordList = NakamaSerializer.deserialize(_namespace, "ApiLeaderboardRecordList", result) + return out + + # Fetch list of running matches. + func list_matches_async( + p_session : NakamaSession + , p_limit = null # : integer + , p_authoritative = null # : boolean + , p_label = null # : string + , p_min_size = null # : integer + , p_max_size = null # : integer + , p_query = null # : string + ) -> ApiMatchList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiMatchList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/match" + var query_params = "" + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_authoritative != null: + query_params += "authoritative=%s&" % str(bool(p_authoritative)).to_lower() + if p_label != null: + query_params += "label=%s&" % NakamaSerializer.escape_http(p_label) + if p_min_size != null: + query_params += "min_size=%d&" % p_min_size + if p_max_size != null: + query_params += "max_size=%d&" % p_max_size + if p_query != null: + query_params += "query=%s&" % NakamaSerializer.escape_http(p_query) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiMatchList.new(result) + var out : ApiMatchList = NakamaSerializer.deserialize(_namespace, "ApiMatchList", result) + return out + + # Delete one or more notifications for the current user. + func delete_notifications_async( + p_session : NakamaSession + , p_ids = null # : array + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/notification" + var query_params = "" + if p_ids != null: + for elem in p_ids: + query_params += "ids=%s&" % elem + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "DELETE" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Fetch list of notifications. + func list_notifications_async( + p_session : NakamaSession + , p_limit = null # : integer + , p_cacheable_cursor = null # : string + ) -> ApiNotificationList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiNotificationList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/notification" + var query_params = "" + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_cacheable_cursor != null: + query_params += "cacheable_cursor=%s&" % NakamaSerializer.escape_http(p_cacheable_cursor) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiNotificationList.new(result) + var out : ApiNotificationList = NakamaSerializer.deserialize(_namespace, "ApiNotificationList", result) + return out + + # Execute a Lua function on the server. + func rpc_func2_async( + p_bearer_token : String + , p_id : String + , p_payload = null # : string + , p_http_key = null # : string + ) -> ApiRpc: + var urlpath : String = "/v2/rpc/{id}" + urlpath = urlpath.replace("{id}", NakamaSerializer.escape_http(p_id)) + var query_params = "" + if p_payload != null: + query_params += "payload=%s&" % NakamaSerializer.escape_http(p_payload) + if p_http_key != null: + query_params += "http_key=%s&" % NakamaSerializer.escape_http(p_http_key) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + if (p_bearer_token): + var header = "Bearer %s" % p_bearer_token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiRpc.new(result) + var out : ApiRpc = NakamaSerializer.deserialize(_namespace, "ApiRpc", result) + return out + + # Execute a Lua function on the server. + func rpc_func_async( + p_bearer_token : String + , p_id : String + , p_payload : String + , p_http_key = null # : string + ) -> ApiRpc: + var urlpath : String = "/v2/rpc/{id}" + urlpath = urlpath.replace("{id}", NakamaSerializer.escape_http(p_id)) + var query_params = "" + if p_http_key != null: + query_params += "http_key=%s&" % NakamaSerializer.escape_http(p_http_key) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + if (p_bearer_token): + var header = "Bearer %s" % p_bearer_token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_payload).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiRpc.new(result) + var out : ApiRpc = NakamaSerializer.deserialize(_namespace, "ApiRpc", result) + return out + + # Log out a session, invalidate a refresh token, or log out all sessions/refresh tokens for a user. + func session_logout_async( + p_session : NakamaSession + , p_body : ApiSessionLogoutRequest + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/session/logout" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # Get storage objects. + func read_storage_objects_async( + p_session : NakamaSession + , p_body : ApiReadStorageObjectsRequest + ) -> ApiStorageObjects: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiStorageObjects.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/storage" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiStorageObjects.new(result) + var out : ApiStorageObjects = NakamaSerializer.deserialize(_namespace, "ApiStorageObjects", result) + return out + + # Write objects into the storage engine. + func write_storage_objects_async( + p_session : NakamaSession + , p_body : ApiWriteStorageObjectsRequest + ) -> ApiStorageObjectAcks: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiStorageObjectAcks.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/storage" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "PUT" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiStorageObjectAcks.new(result) + var out : ApiStorageObjectAcks = NakamaSerializer.deserialize(_namespace, "ApiStorageObjectAcks", result) + return out + + # Delete one or more objects by ID or username. + func delete_storage_objects_async( + p_session : NakamaSession + , p_body : ApiDeleteStorageObjectsRequest + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/storage/delete" + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "PUT" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_body.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # List publicly readable storage objects in a given collection. + func list_storage_objects_async( + p_session : NakamaSession + , p_collection : String + , p_user_id = null # : string + , p_limit = null # : integer + , p_cursor = null # : string + ) -> ApiStorageObjectList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiStorageObjectList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/storage/{collection}" + urlpath = urlpath.replace("{collection}", NakamaSerializer.escape_http(p_collection)) + var query_params = "" + if p_user_id != null: + query_params += "user_id=%s&" % NakamaSerializer.escape_http(p_user_id) + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiStorageObjectList.new(result) + var out : ApiStorageObjectList = NakamaSerializer.deserialize(_namespace, "ApiStorageObjectList", result) + return out + + # List publicly readable storage objects in a given collection. + func list_storage_objects2_async( + p_session : NakamaSession + , p_collection : String + , p_user_id : String + , p_limit = null # : integer + , p_cursor = null # : string + ) -> ApiStorageObjectList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiStorageObjectList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/storage/{collection}/{userId}" + urlpath = urlpath.replace("{collection}", NakamaSerializer.escape_http(p_collection)) + urlpath = urlpath.replace("{userId}", NakamaSerializer.escape_http(p_user_id)) + var query_params = "" + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiStorageObjectList.new(result) + var out : ApiStorageObjectList = NakamaSerializer.deserialize(_namespace, "ApiStorageObjectList", result) + return out + + # List current or upcoming tournaments. + func list_tournaments_async( + p_session : NakamaSession + , p_category_start = null # : integer + , p_category_end = null # : integer + , p_start_time = null # : integer + , p_end_time = null # : integer + , p_limit = null # : integer + , p_cursor = null # : string + ) -> ApiTournamentList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiTournamentList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/tournament" + var query_params = "" + if p_category_start != null: + query_params += "category_start=%d&" % p_category_start + if p_category_end != null: + query_params += "category_end=%d&" % p_category_end + if p_start_time != null: + query_params += "start_time=%d&" % p_start_time + if p_end_time != null: + query_params += "end_time=%d&" % p_end_time + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiTournamentList.new(result) + var out : ApiTournamentList = NakamaSerializer.deserialize(_namespace, "ApiTournamentList", result) + return out + + # List tournament records. + func list_tournament_records_async( + p_session : NakamaSession + , p_tournament_id : String + , p_owner_ids = null # : array + , p_limit = null # : integer + , p_cursor = null # : string + , p_expiry = null # : string + ) -> ApiTournamentRecordList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiTournamentRecordList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/tournament/{tournamentId}" + urlpath = urlpath.replace("{tournamentId}", NakamaSerializer.escape_http(p_tournament_id)) + var query_params = "" + if p_owner_ids != null: + for elem in p_owner_ids: + query_params += "owner_ids=%s&" % elem + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + if p_expiry != null: + query_params += "expiry=%s&" % NakamaSerializer.escape_http(p_expiry) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiTournamentRecordList.new(result) + var out : ApiTournamentRecordList = NakamaSerializer.deserialize(_namespace, "ApiTournamentRecordList", result) + return out + + # Write a record to a tournament. + func write_tournament_record2_async( + p_session : NakamaSession + , p_tournament_id : String + , p_record : WriteTournamentRecordRequestTournamentRecordWrite + ) -> ApiLeaderboardRecord: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiLeaderboardRecord.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/tournament/{tournamentId}" + urlpath = urlpath.replace("{tournamentId}", NakamaSerializer.escape_http(p_tournament_id)) + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_record.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiLeaderboardRecord.new(result) + var out : ApiLeaderboardRecord = NakamaSerializer.deserialize(_namespace, "ApiLeaderboardRecord", result) + return out + + # Write a record to a tournament. + func write_tournament_record_async( + p_session : NakamaSession + , p_tournament_id : String + , p_record : WriteTournamentRecordRequestTournamentRecordWrite + ) -> ApiLeaderboardRecord: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiLeaderboardRecord.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/tournament/{tournamentId}" + urlpath = urlpath.replace("{tournamentId}", NakamaSerializer.escape_http(p_tournament_id)) + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "PUT" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + content = JSON.stringify(p_record.serialize()).to_utf8_buffer() + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiLeaderboardRecord.new(result) + var out : ApiLeaderboardRecord = NakamaSerializer.deserialize(_namespace, "ApiLeaderboardRecord", result) + return out + + # Attempt to join an open and running tournament. + func join_tournament_async( + p_session : NakamaSession + , p_tournament_id : String + ) -> NakamaAsyncResult: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return NakamaAsyncResult.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/tournament/{tournamentId}/join" + urlpath = urlpath.replace("{tournamentId}", NakamaSerializer.escape_http(p_tournament_id)) + var query_params = "" + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "POST" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return NakamaAsyncResult.new(result) + return NakamaAsyncResult.new() + + # List tournament records for a given owner. + func list_tournament_records_around_owner_async( + p_session : NakamaSession + , p_tournament_id : String + , p_owner_id : String + , p_limit = null # : integer + , p_expiry = null # : string + , p_cursor = null # : string + ) -> ApiTournamentRecordList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiTournamentRecordList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/tournament/{tournamentId}/owner/{ownerId}" + urlpath = urlpath.replace("{tournamentId}", NakamaSerializer.escape_http(p_tournament_id)) + urlpath = urlpath.replace("{ownerId}", NakamaSerializer.escape_http(p_owner_id)) + var query_params = "" + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_expiry != null: + query_params += "expiry=%s&" % NakamaSerializer.escape_http(p_expiry) + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiTournamentRecordList.new(result) + var out : ApiTournamentRecordList = NakamaSerializer.deserialize(_namespace, "ApiTournamentRecordList", result) + return out + + # Fetch zero or more users by ID and/or username. + func get_users_async( + p_session : NakamaSession + , p_ids = null # : array + , p_usernames = null # : array + , p_facebook_ids = null # : array + ) -> ApiUsers: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiUsers.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/user" + var query_params = "" + if p_ids != null: + for elem in p_ids: + query_params += "ids=%s&" % elem + if p_usernames != null: + for elem in p_usernames: + query_params += "usernames=%s&" % elem + if p_facebook_ids != null: + for elem in p_facebook_ids: + query_params += "facebook_ids=%s&" % elem + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiUsers.new(result) + var out : ApiUsers = NakamaSerializer.deserialize(_namespace, "ApiUsers", result) + return out + + # List groups the current user belongs to. + func list_user_groups_async( + p_session : NakamaSession + , p_user_id : String + , p_limit = null # : integer + , p_state = null # : integer + , p_cursor = null # : string + ) -> ApiUserGroupList: + var try_refresh = await _refresh_session(p_session) + if try_refresh != null: + if try_refresh.is_exception(): + return ApiUserGroupList.new(try_refresh.get_exception()) + await p_session.refresh(try_refresh) + var urlpath : String = "/v2/user/{userId}/group" + urlpath = urlpath.replace("{userId}", NakamaSerializer.escape_http(p_user_id)) + var query_params = "" + if p_limit != null: + query_params += "limit=%d&" % p_limit + if p_state != null: + query_params += "state=%d&" % p_state + if p_cursor != null: + query_params += "cursor=%s&" % NakamaSerializer.escape_http(p_cursor) + var uri = "%s%s%s" % [_base_uri, urlpath, "?" + query_params if query_params else ""] + var method = "GET" + var headers = {} + var header = "Bearer %s" % p_session.token + headers["Authorization"] = header + + var content : PackedByteArray + + var result = await _http_adapter.send_async(method, uri, headers, content) + if result is NakamaException: + return ApiUserGroupList.new(result) + var out : ApiUserGroupList = NakamaSerializer.deserialize(_namespace, "ApiUserGroupList", result) + return out diff --git a/addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd b/addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd new file mode 100644 index 0000000..05fc5ae --- /dev/null +++ b/addons/com.heroiclabs.nakama/api/NakamaRTAPI.gd @@ -0,0 +1,902 @@ +extends NakamaAsyncResult + +class_name NakamaRTAPI + +# A chat channel on the server. +class Channel extends NakamaAsyncResult: + + const _SCHEMA = { + "id": {"name": "id", "type": TYPE_STRING, "required": true}, + "presences": {"name": "presences", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"}, + "self": {"name": "self_presence", "type": "UserPresence", "required": true}, + "room_name": {"name": "room_name", "type": TYPE_STRING, "required": false}, + "group_id": {"name": "group_id", "type": TYPE_STRING, "required": false}, + "user_id_one": {"name": "user_id_one", "type": TYPE_STRING, "required": false}, + "user_id_two": {"name": "user_id_two", "type": TYPE_STRING, "required": false} + } + + # The server-assigned channel ID. + var id : String + + # The presences visible on the chat channel. + var presences : Array # of objects NakamaUserPresence + + # The presence of the current user. i.e. Your self. + var self_presence : NakamaRTAPI.UserPresence + + # The name of the chat room, or an empty string if this message was not sent through a chat room. + var room_name : String + + # The ID of the group, or an empty string if this message was not sent through a group channel. + var group_id : String + + # The ID of the first DM user, or an empty string if this message was not sent through a DM chat. + var user_id_one : String + + # The ID of the second DM user, or an empty string if this message was not sent through a DM chat. + var user_id_two : String + + func _init(p_ex = null): + super(p_ex) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "Channel" % [ + id, presences, self_presence, room_name, group_id, user_id_one, user_id_two + ] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> Channel: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "Channel", p_dict), Channel) as Channel + + static func get_result_key() -> String: + return "channel" + + +class ChannelMessageAck extends NakamaAsyncResult: + + const _SCHEMA = { + "channel_id": {"name": "channel_id", "type": TYPE_STRING, "required": true}, + "code": {"name": "code", "type": TYPE_INT, "required": true}, + "create_time": {"name": "create_time", "type": TYPE_STRING, "required": false}, + "message_id": {"name": "message_id", "type": TYPE_STRING, "required": true}, + "persistent": {"name": "persistent", "type": TYPE_BOOL, "required": false}, + "update_time": {"name": "update_time", "type": TYPE_STRING, "required": false}, + "username": {"name": "username", "type": TYPE_STRING, "required": false}, + "room_name": {"name": "room_name", "type": TYPE_STRING, "required": false}, + "group_id": {"name": "group_id", "type": TYPE_STRING, "required": false}, + "user_id_one": {"name": "user_id_one", "type": TYPE_STRING, "required": false}, + "user_id_two": {"name": "user_id_two", "type": TYPE_STRING, "required": false} + } + + # The server-assigned channel ID. + var channel_id : String + + # A user-defined code for the chat message. + var code : int + + # The UNIX time when the message was created. + var create_time : String + + # A unique ID for the chat message. + var message_id : String + + # True if the chat message has been stored in history. + var persistent : bool + + # The UNIX time when the message was updated. + var update_time : String + + # The username of the sender of the message. + var username : String + + # The name of the chat room, or an empty string if this message was not sent through a chat room. + var room_name : String + + # The ID of the group, or an empty string if this message was not sent through a group channel. + var group_id : String + + # The ID of the first DM user, or an empty string if this message was not sent through a DM chat. + var user_id_one : String + + # The ID of the second DM user, or an empty string if this message was not sent through a DM chat. + var user_id_two : String + + func _init(p_ex = null): + super(p_ex) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "ChannelMessageAck" % [ + channel_id, code, create_time, message_id, persistent, update_time, username, room_name, group_id, user_id_one, user_id_two + ] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ChannelMessageAck: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ChannelMessageAck", p_dict), ChannelMessageAck) as ChannelMessageAck + + static func get_result_key() -> String: + return "channel_message_ack" + + +# A batch of join and leave presences on a chat channel. +class ChannelPresenceEvent extends NakamaAsyncResult: + + const _SCHEMA = { + "channel_id": {"name": "channel_id", "type": TYPE_STRING, "required": true}, + "joins": {"name": "joins", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"}, + "leaves": {"name": "leaves", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"}, + "room_name": {"name": "room_name", "type": TYPE_STRING, "required": false}, + "group_id": {"name": "group_id", "type": TYPE_STRING, "required": false}, + "user_id_one": {"name": "user_id_one", "type": TYPE_STRING, "required": false}, + "user_id_two": {"name": "user_id_two", "type": TYPE_STRING, "required": false} + } + + # The unique identifier of the chat channel. + var channel_id : String + + # Presences of the users who joined the channel. + var joins : Array # UserPresence + + # Presences of users who left the channel. + var leaves : Array # UserPresence + + # The name of the chat room, or an empty string if this message was not sent through a chat room. + var room_name : String + + # The ID of the group, or an empty string if this message was not sent through a group channel. + var group_id : String + + # The ID of the first DM user, or an empty string if this message was not sent through a DM chat. + var user_id_one : String + + # The ID of the second DM user, or an empty string if this message was not sent through a DM chat. + var user_id_two : String + + func _init(p_ex = null): + super(p_ex) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "ChannelPresenceEvent" % [ + channel_id, joins, leaves, room_name, group_id, user_id_one, user_id_two + ] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> ChannelPresenceEvent: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "ChannelPresenceEvent", p_dict), ChannelPresenceEvent) as ChannelPresenceEvent + + static func get_result_key() -> String: + return "channel_presence_event" + + +# Describes an error which occurred on the server. +class Error extends NakamaAsyncResult: + + const _SCHEMA = { + "code": {"name": "code", "type": TYPE_INT, "required": true}, + "message": {"name": "message", "type": TYPE_STRING, "required": true}, + "context": {"name": "context", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + } + + # The selection of possible error codes. + enum Code { + # An unexpected result from the server. + RUNTIME_EXCEPTION = 0, + # The server received a message which is not recognised. + UNRECOGNIZED_PAYLOAD = 1, + # A message was expected but contains no content. + MISSING_PAYLOAD = 2, + # Fields in the message have an invalid format. + BAD_INPUT = 3, + # The match id was not found. + MATCH_NOT_FOUND = 4, + # The match join was rejected. + MATCH_JOIN_REJECTED = 5, + # The runtime function does not exist on the server. + RUNTIME_FUNCTION_NOT_FOUND = 6, + #The runtime function executed with an error. + RUNTIME_FUNCTION_EXCEPTION = 7, + } + + # The error code which should be one of "Error.Code" enums. + var code : int + + # A message in English to help developers debug the response. + var message : String + + # Additional error details which may be different for each response. + var context : Dictionary + + func _init(p_ex = null): + super(p_ex) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "Error" % [code, message, context] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> Error: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "Error", p_dict), Error) as Error + + static func get_result_key() -> String: + return "error" + + +# A multiplayer match. +class Match extends NakamaAsyncResult: + + const _SCHEMA = { + "authoritative": {"name": "authoritative", "type": TYPE_BOOL, "required": false}, + "match_id": {"name": "match_id", "type": TYPE_STRING, "required": true}, + "label": {"name": "label", "type": TYPE_STRING, "required": false}, + "presences": {"name": "presences", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"}, + "size": {"name": "size", "type": TYPE_INT, "required": false}, + "self": {"name": "self_user", "type": "UserPresence", "required": true} + } + + # If this match has an authoritative handler on the server. + var authoritative : bool + + # The unique match identifier. + var match_id : String + + # A label for the match which can be filtered on. + var label : String + + # The presences already in the match. + var presences : Array # UserPresence + + # The number of users currently in the match. + var size : int + + # The current user in this match. i.e. Yourself. + var self_user : UserPresence + + func _init(p_ex = null): + super(p_ex) + + static func create(p_ns : GDScript, p_dict : Dictionary): + return _safe_ret(NakamaSerializer.deserialize(p_ns, "Match", p_dict), Match) as Match + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "Match" % [authoritative, match_id, label, presences, size, self_user] + + static func get_result_key() -> String: + return "match" + + +# Some game state update in a match. +class MatchData extends NakamaAsyncResult: + const _SCHEMA = { + "match_id": {"name": "match_id", "type": TYPE_STRING, "required": true}, + "presence": {"name": "presence", "type": "UserPresence", "required": false}, + "op_code": {"name": "op_code", "type": TYPE_INT, "required": false}, + "data": {"name": "data", "type": TYPE_STRING, "required": false} + } + + # The unique match identifier. + var match_id : String + + # The operation code for the state change. + # This value can be used to mark the type of the contents of the state. + var op_code : int = 0 + + # The user that sent this game state update. + var presence : UserPresence + + # The raw base64-encoded contents of the state change. + var base64_data : String + + # The contents of the state change decoded as a UTF-8 string. + var _data + var data : String: + get: + if _data == null and base64_data != '': + _data = Marshalls.base64_to_utf8(base64_data) + return _data if _data != null else '' + set(v): + _data = v + + # The contents of the state change decoded as binary data. + var _binary_data + var binary_data : PackedByteArray: + get: + if _binary_data == null and base64_data != '': + _binary_data = Marshalls.base64_to_raw(base64_data) + return _binary_data + + func _init(p_ex = null): + super(p_ex) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "MatchData" % [match_id, op_code, presence, data] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> MatchData: + var out = _safe_ret(NakamaSerializer.deserialize(p_ns, "MatchData", p_dict), MatchData) as MatchData + # Store the base64 data, ready to be decoded when the developer requests it. + if out._data != null: + out.base64_data = out._data + out._data = null + return out + + static func get_result_key() -> String: + return "match_data" + + +# A batch of join and leave presences for a match. +class MatchPresenceEvent extends NakamaAsyncResult: + const _SCHEMA = { + "match_id": {"name": "match_id", "type": TYPE_STRING, "required": true}, + "joins": {"name": "joins", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"}, + "leaves": {"name": "leaves", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"}, + } + + # Presences of users who joined the match. + var joins : Array + + # Presences of users who left the match. + var leaves : Array + + # The unique match identifier. + var match_id : String + + func _init(p_ex = null): + super(p_ex) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "MatchPresenceEvent" % [match_id, joins, leaves] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> MatchPresenceEvent: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "MatchPresenceEvent", p_dict), MatchPresenceEvent) as MatchPresenceEvent + + static func get_result_key() -> String: + return "match_presence_event" + + +# The result of a successful matchmaker operation sent to the server. +class MatchmakerMatched extends NakamaAsyncResult: + + const _SCHEMA = { + "match_id": {"name": "match_id", "type": TYPE_STRING, "required": false}, + "ticket": {"name": "ticket", "type": TYPE_STRING, "required": true}, + "token": {"name": "token", "type": TYPE_STRING, "required": false}, + "users": {"name": "users", "type": TYPE_ARRAY, "required": false, "content": "MatchmakerUser"}, + "self": {"name": "self_user", "type": "MatchmakerUser", "required": true} + } + + # The id used to join the match. + # A match ID used to join the match. + var match_id : String + + # The ticket sent by the server when the user requested to matchmake for other players. + var ticket : String + + # The token used to join a match. + var token : String + + # The other users matched with this user and the parameters they sent. + var users : Array # MatchmakerUser + + # The current user who matched with opponents. + var self_user : MatchmakerUser + + func _init(p_ex = null): + super(p_ex) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "" % [ + match_id, ticket, token, users, self_user + ] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> MatchmakerMatched: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "MatchmakerMatched", p_dict), MatchmakerMatched) as MatchmakerMatched + + static func get_result_key() -> String: + return "matchmaker_matched" + + +# The matchmaker ticket received from the server. +class MatchmakerTicket extends NakamaAsyncResult: + + const _SCHEMA = { + "ticket": {"name": "ticket", "type": TYPE_STRING, "required": true} + } + + # The ticket generated by the matchmaker. + var ticket : String + + func _init(p_ex = null): + super(p_ex) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> MatchmakerTicket: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "MatchmakerTicket", p_dict), MatchmakerTicket) as MatchmakerTicket + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "" % ticket + + static func get_result_key() -> String: + return "matchmaker_ticket" + + +# The user with the parameters they sent to the server when asking for opponents. +class MatchmakerUser extends NakamaAsyncResult: + + const _SCHEMA = { + "presence": {"name": "presence", "type": "UserPresence", "required": true}, + "party_id": {"name": "party_id", "type": TYPE_STRING, "required": false}, + "string_properties": {"name": "string_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_STRING}, + "numeric_properties": {"name": "numeric_properties", "type": TYPE_DICTIONARY, "required": false, "content": TYPE_FLOAT}, + } + + # The presence of the user. + var presence : UserPresence + + # Party identifier, if this user was matched as a party member. + var party_id : String + + # The numeric properties which this user asked to matchmake with. + var numeric_properties : Dictionary + + # The string properties which this user asked to matchmake with. + var string_properties : Dictionary + + func _init(p_ex = null): + super(p_ex) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "" % [ + presence, numeric_properties, string_properties] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> MatchmakerUser: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "MatchmakerUser", p_dict), MatchmakerUser) as MatchmakerUser + + static func get_result_key() -> String: + return "matchmaker_user" + + +# Receive status updates for users. +class Status extends NakamaAsyncResult: + + const _SCHEMA = { + "presences": {"name": "presences", "type": TYPE_ARRAY, "required": true, "content": "UserPresence"}, + } + + # The status events for the users followed. + var presences := Array() + + func _init(p_ex = null): + super(p_ex) + + static func create(p_ns : GDScript, p_dict : Dictionary) -> Status: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "Status", p_dict), Status) as Status + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "" % [presences] + + static func get_result_key() -> String: + return "status" + + +# A status update event about other users who've come online or gone offline. +class StatusPresenceEvent extends NakamaAsyncResult: + const _SCHEMA = { + "joins": {"name": "joins", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"}, + "leaves": {"name": "leaves", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"}, + } + + # Presences of users who joined the server. + # This join information is in response to a subscription made to be notified when a user comes online. + var joins : Array + + # Presences of users who left the server. + # This leave information is in response to a subscription made to be notified when a user goes offline. + var leaves : Array + + func _init(p_ex = null): + super(p_ex) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "StatusPresenceEvent" % [joins, leaves] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> StatusPresenceEvent: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "StatusPresenceEvent", p_dict), StatusPresenceEvent) as StatusPresenceEvent + + static func get_result_key() -> String: + return "status_presence_event" + + +# A realtime socket stream on the server. +class Stream extends NakamaAsyncResult: + + const _SCHEMA = { + "mode": {"name": "mode", "type": TYPE_INT, "required": true}, + "subject": {"name": "subject", "type": TYPE_STRING, "required": false}, + "subcontext": {"name": "subcontext", "type": TYPE_STRING, "required": false}, + "label": {"name": "label", "type": TYPE_STRING, "required": false}, + } + + # The mode of the stream. + var mode : int + + # The subject of the stream. This is usually a user id. + var subject : String + + # The descriptor of the stream. Used with direct chat messages and contains a second user id. + var subcontext : String + + # Identifies streams which have a context across users like a chat channel room. + var label : String + + func _init(p_ex = null): + super(p_ex) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "Stream" % [mode, subject, subcontext, label] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> Stream: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "Stream", p_dict), Stream) as Stream + + static func get_result_key() -> String: + return "stream" + + +# A batch of joins and leaves on the low level stream. +# Streams are built on to provide abstractions for matches, chat channels, etc. In most cases you'll never need to +# interact with the low level stream itself. +class StreamPresenceEvent extends NakamaAsyncResult: + const _SCHEMA = { + "stream": {"name": "stream", "type": "Stream", "required": true}, + "joins": {"name": "joins", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"}, + "leaves": {"name": "leaves", "type": TYPE_ARRAY, "required": false, "content" : "UserPresence"}, + } + + # Presences of users who left the stream. + var joins : Array + + # Presences of users who joined the stream. + var leaves : Array + + # The identifier for the stream. + var stream : Stream = null + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "StreamPresenceEvent" % [stream, joins, leaves] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> StreamPresenceEvent: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "StreamPresenceEvent", p_dict), StreamPresenceEvent) as StreamPresenceEvent + + static func get_result_key() -> String: + return "stream_presence_event" + + +# A state change received from a stream. +class StreamData extends NakamaAsyncResult: + + const _SCHEMA = { + "stream": {"name": "stream", "type": "Stream", "required": true}, + "sender": {"name": "sender", "type": "UserPresence", "required": false}, + "data": {"name": "state", "type": TYPE_STRING, "required": false}, + "reliable": {"name": "reliable", "type": TYPE_BOOL, "required": false}, + } + + # The user who sent the state change. May be `null`. + var sender : UserPresence = null + + # The contents of the state change. + var state : String + + # The identifier for the stream. + var stream : Stream + + # True if this data was delivered reliably, false otherwise. + var reliable : bool + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "StreamData" % [sender, state, stream] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> StreamData: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "StreamData", p_dict), StreamData) as StreamData + + static func get_result_key() -> String: + return "stream_data" + + +# An object which represents a connected user in the server. +# The server allows the same user to be connected with multiple sessions. To uniquely identify them a tuple of +# `{ node_id, user_id, session_id }` is used which is exposed as this object. +class UserPresence extends NakamaAsyncResult: + + const _SCHEMA = { + "persistence": {"name": "persistence", "type": TYPE_BOOL, "required": false}, + "session_id": {"name": "session_id", "type": TYPE_STRING, "required": true}, + "status": {"name": "status", "type": TYPE_STRING, "required": false}, + "username": {"name": "username", "type": TYPE_STRING, "required": false}, + "user_id": {"name": "user_id", "type": TYPE_STRING, "required": true}, + } + + # If this presence generates stored events like persistent chat messages or notifications. + var persistence : bool + + # The session id of the user. + var session_id : String + + # The status of the user with the presence on the server. + var status : String + + # The username for the user. + var username : String + + # The id of the user. + var user_id : String + + func _init(p_ex = null): + super(p_ex) + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "UserPresence" % [ + persistence, session_id, status, username, user_id] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> UserPresence: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "UserPresence", p_dict), UserPresence) as UserPresence + + static func get_result_key() -> String: + return "user_presence" + + +class Party extends NakamaAsyncResult: + + const _SCHEMA = { + "party_id": {"name": "party_id", "type": TYPE_STRING, "required": true}, + "open": {"name": "open", "type": TYPE_BOOL, "required": false}, + "max_size": {"name": "max_size", "type": TYPE_INT, "required": true}, + "self": {"name": "self_presence", "type": "UserPresence", "required": true}, + "leader": {"name": "leader", "type": "UserPresence", "required": true}, + "presences": {"name": "presences", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"}, + } + + # Unique party identifier. + var party_id : String + + # Open flag. + var open : bool = false + + # Maximum number of party members. + var max_size : int + + # The presence of the current user. i.e. Your self. + var self_presence : NakamaRTAPI.UserPresence + + # Leader. + var leader : NakamaRTAPI.UserPresence + + # All current party members. + var presences : Array # of objects NakamaUserPresence + + func _init(p_ex = null): + super(p_ex) + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "Party" % [ + party_id, open, max_size, self_presence, leader, presences] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> Party: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "Party", p_dict), Party) as Party + + static func get_result_key() -> String: + return "party" + + +# Presence update for a particular party. +class PartyPresenceEvent extends NakamaAsyncResult: + const _SCHEMA = { + "party_id": {"name": "party_id", "type": TYPE_STRING, "required": true}, + "joins": {"name": "joins", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"}, + "leaves": {"name": "leaves", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"}, + } + # The party ID. + var party_id : String + # User presences that have just joined the party. + var joins : Array + # User presences that have just left the party. + var leaves : Array + + func _init(p_ex = null): + super(p_ex) + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "PartyPresenceEvent" % [party_id, joins, leaves] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyPresenceEvent: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyPresenceEvent", p_dict), PartyPresenceEvent) as PartyPresenceEvent + + static func get_result_key() -> String: + return "party_presence_event" + + +# Announcement of a new party leader. +class PartyLeader extends NakamaAsyncResult: + const _SCHEMA = { + "party_id": {"name": "party_id", "type": TYPE_STRING, "required": true}, + "presence": {"name": "presence", "type": "UserPresence", "required": true}, + } + # Party ID to promote a new leader for. + var party_id : String + # The presence of an existing party member to promote as the new leader. + var presence : NakamaRTAPI.UserPresence + + func _init(p_ex = null): + super(p_ex) + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "PartyLeader" % [party_id, presence] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyLeader: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyLeader", p_dict), PartyLeader) as PartyLeader + + static func get_result_key() -> String: + return "party_leader" + + +# Incoming notification for one or more new presences attempting to join the party. +class PartyJoinRequest extends NakamaAsyncResult: + const _SCHEMA = { + "party_id": {"name": "party_id", "type": TYPE_STRING, "required": true}, + "presences": {"name": "presences", "type": TYPE_ARRAY, "required": false, "content": "UserPresence"}, + } + # Party ID these presences are attempting to join. + var party_id : String + # Presences attempting to join. + var presences : Array + + func _init(p_ex = null): + super(p_ex) + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "PartyJoinRequest" % [party_id, presences] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyJoinRequest: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyJoinRequest", p_dict), PartyJoinRequest) as PartyJoinRequest + + static func get_result_key() -> String: + return "party_join_request" + + +# A response from starting a new party matchmaking process. +class PartyMatchmakerTicket extends NakamaAsyncResult: + const _SCHEMA = { + "party_id": {"name": "party_id", "type": TYPE_STRING, "required": true}, + "ticket": {"name": "ticket", "type": TYPE_STRING, "required": true}, + } + # Party ID. + var party_id : String + # The ticket that can be used to cancel matchmaking. + var ticket : String + + func _init(p_ex = null): + super(p_ex) + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "PartyMatchmakerTicket" % [party_id, ticket] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyMatchmakerTicket: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyMatchmakerTicket", p_dict), PartyMatchmakerTicket) as PartyMatchmakerTicket + + static func get_result_key() -> String: + return "party_matchmaker_ticket" + + +# Incoming party data delivered from the server. +class PartyData extends NakamaAsyncResult: + const _SCHEMA = { + "party_id": {"name": "party_id", "type": TYPE_STRING, "required": true}, + "presence": {"name": "presence", "type": "UserPresence", "required": false}, + "op_code": {"name": "op_code", "type": TYPE_INT, "required": true}, + "data": {"name": "data", "type": TYPE_STRING, "required": false} + } + # The party ID. + var party_id : String + # A reference to the user presence that sent this data, if any. + var presence : NakamaRTAPI.UserPresence + # Op code value. + var op_code : int + + # The raw base64-encoded contents of the state change. + var base64_data : String + + # The contents of the state change decoded as a UTF-8 string. + var _data + var data : String: + get: + if _data == null and base64_data != '': + _data = Marshalls.base64_to_utf8(base64_data) + return _data if _data != null else '' + set(v): + _data = v + + # The contents of the state change decoded as binary data. + var _binary_data + var binary_data : PackedByteArray: + get: + if _binary_data == null and base64_data != '': + _binary_data = Marshalls.base64_to_raw(base64_data) + return _binary_data + + func _init(p_ex = null): + super(p_ex) + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "PartyData" % [party_id, presence, op_code, data] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyData: + var out := _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyData", p_dict), PartyData) as PartyData + # Store the base64 data, ready to be decoded when the developer requests it. + if out._data != null: + out.base64_data = out._data + out._data = null + return out + + static func get_result_key() -> String: + return "party_data" + +# End a party, kicking all party members and closing it. (this is both a message and a result) +class PartyClose extends NakamaAsyncResult: + const _SCHEMA = { + "party_id": {"name": "party_id", "type": TYPE_STRING, "required": true}, + } + # Party ID to close. + var party_id : String + + func _init(p_ex = null): + super(p_ex) + + func serialize(): + return NakamaSerializer.serialize(self) + + func get_msg_key() -> String: + return "party_close" + + func _to_string(): + if is_exception(): return get_exception()._to_string() + return "PartyClose" % [party_id] + + static func create(p_ns : GDScript, p_dict : Dictionary) -> PartyClose: + return _safe_ret(NakamaSerializer.deserialize(p_ns, "PartyClose", p_dict), PartyClose) as PartyClose + + static func get_result_key() -> String: + return "party_close" diff --git a/addons/com.heroiclabs.nakama/api/NakamaRTMessage.gd b/addons/com.heroiclabs.nakama/api/NakamaRTMessage.gd new file mode 100644 index 0000000..d3bedd6 --- /dev/null +++ b/addons/com.heroiclabs.nakama/api/NakamaRTMessage.gd @@ -0,0 +1,635 @@ +extends RefCounted +class_name NakamaRTMessage + +# Send a channel join message to the server. +class ChannelJoin: + + const _SCHEMA = { + "persistence": {"name": "persistence", "type": TYPE_BOOL, "required": true}, + "hidden": {"name": "hidden", "type": TYPE_BOOL, "required": true}, + "target": {"name": "target", "type": TYPE_STRING, "required": true}, + "type": {"name": "type", "type": TYPE_INT, "required": true}, + } + + enum ChannelType { + # A chat room which can be created dynamically with a name. + Room = 1, + # A private chat between two users. + DirectMessage = 2, + # A chat within a group on the server. + Group = 3 + } + + var persistence : bool + var hidden : bool + var target : String + var type : int + + func _init(p_target : String, p_type : int, p_persistence : bool, p_hidden : bool): + persistence = p_persistence + hidden = p_hidden + target = p_target + type = p_type if p_type >= ChannelType.Room and p_type <= ChannelType.Group else 0 # Will cause error server side + + func serialize() -> Dictionary: + return NakamaSerializer.serialize(self) + + func get_msg_key() -> String: + return "channel_join" + + func _to_string(): + return "ChannelJoin