t_p6_api: build plugin scripting system
- Add PluginBase (plugin_base.gd) — abstract base class with 12 virtual hooks - Add PluginManifest (plugin_manifest.gd) — custom Resource for plugin metadata - Add PluginManager (plugin_manager.gd) — autoload singleton: directory scan, hook dispatch, lifecycle (load/unload/reload/rescan), cvar integration - Add hello_world example plugin with all hooks demonstrating usage - Register PluginManager autoload in project.godot - Extend rcon_command_handler.gd with 'plugin' subcommand (list/load/unload/ reload/info/rescan) delegating to PluginManager
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
## Plugin Manifest — Custom Resource
|
||||
##
|
||||
## Each plugin directory must contain a plugin.tres file of this type.
|
||||
## The PluginManager scans for these files when discovering plugins.
|
||||
##
|
||||
## Example plugin.tres:
|
||||
## [gd_resource type="Resource" format=3]
|
||||
## [ext_resource type="Script" id="1" path="res://server/scripts/plugin_api/plugin_manifest.gd"]
|
||||
## [resource]
|
||||
## script = ExtResource("1")
|
||||
## name = "Hello World"
|
||||
## version = "1.0.0"
|
||||
## author = "Tactical Shooter Team"
|
||||
## script_path = "hello_world.gd"
|
||||
## enabled = true
|
||||
|
||||
extends Resource
|
||||
class_name PluginManifest
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Exported fields
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
## Human-readable plugin name (e.g. "Hello World").
|
||||
## This is used as the canonical identifier for load/unload/info commands.
|
||||
@export var name: String = &""
|
||||
|
||||
## Plugin version string (e.g. "1.0.0").
|
||||
## Follows semver convention for compatibility checking.
|
||||
@export var version: String = &"1.0.0"
|
||||
|
||||
## Author name, handle, or team name.
|
||||
@export var author: String = &""
|
||||
|
||||
## Path to the main GDScript file, relative to the plugin directory
|
||||
## (e.g. "hello_world.gd" for a script in the same directory).
|
||||
@export var script_path: String = &""
|
||||
|
||||
## Whether the plugin is enabled on initial load.
|
||||
## Set to false to keep the plugin discovered but not auto-loaded.
|
||||
@export var enabled: bool = true
|
||||
|
||||
## Minimum required PluginManager API version (semver string).
|
||||
## Leave empty if no minimum is required.
|
||||
@export var min_api_version: String = &""
|
||||
|
||||
## Maximum allowed PluginManager API version (semver string).
|
||||
## Leave empty if any version is accepted.
|
||||
@export var max_api_version: String = &""
|
||||
|
||||
## Arbitrary key-value metadata (e.g. description, homepage, dependencies).
|
||||
## Useful for plugin browsers and info commands.
|
||||
@export var metadata: Dictionary = {}
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Validation helpers
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
## Returns true if the manifest fields are minimally valid and usable.
|
||||
##
|
||||
## A valid manifest must have:
|
||||
## - A non-empty name
|
||||
## - A non-empty script_path referencing the plugin's main script
|
||||
func is_valid() -> bool:
|
||||
return not name.is_empty() and not script_path.is_empty()
|
||||
|
||||
## Returns true if this plugin is compatible with the given API version.
|
||||
## Uses simple string comparison — extend with proper semver logic as needed.
|
||||
func is_api_compatible(api_version: String) -> bool:
|
||||
if not min_api_version.is_empty() and api_version < min_api_version:
|
||||
return false
|
||||
if not max_api_version.is_empty() and api_version > max_api_version:
|
||||
return false
|
||||
return true
|
||||
|
||||
## Returns a human-readable summary of the manifest.
|
||||
func to_summary() -> String:
|
||||
return "%s v%s by %s (script: %s, enabled: %s)" % [
|
||||
name, version, author, script_path, str(enabled)
|
||||
]
|
||||
Reference in New Issue
Block a user