mirror of
https://github.com/BlueMap-Minecraft/BlueMap.git
synced 2024-11-26 04:25:31 +01:00
Merge branch 'base' into mc/1.15
This commit is contained in:
commit
dda6b71f5a
@ -10,7 +10,8 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
shadow "org.bukkit:bukkit:1.15.2-R0.1-SNAPSHOT"
|
||||
compile group: 'org.bstats', name: 'bstats-bukkit-lite', version: '1.5'
|
||||
|
||||
compile group: 'org.bstats', name: 'bstats-bukkit-lite', version: '1.7'
|
||||
|
||||
compile (project(':BlueMapCommon')) {
|
||||
//exclude dependencies provided by bukkit
|
||||
|
@ -86,7 +86,9 @@ public void onTabComplete(TabCompleteEvent evt) {
|
||||
completions.sort((s1, s2) -> s1.compareToIgnoreCase(s2));
|
||||
evt.setCompletions(completions);
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException ignore) {}
|
||||
} catch (InterruptedException ignore) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (ExecutionException | TimeoutException ignore) {}
|
||||
}
|
||||
|
||||
private class CommandProxy extends BukkitCommand {
|
||||
|
@ -56,12 +56,13 @@
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
|
||||
|
||||
public class BukkitPlugin extends JavaPlugin implements ServerInterface, Listener {
|
||||
|
||||
private static BukkitPlugin instance;
|
||||
|
||||
private Plugin bluemap;
|
||||
private Plugin pluginInstance;
|
||||
private EventForwarder eventForwarder;
|
||||
private BukkitCommands commands;
|
||||
|
||||
@ -76,15 +77,15 @@ public BukkitPlugin() {
|
||||
this.onlinePlayerList = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
this.eventForwarder = new EventForwarder();
|
||||
this.bluemap = new Plugin("bukkit", this);
|
||||
this.commands = new BukkitCommands(this.bluemap);
|
||||
this.pluginInstance = new Plugin("bukkit", this);
|
||||
this.commands = new BukkitCommands(this.pluginInstance);
|
||||
|
||||
BukkitPlugin.instance = this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEnable() {
|
||||
new MetricsLite(this);
|
||||
new MetricsLite(this, 5912);
|
||||
|
||||
//save world so the level.dat is present on new worlds
|
||||
Logger.global.logInfo("Saving all worlds once, to make sure the level.dat is present...");
|
||||
@ -113,6 +114,15 @@ public void onEnable() {
|
||||
//tab completions
|
||||
getServer().getPluginManager().registerEvents(commands, this);
|
||||
|
||||
//update online-player collections
|
||||
this.onlinePlayerList.clear();
|
||||
this.onlinePlayerMap.clear();
|
||||
for (org.bukkit.entity.Player player : getServer().getOnlinePlayers()) {
|
||||
BukkitPlayer bukkitPlayer = new BukkitPlayer(player);
|
||||
onlinePlayerMap.put(player.getUniqueId(), bukkitPlayer);
|
||||
onlinePlayerList.add(bukkitPlayer);
|
||||
}
|
||||
|
||||
//start updating players
|
||||
getServer().getScheduler().runTaskTimer(this, this::updateSomePlayers, 1, 1);
|
||||
|
||||
@ -120,10 +130,11 @@ public void onEnable() {
|
||||
getServer().getScheduler().runTaskAsynchronously(this, () -> {
|
||||
try {
|
||||
Logger.global.logInfo("Loading...");
|
||||
this.bluemap.load();
|
||||
if (bluemap.isLoaded()) Logger.global.logInfo("Loaded!");
|
||||
} catch (Throwable t) {
|
||||
Logger.global.logError("Failed to load!", t);
|
||||
this.pluginInstance.load();
|
||||
if (pluginInstance.isLoaded()) Logger.global.logInfo("Loaded!");
|
||||
} catch (IOException | ParseResourceException | RuntimeException e) {
|
||||
Logger.global.logError("Failed to load!", e);
|
||||
this.pluginInstance.unload();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -132,7 +143,7 @@ public void onEnable() {
|
||||
public void onDisable() {
|
||||
Logger.global.logInfo("Stopping...");
|
||||
getServer().getScheduler().cancelTasks(this);
|
||||
bluemap.unload();
|
||||
pluginInstance.unload();
|
||||
Logger.global.logInfo("Saved and stopped!");
|
||||
}
|
||||
|
||||
@ -165,6 +176,7 @@ public UUID getUUIDForWorld(File worldFolder) throws IOException {
|
||||
try {
|
||||
return futureUUID.get();
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException(e);
|
||||
} catch (ExecutionException e) {
|
||||
if (e.getCause() instanceof IOException) {
|
||||
@ -197,7 +209,7 @@ public File getConfigFolder() {
|
||||
}
|
||||
|
||||
public Plugin getBlueMap() {
|
||||
return bluemap;
|
||||
return pluginInstance;
|
||||
}
|
||||
|
||||
public static BukkitPlugin getInstance() {
|
||||
|
@ -222,7 +222,7 @@ public void renderMaps() throws IOException {
|
||||
while(renderManager.getRenderTaskCount() != 0) {
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException e) {}
|
||||
} catch (InterruptedException e) { Thread.currentThread().interrupt(); return; }
|
||||
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
@ -390,7 +390,7 @@ public static void main(String[] args) throws IOException, ParseResourceExceptio
|
||||
//wait a second to let the webserver start, looks nicer in the log
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ignore) {}
|
||||
} catch (InterruptedException ignore) { Thread.currentThread().interrupt(); }
|
||||
}
|
||||
|
||||
|
||||
@ -452,7 +452,7 @@ private static void printHelp() {
|
||||
filename = file.getAbsolutePath();
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {}
|
||||
} catch (IOException ex) {}
|
||||
|
||||
String command = "java -jar " + filename;
|
||||
|
||||
|
@ -75,7 +75,6 @@ public synchronized void stop() {
|
||||
for (int i = 0; i < renderThreads.length; i++) {
|
||||
if (renderThreads[i] != null) {
|
||||
renderThreads[i].interrupt();
|
||||
renderThreads[i] = null;
|
||||
}
|
||||
}
|
||||
|
||||
@ -141,7 +140,7 @@ public boolean removeRenderTask(RenderTask renderTask) {
|
||||
private void renderThread() {
|
||||
RenderTicket ticket = null;
|
||||
|
||||
while (!Thread.interrupted() && running) {
|
||||
while (running) {
|
||||
synchronized (renderTickets) {
|
||||
ticket = renderTickets.poll();
|
||||
if (ticket != null) renderTicketMap.remove(ticket);
|
||||
@ -163,17 +162,22 @@ private void renderThread() {
|
||||
if (ticket != null) {
|
||||
try {
|
||||
ticket.render();
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException e) {
|
||||
//catch possible runtime exceptions, display them, and wait a while .. then resurrect this render-thread
|
||||
Logger.global.logError("Unexpected exception in render-thread!", e);
|
||||
try {
|
||||
Thread.sleep(10000);
|
||||
} catch (InterruptedException interrupt) { break; }
|
||||
} catch (InterruptedException interrupt) { Thread.currentThread().interrupt(); break; }
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
Thread.sleep(1000); // we don't need a super fast response time, so waiting a second is totally fine
|
||||
} catch (InterruptedException interrupt) { break; }
|
||||
} catch (InterruptedException interrupt) { Thread.currentThread().interrupt(); break; }
|
||||
}
|
||||
|
||||
if (Thread.interrupted()) {
|
||||
Thread.currentThread().interrupt();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ public void onWorldSaveToDisk(final UUID world) {
|
||||
}
|
||||
|
||||
}
|
||||
} catch (InterruptedException ignore) {}
|
||||
} catch (InterruptedException ignore) { Thread.currentThread().interrupt(); }
|
||||
|
||||
}).start();
|
||||
}
|
||||
|
@ -262,6 +262,7 @@ public synchronized void load() throws IOException, ParseResourceException {
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException ex){
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
});
|
||||
@ -316,6 +317,7 @@ public synchronized void load() throws IOException, ParseResourceException {
|
||||
Thread.sleep(TimeUnit.MINUTES.toMillis(30));
|
||||
}
|
||||
} catch (InterruptedException ex){
|
||||
Thread.currentThread().interrupt();
|
||||
return;
|
||||
}
|
||||
});
|
||||
@ -338,11 +340,19 @@ public synchronized void unload() {
|
||||
serverInterface.unregisterAllListeners();
|
||||
|
||||
//stop scheduled threads
|
||||
if (metricsThread != null) metricsThread.interrupt();
|
||||
metricsThread = null;
|
||||
if (metricsThread != null) {
|
||||
metricsThread.interrupt();
|
||||
try {metricsThread.join(1000);} catch (InterruptedException ignore) { Thread.currentThread().interrupt(); }
|
||||
if (metricsThread.isAlive()) Logger.global.logWarning("The metricsThread did not terminate correctly in time!");
|
||||
metricsThread = null;
|
||||
}
|
||||
|
||||
if (periodicalSaveThread != null) periodicalSaveThread.interrupt();
|
||||
periodicalSaveThread = null;
|
||||
if (periodicalSaveThread != null) {
|
||||
periodicalSaveThread.interrupt();
|
||||
try {periodicalSaveThread.join(1000);} catch (InterruptedException ignore) { Thread.currentThread().interrupt(); }
|
||||
if (periodicalSaveThread.isAlive()) Logger.global.logWarning("The periodicalSaveThread did not terminate correctly in time!");
|
||||
periodicalSaveThread = null;
|
||||
}
|
||||
|
||||
//stop services
|
||||
if (renderManager != null) renderManager.stop();
|
||||
|
@ -60,6 +60,7 @@
|
||||
import de.bluecolored.bluemap.core.mca.Chunk;
|
||||
import de.bluecolored.bluemap.core.mca.ChunkAnvil112;
|
||||
import de.bluecolored.bluemap.core.mca.MCAWorld;
|
||||
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
|
||||
import de.bluecolored.bluemap.core.world.Block;
|
||||
import de.bluecolored.bluemap.core.world.World;
|
||||
|
||||
@ -307,7 +308,7 @@ public int reloadCommand(CommandContext<S> context) {
|
||||
source.sendMessage(Text.of(TextColor.RED, "Could not load BlueMap! See the console for details!"));
|
||||
}
|
||||
|
||||
} catch (Exception ex) {
|
||||
} catch (IOException | ParseResourceException | RuntimeException ex) {
|
||||
Logger.global.logError("Failed to reload BlueMap!", ex);
|
||||
|
||||
source.sendMessage(Text.of(TextColor.RED, "There was an error reloading BlueMap! See the console for details!"));
|
||||
|
@ -73,7 +73,7 @@ public void update(File storageFolder) {
|
||||
Logger.global.logDebug("Failed to load player-skin from mojang-servers: " + e);
|
||||
} catch (IOException e) {
|
||||
Logger.global.logError("Failed to write player-head image!", e);
|
||||
} catch (InterruptedException ignore) {}
|
||||
} catch (InterruptedException ignore) { Thread.currentThread().interrupt(); }
|
||||
}).start();
|
||||
}
|
||||
|
||||
@ -87,7 +87,7 @@ public BufferedImage createHead(BufferedImage skinTexture) {
|
||||
Graphics2D g = head.createGraphics();
|
||||
g.drawImage(layer1, 0, 0, null);
|
||||
g.drawImage(layer2, 0, 0, null);
|
||||
} catch (Throwable t) { // There might be problems with headless servers when loading the graphics class
|
||||
} catch (Throwable t) { // There might be problems with headless servers when loading the graphics class, so we catch every exception and error on purpose here
|
||||
Logger.global.noFloodWarning("headless-graphics-fail",
|
||||
"Could not access Graphics2D to render player-skin texture. Try adding '-Djava.awt.headless=true' to your startup flags or ignore this warning.");
|
||||
|
||||
|
@ -142,15 +142,9 @@ private MCAWorld(
|
||||
}
|
||||
|
||||
public BlockState getBlockState(Vector3i pos) {
|
||||
try {
|
||||
|
||||
Vector2i chunkPos = blockToChunk(pos);
|
||||
Chunk chunk = getChunk(chunkPos);
|
||||
return chunk.getBlockState(pos);
|
||||
|
||||
} catch (Exception ex) {
|
||||
return BlockState.MISSING;
|
||||
}
|
||||
Vector2i chunkPos = blockToChunk(pos);
|
||||
Chunk chunk = getChunk(chunkPos);
|
||||
return chunk.getBlockState(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -200,22 +194,22 @@ public Chunk getChunk(Vector2i chunkPos) {
|
||||
Chunk chunk = CHUNK_CACHE.get(new WorldChunkHash(this, chunkPos), () -> this.loadChunkOrEmpty(chunkPos, 2, 1000));
|
||||
return chunk;
|
||||
} catch (UncheckedExecutionException | ExecutionException e) {
|
||||
if (e.getCause() instanceof InterruptedException) Thread.currentThread().interrupt();
|
||||
throw new RuntimeException(e.getCause());
|
||||
}
|
||||
}
|
||||
|
||||
private Chunk loadChunkOrEmpty(Vector2i chunkPos, int tries, long tryInterval) {
|
||||
private Chunk loadChunkOrEmpty(Vector2i chunkPos, int tries, long tryInterval) throws InterruptedException {
|
||||
Exception loadException = null;
|
||||
for (int i = 0; i < tries; i++) {
|
||||
try {
|
||||
return loadChunk(chunkPos);
|
||||
} catch (Exception e) {
|
||||
} catch (IOException | RuntimeException e) {
|
||||
if (loadException != null) e.addSuppressed(loadException);
|
||||
loadException = e;
|
||||
|
||||
if (tryInterval > 0 && i+1 < tries) {
|
||||
try {
|
||||
Thread.sleep(tryInterval);
|
||||
} catch (InterruptedException interrupt) {}
|
||||
Thread.sleep(tryInterval);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -261,7 +255,7 @@ private Chunk loadChunk(Vector2i chunkPos) throws IOException {
|
||||
} else {
|
||||
throw new IOException("Invalid data tag: " + (tag == null ? "null" : tag.getClass().getName()));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (RuntimeException | IOException e) {
|
||||
throw new IOException("Exception trying to load chunk (" + chunkPos + ")", e);
|
||||
}
|
||||
}
|
||||
@ -312,7 +306,7 @@ public Collection<Vector2i> getChunkList(long modifiedSinceMillis, Predicate<Vec
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
} catch (RuntimeException | IOException ex) {
|
||||
Logger.global.logWarning("Failed to read .mca file: " + file.getAbsolutePath() + " (" + ex.toString() + ")");
|
||||
}
|
||||
}
|
||||
|
@ -37,6 +37,7 @@
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import de.bluecolored.bluemap.core.BlueMap;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
|
||||
public class Metrics {
|
||||
|
||||
@ -53,7 +54,9 @@ public static void sendReport(String implementation) {
|
||||
|
||||
try {
|
||||
sendData(data.toString());
|
||||
} catch (Exception ex) {}
|
||||
} catch (IOException | RuntimeException ex) {
|
||||
Logger.global.logDebug("Failed to send Metrics-Report: " + ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static String sendData(String data) throws MalformedURLException, IOException {
|
||||
|
@ -37,6 +37,7 @@
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
@ -116,6 +117,9 @@ public void save(File file, boolean force, boolean useGzip) throws IOException {
|
||||
try {
|
||||
FileUtils.waitForFile(file, 10, TimeUnit.SECONDS);
|
||||
} catch (InterruptedException e) {
|
||||
Thread.currentThread().interrupt();
|
||||
throw new IOException("Failed to get write-access to file: " + file, e);
|
||||
} catch (TimeoutException e) {
|
||||
throw new IOException("Failed to get write-access to file: " + file, e);
|
||||
}
|
||||
|
||||
|
@ -189,8 +189,8 @@ public BlockStateResource build(String blockstateFile) throws IOException {
|
||||
variant.checkValid();
|
||||
|
||||
blockState.variants.add(variant);
|
||||
} catch (Throwable t) {
|
||||
Logger.global.logWarning("Failed to parse a variant of " + blockstateFile + ": " + t);
|
||||
} catch (ParseResourceException | RuntimeException e) {
|
||||
Logger.global.logWarning("Failed to parse a variant of " + blockstateFile + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -208,8 +208,8 @@ public BlockStateResource build(String blockstateFile) throws IOException {
|
||||
variant.checkValid();
|
||||
|
||||
blockState.multipart.add(variant);
|
||||
} catch (Throwable t) {
|
||||
Logger.global.logWarning("Failed to parse a multipart-part of " + blockstateFile + ": " + t);
|
||||
} catch (ParseResourceException | RuntimeException e) {
|
||||
Logger.global.logWarning("Failed to parse a multipart-part of " + blockstateFile + ": " + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -167,13 +167,13 @@ public synchronized void loadTextureFile(File file) throws IOException, ParseRes
|
||||
boolean transparent = texture.get("transparent").getAsBoolean();
|
||||
Vector4f color = readVector4f(texture.get("color").getAsJsonArray());
|
||||
textureList.set(i, new Texture(i, path, color, transparent, EMPTY_BASE64));
|
||||
} catch (Exception ex) {
|
||||
} catch (ParseResourceException | RuntimeException ex) {
|
||||
Logger.global.logWarning("Failed to load texture with id " + i + " from texture file " + file + "!");
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
throw ex;
|
||||
} catch (Exception ex) {
|
||||
} catch (RuntimeException ex) {
|
||||
throw new ParseResourceException("Invalid texture file format!", ex);
|
||||
} finally {
|
||||
regenerateMap();
|
||||
|
@ -29,6 +29,7 @@
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import com.flowpowered.math.vector.Vector2i;
|
||||
@ -63,14 +64,14 @@ public static File coordsToFile(Path root, Vector2i coords, String fileType){
|
||||
* Blocks until a file can be read and written.<br>
|
||||
* <i>(Do not use this method to sync file-access from different threads!)</i>
|
||||
*/
|
||||
public static void waitForFile(File file, long time, TimeUnit unit) throws InterruptedException {
|
||||
public static void waitForFile(File file, long time, TimeUnit unit) throws InterruptedException, TimeoutException {
|
||||
long start = System.currentTimeMillis();
|
||||
long timeout = start + TimeUnit.MILLISECONDS.convert(time, unit);
|
||||
long sleepTime = 1;
|
||||
while(!file.canWrite() || !file.canRead()){
|
||||
Thread.sleep(sleepTime);
|
||||
sleepTime = (long) Math.min(Math.ceil(sleepTime * 1.5), 1000);
|
||||
if (System.currentTimeMillis() > timeout) throw new InterruptedException();
|
||||
if (System.currentTimeMillis() > timeout) throw new TimeoutException();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -183,7 +183,7 @@ public static BlockState fromString(String serializedBlockState) throws IllegalA
|
||||
String blockId = m.group(1).trim();
|
||||
|
||||
return new BlockState(blockId, pt);
|
||||
} catch (Exception ex) {
|
||||
} catch (RuntimeException ex) {
|
||||
throw new IllegalArgumentException("'" + serializedBlockState + "' could not be parsed to a BlockState!");
|
||||
}
|
||||
}
|
||||
|
@ -206,18 +206,16 @@ export default class BlueMap {
|
||||
this.controls.direction = this.controls.targetDirection;
|
||||
this.controls.distance = this.controls.targetDistance;
|
||||
this.controls.angle = this.controls.targetAngle;
|
||||
this.controls.targetPosition.y = this.controls.minHeight;
|
||||
this.controls.position.copy(this.controls.targetPosition);
|
||||
}
|
||||
}
|
||||
if (hashVars.length >= 7){
|
||||
let height = parseInt(hashVars[6]);
|
||||
if (!isNaN(height)){
|
||||
this.controls.minHeight = height;
|
||||
this.controls.targetPosition.y = height;
|
||||
this.controls.terrainHeight = height;
|
||||
|
||||
if (!smooth) {
|
||||
this.controls.position.copy(this.controls.targetPosition);
|
||||
if (this.controls.position.y < this.controls.terrainHeight) this.controls.position.y = this.controls.terrainHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -257,7 +255,7 @@ export default class BlueMap {
|
||||
+ ':' + Math.round(this.controls.targetDirection * 100) / 100
|
||||
+ ':' + Math.round(this.controls.targetDistance * 100) / 100
|
||||
+ ':' + Math.ceil(this.controls.targetAngle * 100) / 100
|
||||
+ ':' + Math.floor(this.controls.targetPosition.y);
|
||||
+ ':' + Math.floor(this.controls.terrainHeight);
|
||||
// only update hash when changed
|
||||
if (window.location.hash !== this.locationHash) {
|
||||
history.replaceState(undefined, undefined, this.locationHash);
|
||||
|
@ -79,7 +79,7 @@ export default class Controls {
|
||||
this.camera = camera;
|
||||
this.element = element;
|
||||
this.heightScene = heightScene;
|
||||
this.minHeight = 0;
|
||||
this.terrainHeight = 70;
|
||||
|
||||
this.raycaster = new Raycaster();
|
||||
this.rayDirection = new Vector3(0, -1, 0);
|
||||
@ -159,8 +159,8 @@ export default class Controls {
|
||||
}
|
||||
|
||||
resetPosition() {
|
||||
this.position = new Vector3(0, 70, 0);
|
||||
this.targetPosition = new Vector3(0, 70, 0);
|
||||
this.position = new Vector3(0, 0, 0);
|
||||
this.targetPosition = new Vector3(0, 0, 0);
|
||||
|
||||
this.distance = 5000;
|
||||
this.targetDistance = 1000;
|
||||
@ -177,13 +177,10 @@ export default class Controls {
|
||||
|
||||
let changed = false;
|
||||
|
||||
let zoomLerp = (this.distance - 100) / 200;
|
||||
if (zoomLerp < 0) zoomLerp = 0;
|
||||
if (zoomLerp > 1) zoomLerp = 1;
|
||||
this.targetPosition.y = 300 * zoomLerp + this.minHeight * (1 - zoomLerp);
|
||||
let targetY = Math.max(this.targetPosition.y, this.terrainHeight);
|
||||
|
||||
this.position.x += (this.targetPosition.x - this.position.x) * this.settings.move.smooth;
|
||||
this.position.y += (this.targetPosition.y - this.position.y) * this.settings.move.smoothY;
|
||||
this.position.y += (targetY - this.position.y) * this.settings.move.smoothY;
|
||||
this.position.z += (this.targetPosition.z - this.position.z) * this.settings.move.smooth;
|
||||
|
||||
this.distance += (this.targetDistance - this.distance) * this.settings.zoom.smooth;
|
||||
@ -241,7 +238,7 @@ export default class Controls {
|
||||
let intersects = this.raycaster.intersectObjects(tileChildren(this.targetPosition));
|
||||
|
||||
if (intersects.length > 0) {
|
||||
this.minHeight = intersects[0].point.y;
|
||||
this.terrainHeight = intersects[0].point.y;
|
||||
}
|
||||
} catch (ignore){}
|
||||
|
||||
@ -251,8 +248,8 @@ export default class Controls {
|
||||
this.raycaster.set(rayStart, this.rayDirection);
|
||||
let intersects = this.raycaster.intersectObjects(tileChildren(this.camera.position));
|
||||
if (intersects.length > 0) {
|
||||
if (intersects[0].point.y > this.minHeight) {
|
||||
this.minHeight = intersects[0].point.y;
|
||||
if (intersects[0].point.y > this.terrainHeight) {
|
||||
this.terrainHeight = intersects[0].point.y;
|
||||
}
|
||||
}
|
||||
} catch (ignore){}
|
||||
|
@ -27,7 +27,7 @@ export default class PlayerMarker extends Marker {
|
||||
if (!this.renderObject){
|
||||
this.iconElement = $(`<div class="marker-player"><img src="assets/playerheads/${this.player}.png" onerror="this.onerror=null;this.src='${STEVE}';"><div class="nameplate">${this.label}</div></div>`);
|
||||
this.iconElement.find("img").click(this.onClick);
|
||||
$(window).on('mousedown touchstart', this.onStopFollowing);
|
||||
$(window).on('mousedown touchstart', this.onUserInput);
|
||||
|
||||
this.renderObject = new CSS2DObject(this.iconElement[0]);
|
||||
this.renderObject.position.copy(this.position);
|
||||
@ -47,6 +47,12 @@ export default class PlayerMarker extends Marker {
|
||||
this.blueMap.hudScene.add(this.renderObject);
|
||||
} else {
|
||||
this.blueMap.hudScene.remove(this.renderObject);
|
||||
|
||||
if (this.follow) {
|
||||
this.follow = false;
|
||||
this.iconElement.removeClass("following");
|
||||
this.blueMap.controls.targetPosition.y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,8 +68,7 @@ export default class PlayerMarker extends Marker {
|
||||
}
|
||||
|
||||
if (this.follow){
|
||||
this.blueMap.controls.targetPosition.x = this.position.x;
|
||||
this.blueMap.controls.targetPosition.z = this.position.z;
|
||||
this.blueMap.controls.targetPosition.copy(this.position);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -97,14 +102,14 @@ export default class PlayerMarker extends Marker {
|
||||
this.follow = true;
|
||||
this.iconElement.addClass("following");
|
||||
|
||||
this.blueMap.controls.targetPosition.x = this.position.x;
|
||||
this.blueMap.controls.targetPosition.z = this.position.z;
|
||||
this.blueMap.controls.targetPosition.copy(this.position);
|
||||
};
|
||||
|
||||
onStopFollowing = event => {
|
||||
if(this.follow) {
|
||||
this.follow = true;
|
||||
onUserInput = e => {
|
||||
if ((e.type !== "mousedown" || e.button === 0) && this.follow) {
|
||||
this.follow = false;
|
||||
this.iconElement.removeClass("following");
|
||||
this.blueMap.controls.targetPosition.y = 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -42,8 +42,11 @@ export default class PlayerMarkerSet {
|
||||
);
|
||||
}).then((liveData) => {
|
||||
this.updateWith(liveData)
|
||||
}).catch((e) => {
|
||||
console.error("Failed to update player-markers!", e);
|
||||
}).catch(() => {
|
||||
this.marker.forEach(marker => {
|
||||
marker.online = false;
|
||||
marker.setVisible(false);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -114,6 +114,7 @@ public void onInitialize() {
|
||||
if (pluginInstance.isLoaded()) Logger.global.logInfo("BlueMap loaded!");
|
||||
} catch (IOException | ParseResourceException e) {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
});
|
||||
|
@ -115,6 +115,7 @@ public void onServerStarting(FMLServerStartingEvent event) {
|
||||
if (pluginInstance.isLoaded()) Logger.global.logInfo("Loaded!");
|
||||
} catch (IOException | ParseResourceException e) {
|
||||
Logger.global.logError("Failed to load bluemap!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
dependencies {
|
||||
shadow "org.spongepowered:spongeapi:7.2.0"
|
||||
compile group: 'org.bstats', name: 'bstats-sponge-lite', version: '1.5'
|
||||
|
||||
compile group: 'org.bstats', name: 'bstats-sponge-lite', version: '1.7'
|
||||
|
||||
compile (project(':BlueMapCommon')) {
|
||||
//exclude dependencies provided by sponge
|
||||
|
@ -116,7 +116,9 @@ public List<String> getSuggestions(CommandSource source, String arguments, Locat
|
||||
completions.add(text);
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException | ExecutionException | TimeoutException ignore) {}
|
||||
} catch (InterruptedException ignore) {
|
||||
Thread.currentThread().interrupt();
|
||||
} catch (ExecutionException | TimeoutException ignore) {}
|
||||
|
||||
completions.sort((s1, s2) -> s1.compareToIgnoreCase(s2));
|
||||
return completions;
|
||||
|
@ -58,6 +58,7 @@
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
import de.bluecolored.bluemap.core.resourcepack.ParseResourceException;
|
||||
import de.bluecolored.bluemap.sponge.SpongeCommands.SpongeCommandProxy;
|
||||
import net.querz.nbt.CompoundTag;
|
||||
import net.querz.nbt.NBTUtil;
|
||||
@ -74,11 +75,7 @@ public class SpongePlugin implements ServerInterface {
|
||||
@ConfigDir(sharedRoot = false)
|
||||
private Path configurationDir;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Inject
|
||||
private MetricsLite2 metrics;
|
||||
|
||||
private Plugin bluemap;
|
||||
private Plugin pluginInstance;
|
||||
private SpongeCommands commands;
|
||||
|
||||
private SpongeExecutorService asyncExecutor;
|
||||
@ -88,14 +85,17 @@ public class SpongePlugin implements ServerInterface {
|
||||
private List<SpongePlayer> onlinePlayerList;
|
||||
|
||||
@Inject
|
||||
public SpongePlugin(org.slf4j.Logger logger) {
|
||||
public SpongePlugin(org.slf4j.Logger logger, MetricsLite2.Factory bstatsFactory) {
|
||||
Logger.global = new Slf4jLogger(logger);
|
||||
|
||||
this.onlinePlayerMap = new ConcurrentHashMap<>();
|
||||
this.onlinePlayerList = Collections.synchronizedList(new ArrayList<>());
|
||||
|
||||
this.bluemap = new Plugin("sponge", this);
|
||||
this.commands = new SpongeCommands(bluemap);
|
||||
this.pluginInstance = new Plugin("sponge", this);
|
||||
this.commands = new SpongeCommands(pluginInstance);
|
||||
|
||||
//init bstats metrics
|
||||
bstatsFactory.make(5911);
|
||||
}
|
||||
|
||||
@Listener
|
||||
@ -121,10 +121,11 @@ public void onServerStart(GameStartingServerEvent evt) {
|
||||
asyncExecutor.execute(() -> {
|
||||
try {
|
||||
Logger.global.logInfo("Loading...");
|
||||
bluemap.load();
|
||||
if (bluemap.isLoaded()) Logger.global.logInfo("Loaded!");
|
||||
} catch (Throwable t) {
|
||||
Logger.global.logError("Failed to load!", t);
|
||||
pluginInstance.load();
|
||||
if (pluginInstance.isLoaded()) Logger.global.logInfo("Loaded!");
|
||||
} catch (IOException | ParseResourceException | RuntimeException e) {
|
||||
Logger.global.logError("Failed to load!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -133,7 +134,7 @@ public void onServerStart(GameStartingServerEvent evt) {
|
||||
public void onServerStop(GameStoppingEvent evt) {
|
||||
Logger.global.logInfo("Stopping...");
|
||||
Sponge.getScheduler().getScheduledTasks(this).forEach(t -> t.cancel());
|
||||
bluemap.unload();
|
||||
pluginInstance.unload();
|
||||
Logger.global.logInfo("Saved and stopped!");
|
||||
}
|
||||
|
||||
@ -142,15 +143,15 @@ public void onServerReload(GameReloadEvent evt) {
|
||||
asyncExecutor.execute(() -> {
|
||||
try {
|
||||
Logger.global.logInfo("Reloading...");
|
||||
bluemap.reload();
|
||||
pluginInstance.reload();
|
||||
Logger.global.logInfo("Reloaded!");
|
||||
} catch (Exception e) {
|
||||
} catch (IOException | ParseResourceException | RuntimeException e) {
|
||||
Logger.global.logError("Failed to load!", e);
|
||||
pluginInstance.unload();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Listener
|
||||
public void onPlayerJoin(ClientConnectionEvent.Join evt) {
|
||||
SpongePlayer player = new SpongePlayer(evt.getTargetEntity());
|
||||
@ -186,8 +187,8 @@ public UUID getUUIDForWorld(File worldFolder) throws IOException {
|
||||
long most = spongeData.getLong("UUIDMost");
|
||||
long least = spongeData.getLong("UUIDLeast");
|
||||
return new UUID(most, least);
|
||||
} catch (Throwable t) {
|
||||
throw new IOException("Failed to read level_sponge.dat", t);
|
||||
} catch (IOException | RuntimeException e) {
|
||||
throw new IOException("Failed to read level_sponge.dat", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user