Commit e0cb1911 authored by Fabian Faßbender's avatar Fabian Faßbender
Browse files

Merge pull request #2 from leMaik/remotedynmap

Looks pretty nice. I like the fact that you are able to receive Files from other Endpoints instead from the Local Filesystem. 
parents 9e262d2f 4db76b07
......@@ -97,11 +97,8 @@
<repositories>
<repository>
<id>cubespace</id>
<url>http://nexus.cube-space.net/content/groups/public/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<id>md_5-releases</id>
<url>http://repo.md-5.net/content/repositories/snapshots/</url>
</repository>
</repositories>
......@@ -154,7 +151,7 @@
<dependency>
<groupId>net.cubespace</groupId>
<artifactId>Yamler-Core</artifactId>
<version>1.2.6-SNAPSHOT</version>
<version>2.3.1-20150720.092759-2</version>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package net.cubespace.dynmap.multiserver;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.cubespace.dynmap.multiserver.Config.Dynmap;
import net.cubespace.dynmap.multiserver.GSON.*;
import net.cubespace.dynmap.multiserver.util.AbstractFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.util.*;
/**
* @author geNAZt (fabian.fassbender42@googlemail.com)
*/
public abstract class AbstractDynmapServer implements DynmapServer {
static Logger logger = LoggerFactory.getLogger(AbstractDynmapServer.class);
private final Integer updateInterval;
private final Gson gson = new Gson();
private DynmapConfig dynmapConfig;
//This dynmaps worlds
private HashMap<String, DynmapWorldConfig> dynmapWorldConfigs = new HashMap<>();
private ArrayList<String> alreadyPlayers = new ArrayList<>();
private List<Player> players = new ArrayList<>();
private AbstractFile dynmapConfigFile;
private class DynmapServerUpdater extends Thread {
private int updateInterval;
public DynmapServerUpdater(Integer updateInterval) {
this.updateInterval = updateInterval;
setName("DynmaServerUpdater-" + dynmapConfig.getTitle());
}
public void run() {
while (true) {
try {
loadWorlds();
} catch (DynmapInitException e) {
logger.warn("Error in getting new Worlds", e);
}
players = new ArrayList<>();
alreadyPlayers = new ArrayList<>();
for (Map.Entry<String, DynmapWorldConfig> dynmapWorldConfig : new HashMap<>(dynmapWorldConfigs).entrySet()) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(getFile("standalone" + File.separator + "dynmap_" + dynmapWorldConfig.getKey() + ".json").getInputStream()))) {
dynmapWorldConfig.setValue(gson.fromJson(reader, DynmapWorldConfig.class));
dynmapWorldConfigs.put(dynmapWorldConfig.getKey(), dynmapWorldConfig.getValue());
for (Player player : dynmapWorldConfig.getValue().getPlayers()) {
if (!alreadyPlayers.contains(player.getName())) {
alreadyPlayers.add(player.getName());
players.add(player);
}
}
} catch (FileNotFoundException e) {
logger.warn("Could not update Dynmap World", e);
} catch (IOException e) {
logger.warn("Could not update Dynmap World", e);
}
}
try {
Thread.sleep(updateInterval * 1000);
} catch (InterruptedException e) {
logger.warn("Interrupted", e);
return;
}
}
}
}
public AbstractDynmapServer(Dynmap config) {
updateInterval = config.UpdateInterval;
}
@Override
public void initialize() throws DynmapInitException {
//Check if the installation is correct
preCheck();
//Read the Dynmap config
readDynmapConfig();
//Check if all Worlds in the Config are there
loadWorlds();
DynmapServerUpdater dynmapServerUpdater = new DynmapServerUpdater(updateInterval);
dynmapServerUpdater.start();
}
private void loadWorlds() throws DynmapInitException {
for (DynmapWorld world : dynmapConfig.getWorlds()) {
logger.info("Checking World " + world.getName());
AbstractFile dynmapWorldConfig = null;
try {
dynmapWorldConfig = getFile("standalone/dynmap_" + world.getName() + ".json");
} catch (IOException e) {
throw new DynmapInitException(e);
}
if (!dynmapWorldConfig.exists()) {
throw new DynmapInitException("World " + world.getName() + " has no config in Dynmap");
}
if (!dynmapWorldConfigs.containsKey(world.getName())) {
try (BufferedReader reader = new BufferedReader(new InputStreamReader(dynmapWorldConfig.getInputStream()))) {
DynmapWorldConfig dynmapWorldConfig1 = gson.fromJson(reader, DynmapWorldConfig.class);
dynmapWorldConfigs.put(world.getName(), dynmapWorldConfig1);
logger.info("Loaded World " + world.getName());
} catch (FileNotFoundException e) {
logger.error("Error in reading in the Worldfile", e);
} catch (IOException e) {
logger.error("Error in closing in the Worldfile", e);
}
}
}
}
private void readDynmapConfig() throws DynmapInitException {
try (BufferedReader reader = new BufferedReader(new InputStreamReader((dynmapConfigFile.getInputStream())))) {
Gson gsonDymapConfig = new GsonBuilder().registerTypeAdapter(Component.class, new ComponentDeserializer()).create();
dynmapConfig = gsonDymapConfig.fromJson(reader, DynmapConfig.class);
Main.updateCoreVersion(dynmapConfig.getCoreversion());
Main.updateDynmapVersion(dynmapConfig.getDynmapversion());
} catch (IOException e) {
throw new DynmapInitException("Could not parse dynmap_config.json", e);
}
}
private void preCheck() throws DynmapInitException {
/**
* The Dynmap must contain:
* standalone/dynmap_config.json
*/
try {
dynmapConfigFile = getFile("standalone/dynmap_config.json");
} catch (IOException e) {
throw new DynmapInitException(e);
}
if (!dynmapConfigFile.exists()) {
try {
Thread.sleep(200);
if (!dynmapConfigFile.exists()) {
throw new DynmapInitException("dynmap_config.json in the standalone Folder is missing. Be sure you started the Dynmap");
}
} catch (InterruptedException e) {
throw new DynmapInitException("dynmap_config.json in the standalone Folder is missing. Be sure you started the Dynmap");
}
}
}
@Override
public Collection<DynmapWorld> getWorlds() {
return dynmapConfig.getWorlds();
}
@Override
public DynmapWorldConfig getWorldConfig(String name) {
return dynmapWorldConfigs.get(name);
}
@Override
public DynmapConfig getDynmapConfig() {
return dynmapConfig;
}
public Collection<Component> getComponents() {
return dynmapConfig.getComponents();
}
public Collection<Player> getPlayers() {
return players;
}
}
......@@ -8,5 +8,6 @@ import net.cubespace.Yamler.Config.Config;
*/
public class Dynmap extends Config {
public String Folder = "test";
public String Url = "";
public Integer UpdateInterval = 1;
}
package net.cubespace.dynmap.multiserver;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import net.cubespace.dynmap.multiserver.Config.Dynmap;
import net.cubespace.dynmap.multiserver.GSON.Component;
import net.cubespace.dynmap.multiserver.GSON.ComponentDeserializer;
import net.cubespace.dynmap.multiserver.GSON.DynmapConfig;
import net.cubespace.dynmap.multiserver.GSON.DynmapWorld;
import net.cubespace.dynmap.multiserver.GSON.DynmapWorldConfig;
import net.cubespace.dynmap.multiserver.GSON.Player;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.cubespace.dynmap.multiserver.GSON.*;
import net.cubespace.dynmap.multiserver.util.AbstractFile;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Collection;
import static net.cubespace.dynmap.multiserver.Lib.Util.Concat.concat;
public interface DynmapServer {
void initialize() throws DynmapInitException;
/**
* @author geNAZt (fabian.fassbender42@googlemail.com)
*/
public class DynmapServer {
static Logger logger = LoggerFactory.getLogger(DynmapServer.class);
Collection<DynmapWorld> getWorlds();
private Gson gson = new Gson();
DynmapWorldConfig getWorldConfig(String name);
private DynmapConfig dynmapConfig;
DynmapConfig getDynmapConfig();
//This dynmaps worlds
private HashMap<String, DynmapWorldConfig> dynmapWorldConfigs = new HashMap<>();
Collection<Component> getComponents();
//Dynmap Files
private File dynmapConfigFile;
Collection<Player> getPlayers();
//Some Dynmap config things
private File file;
private ArrayList<String> alreadyPlayers = new ArrayList<>();
private Player[] players = new Player[0];
private class DynmapServerUpdater extends Thread {
private int updateInterval;
public DynmapServerUpdater(Integer updateInterval) {
this.updateInterval = updateInterval;
setName("DynmaServerUpdater-" + dynmapConfig.getTitle());
}
public void run() {
while(true) {
try {
loadWorlds();
} catch (DynmapInitException e) {
logger.warn("Error in getting new Worlds", e);
}
players = new Player[0];
alreadyPlayers = new ArrayList<>();
for(Map.Entry<String, DynmapWorldConfig> dynmapWorldConfig : new HashMap<>(dynmapWorldConfigs).entrySet()) {
File dynmapWorldConfigFile = new File(file, "standalone" + File.separator + "dynmap_" + dynmapWorldConfig.getKey() + ".json");
try(FileReader fileReader = new FileReader(dynmapWorldConfigFile)) {
dynmapWorldConfig.setValue(gson.fromJson(fileReader, DynmapWorldConfig.class));
dynmapWorldConfigs.put(dynmapWorldConfig.getKey(), dynmapWorldConfig.getValue());
for(Player player : dynmapWorldConfig.getValue().getPlayers()) {
if(!alreadyPlayers.contains(player.getName())) {
alreadyPlayers.add(player.getName());
players = concat(players, new Player[]{player});
}
}
} catch (FileNotFoundException e) {
logger.warn("Could not update Dynmap World", e);
} catch (IOException e) {
logger.warn("Could not update Dynmap World", e);
}
}
try {
Thread.sleep(updateInterval * 1000);
} catch (InterruptedException e) {
}
}
}
}
public DynmapServer(Dynmap config) throws DynmapInitException {
this.file = new File(config.Folder);
//Check if the installation is correct
preCheck();
//Read the Dynmap config
readDynmapConfig();
//Check if all Worlds in the Config are there
loadWorlds();
DynmapServerUpdater dynmapServerUpdater = new DynmapServerUpdater(config.UpdateInterval);
dynmapServerUpdater.start();
}
private void loadWorlds() throws DynmapInitException {
for(DynmapWorld world : dynmapConfig.getWorlds()) {
logger.info("Checking World " + world.getName());
File dynmapWorldConfig = new File(file, "standalone" + File.separator + "dynmap_" + world.getName() + ".json");
if(!dynmapWorldConfig.exists()) {
throw new DynmapInitException("World " + world.getName() + " has no config in Dynmap");
}
if(!dynmapWorldConfigs.containsKey(world.getName())) {
try(FileReader fileReader = new FileReader(dynmapWorldConfig)) {
DynmapWorldConfig dynmapWorldConfig1 = gson.fromJson(fileReader, DynmapWorldConfig.class);
dynmapWorldConfigs.put(world.getName(), dynmapWorldConfig1);
logger.info("Loaded World " + world.getName());
} catch (FileNotFoundException e) {
logger.error("Error in reading in the Worldfile", e);
} catch (IOException e) {
logger.error("Error in closing in the Worldfile", e);
}
}
}
}
private void readDynmapConfig() throws DynmapInitException {
try(FileReader fileReader = new FileReader(dynmapConfigFile)) {
Gson gsonDymapConfig = new GsonBuilder().registerTypeAdapter(Component.class, new ComponentDeserializer()).create();
dynmapConfig = gsonDymapConfig.fromJson(fileReader, DynmapConfig.class);
Main.updateCoreVersion(dynmapConfig.getCoreversion());
Main.updateDynmapVersion(dynmapConfig.getDynmapversion());
} catch (IOException e) {
throw new DynmapInitException("Could not parse dynmap_config.json", e);
}
}
private void preCheck() throws DynmapInitException {
/**
* The Dynmap must contain:
* standalone/dynmap_config.json
*/
dynmapConfigFile = new File(file, "standalone" + File.separator + "dynmap_config.json");
if(!dynmapConfigFile.exists()) {
try {
Thread.sleep(200);
if(!dynmapConfigFile.exists()) {
throw new DynmapInitException("dynmap_config.json in the standalone Folder is missing. Be sure you started the Dynmap");
}
} catch (InterruptedException e) {
throw new DynmapInitException("dynmap_config.json in the standalone Folder is missing. Be sure you started the Dynmap");
}
}
}
public DynmapWorld[] getWorlds() {
return dynmapConfig.getWorlds();
}
public DynmapWorldConfig getWorldConfig(String name) {
return dynmapWorldConfigs.get(name);
}
public File getFolder() {
return file;
}
public Component[] getComponents() {
return dynmapConfig.getComponents();
}
public Player[] getPlayers() {
return players;
}
AbstractFile getFile(String path) throws IOException;
}
......@@ -2,6 +2,9 @@ package net.cubespace.dynmap.multiserver.GSON;
import com.google.gson.annotations.SerializedName;
import java.util.ArrayList;
import java.util.List;
/**
* @author geNAZt (fabian.fassbender42@googlemail.com)
*/
......@@ -15,7 +18,7 @@ public class DynmapConfig {
private Boolean webacht_requires_login = false;
private String quitmessage = "%playername% quit";
private Integer confighash;
private DynmapWorld[] worlds = new DynmapWorld[0];
private List<DynmapWorld> worlds = new ArrayList<>();
private String showlayercontrol = "true";
private String title = "Awesome Multiserver Dynmap";
private String defaultmap;
......@@ -44,7 +47,7 @@ public class DynmapConfig {
@SerializedName("webchat-interval")
private Integer webchat_interval = 5;
private Boolean allowwebchat = false;
private Component[] components = new Component[0];
private List<Component> components = new ArrayList<>();
@SerializedName("msg-chatrequireslogin")
private String msg_chatrequireslogin = "Chat requires login";
@SerializedName("msg-hiddennamequit")
......@@ -74,7 +77,7 @@ public class DynmapConfig {
return confighash;
}
public DynmapWorld[] getWorlds() {
public List<DynmapWorld> getWorlds() {
return worlds;
}
......@@ -174,7 +177,7 @@ public class DynmapConfig {
return allowwebchat;
}
public Component[] getComponents() {
public List<Component> getComponents() {
return components;
}
......@@ -210,7 +213,7 @@ public class DynmapConfig {
this.confighash = confighash;
}
public void setWorlds(DynmapWorld[] worlds) {
public void setWorlds(List<DynmapWorld> worlds) {
this.worlds = worlds;
}
......@@ -310,7 +313,7 @@ public class DynmapConfig {
this.allowwebchat = allowwebchat;
}
public void setComponents(Component[] components) {
public void setComponents(List<Component> components) {
this.components = components;
}
......
package net.cubespace.dynmap.multiserver.GSON;
import java.util.List;
/**
* @author geNAZt (fabian.fassbender42@googlemail.com)
*/
......@@ -10,7 +12,7 @@ public class DynmapWorldConfig {
private Boolean isThundering;
private Integer servertime;
private Integer currentcount;
private Player[] players;
private List<Player> players;
private Integer confighash;
public Long getTimestamp() {
......@@ -37,7 +39,7 @@ public class DynmapWorldConfig {
return currentcount;
}
public Player[] getPlayers() {
public List<Player> getPlayers() {
return players;
}
......@@ -69,7 +71,7 @@ public class DynmapWorldConfig {
this.currentcount = currentcount;
}
public void setPlayers(Player[] players) {
public void setPlayers(List<Player> players) {
this.players = players;
}
......
......@@ -20,15 +20,12 @@ import org.slf4j.LoggerFactory;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONNECTION;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_LENGTH;
import static io.netty.handler.codec.http.HttpHeaders.Names.CONTENT_TYPE;
import static io.netty.handler.codec.http.HttpHeaders.Names.IF_MODIFIED_SINCE;
import static io.netty.handler.codec.http.HttpHeaders.Names.*;
import static io.netty.handler.codec.http.HttpResponseStatus.OK;
import static io.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import static net.cubespace.dynmap.multiserver.Lib.Util.Concat.concat;
/**
* @author geNAZt (fabian.fassbender42@googlemail.com)
......@@ -49,7 +46,7 @@ public class DynmapConfigJSONHandler implements IHandler {
}
public void run() {
while(true) {
while (true) {
try {
updateJson();
Thread.sleep(1000);
......@@ -61,9 +58,9 @@ public class DynmapConfigJSONHandler implements IHandler {
}
public DynmapConfigJSONHandler(Main mainConfig) {
if(gson == null) gson = new Gson();
if (gson == null) gson = new Gson();
if(config == null) {
if (config == null) {
config = new DynmapConfig();
config.setDefaultmap("flat");
config.setDefaultworld("world");
......@@ -73,9 +70,9 @@ public class DynmapConfigJSONHandler implements IHandler {
responseStr = gson.toJson(config);
}
if(start == 0) start = System.currentTimeMillis();
if (start == 0) start = System.currentTimeMillis();
if(dynmapConfigJSONUpdater == null) {
if (dynmapConfigJSONUpdater == null) {
dynmapConfigJSONUpdater = new DynmapConfigJSONUpdater();
dynmapConfigJSONUpdater.start();
}
......@@ -83,23 +80,22 @@ public class DynmapConfigJSONHandler implements IHandler {
private void updateJson() {
//Worlds
DynmapWorld[] dynmapWorlds = new DynmapWorld[0];
Component[] components = new Component[0];
List<DynmapWorld> dynmapWorlds = new ArrayList<>();
List<Component> components = new ArrayList<>();
ArrayList<String> addedComponents = new ArrayList<>();
config.setConfighash(0);
String temp = gson.toJson(config);
for(DynmapServer dynmapServer : net.cubespace.dynmap.multiserver.Main.getDynmapServers()) {
dynmapWorlds = concat(dynmapWorlds, dynmapServer.getWorlds());
for (DynmapServer dynmapServer : net.cubespace.dynmap.multiserver.Main.getDynmapServers()) {
dynmapWorlds.addAll(dynmapServer.getWorlds());
for(Component component : dynmapServer.getComponents()) {
if(component != null) {