Plugin resources
Every Versatia plugin extracts the files it ships under a resources directory into its data
folder when it starts and at every reload. Nothing has to be declared: put the files there and
they appear on the server.
Where the files go
| In the build | In the JAR | On the server |
|---|---|---|
src/main/resources/resources/config.yml | resources/config.yml | plugins/<Name>/config.yml |
src/main/resources/resources/lang/en.yml | resources/lang/en.yml | plugins/<Name>/lang/en.yml |
The directory layout under resources/ is kept. Only files are copied; an empty directory in the
JAR creates nothing.
Everything under src/main/resources/resources/ is copied into the plugin's data folder, with its
layout, and never overwritten once it is there: what you ship are the defaults. Anything else in
src/main/resources/, such as plugin.yml, stays inside the JAR.
The server admin's side, editing the copies and getting a default back, is in Configuration files of the server admin guide.
Existing files are never overwritten
A file that already exists in the data folder is left exactly as it is, whatever the JAR contains.
Server owners edit the extracted copies, and an update of the plugin does not undo their changes.
To get a fresh copy of a file, delete it and run /versatia reload <name>
or restart the plugin.
When it happens
Extraction runs at PLUGIN_RELOAD_OR_START, first: at start before any bean is created, any
@Value property is read or any auto-invoked function runs, and again at
every reload before the values are read. So a value always finds its file, and a file the
administrator deleted comes back with its default at the next reload.
Reading the files is the job of the features built on them. A single value is a @Value property
set from the extracted file, so the shipped file is where the defaults live:
@LocalBean
class Shop {
@Value("greeting", file = "messages.yml")
lateinit var greeting: String
}
Texts shown to players belong to Messages, which reads
messages/. A file of your own format is read in a PLUGIN_RELOAD_OR_START function, so a reload
picks up its changes, with loadYamlOrThrow and the strict getters of the
configuration utilities; never in a constructor, which runs once.
Why every plugin has it
VersatiaPlugin is annotated with @ExtractResources, and an enhancement declared on a base
class applies to every plugin extending it, as explained under
Enhancements and processors. A main
class that extends JavaPlugin directly can carry the annotation itself. The processor behind it
is ExtractResourcesEnhancementProcessor (ResourceProcessors.EXTRACT); it reads the files
from the plugin's own JAR, never from a dependency.
The classpath directory is fixed to resources (ExtractResources.DIRECTORY). Files placed
anywhere else in src/main/resources, such as plugin.yml, stay inside the JAR.
Switching it off
A plugin that wants to handle its files itself switches the feature off on its main class:
@DisableVersatiaFeatures(extractResources = true)
class MyPlugin : VersatiaPlugin()
The descriptor then carries no extraction element at all; nothing happens at runtime. The
annotation is accepted on the main class and on its base classes only, and the nearest declaration
wins: a base class may switch the feature off and a subclass may declare @ExtractResources again.
Writing @DisableVersatiaFeatures without switching anything on, or next to @ExtractResources
on the same class, is a compile error. Every feature a plugin inherits and its switch are listed
under Enhancements on a base class.
Corner cases
- A link counts as a file. Anything at the destination, a symbolic link included, even one pointing nowhere, keeps the JAR's copy out; a configuration the administrator shares through a link is left alone.
- A deleted file comes back at the next reload or start, with the content of the JAR the server runs now.
- Empty directories in the JAR create nothing in the data folder.