Skip to content

Commit 9b64d4b

Browse files
committed
Implemented the Survival Mod API
1 parent 36c66bd commit 9b64d4b

File tree

20 files changed

+629
-2
lines changed

20 files changed

+629
-2
lines changed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,29 @@
11
package net.badlion.bukkitapi;
22

3+
import net.badlion.bukkitapi.command.SurvivalCommand;
4+
import net.badlion.bukkitapi.gui.SurvivalGui;
5+
import net.badlion.bukkitapi.survival.SurvivalManager;
6+
7+
import java.util.Objects;
8+
39
public class BukkitBadlionPlugin extends AbstractBukkitBadlionPlugin {
10+
private SurvivalGui survivalGui;
11+
412
public BukkitBadlionPlugin() {
513
this.setMessageSender(new BukkitPluginMessageSender(this));
14+
this.setSurvivalManager(new SurvivalManager(this));
15+
}
16+
17+
@Override
18+
public void onEnable() {
19+
super.onEnable();
20+
21+
this.survivalGui = new SurvivalGui(this);
22+
23+
Objects.requireNonNull(this.getCommand("survivalapi")).setExecutor(new SurvivalCommand(this));
24+
}
25+
26+
public SurvivalGui getSurvivalGui() {
27+
return this.survivalGui;
628
}
729
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package net.badlion.bukkitapi.command;
2+
3+
import net.badlion.bukkitapi.BukkitBadlionPlugin;
4+
import org.bukkit.command.Command;
5+
import org.bukkit.command.CommandExecutor;
6+
import org.bukkit.command.CommandSender;
7+
import org.bukkit.entity.Player;
8+
9+
public class SurvivalCommand implements CommandExecutor {
10+
private final BukkitBadlionPlugin apiBukkit;
11+
12+
public SurvivalCommand(BukkitBadlionPlugin apiBukkit) {
13+
this.apiBukkit = apiBukkit;
14+
}
15+
16+
@Override
17+
public boolean onCommand(CommandSender commandSender, Command command, String label, String[] args) {
18+
if (!(commandSender instanceof Player)) {
19+
commandSender.sendMessage("This command can only be used by a player.");
20+
return true;
21+
}
22+
23+
this.apiBukkit.getSurvivalGui().open((Player) commandSender);
24+
25+
return true;
26+
}
27+
}
Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package net.badlion.bukkitapi.gui;
2+
3+
import net.badlion.bukkitapi.BukkitBadlionPlugin;
4+
import net.badlion.modapicommon.survival.SurvivalApi;
5+
import net.badlion.modapicommon.survival.SurvivalFeature;
6+
import org.bukkit.ChatColor;
7+
import org.bukkit.Material;
8+
import org.bukkit.Sound;
9+
import org.bukkit.enchantments.Enchantment;
10+
import org.bukkit.entity.Player;
11+
import org.bukkit.event.EventHandler;
12+
import org.bukkit.event.Listener;
13+
import org.bukkit.event.inventory.InventoryClickEvent;
14+
import org.bukkit.inventory.Inventory;
15+
import org.bukkit.inventory.ItemFlag;
16+
import org.bukkit.inventory.ItemStack;
17+
import org.bukkit.inventory.meta.ItemMeta;
18+
19+
import java.util.ArrayList;
20+
import java.util.HashMap;
21+
import java.util.List;
22+
import java.util.Map;
23+
import java.util.Set;
24+
25+
public class SurvivalGui implements Listener {
26+
private static final String INVENTORY_NAME = "Badlion - Survival Mod Features";
27+
28+
private final Inventory inventory;
29+
private final Map<Integer, String> actions;
30+
31+
public SurvivalGui(BukkitBadlionPlugin apiBukkit) {
32+
apiBukkit.getServer().getPluginManager().registerEvents(this, apiBukkit);
33+
34+
int size = 27;
35+
this.inventory = apiBukkit.getServer().createInventory(null, size, SurvivalGui.INVENTORY_NAME);
36+
this.actions = new HashMap<>();
37+
38+
this.refresh();
39+
40+
this.setCloseItem(size - 1);
41+
}
42+
43+
public void refresh() {
44+
Set<SurvivalFeature> enabledFeatures = SurvivalApi.getEnabledFeatures();
45+
int index = 0;
46+
47+
for (SurvivalFeature feature : SurvivalFeature.values()) {
48+
this.setItem(enabledFeatures, index++, feature);
49+
}
50+
}
51+
52+
public void open(Player player) {
53+
player.openInventory(this.inventory);
54+
}
55+
56+
@EventHandler
57+
public void onInventoryClick(InventoryClickEvent event) {
58+
if (event.getView().getTopInventory() == this.inventory) {
59+
event.setCancelled(true);
60+
61+
String action = this.actions.get(event.getRawSlot());
62+
63+
if (action != null) {
64+
if ("CLOSE".equals(action)) {
65+
event.getWhoClicked().closeInventory();
66+
67+
} else {
68+
SurvivalFeature survivalFeature = null;
69+
70+
try {
71+
survivalFeature = SurvivalFeature.valueOf(action);
72+
} catch (IllegalArgumentException ignored) {
73+
74+
}
75+
76+
if (survivalFeature != null) {
77+
boolean enabled = SurvivalApi.getEnabledFeatures().contains(survivalFeature);
78+
79+
if (enabled) {
80+
SurvivalApi.disableFeature(survivalFeature);
81+
} else {
82+
SurvivalApi.enableFeature(survivalFeature);
83+
}
84+
85+
event.getWhoClicked().sendMessage(ChatColor.GREEN + "You " + (enabled ? "disabled " : "enabled ") + survivalFeature.getName());
86+
87+
if (event.getWhoClicked() instanceof Player) { // Should always be true
88+
((Player) event.getWhoClicked()).playSound(event.getWhoClicked().getLocation(), Sound.BLOCK_NOTE_BLOCK_PLING, 1, enabled ? 1 : 2);
89+
}
90+
}
91+
}
92+
}
93+
}
94+
}
95+
96+
private void setCloseItem(int index) {
97+
ItemStack closeItem = new ItemStack(Material.BARRIER);
98+
ItemMeta itemMeta = closeItem.getItemMeta();
99+
100+
if (itemMeta != null) {
101+
itemMeta.setDisplayName(ChatColor.RED + "Close");
102+
closeItem.setItemMeta(itemMeta);
103+
}
104+
105+
this.setItem(index, closeItem, "CLOSE");
106+
}
107+
108+
private void setItem(Set<SurvivalFeature> enabledFeatures, int index, SurvivalFeature feature) {
109+
Material material = Material.getMaterial(feature.getMaterial());
110+
111+
ItemStack itemStack = new ItemStack(material == null ? Material.STONE : material);
112+
ItemMeta itemMeta = itemStack.getItemMeta();
113+
114+
if (itemMeta != null) {
115+
boolean enabled = enabledFeatures.contains(feature);
116+
117+
List<String> lore = new ArrayList<>();
118+
lore.add("");
119+
feature.getLore().forEach(line -> lore.add(ChatColor.GRAY + line));
120+
lore.add("");
121+
lore.add(ChatColor.YELLOW + "Click to " + (enabled ? "disable" : "enable"));
122+
123+
itemMeta.setDisplayName((enabled ? ChatColor.GREEN : ChatColor.RED) + feature.getName());
124+
itemMeta.setLore(lore);
125+
itemMeta.addItemFlags(ItemFlag.HIDE_ATTRIBUTES);
126+
127+
if (enabled) {
128+
itemMeta.addEnchant(Enchantment.DURABILITY, 1, true);
129+
itemMeta.addItemFlags(ItemFlag.HIDE_ENCHANTS);
130+
}
131+
132+
itemStack.setItemMeta(itemMeta);
133+
}
134+
135+
this.setItem(index, itemStack, feature.name());
136+
}
137+
138+
private void setItem(int index, ItemStack itemStack, String action) {
139+
this.inventory.setItem(index, itemStack);
140+
this.actions.put(index, action);
141+
}
142+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package net.badlion.bukkitapi.survival;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
6+
public class SurvivalConfig {
7+
public List<String> features = new ArrayList<>();
8+
}
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
package net.badlion.bukkitapi.survival;
2+
3+
import com.google.gson.JsonElement;
4+
import net.badlion.bukkitapi.BukkitBadlionPlugin;
5+
import net.badlion.modapicommon.AbstractBadlionApi;
6+
import net.badlion.modapicommon.mods.ModType;
7+
import net.badlion.modapicommon.survival.SurvivalFeature;
8+
import org.bukkit.entity.Player;
9+
import org.bukkit.scheduler.BukkitTask;
10+
11+
import java.io.File;
12+
import java.io.FileReader;
13+
import java.io.FileWriter;
14+
import java.util.Arrays;
15+
import java.util.Collections;
16+
import java.util.EnumSet;
17+
import java.util.Set;
18+
import java.util.logging.Level;
19+
20+
public class SurvivalManager extends AbstractBukkitSurvivalManager {
21+
private final BukkitBadlionPlugin apiBukkit;
22+
private final EnumSet<SurvivalFeature> enabledFeatures;
23+
private final SurvivalConfig config;
24+
private BukkitTask refreshTask;
25+
26+
public SurvivalManager(BukkitBadlionPlugin apiBukkit) {
27+
this.apiBukkit = apiBukkit;
28+
this.enabledFeatures = EnumSet.noneOf(SurvivalFeature.class);
29+
this.config = new SurvivalConfig();
30+
this.refreshTask = null;
31+
}
32+
33+
@Override
34+
public void enableAllFeatures() {
35+
this.enabledFeatures.addAll(Arrays.asList(SurvivalFeature.values()));
36+
37+
this.scheduleUpdate();
38+
}
39+
40+
@Override
41+
public void disableAllFeatures() {
42+
this.enabledFeatures.clear();
43+
44+
this.scheduleUpdate();
45+
}
46+
47+
@Override
48+
public void enableFeature(SurvivalFeature feature) {
49+
this.enabledFeatures.add(feature);
50+
51+
this.scheduleUpdate();
52+
}
53+
54+
@Override
55+
public void disableFeature(SurvivalFeature feature) {
56+
this.enabledFeatures.remove(feature);
57+
58+
this.scheduleUpdate();
59+
}
60+
61+
@Override
62+
public Set<SurvivalFeature> getEnabledFeatures() {
63+
return Collections.unmodifiableSet(this.enabledFeatures);
64+
}
65+
66+
@Override
67+
public void loadConfig() {
68+
File file = this.getConfigFile();
69+
70+
if (!file.exists()) {
71+
this.apiBukkit.getLogger().info("No survival config found, creating an empty one");
72+
this.saveConfig();
73+
return;
74+
}
75+
76+
SurvivalConfig survivalConfig;
77+
78+
try (FileReader fileReader = new FileReader(file)) {
79+
survivalConfig = AbstractBadlionApi.GSON_NON_PRETTY.fromJson(fileReader, SurvivalConfig.class);
80+
81+
} catch (Exception ex) {
82+
this.apiBukkit.getLogger().log(Level.SEVERE, "Failed to load survival config: " + ex.getMessage(), ex);
83+
return;
84+
}
85+
86+
this.enabledFeatures.clear();
87+
88+
for (String feature : survivalConfig.features) {
89+
try {
90+
this.enabledFeatures.add(SurvivalFeature.valueOf(feature));
91+
} catch (IllegalArgumentException ignored) {
92+
93+
}
94+
}
95+
96+
this.config.features = survivalConfig.features;
97+
}
98+
99+
@Override
100+
public void sendData(Player player) {
101+
this.sendData(player, this.generateData());
102+
}
103+
104+
private void sendData(Player player, JsonElement data) {
105+
this.apiBukkit.getMessageSender().sendModData(player.getUniqueId(), ModType.SURVIVAL, data);
106+
}
107+
108+
private JsonElement generateData() {
109+
return AbstractBadlionApi.GSON_NON_PRETTY.toJsonTree(this.config);
110+
}
111+
112+
private void scheduleUpdate() {
113+
if (this.refreshTask != null) {
114+
return;
115+
}
116+
117+
this.refreshTask = this.apiBukkit.getServer().getScheduler().runTaskLater(this.apiBukkit, () -> {
118+
this.refreshTask = null;
119+
120+
this.config.features.clear();
121+
this.enabledFeatures.forEach(survivalFeature -> this.config.features.add(survivalFeature.name()));
122+
123+
JsonElement data = this.generateData();
124+
this.apiBukkit.getServer().getOnlinePlayers().forEach(player -> this.sendData(player, data));
125+
126+
this.saveConfig();
127+
128+
this.apiBukkit.getSurvivalGui().refresh();
129+
}, 1L);
130+
}
131+
132+
private File getConfigFile() {
133+
return new File(this.apiBukkit.getDataFolder(), "survival.json");
134+
}
135+
136+
private void saveConfig() {
137+
File file = this.getConfigFile();
138+
139+
File parent = file.getParentFile();
140+
141+
if (!parent.exists() && !parent.mkdirs()) {
142+
this.apiBukkit.getLogger().warning("Failed to create survival config folder");
143+
}
144+
145+
try (FileWriter fileWriter = new FileWriter(file)) {
146+
AbstractBadlionApi.GSON_PRETTY.toJson(this.config, fileWriter);
147+
148+
} catch (Exception ex) {
149+
this.apiBukkit.getLogger().log(Level.SEVERE, "Failed to save survival config: " + ex.getMessage(), ex);
150+
}
151+
}
152+
}

bukkit-1.17/src/main/resources/plugin.yml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,8 @@ name: BadlionClientModAPI
22
main: net.badlion.bukkitapi.BukkitBadlionPlugin
33
version: 2.0
44
author: Badlion
5-
api-version: 1.17
5+
api-version: 1.17
6+
7+
commands:
8+
survivalapi:
9+
permission: badlion.survival

0 commit comments

Comments
 (0)