second commit

This commit is contained in:
pietru 2024-04-12 15:00:01 +02:00
parent 4e31b9e8e4
commit 784191faa3
25 changed files with 526 additions and 50 deletions

126
addons/luaAPI/LICENSE Normal file
View file

@ -0,0 +1,126 @@
===============================================================================
LuaAPI -- lua API bindings for the godot engine.
Copyright (c) 2021-present Trey Moller
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
[ MIT license: https://www.opensource.org/licenses/mit-license.php ]
===============================================================================
[ LuaAPI includes code from Godot 4.0, which has this license statement: ]
Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md).
Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
===============================================================================
[ LuaAPI includes code from godot-cpp, which has this license statement: ]
Copyright (c) 2017-present Godot Engine contributors.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
===============================================================================
[ LuaAPI includes code from Lua 5.1/5.2/5.4, which has this license statement: ]
Copyright (C) 1994-2012 Lua.org, PUC-Rio.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================================================
[ LuaAPI includes code from LuaJIT v2.1, which has this license statement: ]
Copyright (C) 2005-2022 Mike Pall. All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
===============================================================================
[ LuaJIT includes code from dlmalloc, which has this license statement: ]
This is a version (aka dlmalloc) of malloc/free/realloc written by
Doug Lea and released to the public domain, as explained at
https://creativecommons.org/licenses/publicdomain
===============================================================================

137
addons/luaAPI/README.md Normal file
View file

