diff --git a/pom.xml b/pom.xml index 467a62ae9c..a4bd058dad 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ 4.0.0 me.mrCookieSlime Slimefun - 4.2-UNOFFCIAL-20200204 + 4.2-UNOFFCIAL-20200205 1.8 diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java index 31fb130827..6d0c939889 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/api/ErrorReport.java @@ -23,7 +23,7 @@ import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.PlayerProfile; import me.mrCookieSlime.Slimefun.api.Slimefun; -import me.mrCookieSlime.Slimefun.api.TickerTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; public class ErrorReport { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/ChestSlimefunGuide.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/ChestSlimefunGuide.java index 951cffdb0d..0a43d055b7 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/ChestSlimefunGuide.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/ChestSlimefunGuide.java @@ -182,7 +182,7 @@ public void openCategory(PlayerProfile profile, Category category, boolean survi ChestMenu menu = create(p); fillInv(p, profile, menu, survival); - menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(), meta -> meta.setLore(Arrays.asList("", ChatColors.color("&r左键: &7返回主菜单"))))); + menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(p, "", SlimefunPlugin.getLocal().getMessage(p, "guide.back.guide")))); menu.addMenuClickHandler(1, (pl, s, is, action) -> { openMainMenu(profile, survival, 1); return false; @@ -294,7 +294,7 @@ public void openSearch(PlayerProfile profile, String input, boolean survival, bo menu.setEmptySlotsClickable(false); fillInv(p, profile, menu, survival); - addBackButton(menu, 1, profile, survival); + addBackButton(menu, 1, p, profile, survival); int index = 9; // Find items and add them @@ -484,7 +484,7 @@ private void displayItem(ChestMenu menu, PlayerProfile profile, Player p, Object history.add(obj); } - addBackButton(menu, 0, profile, true); + addBackButton(menu, 0, p, profile, true); MenuClickHandler clickHandler = (pl, slot, itemstack, action) -> { displayItem(profile, itemstack, true); @@ -529,16 +529,16 @@ private void fillInv(Player p, PlayerProfile profile, ChestMenu menu, boolean su } } - private void addBackButton(ChestMenu menu, int slot, PlayerProfile profile, boolean survival) { + private void addBackButton(ChestMenu menu, int slot, Player p, PlayerProfile profile, boolean survival) { List playerHistory = profile.getGuideHistory(); if (playerHistory.size() > 1) { - menu.addItem(slot, new CustomItem(ChestMenuUtils.getBackButton(), meta -> meta.setLore(Arrays.asList( - "", - ChatColors.color("&r左键: &7返回上一页"), - ChatColors.color("&rShift + 左键: &7返回主菜单") - )))); + menu.addItem(slot, new CustomItem(ChestMenuUtils.getBackButton(p, + "", + "&rLeft Click: &7Go back to previous Page", + "&rShift + left Click: &7Go back to Main Menu" + ))); menu.addMenuClickHandler(slot, (pl, s, is, action) -> { if (action.isShiftClicked()) { @@ -553,7 +553,7 @@ private void addBackButton(ChestMenu menu, int slot, PlayerProfile profile, bool } else { - menu.addItem(slot, new CustomItem(ChestMenuUtils.getBackButton(), meta -> meta.setLore(Arrays.asList("", ChatColors.color("&r左键: &7返回主菜单"))))); + menu.addItem(slot, new CustomItem(ChestMenuUtils.getBackButton(p, "", SlimefunPlugin.getLocal().getMessage(p, "guide.back.guide")))); menu.addMenuClickHandler(slot, (pl, s, is, action) -> { openMainMenu(profile, survival, 1); return false; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/GuideSettings.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/GuideSettings.java index 56881ea768..86887d50ff 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/GuideSettings.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/guide/GuideSettings.java @@ -55,7 +55,7 @@ public static void openSettings(Player p, ItemStack guide) { } private static void addMenubar(Player p, ChestMenu menu, ItemStack guide) { - menu.addItem(0, new CustomItem(getItem(SlimefunGuideLayout.CHEST), "&e\u21E6 返回", "", "&7返回到指南"), + menu.addItem(0, new CustomItem(getItem(SlimefunGuideLayout.CHEST), "&e\u21E6 " + SlimefunPlugin.getLocal().getMessage(p, "guide.back.title"), "", "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.back.guide")), (pl, slot, item, action) -> { SlimefunGuide.openGuide(pl, guide); return false; @@ -86,7 +86,7 @@ private static void addMenubar(Player p, ChestMenu menu, ItemStack guide) { ), ChestMenuUtils.getEmptyClickHandler()); menu.addItem(6, new CustomItem(Material.COMPARATOR, - "&eSource Code", + "&e" + SlimefunPlugin.getLocal().getMessage(p, "guide.title.source"), "", "&7Last Activity: &a" + NumberUtils.timeDelta(SlimefunPlugin.getGitHubService().getLastUpdate()) + " ago", "&7Forks: &e" + SlimefunPlugin.getGitHubService().getForks(), @@ -240,14 +240,18 @@ else if (SlimefunManager.isItemSimilar(guide, getItem(SlimefunGuideLayout.CHEAT_ i++; } - Language language = SlimefunPlugin.getLocal().getLanguage(p); - String languageName = language.isDefault() ? (SlimefunPlugin.getLocal().getMessage(p, "languages.default") + ChatColor.DARK_GRAY + " (" + language.getName(p) + ")"): SlimefunPlugin.getLocal().getMessage(p, "languages." + language.getID()); + if (SlimefunPlugin.getSettings().translationsEnabled) { + Language language = SlimefunPlugin.getLocal().getLanguage(p); + String languageName = language.isDefault() ? (SlimefunPlugin.getLocal().getMessage(p, "languages.default") + ChatColor.DARK_GRAY + " (" + language.getName(p) + ")"): SlimefunPlugin.getLocal().getMessage(p, "languages." + language.getID()); - menu.addItem(i, new CustomItem(language.getItem(), "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.selected-language") + " &a" + languageName, "", "&7现在你能选择 Slimefun 的语言", "&7请注意: 只能改变文本的语言", "&7并不能将物品的一起修改", "", "&7\u21E8 &e单击修改你的语言"), - (pl, slot, item, action) -> { - openLanguages(pl); - return false; - }); + menu.addItem(i, new CustomItem(language.getItem(), "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.selected-language") + " &a" + languageName, "", "&7You now have the option to change", "&7the language in which Slimefun", "&7will send you messages.", "&7Note that this only translates", "&7messages, not items.", "", "&7\u21E8 &eClick to change your language"), + (pl, slot, item, action) -> { + openLanguages(pl); + return false; + }); + +// i++; + } } private static void openLanguages(Player p) { @@ -258,7 +262,7 @@ private static void openLanguages(Player p) { for (int i = 0; i < 9; i++) { if (i == 1) { - menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(), "&e\u21E6 返回", "", "&7返回到设置面板") + menu.addItem(1, ChestMenuUtils.getBackButton(p, "", "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.back.settings")) , (pl, slot, item, action) -> { openSettings(pl, p.getInventory().getItemInMainHand()); return false; @@ -292,16 +296,21 @@ else if (i == 7) { int slot = 10; for (Language language : SlimefunPlugin.getLocal().getLanguages()) { - menu.addItem(slot, new CustomItem(language.getItem(), ChatColor.GREEN + language.getName(p), "&7( " + language.getProgress() + "% )", "", "&7\u21E8 &e" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.select")), - (pl, i, item, action) -> { - PersistentDataAPI.setString(pl, SlimefunPlugin.getLocal().getKey(), language.getID()); - - String name = language.getName(pl); - SlimefunPlugin.getLocal().sendMessage(pl, "guide.languages.updated", msg -> msg.replace("%lang%", name)); - - openSettings(pl, p.getInventory().getItemInMainHand()); - return false; - }); + menu.addItem(slot, new CustomItem(language.getItem(), + ChatColor.GREEN + language.getName(p), + "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.progress.messages") + ": " + SlimefunPlugin.getLocal().getProgress(language, Language::getMessages) + '%', + "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.progress.researches") + ": " + SlimefunPlugin.getLocal().getProgress(language, Language::getResearches) + '%', + "", + "&7\u21E8 &e" + SlimefunPlugin.getLocal().getMessage(p, "guide.languages.select") + ), (pl, i, item, action) -> { + PersistentDataAPI.setString(pl, SlimefunPlugin.getLocal().getKey(), language.getID()); + + String name = language.getName(pl); + SlimefunPlugin.getLocal().sendMessage(pl, "guide.languages.updated", msg -> msg.replace("%lang%", name)); + + openSettings(pl, p.getInventory().getItemInMainHand()); + return false; + }); slot++; } @@ -320,7 +329,7 @@ private static void openCredits(Player p, int page) { menu.addItem(i, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler()); } else { - menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(), "&e\u21E6 返回", "", "&7返回设置面板")); + menu.addItem(1, new CustomItem(ChestMenuUtils.getBackButton(p, "", "&7" + SlimefunPlugin.getLocal().getMessage(p, "guide.back.settings")))); menu.addMenuClickHandler(1, (pl, slot, item, action) -> { openSettings(pl, p.getInventory().getItemInMainHand()); return false; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/GitHubService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/GitHubService.java index 6d27c1c367..1717deb353 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/GitHubService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/GitHubService.java @@ -16,7 +16,7 @@ import io.github.thebusybiscuit.slimefun4.core.services.github.Contributor; import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubConnector; import io.github.thebusybiscuit.slimefun4.core.services.github.GitHubTask; -import io.github.thebusybiscuit.slimefun4.core.services.github.Translators; +import io.github.thebusybiscuit.slimefun4.core.services.localization.Translators; import io.github.thebusybiscuit.slimefun4.utils.NumberUtils; public class GitHubService { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java index 74609cbd33..36636eeee5 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/LocalizationService.java @@ -8,6 +8,7 @@ import java.util.LinkedHashMap; import java.util.Map; import java.util.Optional; +import java.util.function.Function; import java.util.logging.Level; import org.bukkit.NamespacedKey; @@ -143,30 +144,18 @@ private void addLanguage(String id, String hash) { language.setMessages(messages); language.setResearches(researches); - if (!id.equals("en")) { - language.setProgress(getProgress(language, languages.get("en"))); - } - languages.put(id, language); } } - private double getProgress(Language language, Language defaultLang) { - return DoubleHandler.fixDouble(100.0 * (getTotalKeys(language) / getTotalKeys(defaultLang))); + public double getProgress(Language lang, Function method) { + double defaultKeys = getTotalKeys(method.apply(defaultLanguage)); + if (defaultKeys == 0) return 0; + return DoubleHandler.fixDouble(100.0 * (getTotalKeys(method.apply(lang)) / defaultKeys)); } - private double getTotalKeys(Language language) { - int keys = 0; - - if (language.getMessages() != null) { - keys += language.getMessages().getKeys(true).size(); - } - - if (language.getResearches() != null) { - keys += language.getResearches().getKeys(true).size(); - } - - return keys; + private double getTotalKeys(FileConfiguration cfg) { + return cfg != null ? cfg.getKeys(true).size(): 0; } private FileConfiguration streamConfigFile(String file, FileConfiguration defaults) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java index 2410a07fba..4e02efa489 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Language.java @@ -27,14 +27,6 @@ public String getID() { return id; } - public double getProgress() { - return progress; - } - - public void setProgress(double progress) { - this.progress = progress; - } - public FileConfiguration getMessages() { return messages; } diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SupportedLanguage.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SupportedLanguage.java index 8cf00db400..f0cf42ebb8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SupportedLanguage.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/SupportedLanguage.java @@ -9,8 +9,12 @@ public enum SupportedLanguage { SPANISH("es", "32bd4521983309e0ad76c1ee29874287957ec3d96f8d889324da8c887e485ea8"), RUSSIAN("ru", "16eafef980d6117dabe8982ac4b4509887e2c4621f6a8fe5c9b735a83d775ad"), POLISH("pl", "921b2af8d2322282fce4a1aa4f257a52b68e27eb334f4a181fd976bae6d8eb"), + UKRANIAN("uk", "28b9f52e36aa5c7caaa1e7f26ea97e28f635e8eac9aef74cec97f465f5a6b51"), SWEDISH("sv", "e910904bff9c86f6ed47688e9429c26e8d9c5d5743bd3ebb8e6f5040be192998"), DUTCH("nl", "c23cf210edea396f2f5dfbced69848434f93404eefeabf54b23c073b090adf"), + DANISH("da", "10c23055c392606f7e531daa2676ebe2e348988810c15f15dc5b3733998232"), + FINNISH("fi", "59f2349729a7ec8d4b1478adfe5ca8af96479e983fbad238ccbd81409b4ed"), + NORWEGIAN("no", "e0596e165ec3f389b59cfdda93dd6e363e97d9c6456e7c2e123973fa6c5fda"), CZECH("cs", "48152b7334d7ecf335e47a4f35defbd2eb6957fc7bfe94212642d62f46e61e"), PORTUGESE_PORTUGAL("pt", "ebd51f4693af174e6fe1979233d23a40bb987398e3891665fafd2ba567b5a53a"), PORTUGESE_BRAZIL("pt-BR", "9a46475d5dcc815f6c5f2859edbb10611f3e861c0eb14f088161b3c0ccb2b0d9"), @@ -22,7 +26,10 @@ public enum SupportedLanguage { INDONESIAN("id", "5db2678ccaba7934412cb97ee16d416463a392574c5906352f18dea42895ee"), CHINESE_CHINA("zh-CN", "7f9bc035cdc80f1ab5e1198f29f3ad3fdd2b42d9a69aeb64de990681800b98dc"), CHINESE_TAIWAN("zh-TW", "702a4afb2e1e2e3a1894a8b74272f95cfa994ce53907f9ac140bd3c932f9f"), - HEBREW("he", "1ba086a2cc7272cf5ba49c80248546c22e5ef1bab54120e8a8e5d9e75b6a"); + HEBREW("he", "1ba086a2cc7272cf5ba49c80248546c22e5ef1bab54120e8a8e5d9e75b6a"), + ARABIC("ar", "a4be759a9cf7f0a19a7e8e62f23789ad1d21cebae38af9d9541676a3db001572"), + AFRIKAANS("af", "961a1eacc10524d1f45f23b0e487bb2fc33948d9676b418b19a3da0b109d0e3c"), + MALAY("ms", "754b9041dea6db6db44750f1385a743adf653767b4b8802cad4c585dd3f5be46"); private final String id; private final String textureHash; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Translators.java b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java similarity index 87% rename from src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Translators.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java index 23182d4b4d..077910a5d0 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/github/Translators.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/core/services/localization/Translators.java @@ -1,7 +1,9 @@ -package io.github.thebusybiscuit.slimefun4.core.services.github; +package io.github.thebusybiscuit.slimefun4.core.services.localization; import java.util.concurrent.ConcurrentMap; +import io.github.thebusybiscuit.slimefun4.core.services.github.Contributor; + public class Translators { private final ConcurrentMap contributors; @@ -12,6 +14,7 @@ public Translators(ConcurrentMap contributors) { // Translators - German addTranslator("TheBusyBiscuit", "de", false); addTranslator("MeerBiene", "de", true); + addTranslator("daro2404", "de", true); // Translators - French addTranslator("JustDams", "D4ms_", "fr", true); @@ -30,7 +33,7 @@ public Translators(ConcurrentMap contributors) { addTranslator("andris155", "hu", true); // Translators - Vietnamese - addTranslator("huynhqtienvtag", "vi", false); + addTranslator("HSGamer", "vi", false); addTranslator("JustMangoT", "JFF_JustMango", "vi", true); addTranslator("Julie-Sigtuna", "vi", true); addTranslator("nahkd123", "vi", true); @@ -64,6 +67,10 @@ public Translators(ConcurrentMap contributors) { // Translators - Chinese (China) addTranslator("StarWishsama", "StarWish_Sama", "zh-CN", false); + + // Translators - Chinese (Taiwan) + addTranslator("BrineYT", "zh-TW", true); + addTranslator("mio9", "zh-TW", true); } private void addTranslator(String name, String language, boolean lock) { diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java index 19e27e3574..62f0e88c46 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/AncientAltarListener.java @@ -7,6 +7,7 @@ import java.util.Set; import java.util.UUID; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.AncientAltarTask; import org.bukkit.ChatColor; import org.bukkit.GameMode; import org.bukkit.Location; @@ -34,7 +35,6 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; import me.mrCookieSlime.Slimefun.ancient_altar.AltarRecipe; import me.mrCookieSlime.Slimefun.ancient_altar.Pedestals; -import me.mrCookieSlime.Slimefun.ancient_altar.RitualAnimation; import me.mrCookieSlime.Slimefun.api.BlockStorage; import me.mrCookieSlime.Slimefun.api.Slimefun; @@ -134,7 +134,7 @@ else if (id.equals("ANCIENT_ALTAR")) { ItemUtils.consumeItem(e.getPlayer().getInventory().getItemInMainHand(), false); } - Slimefun.runSync(new RitualAnimation(altars, b, b.getLocation().add(0.5, 1.3, 0.5), result, pedestals, consumed), 10L); + Slimefun.runSync(new AncientAltarTask(altars, b, b.getLocation().add(0.5, 1.3, 0.5), result, pedestals, consumed), 10L); } else { altars.remove(b); diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GearListener.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GearListener.java index bf4ae6830b..21c69289b2 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GearListener.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/listeners/GearListener.java @@ -5,10 +5,10 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.JetBoots; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.Jetpack; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.tasks.JetBootsTask; -import me.mrCookieSlime.Slimefun.Objects.tasks.JetpackTask; -import me.mrCookieSlime.Slimefun.Objects.tasks.MagnetTask; -import me.mrCookieSlime.Slimefun.Objects.tasks.ParachuteTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetBootsTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.JetpackTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.MagnetTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.ParachuteTask; import me.mrCookieSlime.Slimefun.Setup.SlimefunManager; import me.mrCookieSlime.Slimefun.api.Slimefun; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunSetup.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunSetup.java index 0268a7499e..f17e2fa7c8 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunSetup.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/setup/SlimefunSetup.java @@ -170,7 +170,7 @@ import me.mrCookieSlime.Slimefun.Objects.handlers.BlockPlaceHandler; import me.mrCookieSlime.Slimefun.Objects.handlers.ItemUseHandler; import me.mrCookieSlime.Slimefun.Objects.handlers.MultiBlockInteractionHandler; -import me.mrCookieSlime.Slimefun.Objects.tasks.RainbowTicker; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.RainbowTicker; import me.mrCookieSlime.Slimefun.androids.AndroidType; import me.mrCookieSlime.Slimefun.androids.ProgrammableAndroid; import me.mrCookieSlime.Slimefun.api.BlockStorage; diff --git a/src/main/java/me/mrCookieSlime/Slimefun/ancient_altar/RitualAnimation.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java similarity index 94% rename from src/main/java/me/mrCookieSlime/Slimefun/ancient_altar/RitualAnimation.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java index a5ea67ace0..db3e9744b2 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/ancient_altar/RitualAnimation.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/AncientAltarTask.java @@ -1,4 +1,4 @@ -package me.mrCookieSlime.Slimefun.ancient_altar; +package io.github.thebusybiscuit.slimefun4.implementation.tasks; import java.util.Collection; import java.util.HashMap; @@ -19,7 +19,7 @@ import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.api.Slimefun; -public class RitualAnimation implements Runnable { +public class AncientAltarTask implements Runnable { private final List altars; @@ -35,7 +35,7 @@ public class RitualAnimation implements Runnable { private boolean running; private int stage; - public RitualAnimation(List altars, Block altar, Location drop, ItemStack output, List pedestals, List items) { + public AncientAltarTask(List altars, Block altar, Location drop, ItemStack output, List pedestals, List items) { this.dropLocation = drop; this.altar = altar; this.altars = altars; diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java new file mode 100644 index 0000000000..647c7f0f05 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ArmorTask.java @@ -0,0 +1,124 @@ +package io.github.thebusybiscuit.slimefun4.implementation.tasks; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.bukkit.Bukkit; +import org.bukkit.entity.Player; +import org.bukkit.inventory.ItemStack; +import org.bukkit.potion.PotionEffect; +import org.bukkit.potion.PotionEffectType; + +import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece; +import me.mrCookieSlime.Slimefun.SlimefunPlugin; +import me.mrCookieSlime.Slimefun.Lists.SlimefunItems; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunArmorPiece; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.Setup.SlimefunManager; +import me.mrCookieSlime.Slimefun.api.PlayerProfile; +import me.mrCookieSlime.Slimefun.api.Slimefun; +import me.mrCookieSlime.Slimefun.api.energy.ItemEnergy; + +public class ArmorTask implements Runnable { + + private final Set radiationEffects; + + public ArmorTask() { + Set effects = new HashSet<>(); + effects.add(new PotionEffect(PotionEffectType.WITHER, 400, 2)); + effects.add(new PotionEffect(PotionEffectType.BLINDNESS, 400, 3)); + effects.add(new PotionEffect(PotionEffectType.CONFUSION, 400, 3)); + effects.add(new PotionEffect(PotionEffectType.WEAKNESS, 400, 2)); + effects.add(new PotionEffect(PotionEffectType.SLOW, 400, 1)); + effects.add(new PotionEffect(PotionEffectType.SLOW_DIGGING, 400, 1)); + radiationEffects = Collections.unmodifiableSet(effects); + } + + @Override + public void run() { + for (Player p : Bukkit.getOnlinePlayers()) { + if (!p.isValid() || p.isDead()) { + continue; + } + + PlayerProfile.get(p, profile -> { + ItemStack[] armor = p.getInventory().getArmorContents(); + HashedArmorpiece[] cachedArmor = profile.getArmor(); + + handleSlimefunArmor(p, armor, cachedArmor); + checkForSolarHelmet(p); + checkForRadiation(p); + }); + } + } + + private void handleSlimefunArmor(Player p, ItemStack[] armor, HashedArmorpiece[] cachedArmor) { + for (int slot = 0; slot < 4; slot++) { + ItemStack item = armor[slot]; + HashedArmorpiece armorpiece = cachedArmor[slot]; + + if (armorpiece.hasDiverged(item)) { + SlimefunItem sfItem = SlimefunItem.getByItem(item); + if (!(sfItem instanceof SlimefunArmorPiece) || !Slimefun.hasUnlocked(p, sfItem, true)) { + sfItem = null; + } + + armorpiece.update(item, sfItem); + } + + if (item != null && armorpiece.getItem().isPresent()) { + Slimefun.runSync(() -> { + for (PotionEffect effect : armorpiece.getItem().get().getEffects()) { + p.removePotionEffect(effect.getType()); + p.addPotionEffect(effect); + } + }); + } + } + } + + private void checkForSolarHelmet(Player p) { + if (SlimefunManager.isItemSimilar(p.getInventory().getHelmet(), SlimefunItems.SOLAR_HELMET, true) + && Slimefun.hasUnlocked(p, SlimefunItem.getByID("SOLAR_HELMET"), true) + && (p.getWorld().getTime() < 12300 || p.getWorld().getTime() > 23850) + && p.getEyeLocation().getBlock().getLightFromSky() == 15) + { + ItemEnergy.chargeInventory(p, ((Double) Slimefun.getItemValue("SOLAR_HELMET", "charge-amount")).floatValue()); + } + } + + private void checkForRadiation(Player p) { + // Check for a Hazmat Suit + if (!SlimefunManager.isItemSimilar(SlimefunItems.SCUBA_HELMET, p.getInventory().getHelmet(), true) || + !SlimefunManager.isItemSimilar(SlimefunItems.HAZMATSUIT_CHESTPLATE, p.getInventory().getChestplate(), true) || + !SlimefunManager.isItemSimilar(SlimefunItems.HAZMATSUIT_LEGGINGS, p.getInventory().getLeggings(), true) || + !SlimefunManager.isItemSimilar(SlimefunItems.RUBBER_BOOTS, p.getInventory().getBoots(), true)) + { + for (ItemStack item : p.getInventory()) { + if (isRadioactive(p, item)) { + break; + } + } + } + } + + private boolean isRadioactive(Player p, ItemStack item) { + for (ItemStack radioactiveItem : SlimefunPlugin.getRegistry().getRadioactiveItems()) { + if (SlimefunManager.isItemSimilar(item, radioactiveItem, true) && Slimefun.isEnabled(p, radioactiveItem, false)) { + // If the item is enabled in the world, then make radioactivity do its job + SlimefunPlugin.getLocal().sendMessage(p, "messages.radiation"); + + Slimefun.runSync(() -> { + p.addPotionEffects(radiationEffects); + p.setFireTicks(400); + }); + + return true; + } + } + + return false; + } + +} \ No newline at end of file diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/JetBootsTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetBootsTask.java similarity index 93% rename from src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/JetBootsTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetBootsTask.java index 7ff075b9a9..4660f234c8 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/JetBootsTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetBootsTask.java @@ -1,4 +1,4 @@ -package me.mrCookieSlime.Slimefun.Objects.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks; import java.util.concurrent.ThreadLocalRandom; @@ -22,7 +22,6 @@ public JetBootsTask(Player p, double speed) { @Override public void executeTask() { - Player p = Bukkit.getPlayer(uuid); float cost = 0.075F; float charge = ItemEnergy.getStoredEnergy(p.getInventory().getBoots()); double accuracy = DoubleHandler.fixDouble(speed - 0.7); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/JetpackTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetpackTask.java similarity index 92% rename from src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/JetpackTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetpackTask.java index 68f4010467..2a1b22c4a3 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/JetpackTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/JetpackTask.java @@ -1,4 +1,4 @@ -package me.mrCookieSlime.Slimefun.Objects.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks; import org.bukkit.Bukkit; import org.bukkit.Effect; @@ -24,7 +24,6 @@ public void setID(int id) { @Override public void executeTask() { - Player p = Bukkit.getPlayer(uuid); float cost = 0.08F; float charge = ItemEnergy.getStoredEnergy(p.getInventory().getChestplate()); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/MagnetTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/MagnetTask.java similarity index 73% rename from src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/MagnetTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/MagnetTask.java index 0235506ed9..3d5ae50857 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/MagnetTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/MagnetTask.java @@ -1,6 +1,5 @@ -package me.mrCookieSlime.Slimefun.Objects.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks; -import org.bukkit.Bukkit; import org.bukkit.GameMode; import org.bukkit.Sound; import org.bukkit.entity.Entity; @@ -15,8 +14,6 @@ public MagnetTask(Player p) { @Override public void executeTask() { - Player p = Bukkit.getPlayer(uuid); - for (Entity item : p.getNearbyEntities(6D, 6D, 6D)) { if (item instanceof Item && !item.hasMetadata("no_pickup") && ((Item) item).getPickupDelay() <= 0) { item.teleport(p.getEyeLocation()); @@ -26,8 +23,8 @@ public void executeTask() { } @Override - protected boolean cancelTask() { - return super.cancelTask() || p.getGameMode() == GameMode.SPECTATOR; + protected boolean isInvalid() { + return super.isInvalid() || p.getGameMode() == GameMode.SPECTATOR; } } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/ParachuteTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ParachuteTask.java similarity index 82% rename from src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/ParachuteTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ParachuteTask.java index 9d25371cfe..0f97cdad5a 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/ParachuteTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/ParachuteTask.java @@ -1,4 +1,4 @@ -package me.mrCookieSlime.Slimefun.Objects.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -12,7 +12,6 @@ public ParachuteTask(Player p) { @Override void executeTask() { - Player p = Bukkit.getPlayer(uuid); Vector vector = new Vector(0, 1, 0); vector.multiply(-0.1); p.setVelocity(vector); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/RainbowTicker.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/RainbowTicker.java similarity index 96% rename from src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/RainbowTicker.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/RainbowTicker.java index 37f58089d0..680b8811ca 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/RainbowTicker.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/RainbowTicker.java @@ -1,4 +1,4 @@ -package me.mrCookieSlime.Slimefun.Objects.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks; import org.bukkit.block.Block; import org.bukkit.block.data.Waterlogged; diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/SlimefunTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunTask.java similarity index 58% rename from src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/SlimefunTask.java rename to src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunTask.java index a7ba60ce78..bada5685ba 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/SlimefunTask.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/SlimefunTask.java @@ -1,19 +1,15 @@ -package me.mrCookieSlime.Slimefun.Objects.tasks; +package io.github.thebusybiscuit.slimefun4.implementation.tasks; import org.bukkit.Bukkit; import org.bukkit.entity.Player; -import java.util.UUID; - public abstract class SlimefunTask implements Runnable { - - protected UUID uuid; + protected int id; protected Player p; public SlimefunTask(Player p) { - this.p = p; - this.uuid = p.getUniqueId(); + this.p = p; } public void setID(int id) { @@ -22,22 +18,21 @@ public void setID(int id) { @Override public void run() { - if(cancelTask()) return; - executeTask(); + if (!isInvalid()) executeTask(); } /** * * @return True if task was cancelled. */ - protected boolean cancelTask(){ - if (Bukkit.getPlayer(uuid) == null || Bukkit.getPlayer(uuid).isDead() || !Bukkit.getPlayer(uuid).isSneaking()) { + protected boolean isInvalid() { + if (!p.isOnline() || !p.isValid() || p.isDead() || !p.isSneaking()) { Bukkit.getScheduler().cancelTask(id); return true; } - + return false; } abstract void executeTask(); -} +} \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java new file mode 100644 index 0000000000..b8558ce167 --- /dev/null +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/implementation/tasks/TickerTask.java @@ -0,0 +1,361 @@ +package io.github.thebusybiscuit.slimefun4.implementation.tasks; + +import java.text.DecimalFormat; +import java.util.AbstractMap; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; +import java.util.logging.Level; +import java.util.stream.Collectors; + +import org.bukkit.Bukkit; +import org.bukkit.ChatColor; +import org.bukkit.Chunk; +import org.bukkit.Location; +import org.bukkit.Material; +import org.bukkit.block.Block; +import org.bukkit.command.CommandSender; +import org.bukkit.entity.Player; + +import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; +import io.github.thebusybiscuit.cscorelib2.chat.json.ChatComponent; +import io.github.thebusybiscuit.cscorelib2.chat.json.HoverEvent; +import io.github.thebusybiscuit.slimefun4.api.ErrorReport; +import me.mrCookieSlime.Slimefun.SlimefunPlugin; +import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; +import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; +import me.mrCookieSlime.Slimefun.api.BlockStorage; +import me.mrCookieSlime.Slimefun.api.Slimefun; + +public class TickerTask implements Runnable { + + private final DecimalFormat decimalFormat = new DecimalFormat("#.###"); + private final ConcurrentMap move = new ConcurrentHashMap<>(); + private final ConcurrentMap delete = new ConcurrentHashMap<>(); + private final ConcurrentMap blockTimings = new ConcurrentHashMap<>(); + private final ConcurrentMap chunkItemCount = new ConcurrentHashMap<>(); + private final ConcurrentMap machineCount = new ConcurrentHashMap<>(); + private final ConcurrentMap machineTimings = new ConcurrentHashMap<>(); + private final ConcurrentMap chunkTimings = new ConcurrentHashMap<>(); + private final ConcurrentMap buggedBlocks = new ConcurrentHashMap<>(); + private final Set chunksSkipped = new HashSet<>(); + + private final Set tickers = new HashSet<>(); + + private boolean halted = false; + + private int skipped = 0; + private int chunks = 0; + private int machines = 0; + private long time = 0; + + private boolean running = false; + + public void abortTick() { + running = false; + } + + @Override + public void run() { + if (running) return; + + running = true; + long timestamp = System.nanoTime(); + + skipped = 0; + chunks = 0; + machines = 0; + chunkItemCount.clear(); + machineCount.clear(); + time = 0; + chunkTimings.clear(); + chunksSkipped.clear(); + machineTimings.clear(); + blockTimings.clear(); + + Map bugged = new HashMap<>(buggedBlocks); + buggedBlocks.clear(); + + Map remove = new HashMap<>(delete); + + for (Map.Entry entry : remove.entrySet()) { + BlockStorage._integrated_removeBlockInfo(entry.getKey(), entry.getValue()); + delete.remove(entry.getKey()); + } + + if (!halted) { + for (String tickedChunk : BlockStorage.getTickingChunks()) { + long timestamp2 = System.nanoTime(); + chunks++; + + for (Location l : BlockStorage.getTickingLocations(tickedChunk)) { + if (l.getWorld().isChunkLoaded(l.getBlockX() >> 4, l.getBlockZ() >> 4)) { + Block b = l.getBlock(); + SlimefunItem item = BlockStorage.check(l); + + if (item != null && item.getBlockTicker() != null) { + machines++; + + try { + item.getBlockTicker().update(); + + if (item.getBlockTicker().isSynchronized()) { + Slimefun.runSync(() -> { + try { + long timestamp3 = System.nanoTime(); + item.getBlockTicker().tick(b, item, BlockStorage.getLocationInfo(l)); + + Long machinetime = machineTimings.get(item.getID()); + Integer chunk = chunkItemCount.get(tickedChunk); + Integer machine = machineCount.get(item.getID()); + + machineTimings.put(item.getID(), (machinetime != null ? machinetime: 0) + (System.nanoTime() - timestamp3)); + chunkItemCount.put(tickedChunk, (chunk != null ? chunk: 0) + 1); + machineCount.put(item.getID(), (machine != null ? machine: 0) + 1); + blockTimings.put(l, System.nanoTime() - timestamp3); + } catch (Exception x) { + int errors = bugged.getOrDefault(l, 0); + reportErrors(l, item, x, errors); + } + }); + } + else { + long timestamp3 = System.nanoTime(); + item.getBlockTicker().tick(b, item, BlockStorage.getLocationInfo(l)); + + machineTimings.merge(item.getID(), (System.nanoTime() - timestamp3), Long::sum); + chunkItemCount.merge(tickedChunk, 1, Integer::sum); + machineCount.merge(item.getID(), 1, Integer::sum); + blockTimings.put(l, System.nanoTime() - timestamp3); + } + + tickers.add(item.getBlockTicker()); + } catch (Exception x) { + int errors = bugged.getOrDefault(l, 0); + reportErrors(l, item, x, errors); + } + } + else skipped++; + } + else { + skipped += BlockStorage.getTickingLocations(tickedChunk).size(); + chunksSkipped.add(tickedChunk); + chunks--; + break; + } + } + + chunkTimings.put(tickedChunk, System.nanoTime() - timestamp2); + } + } + + for (Map.Entry entry : move.entrySet()) { + BlockStorage._integrated_moveLocationInfo(entry.getKey(), entry.getValue()); + } + move.clear(); + + Iterator iterator = tickers.iterator(); + while (iterator.hasNext()) { + iterator.next().startNewTick(); + iterator.remove(); + } + + time = System.nanoTime() - timestamp; + running = false; + } + + private void reportErrors(Location l, SlimefunItem item, Exception x, int errors) { + errors++; + + if (errors == 1) { + // Generate a new Error-Report + new ErrorReport(x, this, l, item); + + buggedBlocks.put(l, errors); + } + else if (errors == 4) { + Slimefun.getLogger().log(Level.SEVERE, "X: " + l.getBlockX() + " Y: " + l.getBlockY() + " Z: " + l.getBlockZ() + '(' + item.getID() + ")"); + Slimefun.getLogger().log(Level.SEVERE, "has thrown 4 Exceptions in the last 4 Ticks, the Block has been terminated."); + Slimefun.getLogger().log(Level.SEVERE, "Check your /plugins/Slimefun/error-reports/ folder for details."); + Slimefun.getLogger().log(Level.SEVERE, " "); + + BlockStorage._integrated_removeBlockInfo(l, true); + + Bukkit.getScheduler().scheduleSyncDelayedTask(SlimefunPlugin.instance, () -> l.getBlock().setType(Material.AIR)); + } + else { + buggedBlocks.put(l, errors); + } + } + + public String getTime() { + return toMillis(time); + } + + public void info(CommandSender sender) { + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&2== &aSlimefun Diagnostic Tool &2==")); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Halted: &e&l" + String.valueOf(halted).toUpperCase())); + sender.sendMessage(""); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Impact: &e" + toMillis(time))); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Ticked Chunks: &e" + chunks)); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Ticked Machines: &e" + machines)); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Skipped Machines: &e" + skipped)); + sender.sendMessage(""); + sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Ticking Machines:")); + + List> timings = machineCount.keySet().stream() + .map(key -> new AbstractMap.SimpleEntry<>(key, machineTimings.getOrDefault(key, 0L))) + .sorted((o1, o2) -> o2.getValue().compareTo(o1.getValue())) + .collect(Collectors.toList()); + + if (sender instanceof Player) { + ChatComponent component = new ChatComponent(ChatColors.color(" &7&oHover for more Info")); + StringBuilder builder = new StringBuilder(); + int hidden = 0; + + for (Map.Entry entry : timings) { + int count = machineCount.get(entry.getKey()); + + if (entry.getValue() > 500_000) { + builder.append("\n&c") + .append(entry.getKey()) + .append(" - ") + .append(count) + .append("x &7(") + .append(toMillis(entry.getValue())) + .append(", ") + .append(toMillis(entry.getValue() / count)) + .append(" avg/machine)"); + } + else hidden++; + } + + builder.append("\n\n&c+ &4").append(hidden).append(" Hidden"); + component.setHoverEvent(new HoverEvent(builder.toString())); + + component.sendMessage((Player) sender); + } + else { + int hidden = 0; + + for (Map.Entry entry : timings) { + int count = machineCount.get(entry.getKey()); + if (entry.getValue() > 500_000) { + sender.sendMessage(" " + entry.getKey() + " - " + count + "x (" + toMillis(entry.getValue()) + ", " + toMillis(entry.getValue() / count) + " avg/machine)"); + } + else hidden++; + } + + sender.sendMessage("+ " + hidden + " Hidden"); + } + + sender.sendMessage(""); + sender.sendMessage(ChatColors.color("&6Ticking Chunks:")); + + timings = chunkTimings.entrySet().stream() + .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) + .collect(Collectors.toList()); + + if (sender instanceof Player) { + ChatComponent component = new ChatComponent(ChatColors.color(" &7&oHover for more Info")); + StringBuilder builder = new StringBuilder(); + int hidden = 0; + + for (Map.Entry entry : timings) { + if (!chunksSkipped.contains(entry.getKey())) { + if (entry.getValue() > 0) { + builder.append("\n&c") + .append(formatChunk(entry.getKey())) + .append(" - ") + .append(chunkItemCount.getOrDefault(entry.getKey(), 0)) + .append("x &7(") + .append(toMillis(entry.getValue())) + .append(")"); + } + else hidden++; + } + } + + builder.append("\n\n&c+ &4").append(hidden).append(" Hidden"); + component.setHoverEvent(new HoverEvent(builder.toString())); + + component.sendMessage((Player) sender); + } + else { + int hidden = 0; + + for (Map.Entry entry : timings) { + if (!chunksSkipped.contains(entry.getKey())) { + if (entry.getValue() > 0) sender.sendMessage(" " + formatChunk(entry.getKey()) + " - " + + (chunkItemCount.getOrDefault(entry.getKey(), 0)) + "x (" + toMillis(entry.getValue()) + ")"); + else hidden++; + } + } + + sender.sendMessage(ChatColors.color("&c+ &4" + hidden + " Hidden")); + } + } + + private String formatChunk(String chunk) { + String[] components = chunk.split(";"); + return components[0] + " [" + components[2] + "," + components[3] + "]"; + } + + public long getTimings(Block b) { + return blockTimings.getOrDefault(b.getLocation(), 0L); + } + + public long getTimings(String item) { + return machineTimings.getOrDefault(item, 0L); + } + + public long getTimings(Chunk c) { + return chunkTimings.getOrDefault(c.toString(), 0L); + } + + public void addBlockTimings(Location l, long time) { + blockTimings.put(l, time); + } + + public boolean isHalted() { + return halted; + } + + public void halt() { + halted = true; + } + + private String toMillis(long time) { + return decimalFormat.format(time / 1000000F) + "ms"; + } + + @Override + public String toString() { + return "TickerTask {\n" + + " HALTED = " + halted + "\n" + + " tickers = " + tickers + "\n" + + " move = " + move + "\n" + + " delete = " + delete + "\n" + + " chunks = " + chunkItemCount + "\n" + + " machines = " + machineCount + "\n" + + " machinetime = " + machineTimings + "\n" + + " chunktime = " + chunkTimings + "\n" + + " skipped = " + chunksSkipped + "\n" + + "}"; + } + + public void queueMove(Location from, Location to) { + move.put(from, to); + } + + public void queueDelete(Location l, boolean destroy) { + delete.put(l, destroy); + } + +} \ No newline at end of file diff --git a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java index aab1d67db9..c7e0bcfb16 100644 --- a/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java +++ b/src/main/java/io/github/thebusybiscuit/slimefun4/utils/ChestMenuUtils.java @@ -2,6 +2,7 @@ import java.util.Arrays; +import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu; import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -15,7 +16,6 @@ import me.mrCookieSlime.CSCoreLibPlugin.general.Inventory.ChestMenu.MenuClickHandler; import me.mrCookieSlime.Slimefun.SlimefunPlugin; import me.mrCookieSlime.Slimefun.api.SlimefunItemStack; -import me.mrCookieSlime.Slimefun.api.inventory.BlockMenu; public final class ChestMenuUtils { @@ -42,8 +42,8 @@ public static final MenuClickHandler getEmptyClickHandler() { return CLICK_HANDLER; } - public static ItemStack getBackButton() { - return BACK_BUTTON; + public static ItemStack getBackButton(Player p, String... lore) { + return new CustomItem(BACK_BUTTON, "&7\u21E6 " + SlimefunPlugin.getLocal().getMessage(p, "guide.back.title"), lore); } public static ItemStack getMenuButton(Player p) { @@ -87,7 +87,7 @@ public static ItemStack getNextButton(Player p, int page, int pages) { }); } - public static void updateProgressbar(BlockMenu menu, int slot, int timeleft, int time, ItemStack indicator) { + public static void updateProgressbar(ChestMenu menu, int slot, int timeleft, int time, ItemStack indicator) { ItemStack item = indicator.clone(); ItemMeta im = item.getItemMeta(); im.addItemFlags(ItemFlag.HIDE_ATTRIBUTES); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/GEO/GEOScanner.java b/src/main/java/me/mrCookieSlime/Slimefun/GEO/GEOScanner.java index 1cfa42b84f..3f5564da6d 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/GEO/GEOScanner.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/GEO/GEOScanner.java @@ -22,15 +22,15 @@ public static void scanChunk(Player p, Chunk chunk) { return; } - ChestMenu menu = new ChestMenu("&4GEO-Scan Results"); + ChestMenu menu = new ChestMenu("&4GEO 地形扫描结果"); for (int slot : BACKGROUND_SLOTS) { menu.addItem(slot, ChestMenuUtils.getBackground(), ChestMenuUtils.getEmptyClickHandler()); } menu.addItem(4, new CustomItem(SkullItem.fromBase64("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvODQ0OWI5MzE4ZTMzMTU4ZTY0YTQ2YWIwZGUxMjFjM2Q0MDAwMGUzMzMyYzE1NzQ5MzJiM2M4NDlkOGZhMGRjMiJ9fX0="), - "&eScanned Chunk", + "&e已扫描的区块", "", - "&8\u21E8 &7World: " + chunk.getWorld().getName(), + "&8\u21E8 &7世界: " + chunk.getWorld().getName(), "&8\u21E8 &7X: " + chunk.getX() + " Z: " + chunk.getZ() ), ChestMenuUtils.getEmptyClickHandler()); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/GEO/OreGenSystem.java b/src/main/java/me/mrCookieSlime/Slimefun/GEO/OreGenSystem.java index 9199f512bb..5e3cc54121 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/GEO/OreGenSystem.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/GEO/OreGenSystem.java @@ -32,7 +32,7 @@ public static void registerResource(OreGenResource resource) { cfg.save(); if (cfg.getBoolean("enabled")) { - Slimefun.getLogger().log(Level.INFO, "Registering Ore Gen: " + resource.getName()); + Slimefun.getLogger().log(Level.INFO, "正在注册矿物生成器: " + resource.getName()); SlimefunPlugin.getRegistry().getGEOResources().put(resource.getName(), resource); SlimefunPlugin.getRegistry().getGEOResourceConfigs().put(resource.getName(), cfg); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Lists/SlimefunItems.java b/src/main/java/me/mrCookieSlime/Slimefun/Lists/SlimefunItems.java index e40714fd31..9d0172f501 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Lists/SlimefunItems.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Lists/SlimefunItems.java @@ -832,8 +832,8 @@ private SlimefunItems() {} public static final ItemStack TOTEM_OF_UNDYING = new ItemStack(Material.TOTEM_OF_UNDYING); - public static final ItemStack MAGNESIUM_SALT = new SlimefunItemStack("MAGNESIUM_SALT", Material.SUGAR, "&cMagnesium Salt", "", "&7A special type of fuel that can be", "&7used in a Magnesium-powered Generator"); - public static final ItemStack MAGNESIUM_GENERATOR = new SlimefunItemStack("MAGNESIUM_GENERATOR", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTM0M2NlNThkYTU0Yzc5OTI0YTJjOTMzMWNmYzQxN2ZlOGNjYmJlYTliZTQ1YTdhYzg1ODYwYTZjNzMwIn19fQ==", "&cMagnesium-powered Generator", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.GENERATOR), LoreBuilder.powerBuffer(128), LoreBuilder.powerPerSecond(36)); + public static final ItemStack MAGNESIUM_SALT = new SlimefunItemStack("MAGNESIUM_SALT", Material.SUGAR, "&c镁盐", "", "&7是一种能在镁发电机中使用的特殊燃料"); + public static final ItemStack MAGNESIUM_GENERATOR = new SlimefunItemStack("MAGNESIUM_GENERATOR", "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTM0M2NlNThkYTU0Yzc5OTI0YTJjOTMzMWNmYzQxN2ZlOGNjYmJlYTliZTQ1YTdhYzg1ODYwYTZjNzMwIn19fQ==", "&c镁发电机", "", LoreBuilder.machine(MachineTier.MEDIUM, MachineType.GENERATOR), LoreBuilder.powerBuffer(128), LoreBuilder.powerPerSecond(36)); static { INFUSED_ELYTRA.addUnsafeEnchantment(Enchantment.MENDING, 1); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AReactor.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AReactor.java index 8249c30525..c43a646723 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AReactor.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/abstractItems/AReactor.java @@ -88,7 +88,7 @@ public void newInstance(final BlockMenu menu, final Block b) { } if (!BlockStorage.hasBlockInfo(b) || BlockStorage.getLocationInfo(b.getLocation(), "reactor-mode").equals("generator")) { - menu.replaceExistingItem(4, new CustomItem(SkullItem.fromBase64("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTM0M2NlNThkYTU0Yzc5OTI0YTJjOTMzMWNmYzQxN2ZlOGNjYmJlYTliZTQ1YTdhYzg1ODYwYTZjNzMwIn19fQ=="), "&7Focus: &eElectricity", "", "&6Your Reactor will focus on Power Generation", "&6If your Energy Network doesn't need Power", "&6it will not produce any either", "", "&7> Click to change the Focus to &eProduction")); + menu.replaceExistingItem(4, new CustomItem(SkullItem.fromBase64("eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvOTM0M2NlNThkYTU0Yzc5OTI0YTJjOTMzMWNmYzQxN2ZlOGNjYmJlYTliZTQ1YTdhYzg1ODYwYTZjNzMwIn19fQ=="), "&7模式: &e发电", "", "&6反应堆将会专注于发电", "&6当你的能源网络不需要能量时", "&6它也不会发电", "", "&7> 单击切换模式至 &e制造")); menu.addMenuClickHandler(4, (p, slot, item, action) -> { BlockStorage.addBlockInfo(b, "reactor-mode", "production"); newInstance(menu, b); @@ -96,7 +96,7 @@ public void newInstance(final BlockMenu menu, final Block b) { }); } else { - menu.replaceExistingItem(4, new CustomItem(SlimefunItems.PLUTONIUM, "&7Focus: &eProduction", "", "&6Your Reactor will focus on producing goods", "&6If your Energy Network doesn't need Power", "&6it will continue to run and simply will", "&6not generate any Power in the mean time", "", "&7> Click to change the Focus to &ePower Generation")); + menu.replaceExistingItem(4, new CustomItem(SlimefunItems.PLUTONIUM, "&7模式: &e制造", "", "&6Y反应堆将专注于生产副产物", "&6当你的能源网络不需要能量时", "&6它仍会继续运行并停止发电", "", "&7> 单击切换模式至 &e产能")); menu.addMenuClickHandler(4, (p, slot, item, action) -> { BlockStorage.addBlockInfo(b, "reactor-mode", "generator"); newInstance(menu, b); @@ -106,7 +106,7 @@ public void newInstance(final BlockMenu menu, final Block b) { BlockMenu port = getAccessPort(b.getLocation()); if (port != null) { - menu.replaceExistingItem(INFO_SLOT, new CustomItem(new ItemStack(Material.GREEN_WOOL), "&7Access Port", "", "&6Detected", "", "&7> Click to view Access Port")); + menu.replaceExistingItem(INFO_SLOT, new CustomItem(new ItemStack(Material.GREEN_WOOL), "&7访问接口", "", "&6已连接", "", "&7> 单击查看访问接口")); menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> { port.open(p); newInstance(menu, b); @@ -115,7 +115,7 @@ public void newInstance(final BlockMenu menu, final Block b) { }); } else { - menu.replaceExistingItem(INFO_SLOT, new CustomItem(new ItemStack(Material.RED_WOOL), "&7Access Port", "", "&cNot detected", "", "&7Access Port must be", "&7placed 3 blocks above", "&7a reactor!")); + menu.replaceExistingItem(INFO_SLOT, new CustomItem(new ItemStack(Material.RED_WOOL), "&7访问接口", "", "&c未连接", "", "&7访问接口必须放置在反应堆上方的第三格处")); menu.addMenuClickHandler(INFO_SLOT, (p, slot, item, action) -> { newInstance(menu, b); menu.open(p); @@ -186,20 +186,20 @@ private void constructMenu(BlockMenuPreset preset) { preset.addItem(22, new CustomItem(new ItemStack(Material.BLACK_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); - preset.addItem(1, new CustomItem(SlimefunItems.URANIUM, "&7Fuel Slot", "", "&rThis Slot accepts radioactive Fuel such as:", "&2Uranium &ror &aNeptunium"), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(1, new CustomItem(SlimefunItems.URANIUM, "&7燃料槽", "", "&r可以放入放射性燃料", "&r例如 &2铀 &r或者 &a镎"), ChestMenuUtils.getEmptyClickHandler()); for (int i : border_2) { preset.addItem(i, new CustomItem(new ItemStack(Material.CYAN_STAINED_GLASS_PANE), " "), ChestMenuUtils.getEmptyClickHandler()); } if (needsCooling()) { - preset.addItem(7, new CustomItem(this.getCoolant(), "&bCoolant Slot", "", "&rThis Slot accepts Coolant Cells", "&4Without any Coolant Cells, your Reactor", "&4will explode")); + preset.addItem(7, new CustomItem(this.getCoolant(), "&b冷却剂槽", "", "&r可以放入冷却剂", "&4没了冷却剂, 你的反应堆将会爆炸")); } else { - preset.addItem(7, new CustomItem(new ItemStack(Material.BARRIER), "&bCoolant Slot", "", "&rThis Slot accepts Coolant Cells")); + preset.addItem(7, new CustomItem(new ItemStack(Material.BARRIER), "&b冷却剂槽", "", "&r可以放入冷却剂")); for (int i : border_4) { - preset.addItem(i, new CustomItem(new ItemStack(Material.BARRIER), "&cNo Coolant Required"), ChestMenuUtils.getEmptyClickHandler()); + preset.addItem(i, new CustomItem(new ItemStack(Material.BARRIER), "&c暂不需要冷却剂"), ChestMenuUtils.getEmptyClickHandler()); } } } @@ -408,7 +408,7 @@ public BlockMenu getAccessPort(Location l) { @Override public String getRecipeSectionLabel() { - return "&7\u21E9 Available Types of Fuel \u21E9"; + return "&7\u21E9 可用的燃料种类 \u21E9"; } @Override @@ -419,9 +419,9 @@ public List getDisplayRecipes() { ItemStack item = fuel.getInput().clone(); ItemMeta im = item.getItemMeta(); List lore = new ArrayList<>(); - lore.add(ChatColor.translateAlternateColorCodes('&', "&8\u21E8 &7Lasts " + getTimeLeft(fuel.getTicks() / 2))); + lore.add(ChatColor.translateAlternateColorCodes('&', "&8\u21E8 &7剩余 " + getTimeLeft(fuel.getTicks() / 2))); lore.add(ChatColor.translateAlternateColorCodes('&', "&8\u21E8 &e\u26A1 &7" + getEnergyProduction() * 2) + " J/s"); - lore.add(ChatColor.translateAlternateColorCodes('&', "&8\u21E8 &e\u26A1 &7" + DoubleHandler.getFancyDouble((double) fuel.getTicks() * getEnergyProduction()) + " J in total")); + lore.add(ChatColor.translateAlternateColorCodes('&', "&8\u21E8 &e\u26A1 &7总共 " + DoubleHandler.getFancyDouble((double) fuel.getTicks() * getEnergyProduction()) + " J")); im.setLore(lore); item.setItemMeta(im); list.add(item); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/BioGenerator.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/BioGenerator.java index d3a6560b63..7886e6c099 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/BioGenerator.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/BioGenerator.java @@ -71,7 +71,7 @@ public ItemStack getProgressBar() { @Override public String getInventoryTitle() { - return "&2Bio Reactor"; + return "&2生物反应器"; } } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/CoalGenerator.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/CoalGenerator.java index c049ff358b..b8108c08ee 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/CoalGenerator.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/CoalGenerator.java @@ -44,7 +44,7 @@ public ItemStack getProgressBar() { @Override public String getInventoryTitle() { - return "&cCoal Generator"; + return "&c煤炭发电机"; } } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/CombustionGenerator.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/CombustionGenerator.java index 46b023e0e1..c5b4e302e5 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/CombustionGenerator.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/CombustionGenerator.java @@ -29,7 +29,7 @@ public ItemStack getProgressBar() { @Override public String getInventoryTitle() { - return "&cCombustion Reactor"; + return "&c燃烧反应机"; } } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/LavaGenerator.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/LavaGenerator.java index 2717aedba6..28afe6309e 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/LavaGenerator.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/LavaGenerator.java @@ -27,7 +27,7 @@ public ItemStack getProgressBar() { @Override public String getInventoryTitle() { - return "&4Lava Generator"; + return "&4岩浆发电机"; } } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/MagnesiumGenerator.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/MagnesiumGenerator.java index 36ae4be0b4..855f8ec0ae 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/MagnesiumGenerator.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/generators/MagnesiumGenerator.java @@ -28,7 +28,7 @@ public ItemStack getProgressBar() { @Override public String getInventoryTitle() { - return "&cMagnesium-powered Generator"; + return "&c镁发电机"; } } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/gps/ElevatorPlate.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/gps/ElevatorPlate.java index 6cdd398fe7..95a0ac1976 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/gps/ElevatorPlate.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/machines/electric/gps/ElevatorPlate.java @@ -43,7 +43,7 @@ public ElevatorPlate(Category category, SlimefunItemStack item, RecipeType recip @Override public void onPlace(Player p, Block b, SlimefunItem item) { - BlockStorage.addBlockInfo(b, "floor", "&rFloor #0"); + BlockStorage.addBlockInfo(b, "floor", "&r一楼"); BlockStorage.addBlockInfo(b, "owner", p.getUniqueId().toString()); } @@ -138,7 +138,7 @@ public void open(Player p, Block b) { public void openEditor(Player p, Block b) { ChestMenu menu = new ChestMenu("Elevator Settings"); - menu.addItem(4, new CustomItem(Material.NAME_TAG, "&7Floor Name &e(Click to edit)", "", "&r" + ChatColors.color(BlockStorage.getLocationInfo(b.getLocation(), "floor")))); + menu.addItem(4, new CustomItem(Material.NAME_TAG, "&7楼层名 &e(单击编辑)", "", "&r" + ChatColors.color(BlockStorage.getLocationInfo(b.getLocation(), "floor")))); menu.addMenuClickHandler(4, (pl, slot, item, action) -> { pl.closeInventory(); pl.sendMessage(""); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/multiblocks/AncientAltar.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/multiblocks/AncientAltar.java deleted file mode 100644 index da4e2d7b4d..0000000000 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/multiblocks/AncientAltar.java +++ /dev/null @@ -1,5 +0,0 @@ -package me.mrCookieSlime.Slimefun.Objects.SlimefunItem.multiblocks; - -public class AncientAltar { - -} diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/multiblocks/MultiBlockMachine.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/multiblocks/MultiBlockMachine.java index 83072d6ba3..ae0fdf07ff 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/multiblocks/MultiBlockMachine.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/Objects/SlimefunItem/multiblocks/MultiBlockMachine.java @@ -42,7 +42,7 @@ public void register() { protected MultiBlockInteractionHandler getInteractionHandler() { return (p, mb, b) -> { - if (mb == getMultiBlock()) { + if (mb.equals(getMultiBlock())) { if (!isDisabled() && SlimefunPlugin.getProtectionManager().hasPermission(p, b.getLocation(), ProtectableAction.ACCESS_INVENTORIES) && Slimefun.hasUnlocked(p, this, true)) { onInteract(p, b); } diff --git a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/ArmorTask.java b/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/ArmorTask.java deleted file mode 100644 index 3f9226bcee..0000000000 --- a/src/main/java/me/mrCookieSlime/Slimefun/Objects/tasks/ArmorTask.java +++ /dev/null @@ -1,116 +0,0 @@ -package me.mrCookieSlime.Slimefun.Objects.tasks; - -import java.util.Collections; -import java.util.HashSet; -import java.util.Set; - -import org.bukkit.Bukkit; -import org.bukkit.entity.Player; -import org.bukkit.inventory.ItemStack; -import org.bukkit.potion.PotionEffect; -import org.bukkit.potion.PotionEffectType; - -import io.github.thebusybiscuit.slimefun4.api.items.HashedArmorpiece; -import me.mrCookieSlime.Slimefun.SlimefunPlugin; -import me.mrCookieSlime.Slimefun.Lists.SlimefunItems; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunArmorPiece; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Setup.SlimefunManager; -import me.mrCookieSlime.Slimefun.api.PlayerProfile; -import me.mrCookieSlime.Slimefun.api.Slimefun; -import me.mrCookieSlime.Slimefun.api.energy.ItemEnergy; -import me.mrCookieSlime.Slimefun.utils.Utilities; - -public class ArmorTask implements Runnable { - - private final Utilities utilities = SlimefunPlugin.getUtilities(); - private final Set radiationEffects; - - public ArmorTask() { - Set effects = new HashSet<>(); - effects.add(new PotionEffect(PotionEffectType.WITHER, 400, 2)); - effects.add(new PotionEffect(PotionEffectType.BLINDNESS, 400, 3)); - effects.add(new PotionEffect(PotionEffectType.CONFUSION, 400, 3)); - effects.add(new PotionEffect(PotionEffectType.WEAKNESS, 400, 2)); - effects.add(new PotionEffect(PotionEffectType.SLOW, 400, 1)); - effects.add(new PotionEffect(PotionEffectType.SLOW_DIGGING, 400, 1)); - radiationEffects = Collections.unmodifiableSet(effects); - } - - @Override - public void run() { - for (Player p : Bukkit.getOnlinePlayers()) { - if (!p.isValid() || p.isDead()) { - continue; - } - - PlayerProfile.get(p, profile -> { - ItemStack[] armor = p.getInventory().getArmorContents(); - HashedArmorpiece[] cachedArmor = profile.getArmor(); - - for (int slot = 0; slot < 4; slot++) { - ItemStack item = armor[slot]; - HashedArmorpiece armorpiece = cachedArmor[slot]; - - if (armorpiece.hasDiverged(item)) { - SlimefunItem sfItem = SlimefunItem.getByItem(item); - if (!(sfItem instanceof SlimefunArmorPiece) || !Slimefun.hasUnlocked(p, sfItem, true)) { - sfItem = null; - } - - armorpiece.update(item, sfItem); - } - - if (item != null && armorpiece.getItem().isPresent()) { - Slimefun.runSync(() -> { - for (PotionEffect effect : armorpiece.getItem().get().getEffects()) { - p.removePotionEffect(effect.getType()); - p.addPotionEffect(effect); - } - }); - } - } - - if (SlimefunManager.isItemSimilar(p.getInventory().getHelmet(), SlimefunItems.SOLAR_HELMET, true) - && Slimefun.hasUnlocked(p, SlimefunItem.getByID("SOLAR_HELMET"), true) - && (p.getWorld().getTime() < 12300 || p.getWorld().getTime() > 23850) - && p.getEyeLocation().getBlock().getLightFromSky() == 15) - { - ItemEnergy.chargeInventory(p, ((Double) Slimefun.getItemValue("SOLAR_HELMET", "charge-amount")).floatValue()); - } - - // Check for a Hazmat Suit - if (!SlimefunManager.isItemSimilar(SlimefunItems.SCUBA_HELMET, p.getInventory().getHelmet(), true) && - !SlimefunManager.isItemSimilar(SlimefunItems.HAZMATSUIT_CHESTPLATE, p.getInventory().getChestplate(), true) && - !SlimefunManager.isItemSimilar(SlimefunItems.HAZMATSUIT_LEGGINGS, p.getInventory().getLeggings(), true) && - !SlimefunManager.isItemSimilar(SlimefunItems.RUBBER_BOOTS, p.getInventory().getBoots(), true)) - { - for (ItemStack item : p.getInventory()) { - if (isRadioactive(p, item)) { - break; - } - } - } - }); - } - } - - private boolean isRadioactive(Player p, ItemStack item) { - for (ItemStack radioactiveItem : SlimefunPlugin.getRegistry().getRadioactiveItems()) { - if (SlimefunManager.isItemSimilar(item, radioactiveItem, true) && Slimefun.isEnabled(p, radioactiveItem, false)) { - // If the item is enabled in the world, then make radioactivity do its job - SlimefunPlugin.getLocal().sendMessage(p, "messages.radiation"); - - Slimefun.runSync(() -> { - p.addPotionEffects(radiationEffects); - p.setFireTicks(400); - }); - - return true; - } - } - - return false; - } - -} diff --git a/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java b/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java index baace802ed..f7eb23c2c4 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/SlimefunPlugin.java @@ -71,7 +71,7 @@ import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AContainer; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AGenerator; import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.abstractItems.AReactor; -import me.mrCookieSlime.Slimefun.Objects.tasks.ArmorTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.ArmorTask; import io.github.thebusybiscuit.slimefun4.implementation.setup.MiscSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.ResearchSetup; import io.github.thebusybiscuit.slimefun4.implementation.setup.SlimefunSetup; @@ -80,7 +80,7 @@ import me.mrCookieSlime.Slimefun.api.PlayerProfile; import me.mrCookieSlime.Slimefun.api.Slimefun; import me.mrCookieSlime.Slimefun.api.SlimefunBackup; -import me.mrCookieSlime.Slimefun.api.TickerTask; +import io.github.thebusybiscuit.slimefun4.implementation.tasks.TickerTask; import me.mrCookieSlime.Slimefun.api.inventory.UniversalBlockMenu; import me.mrCookieSlime.Slimefun.utils.ConfigCache; import me.mrCookieSlime.Slimefun.utils.Utilities; diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java index f240914ab5..1a44c19a1c 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/BlockStorage.java @@ -95,6 +95,7 @@ public BlockStorage(World w) { long done = 0; long timestamp = System.currentTimeMillis(); long totalBlocks = 0; + int delay = SlimefunPlugin.getCfg().getInt("URID.info-delay"); try { for (File file : f.listFiles()) { @@ -105,7 +106,7 @@ public BlockStorage(World w) { Slimefun.getLogger().log(Level.WARNING, file.getPath()); } else if (file.getName().endsWith(".sfb")) { - if (timestamp + SlimefunPlugin.getSettings().blocksInfoLoadingDelay < System.currentTimeMillis()) { + if (timestamp + delay < System.currentTimeMillis()) { Slimefun.getLogger().log(Level.INFO, "正在加载方块... " + Math.round((((done * 100.0F) / total) * 100.0F) / 100.0F) + "% 已完成 (\"" + w.getName() + "\")"); timestamp = System.currentTimeMillis(); } @@ -474,7 +475,7 @@ public static void clearBlockInfo(Block b, boolean destroy) { } public static void clearBlockInfo(Location l, boolean destroy) { - SlimefunPlugin.getTicker().delete.put(l, destroy); + SlimefunPlugin.getTicker().queueDelete(l, destroy); } public static void _integrated_removeBlockInfo(Location l, boolean destroy) { @@ -514,7 +515,7 @@ public static void moveBlockInfo(Block block, Block newBlock) { } public static void moveBlockInfo(Location from, Location to) { - SlimefunPlugin.getTicker().move.put(from, to); + SlimefunPlugin.getTicker().queueMove(from, to); } @Deprecated diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/TickerTask.java b/src/main/java/me/mrCookieSlime/Slimefun/api/TickerTask.java deleted file mode 100644 index f16131fd59..0000000000 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/TickerTask.java +++ /dev/null @@ -1,353 +0,0 @@ -package me.mrCookieSlime.Slimefun.api; - -import java.text.DecimalFormat; -import java.util.AbstractMap; -import java.util.Comparator; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.ConcurrentMap; -import java.util.logging.Level; -import java.util.stream.Collectors; - -import org.bukkit.Bukkit; -import org.bukkit.ChatColor; -import org.bukkit.Chunk; -import org.bukkit.Location; -import org.bukkit.Material; -import org.bukkit.block.Block; -import org.bukkit.command.CommandSender; -import org.bukkit.entity.Player; - -import io.github.thebusybiscuit.cscorelib2.chat.ChatColors; -import io.github.thebusybiscuit.cscorelib2.chat.json.ChatComponent; -import io.github.thebusybiscuit.cscorelib2.chat.json.HoverEvent; -import io.github.thebusybiscuit.slimefun4.api.ErrorReport; -import me.mrCookieSlime.Slimefun.SlimefunPlugin; -import me.mrCookieSlime.Slimefun.Objects.SlimefunItem.SlimefunItem; -import me.mrCookieSlime.Slimefun.Objects.handlers.BlockTicker; - -public class TickerTask implements Runnable { - - private static final DecimalFormat decimalFormat = new DecimalFormat("#.###"); - - private boolean halted = false; - - protected final ConcurrentMap move = new ConcurrentHashMap<>(); - protected final ConcurrentMap delete = new ConcurrentHashMap<>(); - private final ConcurrentMap blockTimings = new ConcurrentHashMap<>(); - - private final Set tickers = new HashSet<>(); - - private int skipped = 0; - private int chunks = 0; - private int machines = 0; - private long time = 0; - - private final ConcurrentMap chunkItemCount = new ConcurrentHashMap<>(); - private final ConcurrentMap machineCount = new ConcurrentHashMap<>(); - private final ConcurrentMap machineTimings = new ConcurrentHashMap<>(); - private final ConcurrentMap chunkTimings = new ConcurrentHashMap<>(); - private final Set chunksSkipped = new HashSet<>(); - private final ConcurrentMap buggedBlocks = new ConcurrentHashMap<>(); - - private boolean running = false; - - public void abortTick() { - running = false; - } - - @Override - public void run() { - if (running) return; - - running = true; - long timestamp = System.nanoTime(); - - skipped = 0; - chunks = 0; - machines = 0; - chunkItemCount.clear(); - machineCount.clear(); - time = 0; - chunkTimings.clear(); - chunksSkipped.clear(); - machineTimings.clear(); - blockTimings.clear(); - - Map bugged = new HashMap<>(buggedBlocks); - buggedBlocks.clear(); - - Map remove = new HashMap<>(delete); - - for (Map.Entry entry : remove.entrySet()) { - BlockStorage._integrated_removeBlockInfo(entry.getKey(), entry.getValue()); - delete.remove(entry.getKey()); - } - - if (!halted) { - for (String tickedChunk : BlockStorage.getTickingChunks()) { - long timestamp2 = System.nanoTime(); - chunks++; - - for (Location l : BlockStorage.getTickingLocations(tickedChunk)) { - if (l.getWorld().isChunkLoaded(l.getBlockX() >> 4, l.getBlockZ() >> 4)) { - Block b = l.getBlock(); - SlimefunItem item = BlockStorage.check(l); - - if (item != null && item.getBlockTicker() != null) { - machines++; - - try { - item.getBlockTicker().update(); - - if (item.getBlockTicker().isSynchronized()) { - Slimefun.runSync(() -> { - try { - long timestamp3 = System.nanoTime(); - item.getBlockTicker().tick(b, item, BlockStorage.getLocationInfo(l)); - - Long machinetime = machineTimings.get(item.getID()); - Integer chunk = chunkItemCount.get(tickedChunk); - Integer machine = machineCount.get(item.getID()); - - machineTimings.put(item.getID(), (machinetime != null ? machinetime: 0) + (System.nanoTime() - timestamp3)); - chunkItemCount.put(tickedChunk, (chunk != null ? chunk: 0) + 1); - machineCount.put(item.getID(), (machine != null ? machine: 0) + 1); - blockTimings.put(l, System.nanoTime() - timestamp3); - } catch (Exception x) { - int errors = bugged.getOrDefault(l, 0); - reportErrors(l, item, x, errors); - } - }); - } - else { - long timestamp3 = System.nanoTime(); - item.getBlockTicker().tick(b, item, BlockStorage.getLocationInfo(l)); - - machineTimings.merge(item.getID(), (System.nanoTime() - timestamp3), Long::sum); - chunkItemCount.merge(tickedChunk, 1, Integer::sum); - machineCount.merge(item.getID(), 1, Integer::sum); - blockTimings.put(l, System.nanoTime() - timestamp3); - } - - tickers.add(item.getBlockTicker()); - } catch (Exception x) { - int errors = bugged.getOrDefault(l, 0); - reportErrors(l, item, x, errors); - } - } - else skipped++; - } - else { - skipped += BlockStorage.getTickingLocations(tickedChunk).size(); - chunksSkipped.add(tickedChunk); - chunks--; - break; - } - } - - chunkTimings.put(tickedChunk, System.nanoTime() - timestamp2); - } - } - - for (Map.Entry entry : move.entrySet()) { - BlockStorage._integrated_moveLocationInfo(entry.getKey(), entry.getValue()); - } - move.clear(); - - Iterator iterator = tickers.iterator(); - while (iterator.hasNext()) { - iterator.next().startNewTick(); - iterator.remove(); - } - - time = System.nanoTime() - timestamp; - running = false; - } - - private void reportErrors(Location l, SlimefunItem item, Exception x, int errors) { - errors++; - - if (errors == 1) { - // Generate a new Error-Report - new ErrorReport(x, this, l, item); - - buggedBlocks.put(l, errors); - } - else if (errors == 4) { - Slimefun.getLogger().log(Level.SEVERE, "X: " + l.getBlockX() + " Y: " + l.getBlockY() + " Z: " + l.getBlockZ() + '(' + item.getID() + ")"); - Slimefun.getLogger().log(Level.SEVERE, "has thrown 4 Exceptions in the last 4 Ticks, the Block has been terminated."); - Slimefun.getLogger().log(Level.SEVERE, "Check your /plugins/Slimefun/error-reports/ folder for details."); - Slimefun.getLogger().log(Level.SEVERE, " "); - - BlockStorage._integrated_removeBlockInfo(l, true); - - Bukkit.getScheduler().scheduleSyncDelayedTask(SlimefunPlugin.instance, () -> l.getBlock().setType(Material.AIR)); - } - else { - buggedBlocks.put(l, errors); - } - } - - public String getTime() { - return toMillis(time); - } - - public void info(CommandSender sender) { - sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&2== &aSlimefun Diagnostic Tool &2==")); - sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Halted: &e&l" + String.valueOf(halted).toUpperCase())); - sender.sendMessage(""); - sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Impact: &e" + toMillis(time))); - sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Ticked Chunks: &e" + chunks)); - sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Ticked Machines: &e" + machines)); - sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Skipped Machines: &e" + skipped)); - sender.sendMessage(""); - sender.sendMessage(ChatColor.translateAlternateColorCodes('&', "&6Ticking Machines:")); - - List> timings = machineCount.keySet().stream() - .map(key -> new AbstractMap.SimpleEntry<>(key, machineTimings.getOrDefault(key, 0L))) - .sorted((o1, o2) -> o2.getValue().compareTo(o1.getValue())) - .collect(Collectors.toList()); - - if (sender instanceof Player) { - ChatComponent component = new ChatComponent(ChatColors.color(" &7&oHover for more Info")); - StringBuilder builder = new StringBuilder(); - int hidden = 0; - - for (Map.Entry entry : timings) { - int count = machineCount.get(entry.getKey()); - - if (entry.getValue() > 500_000) { - builder.append("\n&c") - .append(entry.getKey()) - .append(" - ") - .append(count) - .append("x &7(") - .append(toMillis(entry.getValue())) - .append(", ") - .append(toMillis(entry.getValue() / count)) - .append(" avg/machine)"); - } - else hidden++; - } - - builder.append("\n\n&c+ &4").append(hidden).append(" Hidden"); - component.setHoverEvent(new HoverEvent(builder.toString())); - - component.sendMessage((Player) sender); - } - else { - int hidden = 0; - - for (Map.Entry entry : timings) { - int count = machineCount.get(entry.getKey()); - if (entry.getValue() > 500_000) { - sender.sendMessage(" " + entry.getKey() + " - " + count + "x (" + toMillis(entry.getValue()) + ", " + toMillis(entry.getValue() / count) + " avg/machine)"); - } - else hidden++; - } - - sender.sendMessage("+ " + hidden + " Hidden"); - } - - sender.sendMessage(""); - sender.sendMessage(ChatColors.color("&6Ticking Chunks:")); - - timings = chunkTimings.entrySet().stream() - .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder())) - .collect(Collectors.toList()); - - if (sender instanceof Player) { - ChatComponent component = new ChatComponent(ChatColors.color(" &7&oHover for more Info")); - StringBuilder builder = new StringBuilder(); - int hidden = 0; - - for (Map.Entry entry : timings) { - if (!chunksSkipped.contains(entry.getKey())) { - if (entry.getValue() > 0) { - builder.append("\n&c") - .append(formatChunk(entry.getKey())) - .append(" - ") - .append(chunkItemCount.getOrDefault(entry.getKey(), 0)) - .append("x &7(") - .append(toMillis(entry.getValue())) - .append(")"); - } - else hidden++; - } - } - - builder.append("\n\n&c+ &4").append(hidden).append(" Hidden"); - component.setHoverEvent(new HoverEvent(builder.toString())); - - component.sendMessage((Player) sender); - } - else { - int hidden = 0; - - for (Map.Entry entry : timings) { - if (!chunksSkipped.contains(entry.getKey())) { - if (entry.getValue() > 0) sender.sendMessage(" " + formatChunk(entry.getKey()) + " - " - + (chunkItemCount.getOrDefault(entry.getKey(), 0)) + "x (" + toMillis(entry.getValue()) + ")"); - else hidden++; - } - } - - sender.sendMessage(ChatColors.color("&c+ &4" + hidden + " Hidden")); - } - } - - private String formatChunk(String chunk) { - String[] components = chunk.split(";"); - return components[0] + " [" + components[2] + "," + components[3] + "]"; - } - - public long getTimings(Block b) { - return blockTimings.getOrDefault(b.getLocation(), 0L); - } - - public long getTimings(String item) { - return machineTimings.getOrDefault(item, 0L); - } - - public long getTimings(Chunk c) { - return chunkTimings.getOrDefault(c.toString(), 0L); - } - - public void addBlockTimings(Location l, long time) { - blockTimings.put(l, time); - } - - public boolean isHalted() { - return halted; - } - - public void halt() { - halted = true; - } - - private String toMillis(long time) { - return decimalFormat.format(time / 1000000F) + "ms"; - } - - @Override - public String toString() { - return "TickerTask {\n" - + " HALTED = " + halted + "\n" - + " tickers = " + tickers + "\n" - + " move = " + move + "\n" - + " delete = " + delete + "\n" - + " chunks = " + chunkItemCount + "\n" - + " machines = " + machineCount + "\n" - + " machinetime = " + machineTimings + "\n" - + " chunktime = " + chunkTimings + "\n" - + " skipped = " + chunksSkipped + "\n" - + "}"; - } - -} diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java index bba5720c52..2d33aaf009 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenu.java @@ -63,11 +63,6 @@ public void save(Location l) { changes = 0; } - @Deprecated - public void move(Block b) { - move(b.getLocation()); - } - public void move(Location l) { this.delete(this.location); this.location = l; diff --git a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java index a83623ed43..3bbe98b0e8 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/api/inventory/BlockMenuPreset.java @@ -55,16 +55,6 @@ public void newInstance(BlockMenu menu, Block b) { // This method can optionally be overridden by implementations } - @Deprecated - public int[] getSlotsAccessedByItemTransport(BlockMenu menu, ItemTransportFlow flow, ItemStack item) { - return getSlotsAccessedByItemTransport((DirtyChestMenu) menu, flow, item); - } - - @Deprecated - public int[] getSlotsAccessedByItemTransport(UniversalBlockMenu menu, ItemTransportFlow flow, ItemStack item) { - return getSlotsAccessedByItemTransport((DirtyChestMenu) menu, flow, item); - } - public int[] getSlotsAccessedByItemTransport(DirtyChestMenu menu, ItemTransportFlow flow, ItemStack item) { // This method will default to this method, can be overridden though return this.getSlotsAccessedByItemTransport(flow); diff --git a/src/main/java/me/mrCookieSlime/Slimefun/utils/ConfigCache.java b/src/main/java/me/mrCookieSlime/Slimefun/utils/ConfigCache.java index 21697fad7d..eba08ff3bb 100644 --- a/src/main/java/me/mrCookieSlime/Slimefun/utils/ConfigCache.java +++ b/src/main/java/me/mrCookieSlime/Slimefun/utils/ConfigCache.java @@ -13,7 +13,7 @@ public final class ConfigCache { public final boolean researchFireworksEnabled; public final List researchesTitles; - public final int blocksInfoLoadingDelay; + public final boolean translationsEnabled; public final int emeraldEnchantsLimit; @@ -23,13 +23,12 @@ public final class ConfigCache { public ConfigCache(Config cfg) { printOutLoading = cfg.getBoolean("options.print-out-loading"); + translationsEnabled = cfg.getBoolean("options.enable-translations"); researchesFreeInCreative = cfg.getBoolean("options.allow-free-creative-research"); researchesTitles = cfg.getStringList("research-ranks"); researchFireworksEnabled = cfg.getBoolean("options.research-unlock-fireworks"); - blocksInfoLoadingDelay = cfg.getInt("URID.info-delay"); - emeraldEnchantsLimit = cfg.getInt("options.emerald-enchantment-limit"); legacyDustWasher = cfg.getBoolean("options.legacy-dust-washer"); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 218f19eb56..b9474a7be7 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -35,6 +35,8 @@ options: max-network-size: 200 # 文本语言 language: zh-CN + # 启用多语言功能 + enable-translations: true guide: # 是否默认使用书与笔进行GUI的展示 diff --git a/src/main/resources/languages/messages_de.yml b/src/main/resources/languages/messages_de.yml index d1c888241a..bb85eecacf 100644 --- a/src/main/resources/languages/messages_de.yml +++ b/src/main/resources/languages/messages_de.yml @@ -98,6 +98,10 @@ guide: pages: next: Nächste Seite previous: Vorherige Seite + back: + title: Zurück + guide: Gehe zurück zum Slimefun-Handbuch + settings: Gehe zurück zu den Einstellungen search: lore: - "&bWonach möchtest du suchen?" @@ -140,6 +144,13 @@ languages: vi: Vietnamesisch zh-CN: Chinesisch (China) zh-TW: Chinesisch (Taiwan) + ar: Arabisch + af: Afrikaans + da: Dänisch + fi: Finnisch + no: Norwegisch + uk: Ukrainisch + ms: Malaiisch machines: ANCIENT_ALTAR: not-enough-pedestals: "&4Es fehlen einige Sockel des Altars &c(%pedestals% / 8)" diff --git a/src/main/resources/languages/messages_en.yml b/src/main/resources/languages/messages_en.yml index 96f04aa2f3..90bb363f4f 100644 --- a/src/main/resources/languages/messages_en.yml +++ b/src/main/resources/languages/messages_en.yml @@ -33,15 +33,25 @@ guide: pages: previous: 'Previous page' next: 'Next page' + + back: + title: 'Back' + guide: 'Go back to the Slimefun Guide' + settings: 'Go back to the Settings Panel' languages: updated: '&aYour language was successfully set to: &b%lang%' selected-language: 'Currently selected:' select: 'Click to select this language' select-default: 'Click to select the default language' + translations: name: '&aIs something missing?' lore: 'Click to add your own translation' + + progress: + messages: 'Chat messages' + researches: 'Research names' title: main: 'Slimefun Guide' @@ -51,6 +61,7 @@ guide: wiki: 'Slimefun4 Wiki' addons: 'Addons for Slimefun4' bugs: 'Bug Reports' + source: 'Source Code' credits: commit: 'Commit' @@ -265,4 +276,11 @@ languages: el: 'Greek' he: 'Hebrew' pt: 'Portugese (Portugal)' - pt-BR: 'Portugese (Brazil)' \ No newline at end of file + pt-BR: 'Portugese (Brazil)' + ar: 'Arabic' + af: 'Afrikaans' + da: 'Danish' + fi: 'Finnish' + no: 'Norwegian' + uk: 'Ukrainian' + ms: 'Malay' \ No newline at end of file diff --git a/src/main/resources/languages/messages_hu.yml b/src/main/resources/languages/messages_hu.yml index 516035b441..82798c8dcc 100644 --- a/src/main/resources/languages/messages_hu.yml +++ b/src/main/resources/languages/messages_hu.yml @@ -88,11 +88,11 @@ guide: languages: select: Kattints a nyelv kiválasztásához select-default: Kattints az alapértelmezett nyelv kiválasztásához + selected-language: 'Jelenleg kiválasztva:' translations: lore: Kattints a saját fordítás hozzáadásához name: "&aHiányzik valami?" updated: "&aA nyelvet sikeresen átállítottad erre: &b%lang%" - selected-language: 'Jelenleg kiválasztva:' pages: next: Következő oldal previous: Előző oldal @@ -103,13 +103,13 @@ guide: message: "&bMit szeretnél keresni?" name: "&7Keresés..." title: + addons: A Slimefun4 kiegészítői + bugs: Hibajelentések credits: Slimefun4 Közreműködők languages: Válaszd ki a kívánt nyelvet main: Slimefun Útmutató settings: Beállítások és Információk wiki: Slimefun4 Wiki - addons: A Slimefun4 kiegészítői - bugs: Hibajelentések tooltips: open-category: Kattints a megnyitáshoz versions-notice: Ezek nagyon fontosak a hibák jelentésekor! @@ -119,25 +119,25 @@ languages: cs: Cseh de: Német default: Szerver-Alapértelmezett + el: Görög en: Angol es: Spanyol fr: Francia + he: Héber hu: Magyar + id: Indonéz it: Olasz lv: Lett nl: Holland pl: Lengyel + pt: Portugál (Portugália) + pt-BR: Portugál (Brazília) ru: Orosz sk: Szlovák sv: Svéd vi: Vietnami - zh-TW: Kínai (Tajvan) - id: Indonéz zh-CN: Kínai (Kína) - el: Görög - he: Héber - pt: Portugál (Portugália) - pt-BR: Portugál (Brazília) + zh-TW: Kínai (Tajvan) machines: ANCIENT_ALTAR: not-enough-pedestals: "&4Az Altar körül nincs elég Pedestal, ami szükséges a működéséhez diff --git a/src/main/resources/languages/messages_sk.yml b/src/main/resources/languages/messages_sk.yml index a458f22272..857de5c0d1 100644 --- a/src/main/resources/languages/messages_sk.yml +++ b/src/main/resources/languages/messages_sk.yml @@ -88,11 +88,11 @@ guide: languages: select: Klikni pre vybratie tohto jazyka select-default: Klikni pre nastavenie východzieho jazyka + selected-language: 'Aktuálne vybraný jazyk: ' translations: lore: Klikni pre pridanie svojho prekladu name: "&aNiečo chýba?" updated: "&aTvoj jazyk bol úspešne nastavený na: &b%lang%" - selected-language: 'Aktuálne vybrané:' pages: next: Ďalšia stránka previous: Predošlá stránka @@ -103,13 +103,13 @@ guide: message: "&bČo by si chcel vyhľadať?" name: "&7Hľadať..." title: + addons: Doplnky pre Slimefun4 + bugs: Report bugov credits: Slimefun4 prispievatelia languages: Nastav si preferovaný jazyk main: Slimefun príručka settings: Nastavenia a informácie wiki: Slimefun4 Wiki - addons: Doplnky pre Slimefun4 - bugs: Report bugov tooltips: open-category: Klikni pre otvorenie versions-notice: Toto je veľmi dôležité pri nahlasovaní bugov! @@ -119,25 +119,25 @@ languages: cs: Čeština de: Nemčina default: Východzí jazyk servera + el: Gréčtina en: Angličtina es: Španielčina fr: Francúzština + he: Hebrejčina hu: Maďarčina + id: Indonézčina it: Taliančina lv: Lotyština nl: Holandčina pl: Poľština + pt: Portugalština (Portugalsko) + pt-BR: Portugalština (Brazília) ru: Ruština sk: Slovenčina sv: Švédština vi: Vietnamčina - zh-TW: Čínština (Taiwan) - id: Indonézčina zh-CN: Čínština (Čína) - el: Gréčtina - he: Hebrejčina - pt: Portugalština (Portugalsko) - pt-BR: Portugalština (Brazília) + zh-TW: Čínština (Taiwan) machines: ANCIENT_ALTAR: not-enough-pedestals: "&4Oltár nie je obkolesený dostatočným počtom podstáv&c(%pedestals% diff --git a/src/main/resources/languages/researches_de.yml b/src/main/resources/languages/researches_de.yml new file mode 100644 index 0000000000..8968108b35 --- /dev/null +++ b/src/main/resources/languages/researches_de.yml @@ -0,0 +1,236 @@ +--- +slimefun: + 24k_gold_block: Ein Palast aus Gold + advanced_android: Verbesserte Roboter + advanced_butcher_android: Verbesserter Killerroboter + advanced_circuit_board: Fortgeschrittener Schaltkreis + advanced_electric_smeltery: Verbesserter elektrischer Schmelzofen + advanced_farmer_android: Verbesserter Farmroboter + advanced_fisherman_android: Verbesserter Fischerroboter + advanced_output_node: Verbesserte Cargo-Knotenpunkte + alloys: Meister der Legierungen + ancient_altar: Alter Altar + ancient_runes: Antike Runen + android_interfaces: Roboter-Interface + android_memory_core: Roboterkern + angel_talisman: Talisman des Engels + animal_growth_accelerator: Wachstumsboost + anvil_talisman: Talisman des Ambosses + armored_jetpack: Gepanzertes Jetpack + armor_forge: Rüstungsherstellung + auto_anvil: Automatischer Amboss + auto_breeder: Futterautomaten + auto_drier: Ein trockener Tag + auto_enchanting: Automatische Verzauberungen + automated_crafting_chamber: Automatisches Craften + automated_panning_machine: Goldwaschen für Fortgeschrittene + automatic_ignition_chamber: Ein automatisierter Schmelzofen + backpacks: Rucksäcke + basic_circuit_board: Einfacher Schaltkreis + battery: Deine erste Batterie + better_carbon_press: Bessere Karbonpresse + better_crop_growth_accelerator: Noch schnellere Pflanzen + better_electric_crucibles: Verbesserter Schmelztiegel + better_electric_furnace: Verbesserter elektrischer Ofen + better_food_fabricator: Essen vom Fließband + better_freezer: Ein besserer Kühlschrank + better_gps_transmitters: Verbesserte Satelliten + better_heated_pressure_chamber: Unter Druck + better_solar_generators: Verbesserte Solargeneratoren + bio_reactor: Biologisch abbaubar + blade_of_vampires: Vampirklinge + blistering_ingots: Radioaktiv und glühend + block_placer: Automatisch Blöcke platzieren + boosted_uranium: Starkes Uran + boots_of_the_stomper: Stampfende Stiefel + bound_armor: Rüstung zum Behalten + bound_tools: Werkzeuge zum Behalten + bound_weapons: Waffen zum Behalten + bronze: Bronze + butcher_androids: Killer-Roboter + cactus_armor: Eine Rüstung aus Kaktus + capacitors: Einfache Kondensatoren + carbonado: Schwarze Diamanten + carbonado_furnace: Carbonado-Ofen + carbonado_tools: Werkzeuge aus Carbonado + carbon_press: Karbonpresse + cargo_basics: Cargo 101 + cargo_nodes: Cargo-Knotenpunkte + chainmail_armor: Kettenrüstung + charging_bench: Unter Strom + coal_generator: Kohleindustrie + cobalt_pickaxe: Eine schnelle Spitzhacke + combustion_reactor: Verbrennungsmotor + common_talisman: Gewöhnlicher Talisman + composter: Kompostierung + compressor_and_carbon: Karbon-Herstellung + cooler: Kühles zum Mitnehmen + copper_wire: Kupferdrähte + crop_growth_accelerator: Beschleunigte Pflanzen + crucible: Schmelztiegel + crushed_ore: Erzpurifikation + damascus_steel: Damaststahl + damascus_steel_armor: Damaststahlrüstung + diet_cookie: Diätkekse + duct_tape: Panzerband + electric_crucible: Elektrischer Schmelztiegel + electric_furnaces: Elektrische Öfen + electric_ingot_machines: Die Barrenfabrik + electric_motor: Elektromotoren + electric_ore_grinding: Zermalmen und Zerquetschen + electric_press: Elektrische Presse + electric_smeltery: Ein besserer Schmelzofen + elemental_staff: Stab der Elemente + elevator: Aufzüge + elytra: Gleitflügel + empowered_android: Hochenergetischer Roboter + empowered_butcher_android: Hochenergetischer Killerroboter + empowered_fisherman_android: Hochenergetischer Anglerroboter + ender_armor: Ender-Rüstung + ender_backpack: Ender-Rucksack + ender_talismans: Ender-Talisman + energized_gps_transmitter: High-End-Satelliten + energized_solar_generator: Solarkraft in der Nacht + energy_regulator: Ein Netzwerk unter Strom + enhanced_furnace: Verbesserter Ofen + essence_of_afterlife: Die Untoten + explosive_tools: Explosives Werkzeug + farmer_shoes: Gartenarbeit + fire_staff: Bezwinger der Flammen + fire_talisman: Talisman des Feuerwehrmanns + first_aid: Erste Hilfe Set + flask_of_knowledge: Erfahrung lagern + fluid_pump: Pumpe + fortune_cookie: Glückskeks + freezer: Eiskalt + fuel: Fossile Brennstoffe + geo_miner: GEO-Mining + geo_scanner: GEO-Scanner + gilded_backpack: Vergoldeter Rucksack + gilded_iron: Glänzendes Eisen + gilded_iron_armor: Vergoldete Eisenrüstung + glowstone_armor: Glühende Rüstung + gold_armor: Glitzernde Rüstung + gold_carats: Hochwertiges Gold + golden_apple_juice: Ein goldener Zaubertrank + gold_pan: Goldgräber + gps_emergency_transmitter: Ein Wegweiser für alle Fälle + gps_setup: GPS-Netzwerke 101 + grappling_hook: Enterhaken + grind_stone: Das Zermalmen von Items + hardened_glass: Verstärktes Glas + hazmat_suit: Gefahrenschutz + heated_pressure_chamber: Beheizte Druckkammer + hercules_pickaxe: Die Kraft von Herkules + high_tier_capacitors: Verbesserte Kondensatoren + high_tier_carbon_press: Ultimative Karbonpresse + high_tier_electric_ingot_machines: Schnelle Barren + high_tier_enhanced_furnaces: High-End-Öfen + hologram_projector: Hologramme + hunter_talisman: Talisman des Jägers + infernal_bonemeal: Knochenmehl für Warzen + infused_hopper: Magischer Trichter + infused_magnet: Verzauberter Magnet + jetboots: Raketenstiefel + jetpacks: Jetpacks + juicer: Leckere Säfte + kelp_cookie: Süßer Seetang + knight_talisman: Talisman des Ritters + lava_crystal: Feurige Angelegenheit + lava_generator: Thermale Energie + lava_talisman: Schwimmen in Lava + lightning_rune: Rune des Blitzes + lumber_axe: Holzfällen mit Stil + lumps: Magische Klumpen + magical_book_cover: Magischer Buchbinder + magic_eye_of_ender: Magisches Enderauge + magician_talisman: Talisman des Magiers + magic_sugar: Magischer Zucker + magic_workbench: Magische Werkbank + magnesium_generator: Energie durch Magnesium + magnet: Magneten + meat_jerky: Dörrfleisch + miner_talisman: Talisman der Mine + misc_power_items: Items mit Energie + monster_jerky: Gepökeltes Zombiefleisch + more_enhanced_furnaces: Noch bessere Öfen + multimeter: Messgeräte + multitools: Schweizer Taschenmesser + nether_gold_pan: Goldwäsche im Nether + nether_ice: Eis aus dem Nether + nether_star_reactor: Netherstern-Reaktor + nickel_and_cobalt: Erzforscher + night_vision_googles: Nachtsichtgerät + nuclear_reactor: Kernkraftwerk + oil: Schwarzes Gold + ore_crusher: Doppelte Erze + ore_washer: Erze waschen + organic_fertilizer: Organischer Dünger + organic_food: Viehfutter + output_chest: Einfache Auffangkiste + parachute: Fallschirm + pickaxe_of_containment: Eine Spitzhacke für Spawner + pickaxe_of_the_seeker: Wer suchet, der findet + pickaxe_of_vein_mining: Minen im großen Stile + plastic_sheet: 'Plastik + +' + portable_crafter: Eine Werkbank zum Mitnehmen + portable_dustbin: Mobile Mülltonnen + pressure_chamber: Druckkammer + programmable_androids: Programmierbare Roboter + radiant_backpack: Strahlender Rucksack + rainbow_blocks: Regenbogen + reactor_access_port: Automatischer Reaktor + reactor_essentials: Kraftwerke für Jedermann + redstone_alloy: Redstone-Legierung + reinforced_alloy: Verstärkte Legierung + reinforced_armor: Verstärkte Rüstung + reinforced_furnace: Verstärkter Ofen + repaired_spawner: Spawner reparieren + scroll_of_dimensional_teleposition: Schwindelerregend + seismic_axe: Die Erdbebenaxt + silicon: Silikon + slime_armor: Schleimige Rüstung + slimefun_metals: Neues Metall + slime_steel_armor: Schleimiger Stahl + smelters_pickaxe: Eine Spitzhacke zum Dahinschmelzen + smeltery: Schmelzofen + solar_generators: Solarenergie + solar_panel_and_helmet: Solarhelm + soulbound_rune: Seelenbindung + special_bows: Robin Hood + special_elytras: Verzauberte Gleitflügel + special_runes: Lila Runen + steel: Die Ära des Stahls + steel_plate: Stahlplatten + steel_thruster: Ein Triebwerk aus Stahl + storm_staff: Die Stärke von Thor + sword_of_beheading: Köpfen mit Köpfchen + synthetic_diamond: Synthetische Diamanten + synthetic_emerald: Falsche Edelsteine + synthetic_sapphire: Synthetische Sapphire + table_saw: Tischsäge + teleporter: Teleportation + teleporter_activation_plates: Beam mich hoch! + tome_of_knowledge_sharing: Erfahrungen teilen + totem_of_undying: Das Totem der Untoten + trash_can: Mülltonne + traveller_talisman: Talisman des Wanderers + uranium: 'Radioaktives Material + +' + walking_sticks: Gehstöcke + warrior_talisman: Talisman des Kriegers + water_staff: Wasserbändiger + water_talisman: Atmen wie ein Fisch + whirlwind_talisman: Talisman des Wirbelwindes + wind_staff: " Bezwinger der Lüfte" + wither_assembler: Ein automatisierter Wither + wither_proof_glass: Anti-Wither Glas + wither_proof_obsidian: Anti-Wither Obsidian + wizard_talisman: Talisman des Zauberers + woven_backpack: Stoff-Rucksack + xp_collector: Erfahrungssammler + bound_backpack: Ein treuer Rucksack + armored_jetboots: Gepanzerte Raketenstiefel diff --git a/src/main/resources/languages/researches_sk.yml b/src/main/resources/languages/researches_sk.yml new file mode 100644 index 0000000000..b5be855502 --- /dev/null +++ b/src/main/resources/languages/researches_sk.yml @@ -0,0 +1,232 @@ +--- +slimefun: + walking_sticks: Vychádzkové paličky + portable_crafter: Prenosný crafter + fortune_cookie: Koláčik šťastia + portable_dustbin: Prenosný kôš + armor_forge: Craftenie brnení + ore_washer: Čistenie rudy + gold_carats: Čisté zlato + smelters_pickaxe: Vypekací krompáč + common_talisman: Obyčajný talizman + anvil_talisman: Talizman kovadliny + miner_talisman: Talizman baníka + hunter_talisman: Talizman lovca + lava_talisman: Talizman chodenia po láve + water_talisman: Talizman dýchania pod vodou + angel_talisman: Talizman anjela + fire_talisman: Talizman bojovníka s ohňom + magician_talisman: Talizman kúzelníka + traveller_talisman: Talizman cestovateľa + warrior_talisman: Talizman bojovníka + knight_talisman: Talizman rytiera + gilded_iron: Žiarivé železo + whirlwind_talisman: Talizman víchrice + lumber_axe: Drevorubačská sekera + uranium: Radioaktívne + crushed_ore: Očistenie rudy + first_aid: Prvá pomoc + night_vision_googles: Okuliare s nočným videním + pickaxe_of_containment: Krompáč spawnerov + slime_steel_armor: Sliznaté oceľové brnenie + 24k_gold_block: Zlaté mesto + composter: Kompostovanie zeme + farmer_shoes: Farmárové boty + explosive_tools: Výbušné nástroje + crucible: Taviareň + ender_talismans: Talizmany endu + armored_jetboots: Obrnené tryskové topánky + bound_weapons: Zbrane naviazané na dušu + bound_tools: Nástroje naviazané na dušu + bound_armor: Brnenie naviazané na dušu + juicer: Lahodné nápoje + repaired_spawner: Opravovanie spawnerov + enhanced_furnace: Vylepšená pec + more_enhanced_furnaces: Lepšie pece + high_tier_enhanced_furnaces: Špičková pec + reinforced_furnace: Zpevnená pec + carbonado_furnace: Pec z brúseného diamantu + electric_motor: Zahrievanie + block_placer: Pokladač blokov + scroll_of_dimensional_teleposition: Otočiť veci naopak + special_bows: Robin Hood + tome_of_knowledge_sharing: Delenie sa s kamarátmi + flask_of_knowledge: Uschovávanie XP + hardened_glass: Odolnosť voči výbuchu + golden_apple_juice: Zlatý elixír + cooler: Prenášanie nápojov + ancient_altar: Staroveký oltár + wither_proof_obsidian: Obsidian odolný voči witherom + ancient_runes: Runy živlov + special_runes: Fialové runy + infernal_bonemeal: Pekelná kostná múčka + rainbow_blocks: Dúhové bloky + infused_hopper: Infusovaný hopper + wither_proof_glass: Sklo odolné voči witherom + duct_tape: Lepiaca páska + plastic_sheet: Plast + android_memory_core: Pamäťové jadro + oil: Olej + fuel: Palivo + hologram_projector: Hologramy + capacitors: Kondenzátory úrovne 1 + high_tier_capacitors: Kondenzátory úrovne 2 + solar_generators: Slnečná elektráreň + electric_furnaces: Napájaná pec + electric_ore_grinding: Drvenie + heated_pressure_chamber: Vyhrievaná tlaková komora + coal_generator: Generátor na uhlie + bio_reactor: Bio-reaktor + auto_enchanting: Automatické enchantovanie a odoberanie enchantov + auto_anvil: Automatická kovadlina + multimeter: Meranie energie + gps_setup: Základné zapojenie GPS + gps_emergency_transmitter: Núdzový GPS waypoint + programmable_androids: Programovateľné androidy + android_interfaces: Rozhrania androidov + geo_scanner: GEO-skenovanie + combustion_reactor: Spaľovací reaktor + teleporter: Základné komponenty teleportera + teleporter_activation_plates: Aktivácia teleportera + better_solar_generators: Vylepšené solárne generátory + better_gps_transmitters: Vylepšené vysielače + elevator: Výťahy + energized_solar_generator: Stála slnečná energia + energized_gps_transmitter: Najvyššia úroveň vysielača + energy_regulator: Elektrická sieť 101 + butcher_androids: Android mäsiar + organic_food: Organické jedlo + auto_breeder: Automatizované kŕmenie + advanced_android: Pokročilé androidy + advanced_butcher_android: Pokročilé androidy - mäsiar + advanced_fisherman_android: Pokročilé androidy - rybár + animal_growth_accelerator: Manipulácia rastu zvierat + xp_collector: Zberač XP + organic_fertilizer: Organické hnojivo + crop_growth_accelerator: Urýchlovač rastu plodín + better_crop_growth_accelerator: Pokročilý urýchlovač rastu plodín + reactor_essentials: Základy reaktoru + nuclear_reactor: Jadrová elektráreň + freezer: Mraznička + cargo_basics: Základy prenosu + cargo_nodes: Nastavenie prenosu + electric_ingot_machines: Elektrická výroba ingotov + automated_crafting_chamber: Automatizované craftenie + better_food_fabricator: Vylepšená výroba jedla + reactor_access_port: Interakcia s reaktorom + fluid_pump: Pumpa na tekutiny + better_freezer: Vylepšená mraznička + boosted_uranium: Nikdy nekončiaci kruh + trash_can: Odpad + electric_smeltery: Elektrická pec + better_electric_furnace: Vylepšená elektrická pec + wither_assembler: Automatizovaný zabijak witherov + elytra: Elytry + special_elytras: Špeciálne elytry + better_electric_crucibles: Vyhrievaná taviareň + nether_ice: Chladivo - ľad z netheru + blistering_ingots: Radioaktivne ingoty + output_chest: Výstupná truhla zo základných strojov + auto_drier: Suchý deň + diet_cookie: Diétny koláčik + charging_bench: Nabíjacia stanica + magnesium_generator: Energia z horčíka + kelp_cookie: Chutná riasa + meat_jerky: Sušené mäso + glowstone_armor: Glowstone Brnenie + lumps: Hrudky a kúzla + ender_backpack: Ender batoh + ender_armor: Ender Brnenie + magic_eye_of_ender: Magiké Oko Endu + magic_sugar: Magický cukor + monster_jerky: Sušené mäso z monštier + slime_armor: Slime brnenie + sword_of_beheading: Meč popráv + basic_circuit_board: Základná obvodová doska + advanced_circuit_board: Pokročilá obvodová doska + smeltery: Taviareň + steel: Vek ocele + misc_power_items: Dôležité veci súvisiace s energiou + battery: Tvoja prvá baterka + steel_plate: Oceľové pokovovanie + steel_thruster: Oceľový pohon + parachute: Padák + grappling_hook: Kotviaci hák + jetpacks: Jetpacky + multitools: Viac nástrojov + solar_panel_and_helmet: Solárna energia + elemental_staff: Elementárne tyče + grind_stone: Brúsiaci kameň + cactus_armor: Kaktusový oblek + gold_pan: Zlatá panvica + magical_book_cover: Magická knižná väzba + slimefun_metals: Nové kovy + ore_crusher: Zdvojnásobenie rudy + bronze: Vytvorenie bronzu + alloys: Pokročilé zliatiny + compressor_and_carbon: Vytvorenie uhlíka + gilded_iron_armor: Pozlatené železné brnenie + synthetic_diamond: Umelé diamanty + pressure_chamber: Tlaková komora + synthetic_sapphire: Umelý zafír + damascus_steel: Damašská oceľ + damascus_steel_armor: Brnenie z Damašskej ocele + reinforced_alloy: Zosilnená zliatina + carbonado: Čierne diamanty + magic_workbench: Magický pracovný stôl + wind_staff: Veterná tyč + reinforced_armor: Vystužené brnenie + silicon: Silicon Valley + fire_staff: Ohnivá palica + lava_crystal: Horúca situácia + synthetic_emerald: Falošný drahokam + chainmail_armor: Krúžkové brnenie + wizard_talisman: Talizman čarodejníka + hazmat_suit: Hazmat oblek + redstone_alloy: Redstonová zliatina + carbonado_tools: Špičkové stroje + gold_armor: Lesklé brnenie + hercules_pickaxe: Herkulesov krompáč + table_saw: Stolová píla + blade_of_vampires: Čepeľ upírov + water_staff: Vodná palica + automated_panning_machine: Automatická zlatá panvica + boots_of_the_stomper: Topánky dupača + pickaxe_of_the_seeker: Krompáč hľadača + backpacks: Batohy + woven_backpack: Tkaný batoh + gilded_backpack: Pozlatený batoh + armored_jetpack: Obrnený jetpack + nickel_and_cobalt: Ešte viac rúd + magnet: Magnetické kovy + infused_magnet: Infúzne magnety + cobalt_pickaxe: Rýchly krompáč + essence_of_afterlife: Čierna mágia + bound_backpack: Skladovanie duší + jetboots: Tryskové topánky + seismic_axe: Seizmická sekera + pickaxe_of_vein_mining: Krompáč žílnej ťažby + high_tier_electric_ingot_machines: Super rýchla výroba ingotu + advanced_output_node: Pokročilý výstupný uzol + carbon_press: Uhlíkový lis + better_carbon_press: Vylepšený uhlíkový lis + empowered_android: Posilnené Androidy + empowered_butcher_android: Posilnené Androidy - Mäsiar + empowered_fisherman_android: Posilnené Androidy - Rybár + high_tier_carbon_press: Ultimátny uhlíkový lis + better_heated_pressure_chamber: Vylepšená vyhrievaná tlaková komora + electric_crucible: Elektrifikovaný téglik + advanced_electric_smeltery: Pokročilá elektrická taviareň + advanced_farmer_android: Pokročilé Androidy - farmár + lava_generator: Generátor lávy + nether_star_reactor: Reaktor z Nether hviezdy + automatic_ignition_chamber: Automatická zapaľovacia komora + copper_wire: Zriedená vodivosť + radiant_backpack: Žiariaci batoh + storm_staff: Palica búrky + soulbound_rune: Runa duší + geo_miner: GEO-Miner + lightning_rune: Runa blesku + totem_of_undying: Totem večnosti + nether_gold_pan: Zlatá panvica z netheru + electric_press: Elektrický lis