From 4d3301da5684263e6de636572117ec43ef84fac9 Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 13:10:56 -0500 Subject: [PATCH 01/18] Sentry Issue #223476291 Check whether worlds are equal before performing distance checks Steps to reproduce: 1) Open treasure on one account 2) Go to Mavericks World on another account, tp to coords of treasure --- .../src/mineplex/core/treasure/TreasureLocation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureLocation.java b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureLocation.java index cdef82335..b729b5d15 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureLocation.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/treasure/TreasureLocation.java @@ -325,7 +325,8 @@ public class TreasureLocation implements Listener event.setTo(newTo); } } - else + else if (event.getFrom().getWorld().equals(_currentTreasure.getCenterBlock().getWorld()) && + event.getTo().getWorld().equals(_currentTreasure.getCenterBlock().getWorld())) { Location fromLocation = event.getFrom(); Location toLocation = event.getTo(); From ed25fe13414a51457028c01a4c1a645c8b3834b4 Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 13:13:27 -0500 Subject: [PATCH 02/18] Sentry Issue #224064210 Have BonusManager check if Carl is enabled before cleaning up items Steps to reproduce: Trigger SQLException in NPCManager so NPCs aren't loaded, or temporarily remove Carl from npcs database --- .../Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java index d1a06f0a4..13f355f0a 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/BonusManager.java @@ -236,11 +236,11 @@ public class BonusManager extends MiniClientPlugin implements I if (event.getType() != UpdateType.TICK) return; - _animation.itemClean(); - if (!_enabled) return; + _animation.itemClean(); + if (!_animationRunning) return; From c4bb9a23d506ba4478fdc44693fdcab2796c71a8 Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 13:42:26 -0500 Subject: [PATCH 03/18] Sentry Issue #223492448 Check if Power Player data is loaded before acting on it Steps to reproduce: 1) Join before server has started up --- .../mineplex/core/bonuses/gui/buttons/PowerPlayClubButton.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PowerPlayClubButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PowerPlayClubButton.java index 67b1ae492..d1282cc18 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PowerPlayClubButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/PowerPlayClubButton.java @@ -170,7 +170,8 @@ public class PowerPlayClubButton implements GuiItem public static boolean isAvailable(Player player, PowerPlayClubRepository repo) { - return !repo.getCachedData(player).getUnclaimedMonths().isEmpty(); + PowerPlayData data = repo.getCachedData(player); + return data != null && !data.getUnclaimedMonths().isEmpty(); } } From 2e23d597023c0d992ebbbdf42fb6afe047edf2ab Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 13:45:45 -0500 Subject: [PATCH 04/18] Sentry Issue #223489411 Check if fired projectile is a WitherSkull before casting Steps to reproduce: 1) Go to Wither Assult 2) Fire enderpearl --- .../game/arcade/game/games/wither/WitherGame.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/wither/WitherGame.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/wither/WitherGame.java index cf3e5eaa7..fb69f56f2 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/wither/WitherGame.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/wither/WitherGame.java @@ -255,11 +255,15 @@ public class WitherGame extends TeamGame implements IBlockRestorer if (GetState() == GameState.Recruit || GetState() == GameState.Prepare) { Projectile proj = event.getEntity(); - WitherSkull ws = (WitherSkull) proj; - if (ws.getShooter() instanceof Wither) + if (proj instanceof WitherSkull) { - event.setCancelled(true); + WitherSkull ws = (WitherSkull) proj; + + if (ws.getShooter() instanceof Wither) + { + event.setCancelled(true); + } } } } From 0725639852645a7695ff935672e3871e0f36cdf1 Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 13:55:54 -0500 Subject: [PATCH 05/18] Sentry Issue #223596821 Check if player has left before performing actions Steps to reproduce: 1) Pick wolf in SSM 2) Hit someone 3) Quit immediately after --- .../game/arcade/game/games/smash/perks/wolf/PerkWolf.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/wolf/PerkWolf.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/wolf/PerkWolf.java index 4482fa932..a5968ac4e 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/wolf/PerkWolf.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/wolf/PerkWolf.java @@ -503,6 +503,12 @@ public class PerkWolf extends SmashPerk UUID uuid = playerIterator.next(); Player player = UtilPlayer.searchExact(uuid); + if (player == null) + { + playerIterator.remove(); + continue; + } + Iterator timeIterator = _repeat.get(uuid).iterator(); while (timeIterator.hasNext()) From 7e9211815f0304ddb3d7e2393b044c53ded2d5f1 Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 14:04:05 -0500 Subject: [PATCH 06/18] Sentry Issue #223481223, #223481117 Reverse check so RHS can be null Steps to reproduce: 1) Pick Wither Skeleton in SSM 2) Throw wither image away from other player so it has no target 3) When it's standing still (i.e no target), have the other player punch the image --- .../game/games/smash/perks/witherskeleton/PerkWitherImage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/witherskeleton/PerkWitherImage.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/witherskeleton/PerkWitherImage.java index 6c09145df..ba5a90767 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/witherskeleton/PerkWitherImage.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/witherskeleton/PerkWitherImage.java @@ -169,7 +169,7 @@ public class PerkWitherImage extends SmashPerk } } - if (event.getTarget() != null && _skeletons.get(event.getTarget().getUniqueId()).equals(event.getEntity())) + if (event.getTarget() != null && event.getEntity().equals(_skeletons.get(event.getTarget().getUniqueId()))) { event.setCancelled(true); } From cb9ac1fc9fdc86093af8053a38d137c80be9077b Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 14:28:45 -0500 Subject: [PATCH 07/18] Sentry Issue #223481030 Prevent Fish Flurry from activating if no suitable blocks are found Steps to reproduce: 1) Select squid on hyrule castle 2) Activate fish flurry while looking at middle of empty side of castle --- .../smash/perks/squid/PerkFishFlurry.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/squid/PerkFishFlurry.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/squid/PerkFishFlurry.java index 539e98cf9..184f1b135 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/squid/PerkFishFlurry.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/squid/PerkFishFlurry.java @@ -102,11 +102,6 @@ public class PerkFishFlurry extends SmashPerk implements IThrown return; } - if (!Recharge.Instance.use(player, GetName(), COOLDOWN, true, true)) - { - return; - - } event.setCancelled(true); Set blocks = new HashSet<>(); @@ -131,10 +126,18 @@ public class PerkFishFlurry extends SmashPerk implements IThrown blocks.add(cur); } - _active.add(new DataSquidGeyser(player, blocks)); + if (!blocks.isEmpty()) + { + if (!Recharge.Instance.use(player, GetName(), COOLDOWN, true, true)) + { + return; + } - // Inform - UtilPlayer.message(player, F.main("Game", "You used " + F.skill(GetName()) + ".")); + _active.add(new DataSquidGeyser(player, blocks)); + + // Inform + UtilPlayer.message(player, F.main("Game", "You used " + F.skill(GetName()) + ".")); + } } @EventHandler From 7af7abd615ae1d540bd86fc9fa0def5ff8c6081b Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 14:32:08 -0500 Subject: [PATCH 08/18] Sentry Issue #223589200 Fix PetManager trying to rename a pet when it doesn't exist Steps to reproduce: 1) Somehow make MSSQL slow 2) Rename pet, and disable pet --- .../Mineplex.Core/src/mineplex/core/pet/PetManager.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java b/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java index ce936a333..3b7a1b0e3 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/pet/PetManager.java @@ -169,8 +169,12 @@ public class PetManager extends MiniClientPlugin if (player != null && player.isOnline()) { - getActivePet(playerName).setCustomNameVisible(true); - getActivePet(playerName).setCustomName(_petRenameQueue.get(playerName)); + Creature activePet = getActivePet(playerName); + if (activePet != null) + { + activePet.setCustomNameVisible(true); + activePet.setCustomName(_petRenameQueue.get(playerName)); + } } } From 9571db123d350367a1d0d4688b172844f65e6f72 Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 14:36:59 -0500 Subject: [PATCH 09/18] Sentry Issue #223483175 Fix badly implement Player check in PerkBoneRush Steps to reproduce: 1) Pick Skeletal Horse 2) Bone rush on some mob (i.e. cows in swamp) --- .../game/games/smash/perks/skeletalhorse/PerkBoneRush.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/skeletalhorse/PerkBoneRush.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/skeletalhorse/PerkBoneRush.java index 4fc78ea1b..f1d281713 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/skeletalhorse/PerkBoneRush.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/smash/perks/skeletalhorse/PerkBoneRush.java @@ -193,7 +193,7 @@ public class PerkBoneRush extends SmashPerk implements IThrown return; } - if (!(target instanceof Player || data.getThrower() instanceof Player)) + if (!(target instanceof Player) || !(data.getThrower() instanceof Player)) { return; } From 3f40432268c24a101e3e8af1f84e1531bc44798b Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 14:53:02 -0500 Subject: [PATCH 10/18] Sentry Issue #223474603 Handle null gun in Minestrike Steps to reproduce: 1) Bring a player down to low health using a molotov 2) Kill them with a grenade --- .../game/games/minestrike/Minestrike.java | 37 +++++++++++-------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java index 088a6f1ef..b5d69dd75 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java @@ -414,22 +414,29 @@ public class Minestrike extends TeamGame int amount; String gunType = (String) event.GetLog().GetLastDamager().GetDamage().getFirst().getMetadata().get("gunType"); - switch (gunType) + if (gunType == null) { - case "AWP": - amount = 100; - break; - case "PPBIZON": - amount = 600; - break; - case "NOVA": - amount = 900; - break; - case "KNIFE": - amount = 1500; - break; - default: - amount = 300; + amount = 300; + } + else + { + switch (gunType) + { + case "AWP": + amount = 100; + break; + case "PPBIZON": + amount = 600; + break; + case "NOVA": + amount = 900; + break; + case "KNIFE": + amount = 1500; + break; + default: + amount = 300; + } } _shopManager.addMoney(killer, amount, "kill with " + event.GetLog().GetLastDamager().GetReason()); From b3cc9f29e2ebad4d289e0a7bea4f215b92a2ec2c Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 14:56:33 -0500 Subject: [PATCH 11/18] Sentry Issue #223905084 Prevent NewsManager from updating news when none exists Steps to reproduce: 1) Join the server while the server is starting up --- Plugins/Mineplex.Hub/src/mineplex/hub/modules/NewsManager.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/NewsManager.java b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/NewsManager.java index 2e1c958d6..0679e29ba 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/modules/NewsManager.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/modules/NewsManager.java @@ -253,6 +253,9 @@ public class NewsManager extends MiniPlugin { if (event.getType() != UpdateType.FASTEST) return; + + if (_news.length == 0) + return; String text = ""; double healthPercent = 1; From 3e8b23c6f46503d3e5b3ec0194dea989d8e32c2c Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 26 Feb 2017 15:05:31 -0500 Subject: [PATCH 12/18] Sentry Issue #223473496 Don't bother with failsafe if the game is null (i.e. beyond dead) Steps to reproduce: 1) Quit server at just the right time --- .../game/arcade/managers/ProgressingKitManager.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/ProgressingKitManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/ProgressingKitManager.java index b092d0a17..2ce6c2ac3 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/ProgressingKitManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/ProgressingKitManager.java @@ -157,12 +157,15 @@ public class ProgressingKitManager implements Listener PlayerKit playerKit = _manager.getKitProgressionManager().getDataManager().get(player.getUniqueId()); try { - for (Kit kit : _manager.GetGame().GetKits()) + if (_manager.GetGame() != null) { - if (kit instanceof ProgressingKit) + for (Kit kit : _manager.GetGame().GetKits()) { - ProgressingKit progressingKit = (ProgressingKit) kit; - _manager.getKitProgressionManager().getRepository().insertOrUpdate(playerKit, progressingKit.getInternalName()); + if (kit instanceof ProgressingKit) + { + ProgressingKit progressingKit = (ProgressingKit) kit; + _manager.getKitProgressionManager().getRepository().insertOrUpdate(playerKit, progressingKit.getInternalName()); + } } } } From 9669e960a78b30417272246e5b99246f2a0fb442 Mon Sep 17 00:00:00 2001 From: samczsun Date: Fri, 17 Feb 2017 16:25:58 -0500 Subject: [PATCH 13/18] Autorotate maps --- .../api/enderchest/EnderchestWorldLoader.java | 2 +- .../Nautilus.Game.Arcade.UHC.WorldGen/pom.xml | 10 +++ .../nautilus/game/arcade/uhc/WorldGen.java | 76 ++++++++++++++++--- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/enderchest/EnderchestWorldLoader.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/enderchest/EnderchestWorldLoader.java index 5a196c26e..c11615902 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/enderchest/EnderchestWorldLoader.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/api/enderchest/EnderchestWorldLoader.java @@ -26,7 +26,7 @@ public class EnderchestWorldLoader { TimingManager.start(TIMINGS_PREFIX + "DownloadMap"); String fileName = mapType + "_map.zip"; - File f = _webCall.getFile("map/" + mapType + "/random", fileName); + File f = _webCall.getFile("map/" + mapType + "/next", fileName); TimingManager.stop(TIMINGS_PREFIX + "DownloadMap"); TimingManager.start(TIMINGS_PREFIX + "CreateFolders"); diff --git a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml index 52ebd07c0..879b9a7c8 100644 --- a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml +++ b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml @@ -19,10 +19,20 @@ 1.8.8-1.9-SNAPSHOT compile + + com.mineplex + mineplex-core + dev-SNAPSHOT + org.zeroturnaround zt-zip 1.9 + + org.slf4j + slf4j-simple + 1.7.21 + diff --git a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java index 2dd1a54be..da1bfe3a0 100644 --- a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java +++ b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java @@ -1,7 +1,29 @@ package nautilus.game.arcade.uhc; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; +import java.util.concurrent.TimeUnit; +import java.util.logging.Level; +import java.util.zip.ZipEntry; + import net.minecraft.server.v1_8_R3.BiomeBase; + import org.apache.commons.io.FileUtils; +import org.apache.http.HttpResponse; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.message.BasicHeader; +import org.apache.http.protocol.HTTP; import org.bukkit.Bukkit; import org.bukkit.Difficulty; import org.bukkit.World; @@ -14,20 +36,15 @@ import org.spigotmc.WatchdogThread; import org.zeroturnaround.zip.ZipEntrySource; import org.zeroturnaround.zip.ZipUtil; -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.IOException; -import java.io.InputStream; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ThreadLocalRandom; -import java.util.logging.Level; -import java.util.zip.ZipEntry; +import com.google.gson.JsonObject; + +import mineplex.core.common.Constants; +import mineplex.core.common.api.ApiHost; public class WorldGen extends JavaPlugin implements Runnable, Listener { + private static final int TIMEOUT = (int) TimeUnit.SECONDS.toMillis(10); + private static final int MIN_X = -1000; private static final int MIN_Z = -1000; private static final int MAX_X = 1000; @@ -240,6 +257,41 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener FileUtils.deleteQuietly(worldFolder); - getLogger().info("Finished generating world seed " + seed); + RequestConfig config = RequestConfig.custom() + .setConnectTimeout(TIMEOUT) + .setSocketTimeout(TIMEOUT) + .build(); + + CloseableHttpClient httpClient = HttpClientBuilder.create() + .setDefaultRequestConfig(config) + .build(); + + HttpPost request = new HttpPost("http://" + ApiHost.getEnderchestService().getHost() + ":" + ApiHost.getEnderchestService().getPort() + "/map/uhc/upload"); + request.addHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("name", outputFile.getName()); + jsonObject.addProperty("location", outputFile.toURI().toString()); + + request.setEntity(new StringEntity(Constants.GSON.toJson(jsonObject), StandardCharsets.UTF_8)); + + try + { + HttpResponse response = httpClient.execute(request); + + if (response.getStatusLine().getStatusCode() != 200) { + getLogger().severe("Failed to upload " + seed + ": " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); + } else { + getLogger().info("Uploaded " + seed + "!"); + } + } + catch (IOException e) + { + e.printStackTrace(); + } + finally + { + getLogger().info("Finished generating world seed " + seed); + } } } From dedcd254b001de48b42c660cc4cef9cea8997bbb Mon Sep 17 00:00:00 2001 From: samczsun Date: Sat, 18 Feb 2017 14:10:57 -0500 Subject: [PATCH 14/18] Clean up maps on local server --- .../nautilus/game/arcade/uhc/WorldGen.java | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java index da1bfe3a0..debfeea29 100644 --- a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java +++ b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java @@ -258,9 +258,9 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener FileUtils.deleteQuietly(worldFolder); RequestConfig config = RequestConfig.custom() - .setConnectTimeout(TIMEOUT) - .setSocketTimeout(TIMEOUT) - .build(); + .setConnectTimeout(TIMEOUT) + .setSocketTimeout(TIMEOUT) + .build(); CloseableHttpClient httpClient = HttpClientBuilder.create() .setDefaultRequestConfig(config) @@ -277,12 +277,33 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener try { + getLogger().info("Uploading " + seed + "!"); HttpResponse response = httpClient.execute(request); - if (response.getStatusLine().getStatusCode() != 200) { - getLogger().severe("Failed to upload " + seed + ": " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); - } else { + if (response.getStatusLine().getStatusCode() != 200) + { + if (response.getStatusLine().getStatusCode() == 409) + { + getLogger().warning("Oops - Server rejected " + seed + " because it was already generated"); + + if (!outputFile.delete()) + { + getLogger().warning("Could not clean up " + seed); + } + } + else + { + getLogger().severe("Failed to upload " + seed + ": " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); + } + } + else + { getLogger().info("Uploaded " + seed + "!"); + + if (!outputFile.delete()) + { + getLogger().warning("Could not clean up " + seed); + } } } catch (IOException e) From f8dbbce106345e2e87e4a61121e8b55e8e3297dc Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 19 Feb 2017 16:52:34 -0500 Subject: [PATCH 15/18] Cleanup --- .../Nautilus.Game.Arcade.UHC.WorldGen/pom.xml | 10 +- .../nautilus/game/arcade/uhc/WorldGen.java | 443 +++++++++--------- 2 files changed, 238 insertions(+), 215 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml index 879b9a7c8..2c02322e7 100644 --- a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml +++ b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml @@ -19,16 +19,16 @@ 1.8.8-1.9-SNAPSHOT compile - - com.mineplex - mineplex-core - dev-SNAPSHOT - org.zeroturnaround zt-zip 1.9 + + org.apache.httpcomponents + httpclient + 4.5.2 + org.slf4j slf4j-simple diff --git a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java index debfeea29..c2e322e7f 100644 --- a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java +++ b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java @@ -7,7 +7,9 @@ import java.io.IOException; import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.logging.Level; @@ -28,20 +30,16 @@ import org.bukkit.Bukkit; import org.bukkit.Difficulty; import org.bukkit.World; import org.bukkit.WorldCreator; -import org.bukkit.event.EventHandler; -import org.bukkit.event.Listener; -import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.plugin.java.JavaPlugin; import org.spigotmc.WatchdogThread; import org.zeroturnaround.zip.ZipEntrySource; import org.zeroturnaround.zip.ZipUtil; +import com.google.gson.Gson; import com.google.gson.JsonObject; -import mineplex.core.common.Constants; -import mineplex.core.common.api.ApiHost; - -public class WorldGen extends JavaPlugin implements Runnable, Listener +public class WorldGen extends JavaPlugin { private static final int TIMEOUT = (int) TimeUnit.SECONDS.toMillis(10); @@ -51,6 +49,35 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener private static final int MAX_Z = 1000; private static final int VIEW_DISTANCE = 5; + private static final String API_HOST_FILE = "api-config.dat"; + private static final Map API_HOST_MAP = new HashMap<>(); + + static + { + try + { + File configFile = new File(API_HOST_FILE); + YamlConfiguration configuration = YamlConfiguration.loadConfiguration(configFile); + + for (String key : configuration.getKeys(false)) + { + String ip = configuration.getConfigurationSection(key).getString("ip"); + // Use parseInt to catch non-ints instead of a 0 + int port = Integer.parseInt(configuration.getConfigurationSection(key).getString("port")); + if (ip == null) + { + throw new NullPointerException(); + } + + API_HOST_MAP.put(key, ip + ":" + port); + } + } + catch (Throwable t) + { + t.printStackTrace(); + } + } + @Override public void onEnable() { @@ -61,161 +88,127 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener WatchdogThread.doStop(); - getServer().getScheduler().runTaskTimer(this, this, 20L, 20L * 5L); - getServer().getPluginManager().registerEvents(this, this); - } - - @EventHandler - public void onJoin(AsyncPlayerPreLoginEvent event) - { - event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); - event.setKickMessage("Shoo, go away"); - } - - @Override - public void run() - { - File root = new File("."); - - if (!root.exists()) - { - getLogger().severe("Root folder does not exist. Aborting"); - getServer().shutdown(); - return; - } - - File outputDirectory = new File(root, "output"); - if (!outputDirectory.exists()) - { - if (!outputDirectory.mkdir()) - { - getLogger().severe("Could not create output folder. Aborting"); - getServer().shutdown(); - return; - } - } - - long seed = ThreadLocalRandom.current().nextLong(); - - File outputFile = new File(outputDirectory, "UHC_Map" + seed + ".zip"); - - if (outputFile.exists()) - { - getLogger().info("Seed " + seed + " has already been generated. Skipping"); - return; - } try { - if (!outputFile.createNewFile()) + File root = new File("."); + + if (!root.exists()) { - getLogger().severe("Could not create new output file. Aborting"); - getServer().shutdown(); + getLogger().severe("Root folder does not exist. Aborting"); + System.exit(0); return; } - } - catch (IOException e) - { - getLogger().log(Level.SEVERE, "Could not create new output file. Aborting", e); - getServer().shutdown(); - return; - } - getLogger().info("Generating world seed " + seed); - - World world = new WorldCreator("generating") - .environment(World.Environment.NORMAL) - .seed(seed) - .createWorld(); - world.setDifficulty(Difficulty.HARD); - world.setKeepSpawnInMemory(false); - - int minChunkX = (MIN_X >> 4) - VIEW_DISTANCE; - int minChunkZ = (MIN_Z >> 4) - VIEW_DISTANCE; - int maxChunkX = (MAX_X >> 4) + VIEW_DISTANCE; - int maxChunkZ = (MAX_Z >> 4) + VIEW_DISTANCE; - - for (int x = minChunkX; x <= maxChunkX; x++) - { - getLogger().info("Generating x coord " + x); - for (int z = minChunkZ; z <= maxChunkZ; z++) + File outputDirectory = new File(root, "output"); + if (!outputDirectory.exists()) { - world.getChunkAt(x, z).load(true); - } - } - - for (int x = minChunkX; x <= maxChunkX; x++) - { - getLogger().info("Unloading x coord " + x); - for (int z = minChunkZ; z <= maxChunkZ; z++) - { - world.getChunkAt(x, z).unload(true, false); - } - } - - getLogger().info("Unloading and saving world"); - - Bukkit.unloadWorld(world, true); - - getLogger().info("Finished unloading and saving world"); - - StringBuilder worldconfig = new StringBuilder(); - worldconfig.append("MAP_NAME:UHC World").append(System.lineSeparator()); - worldconfig.append("MAP_AUTHOR:Mineplex").append(System.lineSeparator()); - worldconfig.append("MIN_X:").append(MIN_X).append(System.lineSeparator()); - worldconfig.append("MIN_Z:").append(MIN_Z).append(System.lineSeparator()); - worldconfig.append("MAX_X:").append(MAX_X).append(System.lineSeparator()); - worldconfig.append("MAX_Z:").append(MAX_Z).append(System.lineSeparator()); - for (int i = 1; i <= 60; i++) - { - worldconfig.append("TEAM_NAME:").append(i).append(System.lineSeparator()); - worldconfig.append("TEAM_SPAWNS:0,0,0").append(System.lineSeparator()); - } - - File worldFolder = new File(root, "generating"); - - File regionFolder = new File(worldFolder, "region"); - - File[] regionFiles = regionFolder.listFiles(); - - if (regionFiles == null) - { - getLogger().severe("Unexpected null region files. Aborting"); - getServer().shutdown(); - return; - } - - List zipEntrySourceList = new ArrayList<>(); - zipEntrySourceList.add(new ZipEntrySource() - { - @Override - public String getPath() - { - return "WorldConfig.dat"; + if (!outputDirectory.mkdir()) + { + getLogger().severe("Could not create output folder. Aborting"); + System.exit(0); + return; + } } - @Override - public ZipEntry getEntry() + long seed = ThreadLocalRandom.current().nextLong(); + + File outputFile = new File(outputDirectory, "UHC_Map" + seed + ".zip"); + + if (outputFile.exists()) { - return new ZipEntry(getPath()); + getLogger().info("Seed " + seed + " has already been generated. Skipping"); + System.exit(0); + return; } - @Override - public InputStream getInputStream() throws IOException + try { - return new ByteArrayInputStream(worldconfig.toString().getBytes(StandardCharsets.UTF_8)); + if (!outputFile.createNewFile()) + { + getLogger().severe("Could not create new output file. Aborting"); + System.exit(0); + return; + } + } + catch (IOException e) + { + getLogger().log(Level.SEVERE, "Could not create new output file. Aborting", e); + System.exit(0); + return; } - }); + getLogger().info("Generating world seed " + seed); - for (File file : regionFiles) - { + World world = new WorldCreator("generating") + .environment(World.Environment.NORMAL) + .seed(seed) + .createWorld(); + world.setDifficulty(Difficulty.HARD); + world.setKeepSpawnInMemory(false); + + int minChunkX = (MIN_X >> 4) - VIEW_DISTANCE; + int minChunkZ = (MIN_Z >> 4) - VIEW_DISTANCE; + int maxChunkX = (MAX_X >> 4) + VIEW_DISTANCE; + int maxChunkZ = (MAX_Z >> 4) + VIEW_DISTANCE; + + for (int x = minChunkX; x <= maxChunkX; x++) + { + getLogger().info("Generating x coord " + x); + for (int z = minChunkZ; z <= maxChunkZ; z++) + { + world.getChunkAt(x, z).load(true); + } + } + + for (int x = minChunkX; x <= maxChunkX; x++) + { + getLogger().info("Unloading x coord " + x); + for (int z = minChunkZ; z <= maxChunkZ; z++) + { + world.getChunkAt(x, z).unload(true, false); + } + } + + getLogger().info("Unloading and saving world"); + + Bukkit.unloadWorld(world, true); + + getLogger().info("Finished unloading and saving world"); + + StringBuilder worldconfig = new StringBuilder(); + worldconfig.append("MAP_NAME:UHC World").append(System.lineSeparator()); + worldconfig.append("MAP_AUTHOR:Mineplex").append(System.lineSeparator()); + worldconfig.append("MIN_X:").append(MIN_X).append(System.lineSeparator()); + worldconfig.append("MIN_Z:").append(MIN_Z).append(System.lineSeparator()); + worldconfig.append("MAX_X:").append(MAX_X).append(System.lineSeparator()); + worldconfig.append("MAX_Z:").append(MAX_Z).append(System.lineSeparator()); + for (int i = 1; i <= 60; i++) + { + worldconfig.append("TEAM_NAME:").append(i).append(System.lineSeparator()); + worldconfig.append("TEAM_SPAWNS:0,0,0").append(System.lineSeparator()); + } + + File worldFolder = new File(root, "generating"); + + File regionFolder = new File(worldFolder, "region"); + + File[] regionFiles = regionFolder.listFiles(); + + if (regionFiles == null) + { + getLogger().severe("Unexpected null region files. Aborting"); + System.exit(0); + return; + } + + List zipEntrySourceList = new ArrayList<>(); zipEntrySourceList.add(new ZipEntrySource() { @Override public String getPath() { - return "region/" + file.getName(); + return "WorldConfig.dat"; } @Override @@ -227,92 +220,122 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener @Override public InputStream getInputStream() throws IOException { - return new FileInputStream(file); + return new ByteArrayInputStream(worldconfig.toString().getBytes(StandardCharsets.UTF_8)); } }); - } - zipEntrySourceList.add(new ZipEntrySource() - { - @Override - public String getPath() + + for (File file : regionFiles) { - return "level.dat"; - } - - @Override - public ZipEntry getEntry() - { - return new ZipEntry(getPath()); - } - - @Override - public InputStream getInputStream() throws IOException - { - return new FileInputStream(new File(worldFolder, "level.dat")); - } - }); - - ZipUtil.pack(zipEntrySourceList.toArray(new ZipEntrySource[zipEntrySourceList.size()]), outputFile); - - FileUtils.deleteQuietly(worldFolder); - - RequestConfig config = RequestConfig.custom() - .setConnectTimeout(TIMEOUT) - .setSocketTimeout(TIMEOUT) - .build(); - - CloseableHttpClient httpClient = HttpClientBuilder.create() - .setDefaultRequestConfig(config) - .build(); - - HttpPost request = new HttpPost("http://" + ApiHost.getEnderchestService().getHost() + ":" + ApiHost.getEnderchestService().getPort() + "/map/uhc/upload"); - request.addHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); - - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("name", outputFile.getName()); - jsonObject.addProperty("location", outputFile.toURI().toString()); - - request.setEntity(new StringEntity(Constants.GSON.toJson(jsonObject), StandardCharsets.UTF_8)); - - try - { - getLogger().info("Uploading " + seed + "!"); - HttpResponse response = httpClient.execute(request); - - if (response.getStatusLine().getStatusCode() != 200) - { - if (response.getStatusLine().getStatusCode() == 409) + zipEntrySourceList.add(new ZipEntrySource() { - getLogger().warning("Oops - Server rejected " + seed + " because it was already generated"); + @Override + public String getPath() + { + return "region/" + file.getName(); + } + + @Override + public ZipEntry getEntry() + { + return new ZipEntry(getPath()); + } + + @Override + public InputStream getInputStream() throws IOException + { + return new FileInputStream(file); + } + }); + } + + zipEntrySourceList.add(new ZipEntrySource() + { + @Override + public String getPath() + { + return "level.dat"; + } + + @Override + public ZipEntry getEntry() + { + return new ZipEntry(getPath()); + } + + @Override + public InputStream getInputStream() throws IOException + { + return new FileInputStream(new File(worldFolder, "level.dat")); + } + }); + + ZipUtil.pack(zipEntrySourceList.toArray(new ZipEntrySource[zipEntrySourceList.size()]), outputFile); + + FileUtils.deleteQuietly(worldFolder); + + RequestConfig config = RequestConfig.custom() + .setConnectTimeout(TIMEOUT) + .setSocketTimeout(TIMEOUT) + .build(); + + CloseableHttpClient httpClient = HttpClientBuilder.create() + .setDefaultRequestConfig(config) + .build(); + + HttpPost request = new HttpPost("http://" + API_HOST_MAP.get("ENDERCHEST") + "/map/uhc/upload"); + request.addHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("name", outputFile.getName()); + jsonObject.addProperty("location", outputFile.toURI().toString()); + + request.setEntity(new StringEntity(new Gson().toJson(jsonObject), StandardCharsets.UTF_8)); + + try + { + getLogger().info("Uploading " + seed + "!"); + HttpResponse response = httpClient.execute(request); + + if (response.getStatusLine().getStatusCode() != 200) + { + if (response.getStatusLine().getStatusCode() == 409) + { + getLogger().warning("Oops - Server rejected " + seed + " because it was already generated"); + + if (!outputFile.delete()) + { + getLogger().warning("Could not clean up " + seed); + } + } + else + { + getLogger().severe("Failed to upload " + seed + ": " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); + } + } + else + { + getLogger().info("Uploaded " + seed + "!"); if (!outputFile.delete()) { getLogger().warning("Could not clean up " + seed); } } - else - { - getLogger().severe("Failed to upload " + seed + ": " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); - } } - else + catch (IOException e) { - getLogger().info("Uploaded " + seed + "!"); - - if (!outputFile.delete()) - { - getLogger().warning("Could not clean up " + seed); - } + e.printStackTrace(); + } + finally + { + getLogger().info("Finished generating world seed " + seed); } } - catch (IOException e) + catch (Throwable t) { - e.printStackTrace(); - } - finally - { - getLogger().info("Finished generating world seed " + seed); + t.printStackTrace(); } + System.exit(0); } } From b782f5ced9b842edbffd817b704587ec5eb5cdfc Mon Sep 17 00:00:00 2001 From: samczsun Date: Sun, 19 Feb 2017 23:53:19 -0500 Subject: [PATCH 16/18] Speed up generation --- .../nautilus/game/arcade/uhc/WorldGen.java | 465 +++++++++--------- .../game/arcade/game/games/uhc/UHC.java | 12 +- 2 files changed, 248 insertions(+), 229 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java index c2e322e7f..812b1f45a 100644 --- a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java +++ b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java @@ -1,10 +1,7 @@ package nautilus.game.arcade.uhc; -import java.io.ByteArrayInputStream; import java.io.File; -import java.io.FileInputStream; import java.io.IOException; -import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; @@ -13,7 +10,6 @@ import java.util.Map; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.logging.Level; -import java.util.zip.ZipEntry; import net.minecraft.server.v1_8_R3.BiomeBase; @@ -27,26 +23,35 @@ import org.apache.http.impl.client.HttpClientBuilder; import org.apache.http.message.BasicHeader; import org.apache.http.protocol.HTTP; import org.bukkit.Bukkit; +import org.bukkit.Chunk; import org.bukkit.Difficulty; import org.bukkit.World; +import org.bukkit.WorldBorder; import org.bukkit.WorldCreator; import org.bukkit.configuration.file.YamlConfiguration; +import org.bukkit.craftbukkit.v1_8_R3.CraftWorld; +import org.bukkit.entity.Entity; +import org.bukkit.event.EventHandler; +import org.bukkit.event.Listener; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.world.ChunkUnloadEvent; +import org.bukkit.event.world.WorldInitEvent; import org.bukkit.plugin.java.JavaPlugin; import org.spigotmc.WatchdogThread; +import org.zeroturnaround.zip.ByteSource; +import org.zeroturnaround.zip.FileSource; import org.zeroturnaround.zip.ZipEntrySource; import org.zeroturnaround.zip.ZipUtil; import com.google.gson.Gson; import com.google.gson.JsonObject; -public class WorldGen extends JavaPlugin +public class WorldGen extends JavaPlugin implements Listener { private static final int TIMEOUT = (int) TimeUnit.SECONDS.toMillis(10); - private static final int MIN_X = -1000; - private static final int MIN_Z = -1000; - private static final int MAX_X = 1000; - private static final int MAX_Z = 1000; + // The world will be -MAP_SIZE to MAP_SIZE large + private static final int MAP_SIZE = 1000; private static final int VIEW_DISTANCE = 5; private static final String API_HOST_FILE = "api-config.dat"; @@ -78,264 +83,276 @@ public class WorldGen extends JavaPlugin } } + @EventHandler + public void login(AsyncPlayerPreLoginEvent event) + { + event.setKickMessage("get out"); + event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER); + } + + @EventHandler + public void unload(ChunkUnloadEvent event) + { + event.setCancelled(true); + } + + @EventHandler + public void init(WorldInitEvent event) + { + // Prevent any eager generation + event.getWorld().setKeepSpawnInMemory(false); + } + @Override public void onEnable() { + getLogger().info("Cleaning up other worlds"); + for (World world : getServer().getWorlds()) + { + world.setKeepSpawnInMemory(false); + world.setSpawnFlags(false, false); + world.setAmbientSpawnLimit(0); + world.setAnimalSpawnLimit(0); + world.setMonsterSpawnLimit(0); + world.setWaterAnimalSpawnLimit(0); + world.getEntities().forEach(Entity::remove); + for (Chunk chunk : world.getLoadedChunks()) + { + chunk.unload(false, false); + } + getServer().unloadWorld(world, false); + getLogger().info("Unloaded " + world.getName()); + } + + getLogger().info("Replacing biomes"); BiomeBase.getBiomes()[BiomeBase.OCEAN.id] = BiomeBase.PLAINS; BiomeBase.getBiomes()[BiomeBase.DEEP_OCEAN.id] = BiomeBase.PLAINS; BiomeBase.getBiomes()[BiomeBase.SWAMPLAND.id] = BiomeBase.PLAINS; BiomeBase.getBiomes()[BiomeBase.RIVER.id] = BiomeBase.PLAINS; + getLogger().info("Forcing system GC"); + System.gc(); + WatchdogThread.doStop(); + getServer().getPluginManager().registerEvents(this, this); + + File root = new File("."); + + if (!root.exists()) + { + getLogger().severe("Root folder does not exist. Aborting"); + System.exit(0); + return; + } + + File outputDirectory = new File(root, "output"); + if (!outputDirectory.exists()) + { + if (!outputDirectory.mkdir()) + { + getLogger().severe("Could not create output folder. Aborting"); + System.exit(0); + return; + } + } + + long seed = ThreadLocalRandom.current().nextLong(); + + File outputFile = new File(outputDirectory, "UHC_Map" + seed + ".zip"); + + if (outputFile.exists()) + { + getLogger().info("Seed " + seed + " has already been generated. Skipping"); + System.exit(0); + return; + } try { - File root = new File("."); - - if (!root.exists()) + if (!outputFile.createNewFile()) { - getLogger().severe("Root folder does not exist. Aborting"); + getLogger().severe("Could not create new output file. Aborting"); System.exit(0); return; } + } + catch (IOException e) + { + getLogger().log(Level.SEVERE, "Could not create new output file. Aborting", e); + System.exit(0); + return; + } - File outputDirectory = new File(root, "output"); - if (!outputDirectory.exists()) + File previousSession = new File("generating"); + + if (previousSession.exists()) + { + if (!FileUtils.deleteQuietly(previousSession)) { - if (!outputDirectory.mkdir()) - { - getLogger().severe("Could not create output folder. Aborting"); - System.exit(0); - return; - } - } - - long seed = ThreadLocalRandom.current().nextLong(); - - File outputFile = new File(outputDirectory, "UHC_Map" + seed + ".zip"); - - if (outputFile.exists()) - { - getLogger().info("Seed " + seed + " has already been generated. Skipping"); + getLogger().severe("Could not delete previous generation session. Aborting"); System.exit(0); return; } + } - try + getLogger().info("Generating world seed " + seed); + + World world = new WorldCreator("generating") + .environment(World.Environment.NORMAL) + .seed(seed) + .createWorld(); + world.setKeepSpawnInMemory(false); + world.setDifficulty(Difficulty.HARD); + WorldBorder border = world.getWorldBorder(); + border.setCenter(0.0, 0.0); + border.setSize(MAP_SIZE * 2); + + int minChunkX = (-MAP_SIZE >> 4) - VIEW_DISTANCE; + int minChunkZ = (-MAP_SIZE >> 4) - VIEW_DISTANCE; + int maxChunkX = (MAP_SIZE >> 4) + VIEW_DISTANCE; + int maxChunkZ = (MAP_SIZE >> 4) + VIEW_DISTANCE; + + net.minecraft.server.v1_8_R3.WorldServer nmsWorld = ((CraftWorld) world).getHandle(); +// +// Field mfield = nmsWorld.getClass().getDeclaredField("M"); +// mfield.setAccessible(true); +// +// HashTreeSet treeSet = ((HashTreeSet) mfield.get(nmsWorld)); + + for (int x = minChunkX; x <= maxChunkX; x++) + { + getLogger().info("Generating x coord " + x); + for (int z = minChunkZ; z <= maxChunkZ; z++) { - if (!outputFile.createNewFile()) - { - getLogger().severe("Could not create new output file. Aborting"); - System.exit(0); - return; - } - } - catch (IOException e) - { - getLogger().log(Level.SEVERE, "Could not create new output file. Aborting", e); - System.exit(0); - return; + world.getChunkAt(x, z).load(true); + nmsWorld.a(true); + // Manually tick blocks - this should be the equivalent of letting a full server tick run once + // between each chunk generation, except we cut out the extra useless stuff } - getLogger().info("Generating world seed " + seed); +// System.out.println("M: " + treeSet.size()); +// System.out.println("E: " + nmsWorld.entityList.size()); +// System.out.println("TE: " + nmsWorld.tileEntityList.size()); +// System.out.println("C: " + nmsWorld.chunkProviderServer.chunks.size()); + } - World world = new WorldCreator("generating") - .environment(World.Environment.NORMAL) - .seed(seed) - .createWorld(); - world.setDifficulty(Difficulty.HARD); - world.setKeepSpawnInMemory(false); - - int minChunkX = (MIN_X >> 4) - VIEW_DISTANCE; - int minChunkZ = (MIN_Z >> 4) - VIEW_DISTANCE; - int maxChunkX = (MAX_X >> 4) + VIEW_DISTANCE; - int maxChunkZ = (MAX_Z >> 4) + VIEW_DISTANCE; - - for (int x = minChunkX; x <= maxChunkX; x++) + for (int x = minChunkX; x <= maxChunkX; x++) + { + getLogger().info("Unloading x coord " + x); + for (int z = minChunkZ; z <= maxChunkZ; z++) { - getLogger().info("Generating x coord " + x); - for (int z = minChunkZ; z <= maxChunkZ; z++) - { - world.getChunkAt(x, z).load(true); - } + world.getChunkAt(x, z).unload(true, false); } - for (int x = minChunkX; x <= maxChunkX; x++) +// System.out.println("M: " + treeSet.size()); +// System.out.println("E: " + nmsWorld.entityList.size()); +// System.out.println("TE: " + nmsWorld.tileEntityList.size()); +// System.out.println("C: " + nmsWorld.chunkProviderServer.chunks.size()); + } + + getLogger().info("Unloading and saving world"); + + Bukkit.unloadWorld(world, true); + + getLogger().info("Finished unloading and saving world"); + + StringBuilder worldconfig = new StringBuilder(); + worldconfig.append("MAP_NAME:UHC World").append(System.lineSeparator()); + worldconfig.append("MAP_AUTHOR:Mineplex").append(System.lineSeparator()); + worldconfig.append("MIN_X:").append(-MAP_SIZE).append(System.lineSeparator()); + worldconfig.append("MIN_Z:").append(-MAP_SIZE).append(System.lineSeparator()); + worldconfig.append("MAX_X:").append(MAP_SIZE).append(System.lineSeparator()); + worldconfig.append("MAX_Z:").append(MAP_SIZE).append(System.lineSeparator()); + for (int i = 1; i <= 60; i++) + { + worldconfig.append("TEAM_NAME:").append(i).append(System.lineSeparator()); + worldconfig.append("TEAM_SPAWNS:0,0,0").append(System.lineSeparator()); + } + + File worldFolder = new File(root, "generating"); + + File regionFolder = new File(worldFolder, "region"); + + File[] regionFiles = regionFolder.listFiles(); + + if (regionFiles == null) + { + getLogger().severe("Unexpected null region files. Aborting"); + System.exit(0); + return; + } + + List zipEntrySourceList = new ArrayList<>(); + zipEntrySourceList.add(new ByteSource("WorldConfig.dat", worldconfig.toString().getBytes(StandardCharsets.UTF_8))); + for (File file : regionFiles) + { + zipEntrySourceList.add(new FileSource("region/" + file.getName(), file)); + } + zipEntrySourceList.add(new FileSource("level.dat", new File(worldFolder, "level.dat"))); + + ZipUtil.pack(zipEntrySourceList.toArray(new ZipEntrySource[zipEntrySourceList.size()]), outputFile); + + FileUtils.deleteQuietly(worldFolder); + + RequestConfig config = RequestConfig.custom() + .setConnectTimeout(TIMEOUT) + .setSocketTimeout(TIMEOUT) + .build(); + + CloseableHttpClient httpClient = HttpClientBuilder.create() + .setDefaultRequestConfig(config) + .build(); + + HttpPost request = new HttpPost("http://" + API_HOST_MAP.get("ENDERCHEST") + "/map/uhc/upload"); + request.addHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); + + JsonObject jsonObject = new JsonObject(); + jsonObject.addProperty("name", outputFile.getName()); + jsonObject.addProperty("location", outputFile.toURI().toString()); + + request.setEntity(new StringEntity(new Gson().toJson(jsonObject), StandardCharsets.UTF_8)); + + try + { + getLogger().info("Uploading " + seed + "!"); + HttpResponse response = httpClient.execute(request); + + if (response.getStatusLine().getStatusCode() != 200) { - getLogger().info("Unloading x coord " + x); - for (int z = minChunkZ; z <= maxChunkZ; z++) + if (response.getStatusLine().getStatusCode() == 409) { - world.getChunkAt(x, z).unload(true, false); - } - } - - getLogger().info("Unloading and saving world"); - - Bukkit.unloadWorld(world, true); - - getLogger().info("Finished unloading and saving world"); - - StringBuilder worldconfig = new StringBuilder(); - worldconfig.append("MAP_NAME:UHC World").append(System.lineSeparator()); - worldconfig.append("MAP_AUTHOR:Mineplex").append(System.lineSeparator()); - worldconfig.append("MIN_X:").append(MIN_X).append(System.lineSeparator()); - worldconfig.append("MIN_Z:").append(MIN_Z).append(System.lineSeparator()); - worldconfig.append("MAX_X:").append(MAX_X).append(System.lineSeparator()); - worldconfig.append("MAX_Z:").append(MAX_Z).append(System.lineSeparator()); - for (int i = 1; i <= 60; i++) - { - worldconfig.append("TEAM_NAME:").append(i).append(System.lineSeparator()); - worldconfig.append("TEAM_SPAWNS:0,0,0").append(System.lineSeparator()); - } - - File worldFolder = new File(root, "generating"); - - File regionFolder = new File(worldFolder, "region"); - - File[] regionFiles = regionFolder.listFiles(); - - if (regionFiles == null) - { - getLogger().severe("Unexpected null region files. Aborting"); - System.exit(0); - return; - } - - List zipEntrySourceList = new ArrayList<>(); - zipEntrySourceList.add(new ZipEntrySource() - { - @Override - public String getPath() - { - return "WorldConfig.dat"; - } - - @Override - public ZipEntry getEntry() - { - return new ZipEntry(getPath()); - } - - @Override - public InputStream getInputStream() throws IOException - { - return new ByteArrayInputStream(worldconfig.toString().getBytes(StandardCharsets.UTF_8)); - } - }); - - - for (File file : regionFiles) - { - zipEntrySourceList.add(new ZipEntrySource() - { - @Override - public String getPath() - { - return "region/" + file.getName(); - } - - @Override - public ZipEntry getEntry() - { - return new ZipEntry(getPath()); - } - - @Override - public InputStream getInputStream() throws IOException - { - return new FileInputStream(file); - } - }); - } - - zipEntrySourceList.add(new ZipEntrySource() - { - @Override - public String getPath() - { - return "level.dat"; - } - - @Override - public ZipEntry getEntry() - { - return new ZipEntry(getPath()); - } - - @Override - public InputStream getInputStream() throws IOException - { - return new FileInputStream(new File(worldFolder, "level.dat")); - } - }); - - ZipUtil.pack(zipEntrySourceList.toArray(new ZipEntrySource[zipEntrySourceList.size()]), outputFile); - - FileUtils.deleteQuietly(worldFolder); - - RequestConfig config = RequestConfig.custom() - .setConnectTimeout(TIMEOUT) - .setSocketTimeout(TIMEOUT) - .build(); - - CloseableHttpClient httpClient = HttpClientBuilder.create() - .setDefaultRequestConfig(config) - .build(); - - HttpPost request = new HttpPost("http://" + API_HOST_MAP.get("ENDERCHEST") + "/map/uhc/upload"); - request.addHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); - - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("name", outputFile.getName()); - jsonObject.addProperty("location", outputFile.toURI().toString()); - - request.setEntity(new StringEntity(new Gson().toJson(jsonObject), StandardCharsets.UTF_8)); - - try - { - getLogger().info("Uploading " + seed + "!"); - HttpResponse response = httpClient.execute(request); - - if (response.getStatusLine().getStatusCode() != 200) - { - if (response.getStatusLine().getStatusCode() == 409) - { - getLogger().warning("Oops - Server rejected " + seed + " because it was already generated"); - - if (!outputFile.delete()) - { - getLogger().warning("Could not clean up " + seed); - } - } - else - { - getLogger().severe("Failed to upload " + seed + ": " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); - } - } - else - { - getLogger().info("Uploaded " + seed + "!"); + getLogger().warning("Oops - Server rejected " + seed + " because it was already generated"); if (!outputFile.delete()) { getLogger().warning("Could not clean up " + seed); } } + else + { + getLogger().severe("Failed to upload " + seed + ": " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); + } } - catch (IOException e) + else { - e.printStackTrace(); - } - finally - { - getLogger().info("Finished generating world seed " + seed); + getLogger().info("Uploaded " + seed + "!"); + + if (!outputFile.delete()) + { + getLogger().warning("Could not clean up " + seed); + } } } - catch (Throwable t) + catch (IOException e) { - t.printStackTrace(); + getLogger().log(Level.SEVERE, "An error occurred while uploading " + seed + "!", e); } - System.exit(0); + finally + { + getLogger().info("Finished generating world seed " + seed); + } + + Bukkit.shutdown(); } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java index e79c8f261..3e5b66bc6 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java @@ -365,17 +365,19 @@ public abstract class UHC extends Game UtilPlayer.message(caller, F.main("Debug", "World info for " + targetWorld.getName())); UtilPlayer.message(caller, F.desc("Chunks", String.valueOf(chunks.length))); UtilPlayer.message(caller, F.desc("Entities", String.valueOf(targetWorld.getEntities().size()))); - UtilPlayer.message(caller, F.desc("Tile Entities", String.valueOf(Arrays.stream(chunks).map(Chunk::getTileEntities).map(Arrays::asList).flatMap(Collection::stream) - .count()))); + UtilPlayer.message(caller, F.desc("Tile Entities", String.valueOf(Arrays.stream(chunks).map(Chunk::getTileEntities).map(Arrays::asList).mapToLong(Collection::size).sum()))); UtilPlayer.message(caller, F.desc("View Distance", String.valueOf(nmsWorld.spigotConfig.viewDistance))); UtilPlayer.message(caller, F.desc("Unload queue size", String.valueOf(nmsWorld.chunkProviderServer.unloadQueue.size()))); try { - HashTreeSet m = (HashTreeSet) nmsWorld.getClass().getField("M").get(nmsWorld); + Field f = nmsWorld.getClass().getDeclaredField("M"); + f.setAccessible(true); + HashTreeSet m = (HashTreeSet) f.get(nmsWorld); + UtilPlayer.message(caller, F.desc("Pending tick", String.valueOf(m.size()))); } - catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) + catch (ReflectiveOperationException e) { e.printStackTrace(); } @@ -571,7 +573,7 @@ public abstract class UHC extends Game } } }); - registerDebugCommand(new DebugCommand("uhccallchunks", Rank.DEVELOPER) + registerDebugCommand(new DebugCommand("uhcallchunks", Rank.DEVELOPER) { @Override From a0e79d87a2f3a6a25c0a546545c303c527cb047e Mon Sep 17 00:00:00 2001 From: samczsun Date: Mon, 20 Feb 2017 21:52:19 -0500 Subject: [PATCH 17/18] Allow ops to use minecraft commands --- Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java b/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java index 0feeae737..71f36d24d 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java @@ -147,8 +147,11 @@ public class Chat extends MiniPlugin || event.getMessage().toLowerCase().startsWith("/bukkit") || event.getMessage().toLowerCase().startsWith("/minecraft")) { - event.getPlayer().sendMessage(F.main(getName(), "Nope, not allowed!")); - event.setCancelled(true); + if (!event.getPlayer().isOp()) + { + event.getPlayer().sendMessage(F.main(getName(), "Nope, not allowed!")); + event.setCancelled(true); + } } } From d072fc3c21b1373380164dce5b95ba20edb8107a Mon Sep 17 00:00:00 2001 From: samczsun Date: Mon, 27 Feb 2017 21:42:30 -0500 Subject: [PATCH 18/18] Direct upload --- .../Nautilus.Game.Arcade.UHC.WorldGen/pom.xml | 10 ---- .../nautilus/game/arcade/uhc/WorldGen.java | 50 ++++++------------- 2 files changed, 14 insertions(+), 46 deletions(-) diff --git a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml index 2c02322e7..52ebd07c0 100644 --- a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml +++ b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/pom.xml @@ -24,15 +24,5 @@ zt-zip 1.9 - - org.apache.httpcomponents - httpclient - 4.5.2 - - - org.slf4j - slf4j-simple - 1.7.21 - diff --git a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java index 812b1f45a..24d2483e7 100644 --- a/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java +++ b/Plugins/Nautilus.Game.Arcade.UHC.WorldGen/src/nautilus/game/arcade/uhc/WorldGen.java @@ -1,27 +1,21 @@ package nautilus.game.arcade.uhc; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; +import java.net.HttpURLConnection; +import java.net.URL; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ThreadLocalRandom; -import java.util.concurrent.TimeUnit; import java.util.logging.Level; import net.minecraft.server.v1_8_R3.BiomeBase; import org.apache.commons.io.FileUtils; -import org.apache.http.HttpResponse; -import org.apache.http.client.config.RequestConfig; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClientBuilder; -import org.apache.http.message.BasicHeader; -import org.apache.http.protocol.HTTP; import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.Difficulty; @@ -42,14 +36,10 @@ import org.zeroturnaround.zip.ByteSource; import org.zeroturnaround.zip.FileSource; import org.zeroturnaround.zip.ZipEntrySource; import org.zeroturnaround.zip.ZipUtil; - -import com.google.gson.Gson; -import com.google.gson.JsonObject; +import org.zeroturnaround.zip.commons.IOUtils; public class WorldGen extends JavaPlugin implements Listener { - private static final int TIMEOUT = (int) TimeUnit.SECONDS.toMillis(10); - // The world will be -MAP_SIZE to MAP_SIZE large private static final int MAP_SIZE = 1000; private static final int VIEW_DISTANCE = 5; @@ -295,32 +285,20 @@ public class WorldGen extends JavaPlugin implements Listener FileUtils.deleteQuietly(worldFolder); - RequestConfig config = RequestConfig.custom() - .setConnectTimeout(TIMEOUT) - .setSocketTimeout(TIMEOUT) - .build(); - - CloseableHttpClient httpClient = HttpClientBuilder.create() - .setDefaultRequestConfig(config) - .build(); - - HttpPost request = new HttpPost("http://" + API_HOST_MAP.get("ENDERCHEST") + "/map/uhc/upload"); - request.addHeader(new BasicHeader(HTTP.CONTENT_TYPE, "application/json")); - - JsonObject jsonObject = new JsonObject(); - jsonObject.addProperty("name", outputFile.getName()); - jsonObject.addProperty("location", outputFile.toURI().toString()); - - request.setEntity(new StringEntity(new Gson().toJson(jsonObject), StandardCharsets.UTF_8)); - try { getLogger().info("Uploading " + seed + "!"); - HttpResponse response = httpClient.execute(request); - if (response.getStatusLine().getStatusCode() != 200) + URL url = new URL("http://" + API_HOST_MAP.get("ENDERCHEST") + "/map/uhc/upload?name=" + outputFile.getName()); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("POST"); + connection.setDoOutput(true); + IOUtils.copy(new FileInputStream(outputFile), connection.getOutputStream()); + connection.connect(); + + if (connection.getResponseCode() != 200) { - if (response.getStatusLine().getStatusCode() == 409) + if (connection.getResponseCode() == 409) { getLogger().warning("Oops - Server rejected " + seed + " because it was already generated"); @@ -331,7 +309,7 @@ public class WorldGen extends JavaPlugin implements Listener } else { - getLogger().severe("Failed to upload " + seed + ": " + response.getStatusLine().getStatusCode() + " " + response.getStatusLine().getReasonPhrase()); + getLogger().severe("Failed to upload " + seed + ": " + connection.getResponseCode() + " " + connection.getResponseMessage()); } } else