@ -0,0 +1,137 @@
Godot Lua API
===============
**Table of contents:**
* [About](#about)
* [Features](#features)
* [Release Builds](#release-builds)
* [Compiling](#compiling)
* [Getting Started](#getting-started)
* [Contributing And Feature Requests](#contributing-and-feature-requests)
About
-------
![Logo](.github/LuaAPI.png)
Art created by [Alex](https://www.instagram.com/redheadalex1)
This is a Godot addon that adds Lua API support via GDScript, C# or GDExtension. Importantly this is **NOT** meant to be a replacement for or alternative to GDScript. This addon provides no functionality to program your game out of the box. This addon allows you to create custom Modding API's in a sandboxed environment. You have control of what people can and can not do within that sandbox.
To use you can either [Compile from source](#compiling) or you can download one of the [release builds](#release-builds).
By default the Lua print function is set to print to the GDEditor console. This can be changed by exposing your own print function as it will overwrite the existing one.
**Some things to note**, this is not the only way to support Modding in your game. It's also not the only way to support Lua Modding in your game. In fact, using this mod to create your Modding API will likely take a lot more work than using native scripts for Modding. However, the advantage using luaAPI over native scripts is that the Lua code is sandboxed. No one can access parts of the engine that you don't explicitly give access to.
If you are looking to make your game using Lua or would like to support Modding without worrying about a sandbox, check out one of these projects:
- [luascript](https://github.com/perbone/luascript) by [perbone](https://github.com/perbone)
- [godot-lua-pluginscript](https://github.com/gilzoide/godot-lua-pluginscript) by [gilzoide](https://github.com/gilzoide)
<br />
We will supply a brief overview here. But for more info check out the [wiki](https://luaapi.weaselgames.info/latest).
For discussion related to this project feel free to join the Weasel Games [Discord](https://discord.gg/vGazqdQZ7p) or [Matrix](https://matrix.weaselgames.net/#/room/#weaselgames:weaselgames.net).
Features
--------------------------------
- Run Lua directly from a string or a text file.
- Push any Variant as a global.
- Call Lua functions from GDScript.
- Choose which libraries you want Lua to have access to.
- LuaError type which is used to report any errors this addon or Lua run into.
- LuaCoroutine type which creates a Lua thread. This is not a OS thread but a coroutine.
- Object passed as userdata. See [wiki](https://luaapi.weaselgames.info/latest/examples/objects/).
- Objects can override most of the Lua metamethods. I.E. __index by defining a function with the same name.
- Callables passed as userdata, which allows you to push a Callable as a Lua function.
- Basic types are passed as userdata (currently: Vector2, Vector3, Color, Rect2, Plane) with a useful metatable. This means you can do things like:
```lua
local v1 = Vector2(1,2)
local v2 = Vector2(100.52,100.83)
v2 = v2.floor()
print(v2.x) -- "100"
print(v1+v2) -- "(101,102)"
change_my_sprite_color(Color(1,0,0,1)) -- If "change_my_sprite_color" was exposed, in GDScript it will receive a Color variant.
```
If a feature is missing that you would like to see feel free to create a [Feature Request](https://github.com/WeaselGames/godot_luaAPI/issues/new?assignees=&labels=feature%20request&template=feature_request.md&title=) or submit a PR
Release Builds
---------------
- [⚙️ GDExtension](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/gdextension.zip)
- [⚙️ GDExtension LuaJIT](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/gdextension-LuaJIT.zip)
- [🐧 Linux Editor](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/linux-editor.zip)
- [🐧 Linux Editor LuaJIT](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/linux-editor-luajit.zip)
- [🐧 Linux Editor Mono](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/linux-editor.zip)
- [🎨 Windows Editor](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/windows-editor.zip)
- [🎨 Windows Editor LuaJIT](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/windows-editor-luajit.zip)
- [🎨 Windows Editor Mono](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/windows-editor-mono.zip)
- [🍎 MacOS Editor](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/macos-editor.zip)
- [🍎 MacOS Editor LuaJIT](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/macos-editor-luajit.zip)
- [🍎 MacOS Editor Mono](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/macos-editor-mono.zip)
- [🗜️ Export Templates](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/export-templates.zip)
- [🗜️ Mono Export Templates](https://github.com/WeaselGames/godot_luaAPI/releases/latest/download/export-templates-mono.zip)
- For previous versions see [releases](https://github.com/WeaselGames/godot_luaAPI/releases)
Compiling
------------
This build is for godot 4.1.
- Start by cloning the Godot 4.1 [source](https://github.com/godotengine/godot) with this command `git clone https://github.com/godotengine/godot`
- Next change directories into the modules folder and clone this repo into a folder named luaAPI with this command `git clone --recurse-submodules https://github.com/WeaselGames/godot_luaAPI luaAPI`. Make sure to use --recurse-submodules to pull the submodules as well.
- Now you can follow the Godot build instructions on their [site](https://docs.godotengine.org/en/stable/contributing/development/compiling).
Getting Started
------------
If you are looking for more in depth information please refer to our [wiki](https://luaapi.weaselgames.info/latest).
Pro Tip: Be sure to download the Export Templates! The Export Templates that come with Godot will not work with this
Editor/Add-on. Please see [Installing Export Templates](EXPORT.MD) for more information.
Dotnet users will also want to refer to [DOTNET.md](DOTNET.md) For additional information and steps that are needed to
make the Editor/Add-on work.
**Running Lua for you first time:**
```gdscript
extends Node
var lua: LuaAPI = LuaAPI.new()
func _lua_print(message: String) -> void:
print(message)
func _ready() -> void:
lua.push_variant("print", _lua_print)
lua.push_variant("message", "Hello lua!")
# All builtin libraries are available to bind with. Use OS and IO at your own risk.
lua.bind_libraries(["base", "table", "string"])
# Most methods return a LuaError in case of an error
var err: LuaError = lua.do_string("""
for i=1,10,1 do
print(message)
end
function get_message()
return "Hello gdScript!"
end
""")
if err is LuaError:
print("ERROR %d: %s" % [err.type, err.message])
return
var val = lua.pull_variant("get_message")
if val is LuaError:
print("ERROR %d: %s" % [val.type, val.message])
return
var message = val.call([])
print(message)
```
Dotnet (mono) users see example redone in C# in [DOTNET.md](DOTNET.md).
Contributing And Feature Requests
---------------
All contributions are welcome, if you would like to contribute submit a PR.
<br />
Additionally if you do not have the time and or the knowledge you can create a [Feature Request](https://github.com/WeaselGames/godot_luaAPI/issues/new?assignees=&labels=feature%20request&template=feature_request.md&title=).
[![lua logo](https://www.lua.org/images/powered-by-lua.gif)](https://www.lua.org/)

View file

View file

@ -0,0 +1,27 @@
[configuration]
entry_symbol = "luaAPI_library_init"
compatibility_minimum = 4.2
[libraries]
linux.x86_64.debug = "bin/libluaapi.linux.template_debug.x86_64.so"
linux.x86_64.release = "bin/libluaapi.linux.template_release.x86_64.so"
linux.x86_32.debug = "bin/libluaapi.linux.template_debug.x86_32.so"
linux.x86_32.release = "bin/libluaapi.linux.template_release.x86_32.so"
windows.x86_64.debug = "bin/libluaapi.windows.template_debug.x86_64.dll"
windows.x86_64.release = "bin/libluaapi.windows.template_release.x86_64.dll"
windows.x86_32.debug = "bin/libluaapi.windows.template_debug.x86_32.dll"
windows.x86_32.release = "bin/libluaapi.windows.template_release.x86_32.dll"
android.debug.x86_64 = "bin/libluaapi.android.template_debug.x86_64.so"
android.release.x86_64 = "bin/libluaapi.android.template_release.x86_64.so"
android.debug.arm64 = "bin/libluaapi.android.template_debug.arm64.so"
android.release.arm64 = "bin/libluaapi.android.template_release.arm64.so"
macos.debug = "bin/libluaapi.macos.template_debug.universal.dylib"
macos.release = "bin/libluaapi.macos.template_release.universal.dylib"
ios.debug.arm64 = "bin/libluaapi.ios.template_debug.arm64.dylib"
ios.release.arm64 = "bin/libluaapi.ios.template_release.arm64.dylib"
ios.debug.simulator = "bin/libluaapi.ios.template_debug.universal.simulator.dylib"
ios.release.simulator = "bin/libluaapi.ios.template_release.universal.simulator.dylib"

32
demo/HelloLua.gd Normal file
View file

@ -0,0 +1,32 @@
extends Node
var lua: LuaAPI = LuaAPI.new()
func _lua_print(message: String):
print(message)
func _ready():
# All builtin libraries are available to bind with. Use Debug, OS and IO at your own risk.
lua.bind_libraries(["base", "table", "string"])
lua.push_variant("print", _lua_print)
lua.push_variant("message", "Hello lua!")
# Most methods return a LuaError in case of an error
var err: LuaError = lua.do_string("""
for i=1,10,1 do
print(message)
end
function get_message()
return "Hello gdScript!"
end
""")
if err is LuaError:
print("ERROR %d: %s" % [err.type, err.message])
return
var ret = lua.call_function("get_message", [])
if ret is LuaError:
print("ERROR %d: %s" % [ret.type, ret.message])
return
print(ret)

6
demo/HelloLua.tscn Normal file
View file

@ -0,0 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://nmbqcw2467rl"]
[ext_resource type="Script" path="res://demo/HelloLua.gd" id="1_a562c"]
[node name="HelloLua" type="Node2D"]
script = ExtResource("1_a562c")

80
main.gd
View file

@ -1,7 +1,10 @@
extends Control extends Control
var games := [] var games := {}
var selected_game := ""
var profiles := {}
var selected_profile := ""
func _ready(): func _ready():
%Games.visible=false %Games.visible=false
%GameTab.visible=false %GameTab.visible=false
@ -21,13 +24,29 @@ func _ready():
%GameClose.pressed.connect(_return_to_list) %GameClose.pressed.connect(_return_to_list)
func register_games(): func register_games():
games.push_back({"name":"dummy","image":"res://icon.svg"}) for gm in DirAccess.get_directories_at(PathHelper.data_path):
games.push_back({"name":"dummy2","image":"res://icon.svg"}) var cfg := PathHelper.get_game_config(gm)
var dt = {
"name":cfg.get_value("Data","game_name","Dummy"),
"image":cfg.get_value("Data","game_icon_path","icon.svg"),
"profiles":[]
}
games[gm]=dt
print("Registered games")
func select_game(key:String):
print("selecting game under key: "+key)
var game_data=games[key]
func select_game(game_data:Dictionary):
var game_name :String= game_data.get("name") if game_data.has("name") else "UNKNOWN" var game_name :String= game_data.get("name") if game_data.has("name") else "UNKNOWN"
var game_image :Texture= load(game_data.get("image")) if game_data.has("name") else load("res://icon.svg") var game_image :Texture= load(game_data.get("image")) if game_data.has("name") else load("res://icon.svg")
selected_game=key
await load_profiles()
display_profiles()
%GameName.text=game_name %GameName.text=game_name
%GameIcon.texture=game_image %GameIcon.texture=game_image
@ -35,31 +54,72 @@ func select_game(game_data:Dictionary):
%GameTab.visible=true %GameTab.visible=true
%Profiles.visible=true %Profiles.visible=true
func load_games(): func load_games():
print("Loading games list...")
var list :ItemList=%Games var list :ItemList=%Games
list.clear() list.clear()
var i:=0 var i:=0
for dt in games: for key in games.keys():
var dt = games[key]
var game_name :String= dt.get("name") if dt.has("name") else "UNKNOWN" var game_name :String= dt.get("name") if dt.has("name") else "UNKNOWN"
var game_image :Texture= load(dt.get("image")) if dt.has("name") else load("res://icon.svg") var game_image :Texture= load(dt.get("image")) if dt.has("name") else load("res://icon.svg")
list.add_item(game_name,game_image) list.add_item(game_name,game_image)
list.set_item_metadata(i,dt) list.set_item_metadata(i,key)
i+=1 i+=1
%Games.visible=true %Games.visible=true
func load_profiles():
profiles["profile1"]={"name":"profile1","image":"res://icon.svg","profiles":[]}
profiles["profile2"]={"name":"profile2","image":"res://icon.svg","profiles":[]}
print("Registered games")
func select_profile(key:String):
var profile_data=profiles[key]
var profile_name :String= profile_data.get("name") if profile_data.has("name") else "UNKNOWN"
var profile_image :Texture= load(profile_data.get("image")) if profile_data.has("image") else load("res://icon.svg")
var profile_desc :String= load(profile_data.get("desc")) if profile_data.has("desc") else "No description defined..."
selected_profile=key
%ProfileName.text=profile_name
%ProfileIcon.texture=profile_image
%ProfileDesc.text=profile_desc
if !%ProfilePanel.visible:
$Anim.play("switch_profile_view")
func display_profiles():
print("Loading profiles list...")
var list :ItemList=%Profiles
list.clear()
var i:=0
for key in profiles.keys():
var dt = profiles[key]
var profile_name :String= dt.get("name") if dt.has("name") else "UNKNOWN"
var profile_image :Texture= load(dt.get("image")) if dt.has("name") else load("res://icon.svg")
list.add_item(profile_name,profile_image)
list.set_item_metadata(i,key)
i+=1
func on_item_activated(id:int,type:String): func on_item_activated(id:int,type:String):
if type=="games": if type=="games":
var data :Dictionary=%Games.get_item_metadata(id) var key :String=%Games.get_item_metadata(id)
select_game(data) select_game(key)
elif type=="profiles": elif type=="profiles":
var data :Dictionary=%Profiles.get_item_metadata(id) var key :String=%Profiles.get_item_metadata(id)
select_profile(key)
func _return_to_list(): func _return_to_list():
selected_game=""
selected_profile=""
load_games() load_games()
%Games.visible=true %Games.visible=true
%GameTab.visible=false %GameTab.visible=false
%Profiles.visible=false %Profiles.visible=false
if %ProfilePanel.visible:
$Anim.play_backwards("switch_profile_view")
func _add_new_profile(): func _add_new_profile():
pass pass

118
main.tscn
View file

@ -2,6 +2,45 @@
[ext_resource type="Script" path="res://main.gd" id="1_ksdsl"] [ext_resource type="Script" path="res://main.gd" id="1_ksdsl"]
[sub_resource type="Animation" id="Animation_ise3b"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Panel/HBoxContainer/ProfilePanel:visible")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Panel/HBoxContainer/ProfilePanel:size_flags_stretch_ratio")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Panel/HBoxContainer/ProfilePanel:modulate")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 0)]
}
[sub_resource type="Animation" id="Animation_m3lq2"] [sub_resource type="Animation" id="Animation_m3lq2"]
resource_name = "switch_profile_view" resource_name = "switch_profile_view"
length = 0.15 length = 0.15
@ -43,45 +82,6 @@ tracks/2/keys = {
"values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 1, 1, 1)] "values": [Color(1, 1, 1, 0), Color(1, 1, 1, 0), Color(1, 1, 1, 1)]
} }
[sub_resource type="Animation" id="Animation_ise3b"]
length = 0.001
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("Panel/HBoxContainer/ProfilePanel:visible")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [false]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("Panel/HBoxContainer/ProfilePanel:size_flags_stretch_ratio")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [0.0]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("Panel/HBoxContainer/ProfilePanel:modulate")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 0,
"values": [Color(1, 1, 1, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_s7q63"] [sub_resource type="AnimationLibrary" id="AnimationLibrary_s7q63"]
_data = { _data = {
"RESET": SubResource("Animation_ise3b"), "RESET": SubResource("Animation_ise3b"),
@ -97,7 +97,7 @@ grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
script = ExtResource("1_ksdsl") script = ExtResource("1_ksdsl")
[node name="AnimationPlayer" type="AnimationPlayer" parent="."] [node name="Anim" type="AnimationPlayer" parent="."]
libraries = { libraries = {
"": SubResource("AnimationLibrary_s7q63") "": SubResource("AnimationLibrary_s7q63")
} }
@ -158,6 +158,7 @@ alignment = 1
[node name="ProfileAdd" type="Button" parent="Panel/HBoxContainer/Cont/GameTab/VBoxContainer"] [node name="ProfileAdd" type="Button" parent="Panel/HBoxContainer/Cont/GameTab/VBoxContainer"]
unique_name_in_owner = true unique_name_in_owner = true
visible = false
layout_mode = 2 layout_mode = 2
text = "Add profile" text = "Add profile"
@ -177,6 +178,7 @@ text = "Return"
[node name="Games" type="ItemList" parent="Panel/HBoxContainer/Cont"] [node name="Games" type="ItemList" parent="Panel/HBoxContainer/Cont"]
unique_name_in_owner = true unique_name_in_owner = true
visible = false
layout_mode = 2 layout_mode = 2
size_flags_vertical = 3 size_flags_vertical = 3
size_flags_stretch_ratio = 4.0 size_flags_stretch_ratio = 4.0
@ -251,3 +253,39 @@ text = "Delete"
unique_name_in_owner = true unique_name_in_owner = true
layout_mode = 2 layout_mode = 2
text = "Open Folder" text = "Open Folder"
[node name="ProfileAddPanel" type="VBoxContainer" parent="Panel/HBoxContainer"]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.0
[node name="ProfileIcon" type="TextureRect" parent="Panel/HBoxContainer/ProfileAddPanel"]
custom_minimum_size = Vector2(96, 96)
layout_mode = 2
expand_mode = 3
stretch_mode = 4
[node name="ProfileName" type="Label" parent="Panel/HBoxContainer/ProfileAddPanel"]
layout_mode = 2
text = "Profile Name"
[node name="ProfileDesc" type="Label" parent="Panel/HBoxContainer/ProfileAddPanel"]
layout_mode = 2
text = "Profile Desc"
[node name="ProfileOptions" type="HBoxContainer" parent="Panel/HBoxContainer/ProfileAddPanel"]
custom_minimum_size = Vector2(0, 32)
layout_mode = 2
[node name="Save" type="Button" parent="Panel/HBoxContainer/ProfileAddPanel/ProfileOptions"]
layout_mode = 2
text = "Launch"
[node name="Cancel" type="Button" parent="Panel/HBoxContainer/ProfileAddPanel/ProfileOptions"]
layout_mode = 2
text = "Edit"
[node name="HTTPRequest" type="HTTPRequest" parent="."]
use_threads = true

View file

@ -12,5 +12,11 @@ config_version=5
config/name="AppLauncher" config/name="AppLauncher"
run/main_scene="res://main.tscn" run/main_scene="res://main.tscn"
config/use_custom_user_dir=true
config/custom_user_dir_name="/percraft/app_launcher"
config/features=PackedStringArray("4.2", "Forward Plus") config/features=PackedStringArray("4.2", "Forward Plus")
config/icon="res://icon.svg" config/icon="res://icon.svg"
[autoload]
PathHelper="*res://utils/PathHelper.gd"

44
utils/PathHelper.gd Normal file
View file

@ -0,0 +1,44 @@
extends Node
var base_path = "user://"
var data_path = "user://"
func _ready():
if OS.has_feature("release"):
base_path=OS.get_executable_path().path_join("data")
data_path=base_path+"data/"
func game_exists(game)->bool:
return DirAccess.dir_exists_absolute(base_path+game)
func game_config_exists(game)->bool:
if !game_exists(game):
return false
return DirAccess.dir_exists_absolute(base_path+game+"/config.cfg")
func create_game_folder(game):
DirAccess.make_dir_recursive_absolute(base_path+game+"/profiles")
var file := ConfigFile.new()
file.set_value("Data","game_name","Dummy")
file.set_value("Data","game_icon_path","icon.svg")
file.save(base_path+game+"/config.cfg")
func get_game_config(game)->ConfigFile:
var file := ConfigFile.new()
if !game_config_exists(game):
file.set_value("Data","game_name","Dummy")
file.set_value("Data","game_icon_path","icon.svg")
file.save(base_path+game+"/config.cfg")
return file
file.load(base_path+game+"/config.cfg")
return file
func game_script_exists(game)->bool:
if !game_exists(game):
return false
return DirAccess.dir_exists_absolute(base_path+game+"/game.lua")