Skip to content

Instantly share code, notes, and snippets.

@Alvin-LB
Created February 15, 2017 21:37
Show Gist options
  • Save Alvin-LB/a30f44d52816898e25c630374db21265 to your computer and use it in GitHub Desktop.
Save Alvin-LB/a30f44d52816898e25c630374db21265 to your computer and use it in GitHub Desktop.
package com.bringholm.itemgenerator.bukkitutils;
import com.google.common.base.Charsets;
import com.google.common.collect.Maps;
import com.google.common.io.Files;
import org.apache.commons.lang.Validate;
import org.bukkit.Bukkit;
import org.bukkit.configuration.InvalidConfigurationException;
import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
import java.io.*;
import java.util.*;
import java.util.logging.Level;
public class CommentYamlConfiguration extends YamlConfiguration {
private Map<Integer, String> comments = Maps.newHashMap();
@Override
public void load(Reader reader) throws IOException, InvalidConfigurationException {
StringBuilder builder = new StringBuilder();
String line;
try (BufferedReader input = reader instanceof BufferedReader ? (BufferedReader) reader : new BufferedReader(reader)) {
int index = 0;
while ((line = input.readLine()) != null) {
if (line.startsWith("#") || line.isEmpty()) {
comments.put(index, line);
}
builder.append(line);
builder.append('\n');
index++;
}
}
this.loadFromString(builder.toString());
}
@Override
public void save(File file) throws IOException {
Validate.notNull(file, "File cannot be null");
Files.createParentDirs(file);
String data = this.saveToString();
if (comments.size() != 0) {
String[] stringArray = data.split("\n");
StringBuilder stringBuilder = new StringBuilder();
int arrayIndex = 0;
for (int i = 0; i < stringArray.length + comments.size(); i++) {
if (comments.containsKey(i)) {
stringBuilder.append("\n").append(comments.get(i));
} else {
stringBuilder.append("\n").append(stringArray[arrayIndex++]);
}
}
data = stringBuilder.toString().substring(1);
}
try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(file), Charsets.UTF_8)) {
writer.write(data);
}
}
@Override
protected String buildHeader() {
return "";
}
@Override
protected String parseHeader(String input) {
return "";
}
public static YamlConfiguration loadConfiguration(File file) {
Validate.notNull(file, "File cannot be null");
YamlConfiguration config = new CommentYamlConfiguration();
try {
config.load(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException | InvalidConfigurationException var4) {
Bukkit.getLogger().log(Level.SEVERE, "Cannot load " + file, var4);
}
return config;
}
public static class JavaPlugin extends org.bukkit.plugin.java.JavaPlugin {
private File configFile;
private FileConfiguration config;
@Override
public void reloadConfig() {
if (configFile == null) {
configFile = new File(this.getDataFolder(), "config.yml");
}
config = loadConfiguration(configFile);
InputStream defConfigStream = this.getResource("config.yml");
if(defConfigStream != null) {
config.setDefaults(loadConfiguration(new InputStreamReader(defConfigStream, Charsets.UTF_8)));
}
}
@Override
public FileConfiguration getConfig() {
if(this.config == null) {
this.reloadConfig();
}
return this.config;
}
}
}
# Configuration file for ItemGenerator
# All time values in this file are entered in the following manner:
# 0ms0s0m0h0d0w (0 being replaceable with any whole number)
# ms - milliseconds, s - seconds, m - minutes, h - hours, d - days, w - weeks
# Of course, not all values need to be present, you could only use 1 of them.
# Example: 5s6h4w would equal 5 seconds, 6 hours and 4 weeks.
# How often the plugin should check if it's time to spawn an item. Anything below 50ms will not be effective, since minecraft
# runs at that speed.
refresh-interval: 50ms
# List of ItemGenerators. Avoid editing this manually, use the in-game commands instead.
item-generators: {}
package com.bringholm.itemgenerator;
import com.bringholm.itemgenerator.bukkitutils.CommentYamlConfiguration;
import com.bringholm.itemgenerator.bukkitutils.TimeParser;
import com.google.common.collect.Maps;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.block.Block;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
import org.bukkit.plugin.Plugin;
import org.bukkit.scheduler.BukkitRunnable;
import java.util.Map;
public class ItemGenerator extends CommentYamlConfiguration.JavaPlugin {
private Map<String, ItemGeneratorData> itemGenerators = Maps.newHashMap();
private long refreshInterval;
@Override
public void onEnable() {
Exception e = refreshConfig();
if (e != null) {
throw new RuntimeException(e);
}
Plugin plugin = this;
new BukkitRunnable() {
@Override
public void run() {
for (Map.Entry<String, ItemGeneratorData> entry : itemGenerators.entrySet()) {
if (entry.getValue().timeStamp <= System.currentTimeMillis()) {
Block block = entry.getValue().location.getBlock();
if (!block.getType().isSolid()) {
block.getWorld().dropItem(block.getLocation().add(0.5, 0, 0.5), entry.getValue().item);
} else {
String string = block.getLocation().getX() + " " + block.getLocation().getY() + " " + block.getLocation().getZ();
plugin.getLogger().warning("The block at " + string + " is obstructed, so an item could not be spawned!");
}
entry.getValue().timeStamp = System.currentTimeMillis() + entry.getValue().interval;
}
}
}
}.runTaskTimer(this, 0, refreshInterval);
}
private Exception refreshConfig() {
saveDefaultConfig();
try {
// ticks = millis / 1000 / 20
refreshInterval = TimeParser.parseAsMillis(getConfig().getString("refresh-interval")) / 50;
itemGenerators.clear();
for (String string : getConfig().getConfigurationSection("item-generators").getKeys(false)) {
Location location = (Location) getConfig().get("item-generators." + string + ".location");
itemGenerators.put(string, new ItemGeneratorData(location, getConfig().getLong("item-generators." + string + ".timestamp"), getConfig().getLong("item-generators." + string + ".interval"), getConfig().getItemStack("item-generators." + string + ".item")));
}
return null;
} catch (Exception e) {
return e;
}
}
private void saveConfigValues() {
getConfig().set("item-generators", null);
for (Map.Entry<String, ItemGeneratorData> entry : itemGenerators.entrySet()) {
String string = entry.getKey();
getConfig().set("item-generators." + string + ".location", entry.getValue().location);
getConfig().set("item-generators." + string + ".timestamp", entry.getValue().timeStamp);
getConfig().set("item-generators." + string + ".interval", entry.getValue().interval);
getConfig().set("item-generators." + string + ".item", entry.getValue().item);
}
saveConfig();
}
@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
if (args.length == 0 || args.length > 3) {
sender.sendMessage(ChatColor.RED + "Incorrect arguments!");
;
return true;
}
if (args[0].equalsIgnoreCase("set") && args.length == 3) {
if (!sender.hasPermission("itemgenerator.add")) {
sender.sendMessage(ChatColor.RED + "You don't have permission to do this!");
return true;
}
if (sender instanceof Player) {
Player player = (Player) sender;
if (itemGenerators.containsKey(args[1])) {
sender.sendMessage(ChatColor.RED + "An ItemGenerator with the name " + args[1] + " already exists!");
} else {
long interval;
try {
if (TimeParser.matchesPattern(args[2])) {
interval = TimeParser.parseAsMillis(args[2]);
} else {
interval = Long.parseLong(args[2]);
}
} catch (NumberFormatException e) {
sender.sendMessage(ChatColor.RED + "Invalid interval! You can either use the time format described in config.yml or just a number of milliseconds!");
return true;
}
ItemStack item = player.getInventory().getItemInMainHand();
if (item == null) {
sender.sendMessage(ChatColor.RED + "You aren't holding anything in your hand!");
return true;
}
itemGenerators.put(args[1], new ItemGeneratorData(player.getLocation().getBlock().getLocation(), 0L, interval, item));
saveConfigValues();
sender.sendMessage(ChatColor.GOLD + "Successfully created ItemGenerator " + args[1] + "!");
}
} else {
sender.sendMessage(ChatColor.RED + "Only players can do this!");
}
} else if ((args[0].equalsIgnoreCase("delete") || args[0].equalsIgnoreCase("remove")) && args.length == 2) {
if (!sender.hasPermission("itemgenerator.remove")) {
sender.sendMessage(ChatColor.RED + "You don't have permission to do this!");
return true;
}
if (itemGenerators.containsKey(args[1])) {
itemGenerators.remove(args[1]);
saveConfigValues();
sender.sendMessage(ChatColor.GOLD + "Successfully removed ItemGenerator " + args[1] + "!");
} else {
sender.sendMessage(ChatColor.RED + "This ItemGenerator doesn't exist!");
}
} else if (args[0].equalsIgnoreCase("reload") && args.length == 1) {
if (!sender.hasPermission("itemgenerator.reload")) {
sender.sendMessage(ChatColor.RED + "You don't have permission to do this!");
return true;
}
Exception e = this.refreshConfig();
if (e != null) {
sender.sendMessage(ChatColor.RED + "Failed to reload config because of " + e + "! Check the console for details!");
throw new RuntimeException(e);
} else {
sender.sendMessage(ChatColor.GOLD + "Successfully reloaded config file!");
}
} else if (args[0].equalsIgnoreCase("list")) {
if (!sender.hasPermission("itemgenerator.list")) {
sender.sendMessage(ChatColor.RED + "You don't have permission to do this!");
return true;
}
if (itemGenerators.size() == 0) {
sender.sendMessage(ChatColor.GOLD + "There are no ItemGenerators to display!");
} else {
sender.sendMessage(ChatColor.GOLD + "Listing all ItemGenerators:");
for (Map.Entry<String, ItemGeneratorData> entry : itemGenerators.entrySet()) {
sender.sendMessage(ChatColor.GOLD + entry.getKey() + " at " + formatLocation(entry.getValue().location));
}
}
} else {
sender.sendMessage(ChatColor.RED + "Incorrect arguments!");
}
return true;
}
private String formatLocation(Location location) {
return location.getX() + " " + location.getY() + " " + location.getZ() + " in world " + location.getWorld().getName();
}
private class ItemGeneratorData {
Location location;
long timeStamp;
long interval;
ItemStack item;
ItemGeneratorData(Location location, long timeStamp, long interval, ItemStack item) {
this.location = location;
this.timeStamp = timeStamp;
this.interval = interval;
this.item = item;
}
}
}
name: ItemGenerator
version: 1.0
main: com.bringholm.itemgenerator.ItemGenerator
author: AlvinB
commands:
itemgenerator:
aliases: [igenerator, itemg, ig]
description: |
/itemgenerator set <name> <interval> - Creates a new ItemGenerator at the current location with the item in hand.
/itemgenerator delete <name> - Deletes the specified ItemGenerator.
/itemgenerator reload - Reloads the configuration file.
usage: /itemgenerator <set|delete> <name> [interval]
permissions:
itemgenerator.*:
description: Gives access to all permissions of this plugin.
children:
itemgenerator.add: true
itemgenerator.remove: true
itemgenerator.reload: true
itemgenerator.list: true
itemgenerator.add:
description: Allows you to add an ItemGenerator
default: op
itemgenerator.remove:
description: Allows you to remove an ItemGenerator
default: op
itemgenerator.reload:
description: Allows you to reload the config file
default: op
itemgenerator.list:
description: Allows you to list all ItemGenerators
default: op
package com.bringholm.itemgenerator.bukkitutils;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TimeParser {
private static final Pattern INPUT_PATTERN = Pattern.compile("([0-9]+(ms|[mshdw]))+");
public static long parseAsMillis(String time) {
time = time.toLowerCase();
if (matchesPattern(time)) {
long millisTime = 0;
char[] chars = time.toCharArray();
String currentNum = "";
for (int i = 0; i < chars.length; i++) {
char c = chars[i];
if (Character.isDigit(c)) {
currentNum += c;
} else {
try {
switch (c) {
case 'm':
if (chars[i + 1] == 's') {
millisTime += Long.parseLong(currentNum);
i++;
} else {
millisTime += Long.parseLong(currentNum) * 60000L;
}
break;
case 's':
millisTime += Long.parseLong(currentNum) * 1000L;
break;
case 'h':
millisTime += Long.parseLong(currentNum) * 3600000L;
break;
case 'd':
millisTime += Long.parseLong(currentNum) * 86400000L;
break;
case 'w':
millisTime += Long.parseLong(currentNum) * 604800000L;
break;
}
} catch (NumberFormatException e) {
throw new IllegalArgumentException("Entered number (" + e.toString().substring(e.toString().lastIndexOf(":") + 3, e.toString().length() - 1) + ") was too large!");
}
currentNum = "";
}
}
return millisTime;
} else {
throw new IllegalArgumentException("Invalid time input!");
}
}
public static boolean matchesPattern(String string) {
string = string.toLowerCase();
Matcher matcher = INPUT_PATTERN.matcher(string);
return matcher.matches();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment