Skip to content

Commit

Permalink
Renderstate rewrite, and moving biomes to datapacks, mc-version and v…
Browse files Browse the repository at this point in the history
…anilla-resources and resource-extensions rewrite (wip)
  • Loading branch information
TBlueF committed May 7, 2024
1 parent a640285 commit 81fe41f
Show file tree
Hide file tree
Showing 131 changed files with 3,759 additions and 2,661 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,14 @@

import de.bluecolored.bluemap.common.config.*;
import de.bluecolored.bluemap.common.config.storage.StorageConfig;
import de.bluecolored.bluemap.core.MinecraftVersion;
import org.jetbrains.annotations.Nullable;

import java.nio.file.Path;
import java.util.Map;

public interface BlueMapConfiguration {

MinecraftVersion getMinecraftVersion();
@Nullable String getMinecraftVersion();

CoreConfig getCoreConfig();

Expand All @@ -48,7 +47,7 @@ public interface BlueMapConfiguration {

Map<String, StorageConfig> getStorageConfigs();

@Nullable Path getResourcePacksFolder();
@Nullable Path getPacksFolder();

@Nullable Path getModsFolder();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,13 @@
import de.bluecolored.bluemap.common.config.MapConfig;
import de.bluecolored.bluemap.common.config.storage.StorageConfig;
import de.bluecolored.bluemap.common.plugin.Plugin;
import de.bluecolored.bluemap.core.MinecraftVersion;
import de.bluecolored.bluemap.core.debug.StateDumper;
import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.map.BmMap;
import de.bluecolored.bluemap.core.resources.datapack.DataPack;
import de.bluecolored.bluemap.core.resources.resourcepack.ResourcePack;
import de.bluecolored.bluemap.core.resources.MinecraftVersion;
import de.bluecolored.bluemap.core.resources.VersionManifest;
import de.bluecolored.bluemap.core.resources.pack.datapack.DataPack;
import de.bluecolored.bluemap.core.resources.pack.resourcepack.ResourcePack;
import de.bluecolored.bluemap.core.storage.Storage;
import de.bluecolored.bluemap.core.util.FileHelper;
import de.bluecolored.bluemap.core.util.Key;
Expand Down Expand Up @@ -74,6 +75,7 @@ public class BlueMapService implements Closeable {
private final BlueMapConfiguration config;
private final WebFilesManager webFilesManager;

private MinecraftVersion minecraftVersion;
private ResourcePack resourcePack;
private final Map<String, World> worlds;
private final Map<String, BmMap> maps;
Expand Down Expand Up @@ -225,7 +227,7 @@ private synchronized void loadMap(String id, MapConfig mapConfig) throws Configu
if (world == null) {
try {
Logger.global.logDebug("Loading world " + worldId + " ...");
world = MCAWorld.load(worldFolder, dimension);
world = MCAWorld.load(worldFolder, dimension, loadDataPack(worldFolder));
worlds.put(worldId, world);
} catch (IOException ex) {
throw new ConfigurationException(
Expand Down Expand Up @@ -320,129 +322,146 @@ public synchronized Storage getOrLoadStorage(String storageId) throws Configurat

public synchronized ResourcePack getOrLoadResourcePack() throws ConfigurationException, InterruptedException {
if (resourcePack == null) {
MinecraftVersion minecraftVersion = config.getMinecraftVersion();
@Nullable Path resourcePackFolder = config.getResourcePacksFolder();
@Nullable Path modsFolder = config.getModsFolder();

Path defaultResourceFile = config.getCoreConfig().getData().resolve("minecraft-client-" + minecraftVersion.getResource().getVersion().getVersionString() + ".jar");
Path resourceExtensionsFile = config.getCoreConfig().getData().resolve("resourceExtensions.zip");

try {
FileHelper.createDirectories(resourcePackFolder);
} catch (IOException ex) {
throw new ConfigurationException(
"BlueMap failed to create this folder:\n" +
resourcePackFolder + "\n" +
"Does BlueMap have sufficient permissions?",
ex);
}
MinecraftVersion minecraftVersion = getOrLoadMinecraftVersion();
Path vanillaResourcePack = minecraftVersion.getResourcePack();

if (Thread.interrupted()) throw new InterruptedException();

if (!Files.exists(defaultResourceFile)) {
if (config.getCoreConfig().isAcceptDownload()) {
//download file
try {
Logger.global.logInfo("Downloading " + minecraftVersion.getResource().getClientUrl() + " to " + defaultResourceFile + " ...");

FileHelper.createDirectories(defaultResourceFile.getParent());
Path tempResourceFile = defaultResourceFile.getParent().resolve(defaultResourceFile.getFileName() + ".filepart");
Files.deleteIfExists(tempResourceFile);
FileUtils.copyURLToFile(new URL(minecraftVersion.getResource().getClientUrl()), tempResourceFile.toFile(), 10000, 10000);
FileHelper.move(tempResourceFile, defaultResourceFile);
} catch (IOException ex) {
throw new ConfigurationException("Failed to download resources!", ex);
}
Deque<Path> packRoots = getPackRoots();
packRoots.addLast(vanillaResourcePack);

} else {
throw new MissingResourcesException();
}
try {
ResourcePack resourcePack = new ResourcePack(minecraftVersion.getResourcePackVersion());
resourcePack.loadResources(packRoots);
this.resourcePack = resourcePack;
} catch (IOException | RuntimeException e) {
throw new ConfigurationException("Failed to parse resources!\n" +
"Is one of your resource-packs corrupted?", e);
}
}

if (Thread.interrupted()) throw new InterruptedException();
return this.resourcePack;
}

try {
Files.deleteIfExists(resourceExtensionsFile);
FileHelper.createDirectories(resourceExtensionsFile.getParent());
URL resourceExtensionsUrl = Objects.requireNonNull(
Plugin.class.getResource(
"/de/bluecolored/bluemap/" + minecraftVersion.getResource().getResourcePrefix() +
"/resourceExtensions.zip")
);
FileUtils.copyURLToFile(resourceExtensionsUrl, resourceExtensionsFile.toFile(), 10000, 10000);
} catch (IOException ex) {
throw new ConfigurationException(
"Failed to create resourceExtensions.zip!\n" +
"Does BlueMap has sufficient write permissions?",
ex);
}
public synchronized DataPack loadDataPack(Path worldFolder) throws ConfigurationException, InterruptedException {
MinecraftVersion minecraftVersion = getOrLoadMinecraftVersion();
Path vanillaDataPack = minecraftVersion.getDataPack();

if (Thread.interrupted()) throw new InterruptedException();
if (Thread.interrupted()) throw new InterruptedException();

try {
ResourcePack resourcePack = new ResourcePack();
// also load world datapacks
Iterable<Path> worldPacks = List.of();
Path worldPacksFolder = worldFolder.resolve("datapacks");
if (Files.isDirectory(worldPacksFolder)) {
try (Stream<Path> worldPacksStream = Files.list(worldPacksFolder)) {
worldPacks = worldPacksStream.toList();
} catch (IOException e) {
throw new ConfigurationException("Failed to access the worlds datapacks folder.", e);
}
}

List<Path> resourcePackRoots = new ArrayList<>();
Deque<Path> packRoots = getPackRoots(worldPacks);
packRoots.addLast(vanillaDataPack);

if (resourcePackFolder != null) {
// load from resourcepack folder
try (Stream<Path> resourcepackFiles = Files.list(resourcePackFolder)) {
resourcepackFiles
.sorted(Comparator.reverseOrder())
.forEach(resourcePackRoots::add);
}
}
try {
DataPack datapack = new DataPack(minecraftVersion.getDataPackVersion());
datapack.loadResources(packRoots);
return datapack;
} catch (IOException | RuntimeException e) {
throw new ConfigurationException("Failed to parse resources!\n" +
"Is one of your resource-packs corrupted?", e);
}
}

if (config.getCoreConfig().isScanForModResources()) {
private synchronized Deque<Path> getPackRoots(Path... additionalRoots) throws ConfigurationException, InterruptedException {
return getPackRoots(List.of(additionalRoots));
}

// load from mods folder
if (modsFolder != null && Files.isDirectory(modsFolder)) {
try (Stream<Path> resourcepackFiles = Files.list(modsFolder)) {
resourcepackFiles
.filter(Files::isRegularFile)
.filter(file -> file.getFileName().toString().endsWith(".jar"))
.forEach(resourcePackRoots::add);
}
}
private synchronized Deque<Path> getPackRoots(Iterable<Path> additionalRoots) throws ConfigurationException, InterruptedException {
@Nullable Path packsFolder = config.getPacksFolder();
@Nullable Path modsFolder = config.getModsFolder();

// load from datapacks
for (Path worldFolder : getWorldFolders()) {
Path datapacksFolder = worldFolder.resolve("datapacks");
if (!Files.isDirectory(datapacksFolder)) continue;
try {
FileHelper.createDirectories(packsFolder);
} catch (IOException ex) {
throw new ConfigurationException(
"BlueMap failed to create this folder:\n" +
packsFolder + "\n" +
"Does BlueMap have sufficient permissions?",
ex);
}

try (Stream<Path> resourcepackFiles = Files.list(worldFolder.resolve("datapacks"))) {
resourcepackFiles.forEach(resourcePackRoots::add);
}
}
Path resourceExtensionsFile = config.getCoreConfig().getData().resolve("resourceExtensions.zip");

}
if (Thread.interrupted()) throw new InterruptedException();

try {
Files.deleteIfExists(resourceExtensionsFile);
FileHelper.createDirectories(resourceExtensionsFile.getParent());
URL resourceExtensionsUrl = Objects.requireNonNull(
Plugin.class.getResource("/de/bluecolored/bluemap/resourceExtensions.zip")
);
FileUtils.copyURLToFile(resourceExtensionsUrl, resourceExtensionsFile.toFile(), 10000, 10000);
} catch (IOException ex) {
throw new ConfigurationException(
"Failed to create resourceExtensions.zip!\n" +
"Does BlueMap has sufficient write permissions?",
ex);
}

resourcePackRoots.add(resourceExtensionsFile);
resourcePackRoots.add(defaultResourceFile);
Deque<Path> packRoots = new LinkedList<>();

resourcePack.loadResources(resourcePackRoots);
// load from pack folder
if (packsFolder != null && Files.isDirectory(packsFolder)) {
try (Stream<Path> packFiles = Files.list(packsFolder)) {
packFiles
.sorted(Comparator.reverseOrder())
.forEach(packRoots::add);
} catch (IOException e) {
throw new ConfigurationException("Failed to access packs folder.", e);
}
}

this.resourcePack = resourcePack;
} catch (IOException | RuntimeException e) {
throw new ConfigurationException("Failed to parse resources!\n" +
"Is one of your resource-packs corrupted?", e);
// add additional roots
additionalRoots.forEach(packRoots::add);

// load from mods folder
if (config.getCoreConfig().isScanForModResources() && modsFolder != null && Files.isDirectory(modsFolder)) {
try (Stream<Path> packFiles = Files.list(modsFolder)) {
packFiles
.filter(Files::isRegularFile)
.filter(file -> file.getFileName().toString().endsWith(".jar"))
.forEach(packRoots::add);
} catch (IOException e) {
throw new ConfigurationException("Failed to access packs folder.", e);
}
}

return this.resourcePack;
packRoots.add(resourceExtensionsFile);
return packRoots;
}

private Collection<Path> getWorldFolders() {
Set<Path> folders = new HashSet<>();
for (MapConfig mapConfig : config.getMapConfigs().values()) {
Path folder = mapConfig.getWorld();
if (folder == null) continue;
folder = folder.toAbsolutePath().normalize();
if (Files.isDirectory(folder)) {
folders.add(folder);
public synchronized MinecraftVersion getOrLoadMinecraftVersion() throws ConfigurationException {
if (this.minecraftVersion == null) {
try {
this.minecraftVersion = MinecraftVersion.load(
config.getMinecraftVersion(),
config.getCoreConfig().getData(),
config.getCoreConfig().isAcceptDownload()
);
} catch (IOException ex) {
if (!config.getCoreConfig().isAcceptDownload()) {
throw new MissingResourcesException();
} else {
throw new ConfigurationException("""
BlueMap was not able to download some important resources!
Make sure BlueMap is able to connect to mojang-servers (%s)."""
.formatted(VersionManifest.DOMAIN), ex);
}
}
}
return folders;

return this.minecraftVersion;
}

public BlueMapConfiguration getConfig() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,13 +49,13 @@ public RenderManagerImpl(BlueMapAPIImpl api, Plugin plugin) {
@Override
public boolean scheduleMapUpdateTask(BlueMapMap map, boolean force) {
BlueMapMapImpl cmap = castMap(map);
return renderManager.scheduleRenderTask(new MapUpdateTask(cmap.getBmMap(), force));
return renderManager.scheduleRenderTask(new MapUpdateTask(cmap.getBmMap(), s -> force));
}

@Override
public boolean scheduleMapUpdateTask(BlueMapMap map, Collection<Vector2i> regions, boolean force) {
BlueMapMapImpl cmap = castMap(map);
return renderManager.scheduleRenderTask(new MapUpdateTask(cmap.getBmMap(), regions, force));
return renderManager.scheduleRenderTask(new MapUpdateTask(cmap.getBmMap(), regions, s -> force));
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,8 @@
import de.bluecolored.bluemap.common.config.storage.StorageConfig;
import de.bluecolored.bluemap.common.serverinterface.ServerWorld;
import de.bluecolored.bluemap.core.BlueMap;
import de.bluecolored.bluemap.core.MinecraftVersion;
import de.bluecolored.bluemap.core.logger.Logger;
import de.bluecolored.bluemap.core.resources.datapack.DataPack;
import de.bluecolored.bluemap.core.resources.pack.datapack.DataPack;
import de.bluecolored.bluemap.core.util.FileHelper;
import de.bluecolored.bluemap.core.util.Key;
import lombok.Builder;
Expand All @@ -51,26 +50,26 @@ public class BlueMapConfigManager implements BlueMapConfiguration {

private final ConfigManager configManager;

private final MinecraftVersion minecraftVersion;
private final CoreConfig coreConfig;
private final WebserverConfig webserverConfig;
private final WebappConfig webappConfig;
private final PluginConfig pluginConfig;
private final Map<String, MapConfig> mapConfigs;
private final Map<String, StorageConfig> storageConfigs;
private final Path resourcePacksFolder;
private final Path packsFolder;
private final @Nullable String minecraftVersion;
private final @Nullable Path modsFolder;

@Builder
private BlueMapConfigManager(
@NonNull MinecraftVersion minecraftVersion,
@NonNull Path configRoot,
@Nullable String minecraftVersion,
@Nullable Path defaultDataFolder,
@Nullable Path defaultWebroot,
@Nullable Collection<ServerWorld> autoConfigWorlds,
@Nullable Boolean usePluginConfig,
@Nullable Boolean useMetricsConfig,
@Nullable Path resourcePacksFolder,
@Nullable Path packsFolder,
@Nullable Path modsFolder
) throws ConfigurationException {
// set defaults
Expand All @@ -79,18 +78,18 @@ private BlueMapConfigManager(
if (autoConfigWorlds == null) autoConfigWorlds = Collections.emptyList();
if (usePluginConfig == null) usePluginConfig = true;
if (useMetricsConfig == null) useMetricsConfig = true;
if (resourcePacksFolder == null) resourcePacksFolder = configRoot.resolve("resourcepacks");
if (packsFolder == null) packsFolder = configRoot.resolve("packs");

// load
this.minecraftVersion = minecraftVersion;
this.configManager = new ConfigManager(configRoot);
this.coreConfig = loadCoreConfig(defaultDataFolder, useMetricsConfig);
this.webappConfig = loadWebappConfig(defaultWebroot);
this.webserverConfig = loadWebserverConfig(webappConfig.getWebroot(), coreConfig.getData());
this.pluginConfig = usePluginConfig ? loadPluginConfig() : new PluginConfig();
this.storageConfigs = Collections.unmodifiableMap(loadStorageConfigs(webappConfig.getWebroot()));
this.mapConfigs = Collections.unmodifiableMap(loadMapConfigs(autoConfigWorlds));
this.resourcePacksFolder = resourcePacksFolder;
this.packsFolder = packsFolder;
this.minecraftVersion = minecraftVersion;
this.modsFolder = modsFolder;
}

Expand Down
Loading

0 comments on commit 81fe41f

Please sign in to comment.