1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00

Fixed Emergency Transmitters + Reduced technical debt

This commit is contained in:
TheBusyBiscuit 2020-04-23 18:08:15 +02:00
parent a04676b27c
commit d896462c2d
24 changed files with 156 additions and 135 deletions

View File

@ -71,6 +71,7 @@
* Fixed #893
* Fixed #1798
* Fixed #1490
* Fixed GPS Emergency Transmitters not working
## Release Candidate 10 (28 Mar 2020)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#10

View File

@ -4,10 +4,11 @@ import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.logging.Level;
@ -35,6 +36,8 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
public class ErrorReport {
private static final DateTimeFormatter dateFormat = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm", Locale.ROOT);
private File file;
public ErrorReport(Throwable throwable, SlimefunAddon addon, Consumer<PrintStream> printer) {
@ -148,7 +151,7 @@ public class ErrorReport {
}
private static File getNewFile() {
String path = "plugins/Slimefun/error-reports/" + new SimpleDateFormat("yyyy-MM-dd-HH-mm").format(new Date());
String path = "plugins/Slimefun/error-reports/" + dateFormat.format(LocalDateTime.now());
File newFile = new File(path + ".err");
if (newFile.exists()) {

View File

@ -42,8 +42,6 @@ final class ContributorsMenu {
List<Contributor> contributors = new ArrayList<>(SlimefunPlugin.getGitHubService().getContributors().values());
contributors.sort(Comparator.comparingInt(Contributor::index));
int pages = (contributors.size() - 1) / 36 + 1;
for (int i = page * 36; i < contributors.size() && i < (page + 1) * 36; i++) {
Contributor contributor = contributors.get(i);
ItemStack skull = getContributorHead(p, contributor);
@ -58,6 +56,8 @@ final class ContributorsMenu {
});
}
int pages = (contributors.size() - 1) / 36 + 1;
menu.addItem(46, ChestMenuUtils.getPreviousButton(p, page + 1, pages));
menu.addMenuClickHandler(46, (pl, slot, item, action) -> {
if (page > 0) open(pl, page - 1);

View File

@ -80,7 +80,7 @@ public final class SlimefunGuideSettings {
menu.addItem(4, new CustomItem(Material.WRITABLE_BOOK, "&aSlimefun Version", "&7&o" + SlimefunPlugin.getLocal().getMessage(p, "guide.tooltips.versions-notice"), "", "&rMinecraft Version: &a" + Bukkit.getBukkitVersion(), "&rSlimefun Version: &a" + SlimefunPlugin.getVersion(), "&rCS-CoreLib Version: &a" + SlimefunPlugin.getCSCoreLibVersion()), ChestMenuUtils.getEmptyClickHandler());
menu.addItem(6, new CustomItem(Material.COMPARATOR, "&e" + SlimefunPlugin.getLocal().getMessage(p, "guide.title.source"), "", "&7Last Activity: &a" + NumberUtils.timeDelta(SlimefunPlugin.getGitHubService().getLastUpdate()) + " ago", "&7Forks: &e" + SlimefunPlugin.getGitHubService().getForks(), "&7Stars: &e" + SlimefunPlugin.getGitHubService().getStars(), "", "&7&oSlimefun 4 is a community project,", "&7&othe source code is available on GitHub", "&7&oand if you want to keep this Plugin alive,", "&7&othen please consider contributing to it", "", "&7\u21E8 &eClick to go to GitHub"));
menu.addItem(6, new CustomItem(Material.COMPARATOR, "&e" + SlimefunPlugin.getLocal().getMessage(p, "guide.title.source"), "", "&7Last Activity: &a" + NumberUtils.getElapsedTime(SlimefunPlugin.getGitHubService().getLastUpdate()) + " ago", "&7Forks: &e" + SlimefunPlugin.getGitHubService().getForks(), "&7Stars: &e" + SlimefunPlugin.getGitHubService().getStars(), "", "&7&oSlimefun 4 is a community project,", "&7&othe source code is available on GitHub", "&7&oand if you want to keep this Plugin alive,", "&7&othen please consider contributing to it", "", "&7\u21E8 &eClick to go to GitHub"));
menu.addMenuClickHandler(6, (pl, slot, item, action) -> {
pl.closeInventory();
ChatUtils.sendURL(pl, "https://github.com/TheBusyBiscuit/Slimefun4");

View File

@ -230,33 +230,21 @@ public class CargoNet extends ChestTerminalNetwork {
List<Location> outputs = output.get(entry.getValue());
if (outputs != null) {
List<Location> outputlist = new LinkedList<>(outputs);
List<Location> outputList = new LinkedList<>(outputs);
if (roundrobin) {
int index = roundRobin.getOrDefault(input, 0);
if (index < outputlist.size()) {
for (int i = 0; i < index; i++) {
Location temp = outputlist.remove(0);
outputlist.add(temp);
}
index++;
}
else {
index = 1;
}
roundRobin.put(input, index);
roundRobinSort(input, outputList);
}
for (Location out : outputlist) {
for (Location out : outputList) {
Optional<Block> target = getAttachedBlock(out.getBlock());
if (target.isPresent()) {
stack = CargoUtils.insert(out.getBlock(), target.get(), stack, -1);
if (stack == null) break;
if (stack == null) {
break;
}
}
}
}
@ -282,6 +270,24 @@ public class CargoNet extends ChestTerminalNetwork {
}
}
private void roundRobinSort(Location input, List<Location> outputs) {
int index = roundRobin.getOrDefault(input, 0);
if (index < outputs.size()) {
for (int i = 0; i < index; i++) {
Location temp = outputs.remove(0);
outputs.add(temp);
}
index++;
}
else {
index = 1;
}
roundRobin.put(input, index);
}
private static int getFrequency(Location l) {
try {
String str = BlockStorage.getLocationInfo(l).getString("frequency");

View File

@ -119,7 +119,8 @@ final class CargoUtils {
ItemStackWrapper wrapper = new ItemStackWrapper(template);
for (int slot = minSlot; slot < maxSlot; slot++) {
ItemStack itemInSlot = contents[slot]; // changes to this ItemStack is reflected into item in inventory
// Changes to this ItemStack are synchronized with the Item in the Inventory
ItemStack itemInSlot = contents[slot];
if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true) && matchesFilter(node, itemInSlot, -1)) {
if (itemInSlot.getAmount() > template.getAmount()) {
@ -265,7 +266,8 @@ final class CargoUtils {
ItemStackWrapper wrapper = new ItemStackWrapper(stack);
for (int slot = minSlot; slot < maxSlot; slot++) {
ItemStack itemInSlot = contents[slot]; // changes to this ItemStack is reflected into item in inventory
// Changes to this ItemStack are synchronized with the Item in the Inventory
ItemStack itemInSlot = contents[slot];
if (itemInSlot == null) {
inv.setItem(slot, stack);
@ -273,6 +275,7 @@ final class CargoUtils {
}
else {
int maxStackSize = itemInSlot.getType().getMaxStackSize();
if (SlimefunUtils.isItemSimilar(itemInSlot, wrapper, true, false) && itemInSlot.getAmount() < maxStackSize) {
int amount = itemInSlot.getAmount() + stack.getAmount();
@ -284,7 +287,9 @@ final class CargoUtils {
}
itemInSlot.setAmount(Math.min(amount, maxStackSize));
inv.setItem(slot, itemInSlot); // setting item in inventory will clone the ItemStack
// Setting item in inventory will clone the ItemStack
inv.setItem(slot, itemInSlot);
return stack;
}
}

View File

@ -4,13 +4,13 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.logging.Level;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@ -26,20 +26,27 @@ import me.mrCookieSlime.Slimefun.api.Slimefun;
*/
public class BackupService implements Runnable {
private static final int MAX_BACKUPS = 20;
private final DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd-HH-mm", Locale.ROOT);
private final File directory = new File("data-storage/Slimefun/block-backups");
@Override
public void run() {
DateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH-mm");
List<File> backups = Arrays.asList(directory.listFiles());
File folder = new File("data-storage/Slimefun/block-backups");
List<File> backups = Arrays.asList(folder.listFiles());
if (backups.size() > 20) {
deleteOldBackups(format, backups);
if (backups.size() > MAX_BACKUPS) {
try {
deleteOldBackups(backups);
}
catch (IOException e) {
Slimefun.getLogger().log(Level.WARNING, "Could not delete an old backup", e);
}
}
File file = new File("data-storage/Slimefun/block-backups/" + format.format(new Date()) + ".zip");
File file = new File(directory, format.format(LocalDateTime.now()) + ".zip");
if (!file.exists() || file.delete()) {
if (!file.exists()) {
try {
if (file.createNewFile()) {
try (ZipOutputStream output = new ZipOutputStream(new FileOutputStream(file))) {
@ -126,20 +133,16 @@ public class BackupService implements Runnable {
}
}
private void deleteOldBackups(DateFormat format, List<File> backups) {
private void deleteOldBackups(List<File> backups) throws IOException {
Collections.sort(backups, (a, b) -> {
try {
return (int) (format.parse(a.getName().replace(".zip", "")).getTime() - format.parse(b.getName().replace(".zip", "")).getTime());
}
catch (ParseException e) {
return 0;
}
LocalDateTime time1 = LocalDateTime.parse(a.getName().substring(0, a.getName().length() - 4), format);
LocalDateTime time2 = LocalDateTime.parse(b.getName().substring(0, b.getName().length() - 4), format);
return time2.compareTo(time1);
});
for (int i = backups.size() - 20; i > 0; i--) {
if (!backups.get(i).delete()) {
Slimefun.getLogger().log(Level.WARNING, "Could not delete backup {0}", backups.get(i).getName());
}
for (int i = backups.size() - MAX_BACKUPS; i > 0; i--) {
Files.delete(backups.get(i).toPath());
}
}

View File

@ -1,6 +1,6 @@
package io.github.thebusybiscuit.slimefun4.core.services.github;
import java.util.Date;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
@ -33,7 +33,7 @@ public class GitHubService {
private int pullRequests = 0;
private int forks = 0;
private int stars = 0;
private Date lastUpdate = new Date();
private LocalDateTime lastUpdate = LocalDateTime.now();
public GitHubService(String repository) {
this.repository = repository;
@ -127,7 +127,7 @@ public class GitHubService {
return pullRequests;
}
public Date getLastUpdate() {
public LocalDateTime getLastUpdate() {
return lastUpdate;
}

View File

@ -55,6 +55,20 @@ public class ThirdPartyPluginService {
category.register();
}
// WorldEdit Hook to clear Slimefun Data upon //set 0 //cut or any other equivalent
if (isPluginInstalled("WorldEdit")) {
try {
Class.forName("com.sk89q.worldedit.extent.Extent");
new WorldEditHook();
}
catch (Throwable x) {
String version = plugin.getServer().getPluginManager().getPlugin("WorldEdit").getDescription().getVersion();
Slimefun.getLogger().log(Level.WARNING, "Maybe consider updating WorldEdit or Slimefun?");
Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to hook into WorldEdit v" + version);
}
}
/*
* These Items are not marked as soft-dependencies and
* therefore need to be loaded after the Server has finished
@ -66,20 +80,6 @@ public class ThirdPartyPluginService {
}
isChestTerminalInstalled = isPluginInstalled("ChestTerminal");
// WorldEdit Hook to clear Slimefun Data upon //set 0 //cut or any other equivalent
if (isPluginInstalled("WorldEdit")) {
try {
Class.forName("com.sk89q.worldedit.extent.Extent");
new WorldEditHook();
}
catch (Exception x) {
String version = plugin.getServer().getPluginManager().getPlugin("WorldEdit").getDescription().getVersion();
Slimefun.getLogger().log(Level.WARNING, "Maybe consider updating WorldEdit or Slimefun?");
Slimefun.getLogger().log(Level.WARNING, x, () -> "Failed to hook into WorldEdit v" + version);
}
}
});
}

View File

@ -186,7 +186,6 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
return false;
});
int index = 9;
int pages = (category.getItems().size() - 1) / CATEGORY_SIZE + 1;
menu.addItem(46, ChestMenuUtils.getPreviousButton(p, page, pages));
@ -203,6 +202,7 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
return false;
});
int index = 9;
int categoryIndex = CATEGORY_SIZE * (page - 1);
for (int i = 0; i < CATEGORY_SIZE; i++) {
@ -443,10 +443,6 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
Player p = profile.getPlayer();
if (p == null) return;
ItemStack result = item.getRecipeOutput();
RecipeType recipeType = item.getRecipeType();
ItemStack[] recipe = item.getRecipe();
ChestMenu menu = create(p);
Optional<String> wiki = item.getWikipage();
@ -465,6 +461,10 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
profile.getGuideHistory().add(item);
}
ItemStack result = item.getRecipeOutput();
RecipeType recipeType = item.getRecipeType();
ItemStack[] recipe = item.getRecipe();
displayItem(menu, profile, p, item, result, recipeType, recipe, task);
if (item instanceof RecipeDisplayItem) {
@ -479,8 +479,6 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
}
private void displayItem(ChestMenu menu, PlayerProfile profile, Player p, Object item, ItemStack output, RecipeType recipeType, ItemStack[] recipe, RecipeChoiceTask task) {
boolean isSlimefunRecipe = item instanceof SlimefunItem;
addBackButton(menu, 0, p, profile);
MenuClickHandler clickHandler = (pl, slot, itemstack, action) -> {
@ -495,6 +493,8 @@ public class ChestSlimefunGuide implements SlimefunGuideImplementation {
return false;
};
boolean isSlimefunRecipe = item instanceof SlimefunItem;
for (int i = 0; i < 9; i++) {
ItemStack recipeItem = getDisplayItem(p, isSlimefunRecipe, recipe[i]);
menu.addItem(recipeSlots[i], recipeItem, clickHandler);

View File

@ -100,7 +100,6 @@ abstract class Android extends SlimefunItem {
public void openScript(Player p, Block b, String script) {
ChestMenu menu = new ChestMenu(ChatColor.DARK_AQUA + SlimefunPlugin.getLocal().getMessage(p, "android.scripts.editor"));
String[] commands = PatternUtils.DASH.split(script);
menu.addItem(0, new CustomItem(ScriptAction.START.getItem(), SlimefunPlugin.getLocal().getMessage(p, "android.scripts.instructions.START"), "", "&7\u21E8 &eLeft Click &7to return to the Android's interface"));
menu.addMenuClickHandler(0, (pl, slot, item, action) -> {
@ -108,6 +107,8 @@ abstract class Android extends SlimefunItem {
return false;
});
String[] commands = PatternUtils.DASH.split(script);
for (int i = 1; i < commands.length; i++) {
int index = i;
@ -182,7 +183,6 @@ abstract class Android extends SlimefunItem {
List<Config> scripts = getUploadedScripts();
int index = 0;
int pages = (scripts.size() / 45) + 1;
for (int i = 45; i < 54; i++) {
@ -222,6 +222,7 @@ abstract class Android extends SlimefunItem {
return false;
});
int index = 0;
int categoryIndex = 45 * (page - 1);
for (int i = 0; i < 45; i++) {

View File

@ -40,7 +40,6 @@ public abstract class MinerAndroid extends ProgrammableAndroid {
Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty() && SlimefunPlugin.getProtectionManager().hasPermission(Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))), block.getLocation(), ProtectableAction.BREAK_BLOCK)) {
String item = BlockStorage.checkID(block);
AndroidMineEvent event = new AndroidMineEvent(block, new AndroidInstance(this, b));
Bukkit.getPluginManager().callEvent(event);
@ -50,7 +49,8 @@ public abstract class MinerAndroid extends ProgrammableAndroid {
}
// We only want to break non-Slimefun blocks
if (item == null) {
String blockId = BlockStorage.checkID(block);
if (blockId == null) {
for (ItemStack drop : drops) {
if (menu.fits(drop, getOutputSlots())) {
menu.pushItem(drop, getOutputSlots());
@ -67,7 +67,6 @@ public abstract class MinerAndroid extends ProgrammableAndroid {
Collection<ItemStack> drops = block.getDrops(effectivePickaxe);
if (!MaterialCollections.getAllUnbreakableBlocks().contains(block.getType()) && !drops.isEmpty() && SlimefunPlugin.getProtectionManager().hasPermission(Bukkit.getOfflinePlayer(UUID.fromString(BlockStorage.getLocationInfo(b.getLocation(), "owner"))), block.getLocation(), ProtectableAction.BREAK_BLOCK)) {
SlimefunItem item = BlockStorage.check(block);
AndroidMineEvent event = new AndroidMineEvent(block, new AndroidInstance(this, b));
Bukkit.getPluginManager().callEvent(event);
@ -77,7 +76,8 @@ public abstract class MinerAndroid extends ProgrammableAndroid {
}
// We only want to break non-Slimefun blocks
if (item == null) {
SlimefunItem blockId = BlockStorage.check(block);
if (blockId == null) {
for (ItemStack drop : drops) {
if (menu.fits(drop, getOutputSlots())) {
menu.pushItem(drop, getOutputSlots());

View File

@ -1,4 +1,4 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;
package io.github.thebusybiscuit.slimefun4.implementation.items.electric;
import org.bukkit.block.Block;
import org.bukkit.entity.Player;
@ -17,8 +17,8 @@ import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker;
import me.mrCookieSlime.Slimefun.api.SlimefunItemStack;
/**
* The {@link EnergyRegulator} is a special type of {@link SlimefunItem}.
* It serves as the heart of every {@link EnergyNet}.
* The {@link EnergyRegulator} is a special type of {@link SlimefunItem} which serves as the heart of every
* {@link EnergyNet}.
*
* @author TheBusyBiscuit
*

View File

@ -86,7 +86,6 @@ public class AutoDisenchanter extends AContainer {
Set<ItemEnchantment> emeraldEnchantments = new HashSet<>();
for (int slot : getInputSlots()) {
ItemStack target = menu.getItemInSlot(slot == getInputSlots()[0] ? getInputSlots()[1] : getInputSlots()[0]);
ItemStack item = menu.getItemInSlot(slot);
// Check if disenchantable
@ -106,6 +105,8 @@ public class AutoDisenchanter extends AContainer {
return;
}
ItemStack target = menu.getItemInSlot(slot == getInputSlots()[0] ? getInputSlots()[1] : getInputSlots()[0]);
// Disenchanting
if (item != null && target != null && target.getType() == Material.BOOK) {
int amount = 0;

View File

@ -78,15 +78,15 @@ public abstract class Refinery extends AContainer implements RecipeDisplayItem {
else {
for (int slot : getInputSlots()) {
if (SlimefunUtils.isItemSimilar(menu.getItemInSlot(slot), SlimefunItems.BUCKET_OF_OIL, true)) {
MachineRecipe r = new MachineRecipe(40, new ItemStack[0], new ItemStack[] { SlimefunItems.BUCKET_OF_FUEL });
if (!menu.fits(SlimefunItems.BUCKET_OF_FUEL, getOutputSlots())) {
return;
}
MachineRecipe recipe = new MachineRecipe(40, new ItemStack[0], new ItemStack[] { SlimefunItems.BUCKET_OF_FUEL });
menu.consumeItem(slot);
processing.put(b, r);
progress.put(b, r.getTicks());
processing.put(b, recipe);
progress.put(b, recipe.getTicks());
break;
}
}

View File

@ -109,13 +109,16 @@ public class XPCollector extends SlimefunItem implements InventoryBlock, EnergyN
int xp = 0;
while (iterator.hasNext() && xp == 0) {
Entity n = iterator.next();
if (ChargableBlock.getCharge(b) < ENERGY_CONSUMPTION) return;
Entity entity = iterator.next();
xp = getEXP(b) + ((ExperienceOrb) n).getExperience();
if (ChargableBlock.getCharge(b) < ENERGY_CONSUMPTION) {
return;
}
xp = getEXP(b) + ((ExperienceOrb) entity).getExperience();
ChargableBlock.addCharge(b, -ENERGY_CONSUMPTION);
n.remove();
entity.remove();
int withdrawn = 0;
BlockMenu menu = BlockStorage.getInventory(b);
@ -126,6 +129,7 @@ public class XPCollector extends SlimefunItem implements InventoryBlock, EnergyN
menu.pushItem(SlimefunItems.FILLED_FLASK_OF_KNOWLEDGE.clone(), getOutputSlots());
}
}
BlockStorage.addBlockInfo(b, "stored-exp", String.valueOf(xp - withdrawn));
}
}

View File

@ -0,0 +1,8 @@
/**
* This package contains the different implementations of
* {@link me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem} that are also an
* {@link io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent} with the type {@code CONSUMER}.
*
* Machines do not generate power, they consume it.
*/
package io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines;

View File

@ -58,7 +58,6 @@ public class StormStaff extends SimpleSlimefunItem<ItemUseHandler> {
@Override
public ItemUseHandler getItemHandler() {
return e -> {
Player p = e.getPlayer();
ItemStack item = e.getItem();
if (!item.hasItemMeta()) return;
@ -70,6 +69,8 @@ public class StormStaff extends SimpleSlimefunItem<ItemUseHandler> {
ItemMeta sfItemMeta = sfItem.getItemMeta();
List<String> sfItemLore = sfItemMeta.getLore();
Player p = e.getPlayer();
// Index 1 and 3 in SlimefunItems.STAFF_STORM has lores with words and stuff so we check for them.
if (itemLore.size() < 6 && itemLore.get(1).equals(sfItemLore.get(1)) && itemLore.get(3).equals(sfItemLore.get(3))) {
if (p.getFoodLevel() >= 4 || p.getGameMode() == GameMode.CREATIVE) {

View File

@ -26,7 +26,7 @@ public class GrapplingHook extends SimpleSlimefunItem<ItemUseHandler> {
public GrapplingHook(Category category, SlimefunItemStack item, RecipeType recipeType, ItemStack[] recipe) {
super(category, item, recipeType, recipe);
addItemSetting(despawnTicks);
}
@ -36,16 +36,16 @@ public class GrapplingHook extends SimpleSlimefunItem<ItemUseHandler> {
Player p = e.getPlayer();
UUID uuid = p.getUniqueId();
if (!e.getClickedBlock().isPresent() && !SlimefunPlugin.getGrapplingHookListener().isJumping(uuid)) {
if (!e.getClickedBlock().isPresent() && !SlimefunPlugin.getGrapplingHookListener().isGrappling(uuid)) {
e.cancel();
ItemStack item = e.getItem();
if (p.getInventory().getItemInOffHand().getType() == Material.BOW) {
// Cancel, to fix dupe #740
return;
}
ItemStack item = e.getItem();
if (item.getType() == Material.LEAD) {
item.setAmount(item.getAmount() - 1);
}

View File

@ -1,7 +1,8 @@
package io.github.thebusybiscuit.slimefun4.implementation.listeners;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
@ -9,6 +10,7 @@ import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.entity.EntityDeathEvent;
import io.github.thebusybiscuit.slimefun4.utils.SlimefunUtils;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
@ -21,7 +23,7 @@ import me.mrCookieSlime.Slimefun.Lists.SlimefunItems;
*/
public class DeathpointListener implements Listener {
private final SimpleDateFormat format = new SimpleDateFormat("(MMM d, yyyy @ hh:mm)");
private final DateTimeFormatter format = DateTimeFormatter.ofPattern("(MMM dd, yyyy @ hh:mm)", Locale.ROOT);
public DeathpointListener(SlimefunPlugin plugin) {
plugin.getServer().getPluginManager().registerEvents(this, plugin);
@ -32,8 +34,8 @@ public class DeathpointListener implements Listener {
if (e.getEntity().getType() == EntityType.PLAYER) {
Player p = (Player) e.getEntity();
if (p.getInventory().containsAtLeast(SlimefunItems.GPS_EMERGENCY_TRANSMITTER, 1)) {
SlimefunPlugin.getGPSNetwork().addWaypoint(p, "player:death " + SlimefunPlugin.getLocal().getMessage(p, "gps.deathpoint").replace("%date%", format.format(new Date())), p.getLocation().getBlock().getLocation());
if (SlimefunUtils.containsSimilarItem(p.getInventory(), SlimefunItems.GPS_EMERGENCY_TRANSMITTER, true)) {
SlimefunPlugin.getGPSNetwork().addWaypoint(p, "player:death " + SlimefunPlugin.getLocal().getMessage(p, "gps.deathpoint").replace("%date%", format.format(LocalDateTime.now())), p.getLocation().getBlock().getLocation());
}
}
}

View File

@ -29,7 +29,7 @@ public class GrapplingHookListener implements Listener {
private GrapplingHook grapplingHook;
private final Map<UUID, Boolean> jumpState = new HashMap<>();
private final Map<UUID, Boolean> grappleState = new HashMap<>();
private final Set<UUID> invulnerable = new HashSet<>();
private final Map<UUID, Entity[]> temporaryEntities = new HashMap<>();
@ -76,10 +76,10 @@ public class GrapplingHookListener implements Listener {
}
private void handleGrapplingHook(Arrow arrow) {
if (arrow != null && arrow.getShooter() instanceof Player && jumpState.containsKey(((Player) arrow.getShooter()).getUniqueId())) {
if (arrow != null && arrow.getShooter() instanceof Player && grappleState.containsKey(((Player) arrow.getShooter()).getUniqueId())) {
Player p = (Player) arrow.getShooter();
if (p.getGameMode() != GameMode.CREATIVE && (boolean) jumpState.get(p.getUniqueId())) {
if (p.getGameMode() != GameMode.CREATIVE && (boolean) grappleState.get(p.getUniqueId())) {
arrow.getWorld().dropItem(arrow.getLocation(), SlimefunItems.GRAPPLING_HOOK);
}
@ -98,7 +98,7 @@ public class GrapplingHookListener implements Listener {
}
Slimefun.runSync(() -> {
jumpState.remove(p.getUniqueId());
grappleState.remove(p.getUniqueId());
temporaryEntities.remove(p.getUniqueId());
}, 20L);
}
@ -127,25 +127,25 @@ public class GrapplingHookListener implements Listener {
}
Slimefun.runSync(() -> {
jumpState.remove(p.getUniqueId());
grappleState.remove(p.getUniqueId());
temporaryEntities.remove(p.getUniqueId());
}, 20L);
}
}
}
public boolean isJumping(UUID uuid) {
return jumpState.containsKey(uuid);
public boolean isGrappling(UUID uuid) {
return grappleState.containsKey(uuid);
}
public void addGrapplingHook(UUID uuid, Arrow arrow, Bat b, boolean state, long despawnTicks) {
jumpState.put(uuid, state);
grappleState.put(uuid, state);
invulnerable.add(uuid);
temporaryEntities.put(uuid, new Entity[] { b, arrow });
// To fix issue #253
Slimefun.runSync(() -> {
if (jumpState.containsKey(uuid)) {
if (grappleState.containsKey(uuid)) {
SlimefunPlugin.getBowListener().getBows().remove(uuid);
for (Entity n : temporaryEntities.get(uuid)) {
@ -154,7 +154,7 @@ public class GrapplingHookListener implements Listener {
Slimefun.runSync(() -> {
invulnerable.remove(uuid);
jumpState.remove(uuid);
grappleState.remove(uuid);
temporaryEntities.remove(uuid);
}, 20L);
}

View File

@ -59,6 +59,7 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.cargo.ReactorAcce
import io.github.thebusybiscuit.slimefun4.implementation.items.cargo.TrashCan;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.BasicCircuitBoard;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.Capacitor;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.EnergyRegulator;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.JetBoots;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.Jetpack;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.gadgets.MultiTool;
@ -89,7 +90,6 @@ import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.ElectricPress;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.ElectricSmeltery;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.ElectrifiedCrucible;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.EnergyRegulator;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.FluidPump;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.FoodComposter;
import io.github.thebusybiscuit.slimefun4.implementation.items.electric.machines.FoodFabricator;

View File

@ -1,17 +1,12 @@
package io.github.thebusybiscuit.slimefun4.utils;
import java.text.NumberFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.Locale;
import java.util.logging.Level;
import org.bukkit.ChatColor;
import me.mrCookieSlime.Slimefun.SlimefunPlugin;
import me.mrCookieSlime.Slimefun.api.Slimefun;
public final class NumberUtils {
private NumberUtils() {}
@ -20,16 +15,8 @@ public final class NumberUtils {
return NumberFormat.getNumberInstance(Locale.US).format(i);
}
public static Date parseGitHubDate(String date) {
try {
// We have to create this instance here because it is not thread-safe
// and should not exist on a static level.
return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date.replace('T', ' ').replace("Z", ""));
}
catch (ParseException x) {
Slimefun.getLogger().log(Level.SEVERE, x, () -> "An Error occured while parsing a GitHub-Date for Slimefun " + SlimefunPlugin.getVersion());
return null;
}
public static LocalDateTime parseGitHubDate(String date) {
return LocalDateTime.parse(date.substring(0, date.length() - 1));
}
public static ChatColor getColorFromPercentage(float percentage) {
@ -41,9 +28,8 @@ public final class NumberUtils {
else return ChatColor.GREEN;
}
public static String timeDelta(Date date) {
long timestamp = date.getTime();
int hours = (int) ((System.currentTimeMillis() - timestamp) / (1000 * 60 * 60));
public static String getElapsedTime(LocalDateTime date) {
long hours = Duration.between(date, LocalDateTime.now()).toHours();
if (hours == 0) {
return "< 1h";

View File

@ -5,7 +5,7 @@ description: Slimefun basically turns your entire Server into a FTB modpack with
website: https://github.com/TheBusyBiscuit/Slimefun4
main: me.mrCookieSlime.Slimefun.SlimefunPlugin
softdepend: [CS-CoreLib, PlaceholderAPI, EmeraldEnchants]
softdepend: [CS-CoreLib, PlaceholderAPI, WorldEdit, EmeraldEnchants]
api-version: 1.13