343 lines
10 KiB
Java
343 lines
10 KiB
Java
package amidst.gui.main;
|
|
|
|
import java.awt.Component;
|
|
import java.awt.Point;
|
|
import java.awt.Toolkit;
|
|
import java.awt.datatransfer.StringSelection;
|
|
import java.awt.image.BufferedImage;
|
|
import java.io.File;
|
|
import java.io.IOException;
|
|
import java.util.List;
|
|
import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
import javax.imageio.ImageIO;
|
|
|
|
import amidst.Application;
|
|
import amidst.documentation.AmidstThread;
|
|
import amidst.documentation.CalledOnlyBy;
|
|
import amidst.documentation.NotThreadSafe;
|
|
import amidst.gui.main.menu.MovePlayerPopupMenu;
|
|
import amidst.gui.main.viewer.ViewerFacade;
|
|
import amidst.logging.Log;
|
|
import amidst.mojangapi.MojangApi;
|
|
import amidst.mojangapi.file.MojangApiParsingException;
|
|
import amidst.mojangapi.minecraftinterface.MinecraftInterfaceException;
|
|
import amidst.mojangapi.world.WorldSeed;
|
|
import amidst.mojangapi.world.WorldType;
|
|
import amidst.mojangapi.world.coordinates.CoordinatesInWorld;
|
|
import amidst.mojangapi.world.icon.WorldIcon;
|
|
import amidst.mojangapi.world.player.Player;
|
|
import amidst.mojangapi.world.player.PlayerCoordinates;
|
|
import amidst.settings.biomeprofile.BiomeProfile;
|
|
import amidst.settings.biomeprofile.BiomeProfileSelection;
|
|
import amidst.threading.WorkerExecutor;
|
|
|
|
@NotThreadSafe
|
|
public class Actions {
|
|
private final Application application;
|
|
private final MojangApi mojangApi;
|
|
private final MainWindow mainWindow;
|
|
private final AtomicReference<ViewerFacade> viewerFacade;
|
|
private final BiomeProfileSelection biomeProfileSelection;
|
|
private final WorkerExecutor workerExecutor;
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public Actions(Application application, MojangApi mojangApi,
|
|
MainWindow mainWindow, AtomicReference<ViewerFacade> viewerFacade,
|
|
BiomeProfileSelection biomeProfileSelection,
|
|
WorkerExecutor workerExecutor) {
|
|
this.application = application;
|
|
this.mojangApi = mojangApi;
|
|
this.mainWindow = mainWindow;
|
|
this.viewerFacade = viewerFacade;
|
|
this.biomeProfileSelection = biomeProfileSelection;
|
|
this.workerExecutor = workerExecutor;
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void newFromSeed() {
|
|
WorldSeed seed = mainWindow.askForSeed();
|
|
if (seed != null) {
|
|
newFromSeed(seed);
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void newFromRandom() {
|
|
newFromSeed(WorldSeed.random());
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
private void newFromSeed(WorldSeed worldSeed) {
|
|
WorldType worldType = mainWindow.askForWorldType();
|
|
if (worldType != null) {
|
|
try {
|
|
mainWindow.setWorld(mojangApi.createWorldFromSeed(worldSeed,
|
|
worldType));
|
|
} catch (IllegalStateException | MinecraftInterfaceException e) {
|
|
e.printStackTrace();
|
|
mainWindow.displayException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void openWorldFile() {
|
|
File file = mainWindow.askForMinecraftWorldFile();
|
|
if (file != null) {
|
|
try {
|
|
mainWindow.setWorld(mojangApi.createWorldFromFile(file));
|
|
} catch (IllegalStateException | MinecraftInterfaceException
|
|
| IOException | MojangApiParsingException e) {
|
|
e.printStackTrace();
|
|
mainWindow.displayException(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void switchProfile() {
|
|
application.displayProfileSelectWindow();
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void exit() {
|
|
application.exitGracefully();
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void goToCoordinate() {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
String input = mainWindow.askForCoordinates();
|
|
if (input != null) {
|
|
CoordinatesInWorld coordinates = CoordinatesInWorld
|
|
.tryParse(input);
|
|
if (coordinates != null) {
|
|
viewerFacade.centerOn(coordinates);
|
|
} else {
|
|
Log.w("Invalid location entered, ignoring.");
|
|
mainWindow.displayError("You entered an invalid location.");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void goToSpawn() {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
viewerFacade.centerOn(viewerFacade.getSpawnWorldIcon());
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void goToStronghold() {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
WorldIcon stronghold = mainWindow.askForOptions("Go to",
|
|
"Select Stronghold:",
|
|
viewerFacade.getStrongholdWorldIcons());
|
|
if (stronghold != null) {
|
|
viewerFacade.centerOn(stronghold);
|
|
}
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void goToPlayer() {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
List<WorldIcon> playerWorldIcons = viewerFacade
|
|
.getPlayerWorldIcons();
|
|
if (!playerWorldIcons.isEmpty()) {
|
|
WorldIcon player = mainWindow.askForOptions("Go to",
|
|
"Select player:", playerWorldIcons);
|
|
if (player != null) {
|
|
viewerFacade.centerOn(player);
|
|
}
|
|
} else {
|
|
mainWindow.displayError("There are no players in this world.");
|
|
}
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void savePlayerLocations() {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
viewerFacade.savePlayerLocations();
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void reloadPlayerLocations() {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
viewerFacade.loadPlayers(workerExecutor);
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void howCanIMoveAPlayer() {
|
|
mainWindow
|
|
.displayMessage(
|
|
"How can I move a player?",
|
|
"If you load the world from a Minecraft save folder, you can change the player locations.\n"
|
|
+ "1. Scroll the map to and right-click on the new player location, this opens a popup menu.\n"
|
|
+ "2. Select the player you want to move to the new location.\n"
|
|
+ "3. Enter the new player height (y-coordinate).\n"
|
|
+ "4. Save player locations.\n\n"
|
|
+ "WARNING: This will change the contents of the save folder, so there is a chance that the world gets corrupted.\n"
|
|
+ "We try to minimize the risk by creating a backup of the changed file, before it is changed.\n"
|
|
+ "If the backup fails, we will not write the changes.\n"
|
|
+ "You can find the backup files in a sub folder of the world, named 'amidst/backup'.\n"
|
|
+ "Especially, make sure to not have the world loaded in Minecraft during this process.");
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void copySeedToClipboard() {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
String seed = "" + viewerFacade.getWorldSeed().getLong();
|
|
StringSelection selection = new StringSelection(seed);
|
|
Toolkit.getDefaultToolkit().getSystemClipboard()
|
|
.setContents(selection, selection);
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void saveCaptureImage() {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
BufferedImage image = viewerFacade.createCaptureImage();
|
|
String suggestedFilename = "screenshot_"
|
|
+ viewerFacade.getWorldType().getFilenameText() + "_"
|
|
+ viewerFacade.getWorldSeed().getLong() + ".png";
|
|
File file = mainWindow
|
|
.askForCaptureImageSaveFile(suggestedFilename);
|
|
if (file != null) {
|
|
saveImageToFile(image, file);
|
|
}
|
|
image.flush();
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void selectBiomeProfile(BiomeProfile profile) {
|
|
biomeProfileSelection.set(profile);
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
viewerFacade.reloadBackgroundLayer();
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void checkForUpdates() {
|
|
application.checkForUpdates(mainWindow);
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void viewLicense() {
|
|
application.displayLicenseWindow();
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void about() {
|
|
mainWindow
|
|
.displayMessage(
|
|
"About",
|
|
"Amidst - Advanced Minecraft Interfacing and Data/Structure Tracking\n\n"
|
|
+ "Author: Skidoodle aka skiphs\n"
|
|
+ "Mail: toolbox4minecraft+amidst@gmail.com\n"
|
|
+ "Project Page: https://github.com/toolbox4minecraft/amidst");
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void adjustZoom(int notches) {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
viewerFacade.adjustZoom(notches);
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void adjustZoom(Point mousePosition, int notches) {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
viewerFacade.adjustZoom(mousePosition, notches);
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void selectWorldIcon(WorldIcon worldIcon) {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
viewerFacade.selectWorldIcon(worldIcon);
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void showPlayerPopupMenu(CoordinatesInWorld targetCoordinates,
|
|
Component component, int x, int y) {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
if (viewerFacade.canSavePlayerLocations()) {
|
|
new MovePlayerPopupMenu(this,
|
|
viewerFacade.getMovablePlayerList(), targetCoordinates)
|
|
.show(component, x, y);
|
|
}
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
public void movePlayer(Player player, CoordinatesInWorld targetCoordinates) {
|
|
ViewerFacade viewerFacade = this.viewerFacade.get();
|
|
if (viewerFacade != null) {
|
|
PlayerCoordinates currentCoordinates = player
|
|
.getPlayerCoordinates();
|
|
long currentHeight = currentCoordinates.getY();
|
|
String input = mainWindow.askForPlayerHeight(currentHeight);
|
|
if (input != null) {
|
|
player.moveTo(targetCoordinates,
|
|
tryParseLong(input, currentHeight),
|
|
currentCoordinates.getDimension());
|
|
viewerFacade.reloadPlayerLayer();
|
|
if (mainWindow
|
|
.askToConfirm(
|
|
"Save Player Location",
|
|
"Do you want to save the player locations NOW? Make sure to not have the world opened in minecraft at the same time!")) {
|
|
viewerFacade.savePlayerLocations();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
private long tryParseLong(String text, long defaultValue) {
|
|
try {
|
|
return Long.parseLong(text);
|
|
} catch (NumberFormatException e) {
|
|
return defaultValue;
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
private void saveImageToFile(BufferedImage image, File file) {
|
|
try {
|
|
ImageIO.write(image, "png", appendPNGFileExtensionIfNecessary(file));
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
@CalledOnlyBy(AmidstThread.EDT)
|
|
private File appendPNGFileExtensionIfNecessary(File file) {
|
|
String filename = file.toString();
|
|
if (!filename.toLowerCase().endsWith(".png")) {
|
|
filename += ".png";
|
|
}
|
|
return new File(filename);
|
|
}
|
|
}
|