mirror of
https://github.com/BlueMap-Minecraft/BlueMap.git
synced 2024-11-22 10:35:16 +01:00
Start implementing the forge-mod
This commit is contained in:
parent
1ddc229047
commit
d172d0f27d
@ -35,16 +35,24 @@ build.dependsOn shadowJar {
|
||||
relocate 'com.typesafe', 'de.bluecolored.bluemap.typesafe'
|
||||
relocate 'net.querz', 'de.bluecolored.bluemap.querz'
|
||||
relocate 'ninja', 'de.bluecolored.bluemap.ninja'
|
||||
relocate 'org.apache', 'de.bluecolored.bluemap.apache'
|
||||
relocate 'org.apache.commons', 'de.bluecolored.bluemap.apache.commons'
|
||||
relocate 'org.yaml', 'de.bluecolored.bluemap.yaml'
|
||||
}
|
||||
|
||||
processResources {
|
||||
from(sourceSets.main.resources.srcDirs) {
|
||||
include 'mcmod.info'
|
||||
include 'mcmod.info','META-INF/mods.toml'
|
||||
|
||||
expand (
|
||||
version: project.version
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
reobf {
|
||||
shadowJar {
|
||||
mappings = createMcpToSrg.output
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,20 @@
|
||||
package de.bluecolored.bluemap.forge;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.CommandSource;
|
||||
import de.bluecolored.bluemap.common.plugin.text.Text;
|
||||
import net.minecraft.util.text.ITextComponent;
|
||||
|
||||
public class ForgeCommandSource implements CommandSource {
|
||||
|
||||
private net.minecraft.command.CommandSource delegate;
|
||||
|
||||
public ForgeCommandSource(net.minecraft.command.CommandSource delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sendMessage(Text text) {
|
||||
delegate.sendFeedback(ITextComponent.Serializer.fromJson(text.toJSONString()), false);
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,133 @@
|
||||
package de.bluecolored.bluemap.forge;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
import com.mojang.brigadier.LiteralMessage;
|
||||
import com.mojang.brigadier.arguments.ArgumentType;
|
||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.exceptions.CommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
import com.mojang.brigadier.exceptions.DynamicCommandExceptionType;
|
||||
import com.mojang.brigadier.exceptions.SimpleCommandExceptionType;
|
||||
|
||||
import de.bluecolored.bluemap.common.plugin.Commands;
|
||||
import de.bluecolored.bluemap.common.plugin.Plugin;
|
||||
import de.bluecolored.bluemap.common.plugin.text.Text;
|
||||
import de.bluecolored.bluemap.common.plugin.text.TextColor;
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.entity.player.PlayerEntity;
|
||||
import net.minecraftforge.server.permission.PermissionAPI;
|
||||
|
||||
public class ForgeCommands {
|
||||
|
||||
private ForgeMod mod;
|
||||
private Plugin bluemap;
|
||||
private Commands commands;
|
||||
|
||||
public ForgeCommands(ForgeMod mod, Plugin bluemap) {
|
||||
this.mod = mod;
|
||||
this.bluemap = bluemap;
|
||||
this.commands = bluemap.getCommands();
|
||||
}
|
||||
|
||||
public void registerCommands(CommandDispatcher<CommandSource> dispatcher) {
|
||||
|
||||
LiteralArgumentBuilder<CommandSource> base = literal("bluemap");
|
||||
|
||||
base.executes(c -> {
|
||||
if (!checkPermission(c, "bluemap.status")) return 0;
|
||||
|
||||
commands.executeRootCommand(new ForgeCommandSource(c.getSource()));
|
||||
return 1;
|
||||
});
|
||||
|
||||
base.then(literal("reload")).executes(c -> {
|
||||
if (!checkPermission(c, "bluemap.reload")) return 0;
|
||||
|
||||
commands.executeReloadCommand(new ForgeCommandSource(c.getSource()));
|
||||
return 1;
|
||||
});
|
||||
|
||||
base.then(literal("pause")).executes(c -> {
|
||||
if (!checkPermission(c, "bluemap.pause")) return 0;
|
||||
|
||||
commands.executePauseCommand(new ForgeCommandSource(c.getSource()));
|
||||
return 1;
|
||||
});
|
||||
|
||||
base.then(literal("resume")).executes(c -> {
|
||||
if (!checkPermission(c, "bluemap.resume")) return 0;
|
||||
|
||||
commands.executeResumeCommand(new ForgeCommandSource(c.getSource()));
|
||||
return 1;
|
||||
});
|
||||
|
||||
Command<CommandSource> renderCommand = c -> {
|
||||
if (!checkPermission(c, "bluemap.render")) return 0;
|
||||
|
||||
String worldName = null;
|
||||
try {
|
||||
c.getArgument("world", String.class);
|
||||
} catch (IllegalArgumentException ex) {}
|
||||
|
||||
int blockRadius = -1;
|
||||
try {
|
||||
c.getArgument("block-radius", Integer.class);
|
||||
} catch (IllegalArgumentException ex) {}
|
||||
|
||||
PlayerEntity player = null;
|
||||
try {
|
||||
player = c.getSource().asPlayer();
|
||||
} catch (CommandSyntaxException ex) {}
|
||||
|
||||
if (player == null) {
|
||||
if (worldName == null) throw new SimpleCommandExceptionType(new LiteralMessage("There is no world with this name: " + worldName)).create();
|
||||
} else {
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
base.then(literal("render")).executes(renderCommand);
|
||||
base.then(literal("render")).then(argument("world", StringArgumentType.word())).executes(renderCommand);
|
||||
base.then(literal("render")).then(argument("block-radius", IntegerArgumentType.integer(0))).executes(renderCommand);
|
||||
base.then(literal("render")).then(argument("world", StringArgumentType.word())).then(argument("block-radius", IntegerArgumentType.integer(0))).executes(renderCommand);
|
||||
|
||||
dispatcher.register(base);
|
||||
}
|
||||
|
||||
private boolean checkPermission(CommandContext<CommandSource> command, String permission) {
|
||||
ForgeCommandSource cs = new ForgeCommandSource(command.getSource());
|
||||
|
||||
boolean hasPermission = false;
|
||||
try {
|
||||
if (PermissionAPI.hasPermission(command.getSource().asPlayer(), permission)) {
|
||||
hasPermission = true;
|
||||
}
|
||||
} catch (CommandSyntaxException ex) {
|
||||
if (command.getSource().hasPermissionLevel(2)) {
|
||||
hasPermission = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasPermission) {
|
||||
cs.sendMessage(Text.of(TextColor.RED, "You don't have the permissions to use this command!"));
|
||||
}
|
||||
|
||||
return hasPermission;
|
||||
}
|
||||
|
||||
public static LiteralArgumentBuilder<CommandSource> literal(String name){
|
||||
return LiteralArgumentBuilder.<CommandSource>literal(name);
|
||||
}
|
||||
|
||||
public static <S extends CommandSource, T> RequiredArgumentBuilder<S, T> argument(String name, ArgumentType<T> type){
|
||||
return RequiredArgumentBuilder.<S, T>argument(name, type);
|
||||
}
|
||||
|
||||
}
|
@ -12,8 +12,6 @@
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerEventListener;
|
||||
import de.bluecolored.bluemap.common.plugin.serverinterface.ServerInterface;
|
||||
import de.bluecolored.bluemap.core.logger.Logger;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.server.ServerWorld;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
@ -26,13 +24,15 @@ public class ForgeMod implements ServerInterface {
|
||||
|
||||
private Plugin bluemap;
|
||||
|
||||
private MinecraftServer server;
|
||||
private Map<String, UUID> worldUUIDs;
|
||||
|
||||
private ForgeCommands commands;
|
||||
|
||||
public ForgeMod() {
|
||||
Logger.global = new Log4jLogger(LogManager.getLogger());
|
||||
Logger.global = new Log4jLogger(LogManager.getLogger(Plugin.PLUGIN_NAME));
|
||||
|
||||
this.bluemap = new Plugin("forge", this);
|
||||
this.commands = new ForgeCommands(this, bluemap);
|
||||
this.worldUUIDs = new HashMap<>();
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(this);
|
||||
@ -40,10 +40,15 @@ public ForgeMod() {
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStarting(FMLServerStartingEvent event) {
|
||||
this.server = event.getServer();
|
||||
this.worldUUIDs.clear();
|
||||
|
||||
for (ServerWorld world : event.getServer().getWorlds()) {
|
||||
try {
|
||||
registerWorld(world);
|
||||
} catch (IOException e) {
|
||||
Logger.global.logError("Failed to register world: " + world.getProviderName(), e);
|
||||
}
|
||||
|
||||
try {
|
||||
world.save(null, false, false);
|
||||
} catch (Throwable t) {
|
||||
@ -51,6 +56,8 @@ public void onServerStarting(FMLServerStartingEvent event) {
|
||||
}
|
||||
}
|
||||
|
||||
this.commands.registerCommands(event.getCommandDispatcher());
|
||||
|
||||
new Thread(() -> {
|
||||
try {
|
||||
Logger.global.logInfo("Loading...");
|
||||
@ -62,6 +69,10 @@ public void onServerStarting(FMLServerStartingEvent event) {
|
||||
}).start();
|
||||
}
|
||||
|
||||
private void registerWorld(ServerWorld world) throws IOException {
|
||||
getUUIDForWorld(world);
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public void onServerStopping(FMLServerStoppingEvent event) {
|
||||
Logger.global.logInfo("Stopping...");
|
||||
@ -83,20 +94,21 @@ public void unregisterAllListeners() {
|
||||
|
||||
@Override
|
||||
public UUID getUUIDForWorld(File worldFolder) throws IOException {
|
||||
|
||||
|
||||
worldFolder = worldFolder.getCanonicalFile();
|
||||
|
||||
for (ServerWorld world : server.getWorlds()) {
|
||||
if (worldFolder.equals(world.getSaveHandler().getWorldDirectory().getCanonicalFile())) return getUUIDForWorld(world);
|
||||
synchronized (worldUUIDs) {
|
||||
String key = worldFolder.getCanonicalPath();
|
||||
|
||||
UUID uuid = worldUUIDs.get(key);
|
||||
if (uuid == null) {
|
||||
throw new IOException("There is no world with this folder loaded: " + worldFolder.getPath());
|
||||
}
|
||||
|
||||
return uuid;
|
||||
}
|
||||
|
||||
throw new IOException("There is no world with this folder loaded: " + worldFolder.getPath());
|
||||
}
|
||||
|
||||
public UUID getUUIDForWorld(World world) {
|
||||
public UUID getUUIDForWorld(ServerWorld world) throws IOException {
|
||||
synchronized (worldUUIDs) {
|
||||
String key = world.getWorldInfo().getWorldName();
|
||||
String key = getFolderForWorld(world).getPath();
|
||||
|
||||
UUID uuid = worldUUIDs.get(key);
|
||||
if (uuid == null) {
|
||||
@ -107,11 +119,21 @@ public UUID getUUIDForWorld(World world) {
|
||||
return uuid;
|
||||
}
|
||||
}
|
||||
|
||||
private File getFolderForWorld(ServerWorld world) throws IOException {
|
||||
File worldFolder = world.getSaveHandler().getWorldDirectory();
|
||||
|
||||
int dimensionId = world.getDimension().getType().getId();
|
||||
if (dimensionId != 0) {
|
||||
worldFolder = new File(worldFolder, "DIM" + dimensionId);
|
||||
}
|
||||
|
||||
return worldFolder.getCanonicalFile();
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getConfigFolder() {
|
||||
//TODO
|
||||
return new File(server.getDataDirectory(), "config");
|
||||
return new File("config/bluemap");
|
||||
}
|
||||
|
||||
}
|
||||
|
25
BlueMapForge/src/main/resources/META-INF/mods.toml
Normal file
25
BlueMapForge/src/main/resources/META-INF/mods.toml
Normal file
@ -0,0 +1,25 @@
|
||||
modLoader="javafml"
|
||||
loaderVersion="[28,)"
|
||||
issueTrackerURL="https://github.com/BlueMap-Minecraft/BlueMap/issues"
|
||||
[[mods]]
|
||||
modId="bluemap"
|
||||
version="${version}"
|
||||
displayName="BlueMap"
|
||||
displayURL="https://github.com/BlueMap-Minecraft/BlueMap"
|
||||
authors="Blue (TBlueF, Lukas Rieger)"
|
||||
description='''
|
||||
A 3d-map of your Minecraft worlds view-able in your browser using three.js (WebGL)
|
||||
'''
|
||||
|
||||
[[dependencies.bluemap]]
|
||||
modId="forge"
|
||||
mandatory=true
|
||||
versionRange="[28,)"
|
||||
ordering="NONE"
|
||||
side="SERVER"
|
||||
[[dependencies.bluemap]]
|
||||
modId="minecraft"
|
||||
mandatory=true
|
||||
versionRange="[1.15.2]"
|
||||
ordering="NONE"
|
||||
side="SERVER"
|
11
BlueMapForge/src/main/resources/bluemap-forge-defaults.conf
Normal file
11
BlueMapForge/src/main/resources/bluemap-forge-defaults.conf
Normal file
@ -0,0 +1,11 @@
|
||||
accept-download: false
|
||||
metrics: true
|
||||
renderThreadCount: -2
|
||||
data: "bluemap"
|
||||
webroot: "bluemap/web"
|
||||
useCookies: true
|
||||
webserver {
|
||||
enabled: true
|
||||
port: 8100
|
||||
maxConnectionCount: 100
|
||||
}
|
166
BlueMapForge/src/main/resources/bluemap-forge.conf
Normal file
166
BlueMapForge/src/main/resources/bluemap-forge.conf
Normal file
@ -0,0 +1,166 @@
|
||||
## ##
|
||||
## BlueMap ##
|
||||
## ##
|
||||
## by Blue (Lukas Rieger) ##
|
||||
## http://bluecolored.de/ ##
|
||||
## ##
|
||||
|
||||
# By changing the setting (accept-download) below to TRUE you are indicating that you have accepted mojang's EULA (https://account.mojang.com/documents/minecraft_eula),
|
||||
# you confirm that you own a license to Minecraft (Java Edition)
|
||||
# and you agree that BlueMap will download and use this file for you: %minecraft-client-url%
|
||||
# (Alternatively you can download the file yourself and store it here: <data>/minecraft-client-%minecraft-client-version%.jar)
|
||||
# This file contains resources that belong to mojang and you must not redistribute it or do anything else that is not compliant with mojang's EULA.
|
||||
# BlueMap uses resources in this file to generate the 3D-Models used for the map and texture them. (BlueMap will not work without those resources.)
|
||||
# %datetime-iso%
|
||||
accept-download: false
|
||||
|
||||
# This changes the amount of threads that BlueMap will use to render the maps.
|
||||
# A higher value can improve render-speed but could impact performance on the host machine.
|
||||
# This should be always below or equal to the number of available processor-cores.
|
||||
# Zero or a negative value means the amount of of available processor-cores subtracted by the value.
|
||||
# (So a value of -2 with 6 cores results in 4 render-processes)
|
||||
# Default is -2
|
||||
renderThreadCount: -2
|
||||
|
||||
# If this is true, BlueMap might send really basic metrics reports containg only the implementation-type and the version that is being used to https://metrics.bluecolored.de/bluemap/
|
||||
# This allows me to track the basic usage of BlueMap and helps me stay motivated to further develop this tool! Please leave it on :)
|
||||
# An example report looks like this: {"implementation":"forge","version":"%version%"}
|
||||
metrics: true
|
||||
|
||||
# The folder where bluemap saves data-files it needs during runtime or to save e.g. the render-progress to resume it later.
|
||||
data: "bluemap"
|
||||
|
||||
# The webroot of the website that displays the map.
|
||||
webroot: "bluemap/web"
|
||||
|
||||
# Unncomment this to override the path where bluemap stores the data-files.
|
||||
# Default is "<webroot>/data"
|
||||
#webdata: "path/to/data/folder"
|
||||
|
||||
# If the web-application should use cookies to save the configurations of a user.
|
||||
useCookies: true
|
||||
|
||||
webserver {
|
||||
# With this setting you can disable the integrated web-server.
|
||||
# This is usefull if you want to only render the map-data for later use, or if you setup your own webserver.
|
||||
# Default is enabled
|
||||
enabled: true
|
||||
|
||||
# The IP-Adress that the webserver binds to.
|
||||
# If this setting is commented out, bluemap tries to find the default ip-adress of your system.
|
||||
# If you only want to access it locally use "localhost".
|
||||
#ip: "localhost"
|
||||
#ip: "127.0.0.1"
|
||||
|
||||
# The port that the webserver listenes to.
|
||||
# Default is 8100
|
||||
port: 8100
|
||||
|
||||
# Max number of simultaneous connections that the webserver allows
|
||||
# Default is 100
|
||||
maxConnectionCount: 100
|
||||
}
|
||||
|
||||
# This is an array with multiple configured maps.
|
||||
# You can define multiple maps, for different worlds with different render-settings here
|
||||
maps: [
|
||||
|
||||
{
|
||||
# The id of this map
|
||||
# Should only contain word-charactes: [a-zA-Z0-9_]
|
||||
# Changing this value breaks your existing renders.
|
||||
id: "world"
|
||||
|
||||
# The name of this map
|
||||
# This defines the display name of this map, you can change this at any time.
|
||||
# Default is the id of this map
|
||||
name: "World"
|
||||
|
||||
# The path to the save-folder of the world to render.
|
||||
world: "world"
|
||||
|
||||
# The position on the world where the map will be centered if you open it.
|
||||
# You can change this at any time.
|
||||
# This defaults to the world-spawn if you don't set it.
|
||||
#startPos: [500, -820]
|
||||
|
||||
# The color of thy sky as a hex-color
|
||||
# You can change this at any time.
|
||||
# Default is "#7dabff"
|
||||
skyColor: "#7dabff"
|
||||
|
||||
# Defines the ambient light-strength that every block is recieving, regardless of the sunlight/blocklight.
|
||||
# 0 is no ambient light, 1 is fully lighted.
|
||||
# You can change this at any time.
|
||||
# Default is 0
|
||||
ambientLight: 0
|
||||
|
||||
# If this is false, BlueMap tries to omit all blocks that are not visible from above-ground.
|
||||
# More specific: Block-Faces that have a sunlight/skylight value of 0 are removed.
|
||||
# This improves the performance of the map on slower devices by a lot, but might cause some blocks to disappear that should normally be visible.
|
||||
# Changing this value requires a re-render of the map.
|
||||
# Default is false
|
||||
renderCaves: false
|
||||
|
||||
# With the below values you can limit the map-render.
|
||||
# This can be used to ignore the nethers ceiling or render only a certain part of a world.
|
||||
# Changing this values might require a re-render of the map, already rendered tiles outside the limits will not be deleted.
|
||||
# Default is no min or max value (= infinite bounds)
|
||||
#minX: -4000
|
||||
#maxX: 4000
|
||||
#minZ: -4000
|
||||
#maxZ: 4000
|
||||
#minY: 50
|
||||
#maxY: 126
|
||||
|
||||
# Using this, BlueMap pretends that every Block out of the defined render-bounds is AIR,
|
||||
# this means you can see the blocks where the world is cut (instead of having a see-through/xray view).
|
||||
# This has only an effect if you set some render-bounds above.
|
||||
# Changing this value requires a re-render of the map.
|
||||
# Default is true
|
||||
renderEdges: true
|
||||
|
||||
# With this set to true, the generated files for this world are compressed using gzip to save A LOT of space.
|
||||
# Files will be only 5% as big with compression!
|
||||
# Note: If you are using NGINX or Apache to host your map, you can configure them to serve the compressed files directly.
|
||||
# This is much better than disabling the compression.
|
||||
# Changing this value requires a re-render of the map.
|
||||
# Default is true
|
||||
useCompression: true
|
||||
}
|
||||
|
||||
# Here another example for the End-Map
|
||||
# Things we don't want to change from default we can just omit
|
||||
{
|
||||
id: "end"
|
||||
name: "End"
|
||||
world: "world/DIM1"
|
||||
|
||||
# We dont want a blue sky in the end
|
||||
skyColor: "#080010"
|
||||
|
||||
# In the end is no sky-light, so we need to enable this or we won't see anything.
|
||||
renderCaves: true
|
||||
|
||||
# Same here, we don't want a dark map. But not completely lighted, so we see the effect of e.g torches.
|
||||
ambientLight: 0.6
|
||||
}
|
||||
|
||||
# Here another example for the Nether-Map
|
||||
{
|
||||
id: "nether"
|
||||
name: "Nether"
|
||||
world: "world/DIM-1"
|
||||
|
||||
skyColor: "#290000"
|
||||
|
||||
renderCaves: true
|
||||
ambientLight: 0.6
|
||||
|
||||
# We slice the whole world at y:90 so every block above 90 will be air.
|
||||
# This way we don't render the nethers ceiling.
|
||||
maxY: 90
|
||||
renderEdges: true
|
||||
}
|
||||
|
||||
]
|
Loading…
Reference in New Issue
Block a user