This commit is contained in:
samczsun 2017-02-19 16:52:34 -05:00 committed by cnr
parent dedcd254b0
commit f8dbbce106
2 changed files with 238 additions and 215 deletions

View File

@ -19,16 +19,16 @@
<version>1.8.8-1.9-SNAPSHOT</version> <version>1.8.8-1.9-SNAPSHOT</version>
<scope>compile</scope> <scope>compile</scope>
</dependency> </dependency>
<dependency>
<groupId>com.mineplex</groupId>
<artifactId>mineplex-core</artifactId>
<version>dev-SNAPSHOT</version>
</dependency>
<dependency> <dependency>
<groupId>org.zeroturnaround</groupId> <groupId>org.zeroturnaround</groupId>
<artifactId>zt-zip</artifactId> <artifactId>zt-zip</artifactId>
<version>1.9</version> <version>1.9</version>
</dependency> </dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId> <artifactId>slf4j-simple</artifactId>

View File

@ -7,7 +7,9 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.logging.Level; import java.util.logging.Level;
@ -28,20 +30,16 @@ import org.bukkit.Bukkit;
import org.bukkit.Difficulty; import org.bukkit.Difficulty;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.WorldCreator; import org.bukkit.WorldCreator;
import org.bukkit.event.EventHandler; import org.bukkit.configuration.file.YamlConfiguration;
import org.bukkit.event.Listener;
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.spigotmc.WatchdogThread; import org.spigotmc.WatchdogThread;
import org.zeroturnaround.zip.ZipEntrySource; import org.zeroturnaround.zip.ZipEntrySource;
import org.zeroturnaround.zip.ZipUtil; import org.zeroturnaround.zip.ZipUtil;
import com.google.gson.Gson;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import mineplex.core.common.Constants; public class WorldGen extends JavaPlugin
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 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 MAX_Z = 1000;
private static final int VIEW_DISTANCE = 5; private static final int VIEW_DISTANCE = 5;
private static final String API_HOST_FILE = "api-config.dat";
private static final Map<String, String> 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 @Override
public void onEnable() public void onEnable()
{ {
@ -61,161 +88,127 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener
WatchdogThread.doStop(); 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 try
{ {
if (!outputFile.createNewFile()) File root = new File(".");
if (!root.exists())
{ {
getLogger().severe("Could not create new output file. Aborting"); getLogger().severe("Root folder does not exist. Aborting");
getServer().shutdown(); System.exit(0);
return; 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); File outputDirectory = new File(root, "output");
if (!outputDirectory.exists())
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); if (!outputDirectory.mkdir())
} {
} getLogger().severe("Could not create output folder. Aborting");
System.exit(0);
for (int x = minChunkX; x <= maxChunkX; x++) return;
{ }
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<ZipEntrySource> zipEntrySourceList = new ArrayList<>();
zipEntrySourceList.add(new ZipEntrySource()
{
@Override
public String getPath()
{
return "WorldConfig.dat";
} }
@Override long seed = ThreadLocalRandom.current().nextLong();
public ZipEntry getEntry()
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 try
public InputStream getInputStream() throws IOException
{ {
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<ZipEntrySource> zipEntrySourceList = new ArrayList<>();
zipEntrySourceList.add(new ZipEntrySource() zipEntrySourceList.add(new ZipEntrySource()
{ {
@Override @Override
public String getPath() public String getPath()
{ {
return "region/" + file.getName(); return "WorldConfig.dat";
} }
@Override @Override
@ -227,92 +220,122 @@ public class WorldGen extends JavaPlugin implements Runnable, Listener
@Override @Override
public InputStream getInputStream() throws IOException public InputStream getInputStream() throws IOException
{ {
return new FileInputStream(file); return new ByteArrayInputStream(worldconfig.toString().getBytes(StandardCharsets.UTF_8));
} }
}); });
}
zipEntrySourceList.add(new ZipEntrySource()
{ for (File file : regionFiles)
@Override
public String getPath()
{ {
return "level.dat"; zipEntrySourceList.add(new ZipEntrySource()
}
@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)
{ {
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()) if (!outputFile.delete())
{ {
getLogger().warning("Could not clean up " + seed); 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 + "!"); e.printStackTrace();
}
if (!outputFile.delete()) finally
{ {
getLogger().warning("Could not clean up " + seed); getLogger().info("Finished generating world seed " + seed);
}
} }
} }
catch (IOException e) catch (Throwable t)
{ {
e.printStackTrace(); t.printStackTrace();
}
finally
{
getLogger().info("Finished generating world seed " + seed);
} }
System.exit(0);
} }
} }