Plugin Lifecycle
Dokumentace k životnímu cyklu pluginu v Hytale.
Obsah
| Soubor | Popis |
|--------|-------|
| PLUGIN_PHASES.md | Fáze životního cyklu pluginu (setup, start, shutdown) |
| INITIALIZATION.md | Inicializace - registry, komponenty, eventy |
---
Rychlý Přehled
| Fáze | State | Metoda | Co dělat |
|------|-------|--------|----------|
| 1 | NONE | Konstruktor | super(init), withConfig() |
| 2 | SETUP | setup() | Registrace komponent, systémů, příkazů, eventů |
| 3 | START→ENABLED | start() | Logování, verifikace |
| 4 | SHUTDOWN | shutdown() | Sync uložení dat, cleanup |
---
Lifecycle Metody
Každý plugin dědí z JavaPlugin a implementuje tyto metody:
public class MyPlugin extends JavaPlugin { private static MyPlugin instance;
// Konstruktor - POVINNÝ
public MyPlugin(JavaPluginInit init) {
super(init);
}
// Singleton pattern
public static MyPlugin get() {
return instance;
}
// 1. SETUP - Registrace komponent, systémů, příkazů, eventů
@Override
protected void setup() {
instance = this;
// Registrace komponent
// Registrace systémů
// Registrace příkazů
// Registrace eventů
}
// 2. START - Plugin je aktivní, svět je načtený
@Override
protected void start() {
getLogger().atInfo().log("Plugin started!");
}
// 3. SHUTDOWN - Server se vypíná
@Override
protected void shutdown() {
getLogger().atInfo().log("Plugin shutdown!");
// Uložení dat
// Cleanup
}
}
---
Pořadí Volání
1. Konstruktor (JavaPluginInit)
↓
2. setup()
- Registrace komponent
- Registrace systémů
- Registrace příkazů
- Registrace event listenerů
↓
3. [Načítání světů]
↓
4. AllWorldsLoadedEvent
- Načtení konfigurace
- Načtení dat
↓
5. start()
- Plugin je plně aktivní
↓
6. [Server běží]
↓
7. shutdown()
- Uložení dat
- Cleanup
---
setup()
V setup() registruješ vše co plugin potřebuje:
Komponenty
@Override
protected void setup() {
// Registrace vlastních komponent
this.myComponentType = getEntityStoreRegistry().registerComponent(
MyComponent.class,
MyComponent::new
);
}
Systémy
@Override
protected void setup() {
// Registrace ECS systémů
getEntityStoreRegistry().registerSystem(new MyBlockBreakSystem());
getEntityStoreRegistry().registerSystem(new MyDeathSystem());
}
Příkazy
@Override
protected void setup() {
// Registrace příkazů
getCommandRegistry().registerCommand(new MyCommand());
getCommandRegistry().registerCommand(new AnotherCommand());
}
Eventy
@Override
protected void setup() {
// Sync eventy
getEventRegistry().registerGlobal(PlayerReadyEvent.class, this::onPlayerReady); // Async eventy
getEventRegistry().registerAsyncGlobal(PlayerChatEvent.class, future -> {
future.thenAccept(this::onPlayerChat);
});
// World eventy
getEventRegistry().registerGlobal(AllWorldsLoadedEvent.class, event -> {
loadConfig();
});
getEventRegistry().registerGlobal(AddWorldEvent.class, event -> {
onWorldAdded(event.getWorld());
});
}
---
AllWorldsLoadedEvent
Tento event je ideální pro načítání dat která závisí na světech:
@Override
protected void setup() {
getEventRegistry().registerGlobal(AllWorldsLoadedEvent.class, event -> {
// Všechny světy jsou načtené
loadWarps();
loadPlayerData();
initializeWorldSpecificData();
});
}
---
start()
Volá se když je plugin plně aktivní:
@Override
protected void start() {
getLogger().atInfo().log("MyPlugin started!"); // Verifikace že vše je správně načtené
if (warps.isEmpty()) {
getLogger().atWarning().log("No warps loaded!");
}
// Spuštění periodických tasků
startPeriodicTasks();
}
---
shutdown()
Volá se při vypínání serveru:
@Override
protected void shutdown() {
getLogger().atInfo().log("MyPlugin shutting down..."); // Uložení dat
saveAllData();
// Zastavení tasků
stopPeriodicTasks();
// Cleanup
cleanup();
getLogger().atInfo().log("MyPlugin shutdown complete.");
}
Důležité pro Shutdown
@Override
protected void shutdown() {
// Synchronní uložení - server čeká
try {
saveWarps();
savePlayerData();
} catch (Exception e) {
getLogger().at(Level.SEVERE).withCause(e).log("Failed to save data!");
}
}
---
Dostupné Metody z JavaPlugin
Registry
// Command registry
getCommandRegistry().registerCommand(command);// Event registry
getEventRegistry().register(...);
getEventRegistry().registerGlobal(...);
getEventRegistry().registerAsync(...);
// Entity store registry
getEntityStoreRegistry().registerComponent(...);
getEntityStoreRegistry().registerSystem(...);
getEntityStoreRegistry().registerResource(...);
Logger
// Info
getLogger().atInfo().log("Message");
getLogger().atInfo().log("Message with param: %s", param);// Warning
getLogger().atWarning().log("Warning message");
// Error s výjimkou
getLogger().at(Level.SEVERE).withCause(exception).log("Error occurred:");
Data Folder
// Složka pro data pluginu
Path dataFolder = getDataFolder();
Path configPath = dataFolder.resolve("config.json");
---
Singleton Pattern
Běžný vzor pro přístup k pluginu:
public class MyPlugin extends JavaPlugin { private static MyPlugin instance;
public MyPlugin(JavaPluginInit init) {
super(init);
}
@Override
protected void setup() {
instance = this; // Nastav singleton
// ...
}
// Statický getter
public static MyPlugin get() {
return instance;
}
// Gettery pro ComponentType
public ComponentType getMyComponentType() {
return myComponentType;
}
}
// Použití kdekoliv v kódu
MyPlugin plugin = MyPlugin.get();
ComponentType type = MyPlugin.get().getMyComponentType();
---
Kompletní Příklad
public class ExamplePlugin extends JavaPlugin { private static ExamplePlugin instance;
private ComponentType playerStatsType;
private final Map playerDataCache = new ConcurrentHashMap<>();
public ExamplePlugin(JavaPluginInit init) {
super(init);
}
public static ExamplePlugin get() {
return instance;
}
@Override
protected void setup() {
instance = this;
// Komponenty
playerStatsType = getEntityStoreRegistry().registerComponent(
PlayerStats.class,
PlayerStats::new
);
// Systémy
getEntityStoreRegistry().registerSystem(new DeathStatsSystem());
// Příkazy
getCommandRegistry().registerCommand(new StatsCommand());
// Eventy
getEventRegistry().registerGlobal(PlayerReadyEvent.class, this::onPlayerReady);
getEventRegistry().register(PlayerDisconnectEvent.class, this::onPlayerDisconnect);
getEventRegistry().registerGlobal(AllWorldsLoadedEvent.class, e -> loadAllData());
getLogger().atInfo().log("ExamplePlugin setup complete");
}
@Override
protected void start() {
getLogger().atInfo().log("ExamplePlugin started! Loaded %d players", playerDataCache.size());
}
@Override
protected void shutdown() {
getLogger().atInfo().log("ExamplePlugin shutting down...");
saveAllPlayerData();
getLogger().atInfo().log("ExamplePlugin shutdown complete");
}
private void onPlayerReady(PlayerReadyEvent event) {
Player player = event.getPlayer();
loadPlayerData(player.getUuid());
}
private void onPlayerDisconnect(PlayerDisconnectEvent event) {
Player player = event.getPlayer();
savePlayerData(player.getUuid());
}
private void loadAllData() {
// Načti globální data
}
private void loadPlayerData(UUID uuid) {
// Async načtení
}
private void savePlayerData(UUID uuid) {
// Async uložení
}
private void saveAllPlayerData() {
// Sync uložení všech dat
}
public ComponentType getPlayerStatsType() {
return playerStatsType;
}
}
---
Shrnutí
| Metoda | Kdy | Co dělat |
|--------|-----|----------|
| setup() | Inicializace | Registrace komponent, systémů, příkazů, eventů |
| start() | Po načtení | Logování, verifikace, periodické tasky |
| shutdown() | Vypínání | Uložení dat, cleanup |
| Registry | Účel |
|----------|------|
| getCommandRegistry() | Registrace příkazů |
| getEventRegistry() | Registrace event listenerů |
| getEntityStoreRegistry() | Registrace ECS komponent/systémů |