init
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
package net.kewwbec.hub;
|
||||
|
||||
import com.hypixel.hytale.logger.HytaleLogger;
|
||||
import com.hypixel.hytale.server.core.event.events.player.AddPlayerToWorldEvent;
|
||||
import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
|
||||
import com.hypixel.hytale.server.core.event.events.player.RemovedPlayerFromWorldEvent;
|
||||
import com.hypixel.hytale.server.core.plugin.JavaPlugin;
|
||||
import com.hypixel.hytale.server.core.plugin.JavaPluginInit;
|
||||
import com.hypixel.hytale.server.core.universe.world.events.AllWorldsLoadedEvent;
|
||||
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
||||
import net.kewwbec.hub.config.HubConfig;
|
||||
import net.kewwbec.hub.config.HubConfigLoader;
|
||||
import net.kewwbec.hub.listener.HubJoinListener;
|
||||
import net.kewwbec.hub.listener.HubMessageListener;
|
||||
import net.kewwbec.hub.protection.CancelDamageBlockSystem;
|
||||
import net.kewwbec.hub.protection.CancelPlaceBlockSystem;
|
||||
import net.kewwbec.hub.protection.CancelBreakBlockSystem;
|
||||
import net.kewwbec.hub.protection.HubWorldFilter;
|
||||
import net.kewwbec.hub.service.HubWorldService;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public final class HubPlugin extends JavaPlugin {
|
||||
|
||||
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
|
||||
|
||||
private HubConfig config;
|
||||
private HubWorldFilter filter;
|
||||
private HubWorldService worldService;
|
||||
|
||||
public HubPlugin(@Nonnull JavaPluginInit init) {
|
||||
super(init);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setup() {
|
||||
try {
|
||||
this.config = HubConfigLoader.loadOrCreate(getDataDirectory());
|
||||
} catch (IOException e) {
|
||||
((HytaleLogger.Api) LOGGER.at(Level.SEVERE).withCause(e)).log("Failed to load Hub config");
|
||||
this.config = new HubConfig();
|
||||
}
|
||||
this.filter = new HubWorldFilter(config);
|
||||
LOGGER.at(Level.INFO).log("Hub setup complete");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void start() {
|
||||
this.worldService = new HubWorldService(config);
|
||||
HubJoinListener joinListener = new HubJoinListener(config, filter);
|
||||
HubMessageListener messageListener = new HubMessageListener(config, filter);
|
||||
|
||||
getEventRegistry().registerGlobal(AllWorldsLoadedEvent.class, e -> worldService.applyToConfiguredWorlds());
|
||||
worldService.applyToConfiguredWorlds();
|
||||
|
||||
getEventRegistry().registerGlobal(PlayerReadyEvent.class, joinListener::onReady);
|
||||
getEventRegistry().registerGlobal(AddPlayerToWorldEvent.class, messageListener::onAdd);
|
||||
getEventRegistry().registerGlobal(RemovedPlayerFromWorldEvent.class, messageListener::onRemove);
|
||||
|
||||
if (config.protection.disable_block_break) {
|
||||
getEntityStoreRegistry().registerSystem(new CancelBreakBlockSystem(filter));
|
||||
}
|
||||
if (config.protection.disable_block_place) {
|
||||
getEntityStoreRegistry().registerSystem(new CancelPlaceBlockSystem(filter));
|
||||
}
|
||||
if (config.protection.disable_block_damage) {
|
||||
getEntityStoreRegistry().registerSystem(new CancelDamageBlockSystem(filter));
|
||||
}
|
||||
|
||||
LOGGER.at(Level.INFO).log("Hub started");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutdown() {
|
||||
LOGGER.at(Level.INFO).log("Hub shutdown complete");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
package net.kewwbec.hub.config;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public final class HubConfig {
|
||||
|
||||
public WorldsSection worlds = new WorldsSection();
|
||||
public ProtectionSection protection = new ProtectionSection();
|
||||
public MessagesSection messages = new MessagesSection();
|
||||
public SpawnSection spawn = new SpawnSection();
|
||||
|
||||
public static final class WorldsSection {
|
||||
/**
|
||||
* World names this plugin treats as hubs. Empty = apply to every world this server hosts.
|
||||
*/
|
||||
public List<String> hub_worlds = new ArrayList<>();
|
||||
}
|
||||
|
||||
public static final class ProtectionSection {
|
||||
/** Cancel BreakBlockEvent in hub worlds. */
|
||||
public boolean disable_block_break = true;
|
||||
/** Cancel PlaceBlockEvent in hub worlds. */
|
||||
public boolean disable_block_place = true;
|
||||
/** Cancel DamageBlockEvent in hub worlds (mining progress). */
|
||||
public boolean disable_block_damage = true;
|
||||
/** WorldConfig.isPvpEnabled = false on hub worlds. */
|
||||
public boolean disable_pvp = true;
|
||||
/** WorldConfig.isFallDamageEnabled = false on hub worlds. */
|
||||
public boolean disable_fall_damage = true;
|
||||
/**
|
||||
* Master toggle for writing the WorldConfig flags (PvP, fall damage). Set false to manage
|
||||
* them yourself in Hytale's world config and have Hub leave them alone.
|
||||
*/
|
||||
public boolean apply_world_config = true;
|
||||
}
|
||||
|
||||
public static final class MessagesSection {
|
||||
/**
|
||||
* Private welcome shown only to the joining player. {player} is substituted.
|
||||
* Empty/null disables.
|
||||
*/
|
||||
public String welcome = "Welcome to the hub, {player}!";
|
||||
/**
|
||||
* Replaces Hytale's default join broadcast on hub worlds. {player} is substituted.
|
||||
* Empty/null suppresses the join broadcast entirely.
|
||||
*/
|
||||
public String join_announcement = "{player} joined the hub.";
|
||||
/**
|
||||
* Replaces Hytale's default leave broadcast on hub worlds. {player} is substituted.
|
||||
* Empty/null suppresses the leave broadcast entirely.
|
||||
*/
|
||||
public String leave_announcement = "";
|
||||
}
|
||||
|
||||
public static final class SpawnSection {
|
||||
/**
|
||||
* If true, teleport every connecting player to the world's spawn point.
|
||||
*/
|
||||
public boolean teleport_on_join = true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package net.kewwbec.hub.config;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
public final class HubConfigLoader {
|
||||
|
||||
private static final Gson GSON = new GsonBuilder().setPrettyPrinting().create();
|
||||
|
||||
private HubConfigLoader() {
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public static HubConfig loadOrCreate(@Nonnull Path dataDirectory) throws IOException {
|
||||
Path file = dataDirectory.resolve("config.json");
|
||||
if (!Files.exists(file)) {
|
||||
Files.createDirectories(dataDirectory);
|
||||
HubConfig fresh = new HubConfig();
|
||||
Files.writeString(file, GSON.toJson(fresh), StandardCharsets.UTF_8);
|
||||
return fresh;
|
||||
}
|
||||
String json = Files.readString(file, StandardCharsets.UTF_8);
|
||||
HubConfig parsed = GSON.fromJson(json, HubConfig.class);
|
||||
if (parsed == null) parsed = new HubConfig();
|
||||
if (parsed.worlds == null) parsed.worlds = new HubConfig.WorldsSection();
|
||||
if (parsed.protection == null) parsed.protection = new HubConfig.ProtectionSection();
|
||||
if (parsed.messages == null) parsed.messages = new HubConfig.MessagesSection();
|
||||
if (parsed.spawn == null) parsed.spawn = new HubConfig.SpawnSection();
|
||||
return parsed;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package net.kewwbec.hub.listener;
|
||||
|
||||
import com.hypixel.hytale.component.Ref;
|
||||
import com.hypixel.hytale.component.Store;
|
||||
import com.hypixel.hytale.logger.HytaleLogger;
|
||||
import com.hypixel.hytale.math.vector.Transform;
|
||||
import com.hypixel.hytale.server.core.Message;
|
||||
import com.hypixel.hytale.server.core.event.events.player.PlayerReadyEvent;
|
||||
import com.hypixel.hytale.server.core.modules.entity.teleport.Teleport;
|
||||
import com.hypixel.hytale.server.core.universe.PlayerRef;
|
||||
import com.hypixel.hytale.server.core.universe.world.World;
|
||||
import com.hypixel.hytale.server.core.universe.world.WorldConfig;
|
||||
import com.hypixel.hytale.server.core.universe.world.spawn.ISpawnProvider;
|
||||
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
||||
import net.kewwbec.hub.config.HubConfig;
|
||||
import net.kewwbec.hub.protection.HubWorldFilter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.awt.Color;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* On PlayerReadyEvent in a hub world: teleport to spawn and send a private welcome.
|
||||
*
|
||||
* Join/leave broadcasts are handled by HubMessageListener (which replaces Hytale's built-in
|
||||
* join/leave messages on AddPlayerToWorldEvent / RemovedPlayerFromWorldEvent).
|
||||
*/
|
||||
public final class HubJoinListener {
|
||||
|
||||
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
|
||||
|
||||
private final HubConfig config;
|
||||
private final HubWorldFilter filter;
|
||||
|
||||
public HubJoinListener(@Nonnull HubConfig config, @Nonnull HubWorldFilter filter) {
|
||||
this.config = config;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public void onReady(@Nonnull PlayerReadyEvent event) {
|
||||
Ref<EntityStore> ref = event.getPlayerRef();
|
||||
if (ref == null || !ref.isValid()) return;
|
||||
Store<EntityStore> store = ref.getStore();
|
||||
World world = store.getExternalData().getWorld();
|
||||
if (world == null || !filter.isHub(world)) return;
|
||||
|
||||
PlayerRef playerRef = store.getComponent(ref, PlayerRef.getComponentType());
|
||||
if (playerRef == null) return;
|
||||
|
||||
if (config.spawn.teleport_on_join) {
|
||||
try {
|
||||
WorldConfig wcfg = world.getWorldConfig();
|
||||
ISpawnProvider sp = (wcfg == null) ? null : wcfg.getSpawnProvider();
|
||||
if (sp != null) {
|
||||
Transform spawn = sp.getSpawnPoint(world, playerRef.getUuid());
|
||||
if (spawn != null) {
|
||||
store.putComponent(ref, Teleport.getComponentType(),
|
||||
Teleport.createForPlayer(world, spawn));
|
||||
}
|
||||
}
|
||||
} catch (RuntimeException e) {
|
||||
LOGGER.at(Level.WARNING).log("Hub: teleport to spawn failed for %s: %s", playerRef.getUsername(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (config.messages.welcome != null && !config.messages.welcome.isBlank()) {
|
||||
String welcome = config.messages.welcome.replace("{player}", playerRef.getUsername());
|
||||
try {
|
||||
playerRef.sendMessage(Message.raw(welcome).color(Color.YELLOW));
|
||||
} catch (RuntimeException ignored) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package net.kewwbec.hub.listener;
|
||||
|
||||
import com.hypixel.hytale.component.Holder;
|
||||
import com.hypixel.hytale.server.core.Message;
|
||||
import com.hypixel.hytale.server.core.event.events.player.AddPlayerToWorldEvent;
|
||||
import com.hypixel.hytale.server.core.event.events.player.RemovedPlayerFromWorldEvent;
|
||||
import com.hypixel.hytale.server.core.universe.PlayerRef;
|
||||
import com.hypixel.hytale.server.core.universe.world.World;
|
||||
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
||||
import net.kewwbec.hub.config.HubConfig;
|
||||
import net.kewwbec.hub.protection.HubWorldFilter;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Replaces (or suppresses) Hytale's default join/leave broadcasts on hub worlds.
|
||||
*
|
||||
* AddPlayerToWorldEvent / RemovedPlayerFromWorldEvent are fired by Hytale's player-add/remove
|
||||
* systems with a default joinMessage / leaveMessage. The systems check shouldBroadcastJoinMessage
|
||||
* (or leave) after dispatch and broadcast accordingly. We rewrite the message text here, or
|
||||
* suppress entirely if the configured format is blank.
|
||||
*/
|
||||
public final class HubMessageListener {
|
||||
|
||||
private final HubConfig config;
|
||||
private final HubWorldFilter filter;
|
||||
|
||||
public HubMessageListener(@Nonnull HubConfig config, @Nonnull HubWorldFilter filter) {
|
||||
this.config = config;
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
public void onAdd(@Nonnull AddPlayerToWorldEvent event) {
|
||||
if (!filter.isHub(event.getWorld())) return;
|
||||
String username = resolveUsername(event.getHolder());
|
||||
String template = config.messages.join_announcement;
|
||||
if (template == null || template.isBlank()) {
|
||||
event.setBroadcastJoinMessage(false);
|
||||
return;
|
||||
}
|
||||
event.setJoinMessage(Message.raw(template.replace("{player}", username)));
|
||||
event.setBroadcastJoinMessage(true);
|
||||
}
|
||||
|
||||
public void onRemove(@Nonnull RemovedPlayerFromWorldEvent event) {
|
||||
if (!filter.isHub(event.getWorld())) return;
|
||||
String username = resolveUsername(event.getHolder());
|
||||
String template = config.messages.leave_announcement;
|
||||
if (template == null || template.isBlank()) {
|
||||
event.setBroadcastLeaveMessage(false);
|
||||
return;
|
||||
}
|
||||
event.setLeaveMessage(Message.raw(template.replace("{player}", username)));
|
||||
event.setBroadcastLeaveMessage(true);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private static String resolveUsername(@Nullable Holder<EntityStore> holder) {
|
||||
if (holder == null) return "?";
|
||||
PlayerRef ref = holder.getComponent(PlayerRef.getComponentType());
|
||||
return (ref == null) ? "?" : ref.getUsername();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.kewwbec.hub.protection;
|
||||
|
||||
import com.hypixel.hytale.component.ArchetypeChunk;
|
||||
import com.hypixel.hytale.component.CommandBuffer;
|
||||
import com.hypixel.hytale.component.Store;
|
||||
import com.hypixel.hytale.component.query.Query;
|
||||
import com.hypixel.hytale.component.system.EntityEventSystem;
|
||||
import com.hypixel.hytale.server.core.event.events.ecs.BreakBlockEvent;
|
||||
import com.hypixel.hytale.server.core.universe.world.World;
|
||||
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
/**
|
||||
* ECS system that cancels BreakBlockEvent inside hub worlds.
|
||||
*
|
||||
* BreakBlockEvent extends CancellableEcsEvent and is dispatched per-entity
|
||||
* (the breaker) via entityStore.invoke(ref, event). Hytale's BlockHarvestUtils
|
||||
* checks event.isCancelled() and aborts the actual break if true.
|
||||
*/
|
||||
public final class CancelBreakBlockSystem extends EntityEventSystem<EntityStore, BreakBlockEvent> {
|
||||
|
||||
private final HubWorldFilter filter;
|
||||
|
||||
public CancelBreakBlockSystem(@Nonnull HubWorldFilter filter) {
|
||||
super(BreakBlockEvent.class);
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public Query<EntityStore> getQuery() {
|
||||
return Query.any();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(int chunkSlot,
|
||||
@Nonnull ArchetypeChunk<EntityStore> chunk,
|
||||
@Nonnull Store<EntityStore> store,
|
||||
@Nonnull CommandBuffer<EntityStore> commandBuffer,
|
||||
@Nonnull BreakBlockEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
World world = store.getExternalData().getWorld();
|
||||
if (world == null || !filter.isHub(world)) return;
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package net.kewwbec.hub.protection;
|
||||
|
||||
import com.hypixel.hytale.component.ArchetypeChunk;
|
||||
import com.hypixel.hytale.component.CommandBuffer;
|
||||
import com.hypixel.hytale.component.Store;
|
||||
import com.hypixel.hytale.component.query.Query;
|
||||
import com.hypixel.hytale.component.system.EntityEventSystem;
|
||||
import com.hypixel.hytale.server.core.event.events.ecs.DamageBlockEvent;
|
||||
import com.hypixel.hytale.server.core.universe.world.World;
|
||||
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public final class CancelDamageBlockSystem extends EntityEventSystem<EntityStore, DamageBlockEvent> {
|
||||
|
||||
private final HubWorldFilter filter;
|
||||
|
||||
public CancelDamageBlockSystem(@Nonnull HubWorldFilter filter) {
|
||||
super(DamageBlockEvent.class);
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public Query<EntityStore> getQuery() {
|
||||
return Query.any();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(int chunkSlot,
|
||||
@Nonnull ArchetypeChunk<EntityStore> chunk,
|
||||
@Nonnull Store<EntityStore> store,
|
||||
@Nonnull CommandBuffer<EntityStore> commandBuffer,
|
||||
@Nonnull DamageBlockEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
World world = store.getExternalData().getWorld();
|
||||
if (world == null || !filter.isHub(world)) return;
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package net.kewwbec.hub.protection;
|
||||
|
||||
import com.hypixel.hytale.component.ArchetypeChunk;
|
||||
import com.hypixel.hytale.component.CommandBuffer;
|
||||
import com.hypixel.hytale.component.Store;
|
||||
import com.hypixel.hytale.component.query.Query;
|
||||
import com.hypixel.hytale.component.system.EntityEventSystem;
|
||||
import com.hypixel.hytale.server.core.event.events.ecs.PlaceBlockEvent;
|
||||
import com.hypixel.hytale.server.core.universe.world.World;
|
||||
import com.hypixel.hytale.server.core.universe.world.storage.EntityStore;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public final class CancelPlaceBlockSystem extends EntityEventSystem<EntityStore, PlaceBlockEvent> {
|
||||
|
||||
private final HubWorldFilter filter;
|
||||
|
||||
public CancelPlaceBlockSystem(@Nonnull HubWorldFilter filter) {
|
||||
super(PlaceBlockEvent.class);
|
||||
this.filter = filter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nonnull
|
||||
public Query<EntityStore> getQuery() {
|
||||
return Query.any();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(int chunkSlot,
|
||||
@Nonnull ArchetypeChunk<EntityStore> chunk,
|
||||
@Nonnull Store<EntityStore> store,
|
||||
@Nonnull CommandBuffer<EntityStore> commandBuffer,
|
||||
@Nonnull PlaceBlockEvent event) {
|
||||
if (event.isCancelled()) return;
|
||||
World world = store.getExternalData().getWorld();
|
||||
if (world == null || !filter.isHub(world)) return;
|
||||
event.setCancelled(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package net.kewwbec.hub.protection;
|
||||
|
||||
import com.hypixel.hytale.server.core.universe.world.World;
|
||||
import net.kewwbec.hub.config.HubConfig;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Decides whether a given world should have hub behavior applied.
|
||||
*
|
||||
* If {@link HubConfig.WorldsSection#hub_worlds} is empty, every world is a hub world.
|
||||
* Otherwise only worlds whose name matches (case-insensitive) are hubs.
|
||||
*/
|
||||
public final class HubWorldFilter {
|
||||
|
||||
private final List<String> configured;
|
||||
|
||||
public HubWorldFilter(@Nonnull HubConfig config) {
|
||||
this.configured = config.worlds.hub_worlds;
|
||||
}
|
||||
|
||||
public boolean isHub(@Nonnull World world) {
|
||||
if (configured == null || configured.isEmpty()) return true;
|
||||
String name = world.getName();
|
||||
for (String hw : configured) {
|
||||
if (hw != null && hw.equalsIgnoreCase(name)) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package net.kewwbec.hub.service;
|
||||
|
||||
import com.hypixel.hytale.logger.HytaleLogger;
|
||||
import com.hypixel.hytale.server.core.universe.Universe;
|
||||
import com.hypixel.hytale.server.core.universe.world.World;
|
||||
import com.hypixel.hytale.server.core.universe.world.WorldConfig;
|
||||
import net.kewwbec.hub.config.HubConfig;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
|
||||
/**
|
||||
* Applies hub-protection flags to configured worlds at startup. Reads
|
||||
* {@link HubConfig.ProtectionSection} and pushes settings into each world's WorldConfig.
|
||||
*
|
||||
* Only writes settings whose values differ; calls markChanged() once if anything changed.
|
||||
*/
|
||||
public final class HubWorldService {
|
||||
|
||||
private static final HytaleLogger LOGGER = HytaleLogger.forEnclosingClass();
|
||||
|
||||
private final HubConfig config;
|
||||
|
||||
public HubWorldService(@Nonnull HubConfig config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public void applyToConfiguredWorlds() {
|
||||
if (!config.protection.apply_world_config) {
|
||||
LOGGER.at(Level.INFO).log("Hub: apply_world_config=false, skipping world-flag enforcement");
|
||||
return;
|
||||
}
|
||||
|
||||
Universe universe = Universe.get();
|
||||
if (universe == null) {
|
||||
LOGGER.at(Level.WARNING).log("Hub: Universe.get() is null at apply time");
|
||||
return;
|
||||
}
|
||||
|
||||
Collection<World> targets = resolveWorlds(universe);
|
||||
if (targets.isEmpty()) {
|
||||
LOGGER.at(Level.WARNING).log("Hub: no hub worlds resolved (configured: %s)", config.worlds.hub_worlds);
|
||||
return;
|
||||
}
|
||||
|
||||
for (World w : targets) {
|
||||
applyToWorld(w);
|
||||
}
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
private Collection<World> resolveWorlds(@Nonnull Universe universe) {
|
||||
Set<World> out = new HashSet<>();
|
||||
List<String> configured = config.worlds.hub_worlds;
|
||||
if (configured == null || configured.isEmpty()) {
|
||||
out.addAll(universe.getWorlds().values());
|
||||
return out;
|
||||
}
|
||||
for (String name : configured) {
|
||||
World w = universe.getWorld(name);
|
||||
if (w == null) {
|
||||
LOGGER.at(Level.WARNING).log("Hub: configured world '%s' not loaded", name);
|
||||
continue;
|
||||
}
|
||||
out.add(w);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
private void applyToWorld(@Nonnull World world) {
|
||||
WorldConfig cfg = world.getWorldConfig();
|
||||
if (cfg == null) return;
|
||||
|
||||
boolean changed = false;
|
||||
|
||||
if (config.protection.disable_pvp && cfg.isPvpEnabled()) {
|
||||
cfg.setPvpEnabled(false);
|
||||
changed = true;
|
||||
}
|
||||
if (config.protection.disable_fall_damage && cfg.isFallDamageEnabled()) {
|
||||
cfg.setFallDamageEnabled(false);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (changed) {
|
||||
cfg.markChanged();
|
||||
LOGGER.at(Level.INFO).log("Hub: applied protection flags to world '%s'", world.getName());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"Group": "kewwbec",
|
||||
"Name": "Hub",
|
||||
"Version": "0.1.0",
|
||||
"Description": "Lobby/hub behavior: protection, welcome message, spawn-on-join",
|
||||
"IncludesAssetPack": false,
|
||||
"Authors": [
|
||||
{"Name": "kewwbec"}
|
||||
],
|
||||
"ServerVersion": "*",
|
||||
"Dependencies": {
|
||||
"kewwbec:NetworkCore": "*"
|
||||
},
|
||||
"OptionalDependencies": {},
|
||||
"DisabledByDefault": false,
|
||||
"Main": "net.kewwbec.hub.HubPlugin"
|
||||
}
|
||||
Reference in New Issue
Block a user