Skip to content
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
package com.eternalcode.core.configuration.migrations;

import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.migrate.ConfigMigration;
import eu.okaeri.configs.migrate.view.RawConfigView;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import lombok.NonNull;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;

public class Migration_0035_Move_warp_inventory_to_dedicated_file implements ConfigMigration {

private static final Logger LOGGER = Logger
.getLogger(Migration_0035_Move_warp_inventory_to_dedicated_file.class.getName());
private static final String ROOT_KEY = "warpInventory";
private static final String NESTED_KEY = "warp.warpInventory";
private static final String NESTED_SECTION = "warp";

@Override
public boolean migrate(@NonNull OkaeriConfig config, @NonNull RawConfigView view) {
String foundKey = null;
Map<String, Object> warpInventory = this.getFromView(view, ROOT_KEY);

if (warpInventory != null) {
foundKey = ROOT_KEY;
} else {
warpInventory = this.getFromView(view, NESTED_KEY);
if (warpInventory != null) {
foundKey = NESTED_KEY;
}
}

if (warpInventory == null) {
warpInventory = this.getFromFileFallback(config);
}

if (warpInventory == null) {
return false;
}

Map<String, Object> newContent = this.transformData(warpInventory);

if (!this.saveNewConfig(config, newContent)) {
return false;
}

if (foundKey != null) {
view.remove(foundKey);
} else {
view.remove(ROOT_KEY);
view.remove(NESTED_KEY);
}

return true;
}

private Map<String, Object> getFromView(RawConfigView view, String key) {
if (!view.exists(key)) {
return null;
}
Object obj = view.get(key);
return obj instanceof Map ? (Map<String, Object>) obj : null;
}

private Map<String, Object> getFromFileFallback(OkaeriConfig config) {
File bindFile = config.getBindFile().toFile();
if (bindFile == null || !bindFile.exists()) {
return null;
}

try (FileReader reader = new FileReader(bindFile)) {
Map<String, Object> content = new Yaml().load(reader);
if (content == null) {
return null;
}

if (content.containsKey(ROOT_KEY) && content.get(ROOT_KEY) instanceof Map) {
return (Map<String, Object>) content.get(ROOT_KEY);
}

if (content.containsKey(NESTED_SECTION) && content.get(NESTED_SECTION) instanceof Map) {
Map<String, Object> warpSection = (Map<String, Object>) content.get(NESTED_SECTION);
if (warpSection.containsKey(ROOT_KEY) && warpSection.get(ROOT_KEY) instanceof Map) {
return (Map<String, Object>) warpSection.get(ROOT_KEY);
}
}
} catch (Exception exception) {
LOGGER.log(Level.SEVERE, "Failed to read configuration file: " + bindFile.getAbsolutePath(), exception);
}
return null;
}

private Map<String, Object> transformData(Map<String, Object> source) {
Map<String, Object> result = new LinkedHashMap<>();

if (source.containsKey("title")) {
Map<String, Object> display = new LinkedHashMap<>();
display.put("title", source.get("title"));
result.put("display", display);
}

this.copyIfPresent(source, result, "items");
this.copyIfPresent(source, result, "border");
this.copyIfPresent(source, result, "decorationItems");

return result;
}

private void copyIfPresent(Map<String, Object> source, Map<String, Object> target, String key) {
if (source.containsKey(key)) {
target.put(key, source.get(key));
}
}

private boolean saveNewConfig(OkaeriConfig config, Map<String, Object> content) {
File destFile = this.getDestinationFile(config);
if (destFile == null) {
return false;
}

if (destFile.exists() && !this.targetIsSafeToWrite(destFile)) {
return true;
}

if (!destFile.getParentFile().exists()) {
destFile.getParentFile().mkdirs();
}

DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
options.setPrettyFlow(true);
options.setIndent(2);
options.setIndicatorIndent(0);
options.setSplitLines(false);

try (FileWriter writer = new FileWriter(destFile)) {
new Yaml(options).dump(content, writer);
return true;
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Failed to save new configuration file: " + destFile.getAbsolutePath(), e);
return false;
}
}

private File getDestinationFile(OkaeriConfig config) {
File bindFile = config.getBindFile().toFile();
if (bindFile == null) {
return null;
}
File dataFolder = bindFile.getParentFile();
if ("lang".equals(dataFolder.getName())) {
dataFolder = dataFolder.getParentFile();
}
return new File(dataFolder, "warp-inventory.yml");
}

private boolean targetIsSafeToWrite(File file) {
try (FileReader reader = new FileReader(file)) {
Map<String, Object> existing = new Yaml().load(reader);
if (existing == null || !existing.containsKey("items")) {
return true;
}
Object items = existing.get("items");
return items instanceof Map && ((Map<?, ?>) items).isEmpty();
} catch (Exception exception) {
LOGGER.log(Level.SEVERE, "Failed to check if target file is safe to write: " + file.getAbsolutePath(),
exception);
return false;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,38 @@
public class Migrations {

public static final ConfigMigration[] ALL = new ConfigMigration[] {
new Migration_0001_Rename_privateChat_to_msg(),
new Migration_0002_Move_Spawn_Settings_to_spawn_config_section(),
new Migration_0003_Move_tprp_to_dedicated_section(),
new Migration_0006_Move_alert_to_broadcast_section(),
new Migration_0007_Move_clear_to_dedicated_section(),
new Migration_0008_Move_repair_to_dedicated_section(),
new Migration_0009_Improve_Homes_Config(),
new Migration_0010_Move_give_to_dedicated_section(),
new Migration_0011_Move_enchant_to_dedicated_section(),
new Migration_0012_Move_repair_argument_messages_to_dedicated_section(),
new Migration_0013_Move_enchant_messages_to_dedicated_section(),
new Migration_0014_Move_butcher_argument_messages_to_dedicated_section(),
new Migration_0016_Move_feed_messages_to_dedicated_section(),
new Migration_0017_Move_heal_messages_to_dedicated_section(),
new Migration_0018_Move_kill_messages_to_dedicated_section(),
new Migration_0019_Move_speed_messages_to_dedicated_section(),
new Migration_0020_Move_godmode_messages_to_dedicated_section(),
new Migration_0021_Move_fly_messages_to_dedicated_section(),
new Migration_0022_Move_ping_messages_to_dedicated_section(),
new Migration_0023_Move_gamemode_messages_to_dedicated_section(),
new Migration_0024_Move_online_messages_to_dedicated_section(),
new Migration_0025_Move_whois_messages_to_dedicated_section(),
new Migration_0026_Move_butcher_messages_to_dedicated_section(),
new Migration_0027_Move_give_messages_to_dedicated_section(),
new Migration_0028_Move_skull_messages_to_dedicated_section(),
new Migration_0029_Move_enchant_messages_to_dedicated_section(),
new Migration_0015_Move_ignore_messages_to_dedicated_section(),
new Migration_0030_Move_back_to_dedicated_section(),
new Migration_0031_Move_death_messages_to_dedicated_section(),
new Migration_0032_Move_join_quit_messages_to_dedicated_section(),
new Migration_0033_Move_disposal_messages_to_dedicated_section(),
new Migration_0034_Move_chat_settings_messages_to_dedicated_section(),
};
new Migration_0001_Rename_privateChat_to_msg(),
new Migration_0002_Move_Spawn_Settings_to_spawn_config_section(),
new Migration_0003_Move_tprp_to_dedicated_section(),
new Migration_0006_Move_alert_to_broadcast_section(),
new Migration_0007_Move_clear_to_dedicated_section(),
new Migration_0008_Move_repair_to_dedicated_section(),
new Migration_0009_Improve_Homes_Config(),
new Migration_0010_Move_give_to_dedicated_section(),
new Migration_0011_Move_enchant_to_dedicated_section(),
new Migration_0012_Move_repair_argument_messages_to_dedicated_section(),
new Migration_0013_Move_enchant_messages_to_dedicated_section(),
new Migration_0014_Move_butcher_argument_messages_to_dedicated_section(),
new Migration_0016_Move_feed_messages_to_dedicated_section(),
new Migration_0017_Move_heal_messages_to_dedicated_section(),
new Migration_0018_Move_kill_messages_to_dedicated_section(),
new Migration_0019_Move_speed_messages_to_dedicated_section(),
new Migration_0020_Move_godmode_messages_to_dedicated_section(),
new Migration_0021_Move_fly_messages_to_dedicated_section(),
new Migration_0022_Move_ping_messages_to_dedicated_section(),
new Migration_0023_Move_gamemode_messages_to_dedicated_section(),
new Migration_0024_Move_online_messages_to_dedicated_section(),
new Migration_0025_Move_whois_messages_to_dedicated_section(),
new Migration_0026_Move_butcher_messages_to_dedicated_section(),
new Migration_0027_Move_give_messages_to_dedicated_section(),
new Migration_0028_Move_skull_messages_to_dedicated_section(),
new Migration_0029_Move_enchant_messages_to_dedicated_section(),
new Migration_0015_Move_ignore_messages_to_dedicated_section(),
new Migration_0030_Move_back_to_dedicated_section(),
new Migration_0031_Move_death_messages_to_dedicated_section(),
new Migration_0032_Move_join_quit_messages_to_dedicated_section(),
new Migration_0033_Move_disposal_messages_to_dedicated_section(),
new Migration_0034_Move_chat_settings_messages_to_dedicated_section(),
new Migration_0035_Move_warp_inventory_to_dedicated_file(),
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.eternalcode.core.feature.warp;

import org.bukkit.Location;
import org.bukkit.entity.Player;
import java.util.List;

public interface Warp {

String getName();

Location getLocation();

List<String> getPermissions();

default boolean hasPermissions(Player player) {
if (this.getPermissions().isEmpty()) {
return true;
}

for (String permission : this.getPermissions()) {
if (player.hasPermission(permission)) {
return true;
}
}

return false;
}

}
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
package com.eternalcode.core.feature.warp;

import com.eternalcode.commons.bukkit.position.Position;
import eu.okaeri.configs.OkaeriConfig;
import eu.okaeri.configs.annotation.Comment;
import java.time.Duration;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;
import org.bukkit.Material;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Getter
@Accessors(fluent = true)
public class WarpConfig extends OkaeriConfig implements WarpSettings {
Expand All @@ -19,8 +27,8 @@ public class WarpConfig extends OkaeriConfig implements WarpSettings {
@Comment("# Warp inventory auto add new warps")
public boolean autoAddNewWarps = true;

@Comment({"# Options below allow you to customize item representing warp added to GUI, ",
"# you can change almost everything inside language files, after the warp has been added to the inventory."})
@Comment({ "# Options below allow you to customize item representing warp added to GUI, ",
"# you can change almost everything inside language files, after the warp has been added to the inventory." })
public String itemNamePrefix = "&8» &6Warp: &f";

public String itemLore = "&7Click to teleport!";
Expand All @@ -29,4 +37,15 @@ public class WarpConfig extends OkaeriConfig implements WarpSettings {

@Comment("# Texture of the item (only for PLAYER_HEAD material)")
public String itemTexture = "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNzk4ODVlODIzZmYxNTkyNjdjYmU4MDkwOTNlMzNhNDc2ZTI3NDliNjU5OGNhNGEyYTgxZWU2OTczODAzZmI2NiJ9fX0=";

public Map<String, WarpConfigEntry> warps = new ConcurrentHashMap<>();

@Getter
@Accessors(fluent = true)
@NoArgsConstructor
@AllArgsConstructor
public static class WarpConfigEntry extends OkaeriConfig {
public Position position;
public List<String> permissions = new ArrayList<>();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,15 @@

import com.eternalcode.commons.bukkit.position.Position;
import com.eternalcode.commons.bukkit.position.PositionAdapter;
import java.util.ArrayList;
import org.bukkit.Location;

import java.util.Collections;
import java.util.List;

public class WarpImpl implements Warp {
public record WarpImpl(String name, Position position, List<String> permissions) implements Warp {

private final String name;
private final Position position;
private final List<String> permissions;

public WarpImpl(String name, Position position, List<String> permissions) {
this.name = name;
this.position = position;
this.permissions = new ArrayList<>(permissions);
public WarpImpl {
permissions = Collections.unmodifiableList(permissions);
}

@Override
Expand All @@ -32,7 +25,7 @@ public Location getLocation() {

@Override
public List<String> getPermissions() {
return Collections.unmodifiableList(this.permissions);
return this.permissions;
}

}
Loading