2018-08-08 03:16:53 +00:00
|
|
|
/*
|
|
|
|
* This file is part of Baritone.
|
|
|
|
*
|
|
|
|
* Baritone is free software: you can redistribute it and/or modify
|
2018-09-17 22:11:40 +00:00
|
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
2018-08-08 03:16:53 +00:00
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
2018-08-08 04:15:22 +00:00
|
|
|
* Baritone is distributed in the hope that it will be useful,
|
2018-08-08 03:16:53 +00:00
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
2018-09-17 22:11:40 +00:00
|
|
|
* GNU Lesser General Public License for more details.
|
2018-08-08 03:16:53 +00:00
|
|
|
*
|
2018-09-17 22:11:40 +00:00
|
|
|
* You should have received a copy of the GNU Lesser General Public License
|
2018-08-08 03:16:53 +00:00
|
|
|
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2018-09-11 17:28:03 +00:00
|
|
|
package baritone.cache;
|
2018-08-05 04:36:59 +00:00
|
|
|
|
2018-08-22 22:35:32 +00:00
|
|
|
import baritone.Baritone;
|
2018-09-24 19:42:22 +00:00
|
|
|
import baritone.api.cache.IWorldProvider;
|
2019-04-18 01:10:47 +00:00
|
|
|
import baritone.api.utils.Helper;
|
2018-09-04 22:18:30 +00:00
|
|
|
import baritone.utils.accessor.IAnvilChunkLoader;
|
|
|
|
import baritone.utils.accessor.IChunkProviderServer;
|
2018-08-05 04:36:59 +00:00
|
|
|
import net.minecraft.server.integrated.IntegratedServer;
|
|
|
|
import net.minecraft.world.WorldServer;
|
2019-01-25 05:00:44 +00:00
|
|
|
import org.apache.commons.lang3.SystemUtils;
|
2018-08-05 04:36:59 +00:00
|
|
|
|
|
|
|
import java.io.File;
|
2018-08-23 21:37:08 +00:00
|
|
|
import java.io.FileOutputStream;
|
2018-08-05 04:36:59 +00:00
|
|
|
import java.io.IOException;
|
|
|
|
import java.nio.file.Files;
|
|
|
|
import java.nio.file.Path;
|
|
|
|
import java.util.HashMap;
|
|
|
|
import java.util.Map;
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @author Brady
|
2018-11-14 03:53:27 +00:00
|
|
|
* @since 8/4/2018
|
2018-08-05 04:36:59 +00:00
|
|
|
*/
|
2018-11-11 20:35:04 +00:00
|
|
|
public class WorldProvider implements IWorldProvider, Helper {
|
2018-08-05 04:36:59 +00:00
|
|
|
|
2018-11-11 20:35:04 +00:00
|
|
|
private static final Map<Path, WorldData> worldCache = new HashMap<>(); // this is how the bots have the same cached world
|
2018-08-05 04:36:59 +00:00
|
|
|
|
2018-08-22 22:35:32 +00:00
|
|
|
private WorldData currentWorld;
|
2018-08-05 04:36:59 +00:00
|
|
|
|
2018-09-24 19:42:22 +00:00
|
|
|
@Override
|
2018-09-24 19:47:48 +00:00
|
|
|
public final WorldData getCurrentWorld() {
|
2018-08-05 04:36:59 +00:00
|
|
|
return this.currentWorld;
|
|
|
|
}
|
|
|
|
|
2018-11-11 22:22:00 +00:00
|
|
|
/**
|
|
|
|
* Called when a new world is initialized to discover the
|
|
|
|
*
|
|
|
|
* @param dimension The ID of the world's dimension
|
|
|
|
*/
|
|
|
|
public final void initWorld(int dimension) {
|
2018-11-13 00:39:58 +00:00
|
|
|
File directory;
|
|
|
|
File readme;
|
2018-11-11 22:22:00 +00:00
|
|
|
|
2018-08-22 22:35:32 +00:00
|
|
|
IntegratedServer integratedServer = mc.getIntegratedServer();
|
2018-11-11 22:22:00 +00:00
|
|
|
|
|
|
|
// If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file
|
2019-06-03 22:26:57 +00:00
|
|
|
if (mc.isSingleplayer()) {
|
2018-11-11 22:22:00 +00:00
|
|
|
WorldServer localServerWorld = integratedServer.getWorld(dimension);
|
2018-08-05 04:36:59 +00:00
|
|
|
IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider();
|
|
|
|
IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader();
|
2018-08-22 22:35:32 +00:00
|
|
|
directory = loader.getChunkSaveLocation();
|
2018-08-05 04:36:59 +00:00
|
|
|
|
2018-08-25 05:24:19 +00:00
|
|
|
// Gets the "depth" of this directory relative the the game's run directory, 2 is the location of the world
|
2018-08-24 02:26:28 +00:00
|
|
|
if (directory.toPath().relativize(mc.gameDir.toPath()).getNameCount() != 2) {
|
2018-08-22 22:35:32 +00:00
|
|
|
// subdirectory of the main save directory for this world
|
|
|
|
directory = directory.getParentFile();
|
2018-08-05 04:36:59 +00:00
|
|
|
}
|
|
|
|
|
2018-08-22 22:35:32 +00:00
|
|
|
directory = new File(directory, "baritone");
|
2018-08-23 21:40:42 +00:00
|
|
|
readme = directory;
|
2018-11-11 22:22:00 +00:00
|
|
|
} else { // Otherwise, the server must be remote...
|
2019-01-25 05:00:44 +00:00
|
|
|
String folderName = mc.getCurrentServerData().serverIP;
|
|
|
|
if (SystemUtils.IS_OS_WINDOWS) {
|
|
|
|
folderName = folderName.replace(":", "_");
|
|
|
|
}
|
|
|
|
directory = new File(Baritone.getDir(), folderName);
|
2018-11-06 04:01:46 +00:00
|
|
|
readme = Baritone.getDir();
|
2018-08-22 22:35:32 +00:00
|
|
|
}
|
2018-11-11 22:22:00 +00:00
|
|
|
|
2018-08-23 21:40:42 +00:00
|
|
|
// lol wtf is this baritone folder in my minecraft save?
|
|
|
|
try (FileOutputStream out = new FileOutputStream(new File(readme, "readme.txt"))) {
|
2018-08-23 21:37:08 +00:00
|
|
|
// good thing we have a readme
|
|
|
|
out.write("https://github.com/cabaletta/baritone\n".getBytes());
|
2018-08-25 05:24:19 +00:00
|
|
|
} catch (IOException ignored) {}
|
2018-08-23 21:40:42 +00:00
|
|
|
|
2018-11-11 22:22:00 +00:00
|
|
|
// We will actually store the world data in a subfolder: "DIM<id>"
|
|
|
|
Path dir = new File(directory, "DIM" + dimension).toPath();
|
2018-08-22 22:35:32 +00:00
|
|
|
if (!Files.exists(dir)) {
|
|
|
|
try {
|
|
|
|
Files.createDirectories(dir);
|
|
|
|
} catch (IOException ignored) {}
|
2018-08-05 04:36:59 +00:00
|
|
|
}
|
2018-11-11 22:22:00 +00:00
|
|
|
|
2018-08-22 22:35:32 +00:00
|
|
|
System.out.println("Baritone world data dir: " + dir);
|
2018-12-04 01:20:56 +00:00
|
|
|
synchronized (worldCache) {
|
|
|
|
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension));
|
|
|
|
}
|
2018-08-05 04:36:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public final void closeWorld() {
|
2018-08-22 22:35:32 +00:00
|
|
|
WorldData world = this.currentWorld;
|
2018-08-05 04:36:59 +00:00
|
|
|
this.currentWorld = null;
|
2018-08-21 22:18:35 +00:00
|
|
|
if (world == null) {
|
|
|
|
return;
|
|
|
|
}
|
2018-08-22 22:35:32 +00:00
|
|
|
world.onClose();
|
2018-08-05 04:36:59 +00:00
|
|
|
}
|
|
|
|
|
2018-08-22 22:35:32 +00:00
|
|
|
public final void ifWorldLoaded(Consumer<WorldData> currentWorldConsumer) {
|
2018-09-08 04:32:25 +00:00
|
|
|
if (this.currentWorld != null) {
|
2018-08-05 04:36:59 +00:00
|
|
|
currentWorldConsumer.accept(this.currentWorld);
|
2018-09-08 04:32:25 +00:00
|
|
|
}
|
2018-08-05 04:36:59 +00:00
|
|
|
}
|
|
|
|
}
|