.DS_Store
+.gradle
+build
+run
+.idea
+classes
+*.iml
+*.iws
+*.ipr
--- /dev/null
+buildscript {
+ repositories {
+ jcenter()
+ maven { url 'https://www.dimdev.org/maven/' }
+ maven { url 'https://repo.spongepowered.org/maven' }
+ maven { url 'https://plugins.gradle.org/m2/' }
+ }
+ dependencies {
+ classpath 'org.dimdev:ForgeGradle:2.3-SNAPSHOT'
+ classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
+ }
+}
+
+apply plugin: 'net.minecraftforge.gradle.tweaker-client'
+apply plugin: 'java'
+apply plugin: 'org.spongepowered.mixin'
+apply plugin: 'maven-publish'
+
+def mcVersion = '1.13'
+group 'com.irtimaled'
+version "1.0.4-beta4-$mcVersion"
+archivesBaseName = 'BBOutlineReloaded'
+
+sourceCompatibility = 1.8
+targetCompatibility = 1.8
+
+repositories {
+ mavenCentral()
+ maven { url 'https://libraries.minecraft.net/' }
+ maven { url 'https://www.dimdev.org/maven/' }
+ maven { url 'https://repo.spongepowered.org/maven/' }
+}
+
+dependencies {
+ implementation('org.spongepowered:mixin:0.7.11-SNAPSHOT') { transitive = false }
+ implementation('net.minecraft:launchwrapper:1.12') { transitive = false }
+ implementation 'org.ow2.asm:asm:6.2'
+ implementation 'org.ow2.asm:asm-commons:6.2'
+}
+
+minecraft {
+ version = mcVersion
+ mappings = 'snapshot_20180908'
+ runDir = 'run'
+ tweakClass = 'com.irtimaled.bbor.launch.ClientTweaker'
+ makeObfSourceJar = false
+
+ replace "@VERSION@", project.version
+ replaceIn "com/irtimaled/bbor/install/Main.java"
+
+ replace "@MC_VERSION@", project.minecraft.version
+ replaceIn "com/irtimaled/bbor/install/Main.java"
+}
+
+mixin {
+ defaultObfuscationEnv notch
+ add sourceSets.main, 'mixins.bbor.refmap.json'
+}
+
+sourceSets {
+ main
+ debug {
+ compileClasspath += main.compileClasspath
+ }
+}
+
+processResources {
+ filesMatching('profile.json') {
+ expand([
+ 'version': project.version,
+ 'mcVersion': project.minecraft.version,
+ 'tweakClass': project.minecraft.tweakClass,
+ 'formattedTime': new Date().format("yyyy-MM-dd'T'HH:mm:ss'-08:00'")
+ ])
+ }
+
+ // Re-run this task when these change
+ inputs.property "version", project.version
+ inputs.property "mcVersion", project.minecraft.version
+}
+
+jar {
+ finalizedBy reobfJar
+ manifest.attributes(
+ 'Main-Class': 'com.irtimaled.bbor.install.Main'
+ )
+
+ exclude 'META-INF/*.DSA'
+ exclude 'META-INF/*.RSA'
+ exclude 'dummyThing'
+ exclude 'LICENSE.txt'
+
+ classifier = 'vanilla'
+}
+
+artifacts {
+ archives jar
+}
\ No newline at end of file
--- /dev/null
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip
--- /dev/null
+#!/usr/bin/env sh
+
+##############################################################################
+##
+## Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+ ls=`ls -ld "$PRG"`
+ link=`expr "$ls" : '.*-> \(.*\)$'`
+ if expr "$link" : '/.*' > /dev/null; then
+ PRG="$link"
+ else
+ PRG=`dirname "$PRG"`"/$link"
+ fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+ echo "$*"
+}
+
+die () {
+ echo
+ echo "$*"
+ echo
+ exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+ CYGWIN* )
+ cygwin=true
+ ;;
+ Darwin* )
+ darwin=true
+ ;;
+ MINGW* )
+ msys=true
+ ;;
+ NONSTOP* )
+ nonstop=true
+ ;;
+esac
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+ if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+ # IBM's JDK on AIX uses strange locations for the executables
+ JAVACMD="$JAVA_HOME/jre/sh/java"
+ else
+ JAVACMD="$JAVA_HOME/bin/java"
+ fi
+ if [ ! -x "$JAVACMD" ] ; then
+ die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+ fi
+else
+ JAVACMD="java"
+ which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+ MAX_FD_LIMIT=`ulimit -H -n`
+ if [ $? -eq 0 ] ; then
+ if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+ MAX_FD="$MAX_FD_LIMIT"
+ fi
+ ulimit -n $MAX_FD
+ if [ $? -ne 0 ] ; then
+ warn "Could not set maximum file descriptor limit: $MAX_FD"
+ fi
+ else
+ warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+ fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+ GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+ APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+ CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+ JAVACMD=`cygpath --unix "$JAVACMD"`
+
+ # We build the pattern for arguments to be converted via cygpath
+ ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+ SEP=""
+ for dir in $ROOTDIRSRAW ; do
+ ROOTDIRS="$ROOTDIRS$SEP$dir"
+ SEP="|"
+ done
+ OURCYGPATTERN="(^($ROOTDIRS))"
+ # Add a user-defined pattern to the cygpath arguments
+ if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+ OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+ fi
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ i=0
+ for arg in "$@" ; do
+ CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+ CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
+
+ if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
+ eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+ else
+ eval `echo args$i`="\"$arg\""
+ fi
+ i=$((i+1))
+ done
+ case $i in
+ (0) set -- ;;
+ (1) set -- "$args0" ;;
+ (2) set -- "$args0" "$args1" ;;
+ (3) set -- "$args0" "$args1" "$args2" ;;
+ (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+ (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+ (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+ (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+ (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+ (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+ esac
+fi
+
+# Escape application args
+save () {
+ for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+ echo " "
+}
+APP_ARGS=$(save "$@")
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
+ cd "$(dirname "$0")"
+fi
+
+exec "$JAVACMD" "$@"
--- /dev/null
+@if "%DEBUG%" == "" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%" == "" set DIRNAME=.\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS=\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if "%ERRORLEVEL%" == "0" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:init\r
+@rem Get command-line arguments, handling Windows variants\r
+\r
+if not "%OS%" == "Windows_NT" goto win9xME_args\r
+\r
+:win9xME_args\r
+@rem Slurp the command line arguments.\r
+set CMD_LINE_ARGS=\r
+set _SKIP=2\r
+\r
+:win9xME_args_slurp\r
+if "x%~1" == "x" goto execute\r
+\r
+set CMD_LINE_ARGS=%*\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+@rem Execute Gradle\r
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if "%ERRORLEVEL%"=="0" goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
+exit /b 1\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
+++ /dev/null
-package com.irtimaled.bbor;
-
-import org.apache.logging.log4j.LogManager;
-
-public class Logger {
- private static final org.apache.logging.log4j.Logger logger = LogManager.getLogger();
-
- public static void info(String s, Object... objects) {
- if (objects.length == 0) {
- logger.info(s);
- } else {
- logger.info(String.format(s, objects));
- }
- }
-}
+++ /dev/null
-package com.irtimaled.bbor;
-
-import java.lang.reflect.Field;
-import java.util.HashMap;
-import java.util.Map;
-
-public class ReflectionHelper {
- public static <T, R> R getPrivateValue(Class<T> sourceClass, T instance, Class<R> resultClass) {
- try {
- Field f = getField(sourceClass, resultClass);
- if (f != null) {
- return (R) f.get(instance);
- }
- } catch (Exception ignored) {
- }
- return null;
- }
-
- private static Map<Class, Map<Class, Field>> fieldMap = new HashMap<>();
-
- private static <T, R> Field getField(Class<T> sourceClass, Class<R> resultClass) {
- Map<Class, Field> map = fieldMap.computeIfAbsent(sourceClass, k -> new HashMap<>());
- Field field = map.get(resultClass);
- if (field == null) {
- field = getFieldUsingReflection(sourceClass, resultClass);
- if (field != null) {
- field.setAccessible(true);
- map.put(resultClass, field);
- }
- }
- return field;
- }
-
- private static <T, R> Field getFieldUsingReflection(Class<T> sourceClass, Class<R> resultClass) {
- Field[] fields = sourceClass.getDeclaredFields();
- for (Field field : fields) {
- if (field.getType().equals(resultClass))
- return field;
- }
- for (Field field : fields) {
- if (resultClass.isAssignableFrom(field.getType()))
- return field;
- }
- return null;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client;
-
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.client.Minecraft;
-import net.minecraft.network.NetworkManager;
-import net.minecraft.world.World;
-import net.minecraft.world.chunk.Chunk;
-
-import java.io.File;
-
-public class BoundingBoxOutlineReloaded {
- private static ClientProxy proxy;
-
- public static void init() {
- ConfigManager.loadConfig(new File(Minecraft.getInstance().gameDir, "config"));
- proxy = new ClientProxy();
- proxy.init();
- }
-
- public static void chunkLoaded(Chunk chunk) {
- proxy.chunkLoaded(chunk);
- }
-
- public static void worldLoaded(World world) {
- proxy.worldLoaded(world);
- }
-
- public static void keyPressed() {
- proxy.keyPressed();
- }
-
- public static void render(float partialTicks) {
- proxy.tick();
- proxy.render(partialTicks);
- }
-
- public static void playerConnectedToServer(NetworkManager networkManager) {
- proxy.playerConnectedToServer(networkManager);
- }
-
- public static void playerDisconnectedFromServer() {
- proxy.playerDisconnectedFromServer();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client;
-
-import com.irtimaled.bbor.common.BoundingBoxCache;
-import com.irtimaled.bbor.common.models.BoundingBox;
-import com.irtimaled.bbor.common.models.BoundingBoxSlimeChunk;
-import com.irtimaled.bbor.common.models.BoundingBoxWorldSpawn;
-import com.irtimaled.bbor.common.models.WorldData;
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.multiplayer.WorldClient;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.ChunkPos;
-import net.minecraft.util.math.MathHelper;
-import net.minecraft.world.dimension.DimensionType;
-
-import java.awt.*;
-import java.util.HashSet;
-import java.util.Random;
-import java.util.Set;
-import java.util.stream.Collectors;
-
-class ClientBoundingBoxProvider {
- private final ClientDimensionCache dimensionCache;
-
- ClientBoundingBoxProvider(ClientDimensionCache dimensionCache) {
- this.dimensionCache = dimensionCache;
- }
-
- Set<BoundingBox> getBoundingBoxes(DimensionType dimensionType, Boolean outerBoxOnly, WorldClient world) {
- Set<BoundingBox> boundingBoxes = getClientBoundingBoxes(dimensionType);
- BoundingBoxCache boundingBoxCache = dimensionCache.getBoundingBoxes(dimensionType);
- if (boundingBoxCache != null) {
- if (outerBoxOnly) {
- boundingBoxes.addAll(boundingBoxCache.getBoundingBoxes().keySet());
- } else {
- boundingBoxCache.getBoundingBoxes()
- .values()
- .forEach(boundingBoxes::addAll);
- }
- }
-
- return boundingBoxes.stream()
- .filter(bb -> world.isAreaLoaded(bb.getMinBlockPos(), bb.getMaxBlockPos()))
- .collect(Collectors.toSet());
- }
-
- private Set<BoundingBox> getClientBoundingBoxes(DimensionType dimensionType) {
- WorldData worldData = dimensionCache.getWorldData();
-
- Set<BoundingBox> boundingBoxes = new HashSet<>();
- if (worldData != null && dimensionType == DimensionType.OVERWORLD) {
- if (ConfigManager.drawWorldSpawn.getBoolean()) {
- boundingBoxes.add(getWorldSpawnBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
- boundingBoxes.add(buildSpawnChunksBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
- }
- if (ConfigManager.drawLazySpawnChunks.getBoolean()) {
- boundingBoxes.add(getLazySpawnChunksBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
- }
- if (ConfigManager.drawSlimeChunks.getBoolean()) {
- boundingBoxes.addAll(this.getSlimeChunks());
- }
- }
- return boundingBoxes;
- }
-
- private Set<BoundingBoxSlimeChunk> getSlimeChunks() {
- Minecraft minecraft = Minecraft.getInstance();
- int renderDistanceChunks = minecraft.gameSettings.renderDistanceChunks;
- int playerChunkX = MathHelper.floor(minecraft.player.posX / 16.0D);
- int playerChunkZ = MathHelper.floor(minecraft.player.posZ / 16.0D);
- Set<BoundingBoxSlimeChunk> slimeChunks = new HashSet<>();
- for (int chunkX = playerChunkX - renderDistanceChunks; chunkX <= playerChunkX + renderDistanceChunks; ++chunkX) {
- for (int chunkZ = playerChunkZ - renderDistanceChunks; chunkZ <= playerChunkZ + renderDistanceChunks; ++chunkZ) {
- if (isSlimeChunk(chunkX, chunkZ)) {
- ChunkPos chunk = new ChunkPos(chunkX, chunkZ);
- BlockPos minBlockPos = new BlockPos(chunk.getXStart(), 1, chunk.getZStart());
- BlockPos maxBlockPos = new BlockPos(chunk.getXEnd(), 38, chunk.getZEnd());
- if (minecraft.world.isAreaLoaded(minBlockPos, maxBlockPos)) {
- slimeChunks.add(BoundingBoxSlimeChunk.from(minBlockPos, maxBlockPos, Color.GREEN));
- }
- }
- }
- }
- return slimeChunks;
- }
-
- private boolean isSlimeChunk(int chunkX, int chunkZ) {
- WorldData worldData = dimensionCache.getWorldData();
- Random r = new Random(worldData.getSeed() +
- (long) (chunkX * chunkX * 4987142) +
- (long) (chunkX * 5947611) +
- (long) (chunkZ * chunkZ) * 4392871L +
- (long) (chunkZ * 389711) ^ 987234911L);
- return r.nextInt(10) == 0;
- }
-
- private BoundingBox buildSpawnChunksBoundingBox(int spawnX, int spawnZ) {
- return dimensionCache.getOrSetSpawnChunks(() -> buildSpawnChunksBoundingBox(spawnX, spawnZ, 12));
- }
-
- private BoundingBox getLazySpawnChunksBoundingBox(int spawnX, int spawnZ) {
- return dimensionCache.getOrSetLazySpawnChunks(() -> buildSpawnChunksBoundingBox(spawnX, spawnZ, 16));
- }
-
- private BoundingBox buildSpawnChunksBoundingBox(int spawnX, int spawnZ, int size) {
- double chunkSize = 16;
- double midOffset = chunkSize * (size / 2);
- double midX = Math.round((float) (spawnX / chunkSize)) * chunkSize;
- double midZ = Math.round((float) (spawnZ / chunkSize)) * chunkSize;
- BlockPos minBlockPos = new BlockPos(midX - midOffset, 0, midZ - midOffset);
- if (spawnX / chunkSize % 0.5D == 0.0D && spawnZ / chunkSize % 0.5D == 0.0D) {
- midX += chunkSize;
- midZ += chunkSize;
- }
- BlockPos maxBlockPos = new BlockPos(midX + midOffset, 0, midZ + midOffset);
- return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, Color.RED);
- }
-
- private BoundingBox getWorldSpawnBoundingBox(int spawnX, int spawnZ) {
- return dimensionCache.getOrSetWorldSpawn(() -> buildWorldSpawnBoundingBox(spawnX, spawnZ));
- }
-
- private BoundingBox buildWorldSpawnBoundingBox(int spawnX, int spawnZ) {
- BlockPos minBlockPos = new BlockPos(spawnX - 10, 0, spawnZ - 10);
- BlockPos maxBlockPos = new BlockPos(spawnX + 10, 0, spawnZ + 10);
-
- return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, Color.RED);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client;
-
-import com.irtimaled.bbor.common.DimensionCache;
-import com.irtimaled.bbor.common.models.BoundingBox;
-
-import java.util.function.Supplier;
-
-public class ClientDimensionCache extends DimensionCache {
- private BoundingBox worldSpawnBoundingBox;
- private BoundingBox spawnChunksBoundingBox;
- private BoundingBox lazySpawnChunksBoundingBox;
-
- @Override
- public void setWorldData(long seed, int spawnX, int spawnZ) {
- clearClientCache();
- super.setWorldData(seed, spawnX, spawnZ);
- }
-
- @Override
- public void clear() {
- clearClientCache();
- super.clear();
- }
-
- private void clearClientCache() {
- worldSpawnBoundingBox = null;
- spawnChunksBoundingBox = null;
- lazySpawnChunksBoundingBox = null;
- }
-
- BoundingBox getOrSetSpawnChunks(Supplier<BoundingBox> defaultSupplier) {
- if(spawnChunksBoundingBox == null) {
- spawnChunksBoundingBox = defaultSupplier.get();
- }
- return spawnChunksBoundingBox;
- }
-
- BoundingBox getOrSetLazySpawnChunks(Supplier<BoundingBox> defaultSupplier) {
- if(lazySpawnChunksBoundingBox == null) {
- lazySpawnChunksBoundingBox = defaultSupplier.get();
- }
- return lazySpawnChunksBoundingBox;
- }
-
- BoundingBox getOrSetWorldSpawn(Supplier<BoundingBox> defaultSupplier) {
- if(worldSpawnBoundingBox == null) {
- worldSpawnBoundingBox = defaultSupplier.get();
- }
- return worldSpawnBoundingBox;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client;
-
-import com.irtimaled.bbor.common.CommonProxy;
-import com.irtimaled.bbor.common.VillageColorCache;
-import com.irtimaled.bbor.common.VillageProcessor;
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.settings.KeyBinding;
-import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.network.NetworkManager;
-import org.apache.commons.lang3.ArrayUtils;
-
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-
-public class ClientProxy extends CommonProxy {
- private boolean active;
- private boolean outerBoxOnly;
- private KeyBinding activeHotKey;
- private KeyBinding outerBoxOnlyHotKey;
- private ClientRenderer renderer;
- private int remoteUserCount = 0;
-
- public void keyPressed() {
- if (activeHotKey.isPressed()) {
- active = !active;
- if (active)
- PlayerData.setActiveY();
- } else if (outerBoxOnlyHotKey.isPressed()) {
- outerBoxOnly = !outerBoxOnly;
- }
- }
-
- @Override
- public void init() {
- String category = "Bounding Box Outline Reloaded";
- activeHotKey = new KeyBinding("Toggle On/Off", 0x42, category);
- outerBoxOnlyHotKey = new KeyBinding("Toggle Display Outer Box Only", 0x4f, category);
- Minecraft.getInstance().gameSettings.keyBindings = ArrayUtils.addAll(Minecraft.getInstance().gameSettings.keyBindings, activeHotKey, outerBoxOnlyHotKey);
- ClientDimensionCache clientDimensionCache = new ClientDimensionCache();
- renderer = new ClientRenderer(clientDimensionCache);
- dimensionCache = clientDimensionCache;
- }
-
- public void render(float partialTicks) {
- EntityPlayer entityPlayer = Minecraft.getInstance().player;
- PlayerData.setPlayerPosition(partialTicks, entityPlayer);
-
- if (this.active) {
- renderer.render(entityPlayer.dimension, outerBoxOnly);
- }
- }
-
- public void setRemoteUserCount(int remoteUserCount) {
- this.remoteUserCount = remoteUserCount;
- }
-
- protected boolean hasRemoteUsers() {
- return remoteUserCount > 0;
- }
-
- @Override
- public void tick() {
- if (this.active || this.hasRemoteUsers()) {
- super.tick();
- }
- }
-
- public void playerConnectedToServer(NetworkManager networkManager) {
- SocketAddress remoteAddress = networkManager.getRemoteAddress();
- if (remoteAddress instanceof InetSocketAddress) {
- InetSocketAddress socketAddress = (InetSocketAddress) remoteAddress;
- NBTFileParser.loadLocalDatFiles(socketAddress.getHostName(), socketAddress.getPort(), dimensionCache);
- }
- }
-
- public void playerDisconnectedFromServer() {
- active = false;
- villageProcessors.forEach(VillageProcessor::close);
- villageProcessors.clear();
-
- if (ConfigManager.keepCacheBetweenSessions.getBoolean()) return;
- VillageColorCache.clear();
- dimensionCache.clear();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client;
-
-import com.irtimaled.bbor.client.renderers.*;
-import com.irtimaled.bbor.common.models.*;
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.client.Minecraft;
-import net.minecraft.world.dimension.DimensionType;
-import org.lwjgl.opengl.GL11;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-
-public class ClientRenderer {
- private final ClientBoundingBoxProvider clientBoundingBoxProvider;
- private static final Map<Class<? extends BoundingBox>, Renderer> boundingBoxRendererMap = new HashMap<>();
-
- ClientRenderer(ClientDimensionCache dimensionCache) {
- this.clientBoundingBoxProvider = new ClientBoundingBoxProvider(dimensionCache);
- boundingBoxRendererMap.put(BoundingBoxVillage.class, new VillageRenderer());
- boundingBoxRendererMap.put(BoundingBoxSlimeChunk.class, new SlimeChunkRenderer());
- boundingBoxRendererMap.put(BoundingBoxWorldSpawn.class, new WorldSpawnRenderer());
- boundingBoxRendererMap.put(BoundingBoxStructure.class, new StructureRenderer());
- }
-
- public void render(DimensionType dimensionType, Boolean outerBoxesOnly) {
- Set<BoundingBox> boundingBoxes = clientBoundingBoxProvider.getBoundingBoxes(dimensionType, outerBoxesOnly, Minecraft.getInstance().world);
- if (boundingBoxes == null || boundingBoxes.size() == 0)
- return;
-
- GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
- GL11.glLineWidth(2.0f);
- GL11.glDisable(GL11.GL_TEXTURE_2D);
- GL11.glDisable(GL11.GL_CULL_FACE);
-
- if (ConfigManager.alwaysVisible.getBoolean()) {
- GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
- }
- for (BoundingBox bb : boundingBoxes) {
- Renderer renderer = boundingBoxRendererMap.get(bb.getClass());
- if (renderer != null) {
- renderer.render(bb);
- }
- }
-
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
- GL11.glEnable(GL11.GL_CULL_FACE);
- GL11.glEnable(GL11.GL_TEXTURE_2D);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client;
-
-import com.irtimaled.bbor.Logger;
-import com.irtimaled.bbor.common.BoundingBoxCache;
-import com.irtimaled.bbor.common.DimensionCache;
-import com.irtimaled.bbor.common.StructureType;
-import com.irtimaled.bbor.common.models.BoundingBox;
-import com.irtimaled.bbor.common.models.BoundingBoxStructure;
-import com.irtimaled.bbor.common.models.BoundingBoxVillage;
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.nbt.CompressedStreamTools;
-import net.minecraft.nbt.NBTTagCompound;
-import net.minecraft.nbt.NBTTagList;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.dimension.DimensionType;
-
-import java.awt.*;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.util.HashSet;
-import java.util.Set;
-
-class NBTFileParser {
- static void loadLocalDatFiles(String host, int port, DimensionCache dimensionCache) {
- Logger.info("Looking for local structures (host:port=%s:%d)", host, port);
- String path = String.format("BBOutlineReloaded%s%s%s%d", File.separator, host, File.separator, port);
- File localStructuresFolder = new File(ConfigManager.configDir, path);
- Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
- if (!localStructuresFolder.exists()) {
- path = String.format("BBOutlineReloaded%s%s", File.separator, host);
- localStructuresFolder = new File(ConfigManager.configDir, path);
- Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
- }
- if (!localStructuresFolder.exists()) {
- path = String.format("BBOutlineReloaded%s%s,%d", File.separator, host, port);
- localStructuresFolder = new File(ConfigManager.configDir, path);
- Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
- }
- if (!localStructuresFolder.exists()) {
- Logger.info("No local structures folders found");
- return;
- }
- loadWorldData(localStructuresFolder, dimensionCache);
- populateBoundingBoxCache(localStructuresFolder, dimensionCache);
- }
-
- private static void loadWorldData(File localStructuresFolder, DimensionCache dimensionCache) {
- File file = new File(localStructuresFolder, "level.dat");
- NBTTagCompound nbt = loadNbtFile(file);
- if (nbt == null)
- return;
-
- NBTTagCompound data = nbt.getCompound("Data");
- long seed = data.getLong("RandomSeed");
- int spawnX = data.getInt("SpawnX");
- int spawnZ = data.getInt("SpawnZ");
- Logger.info("Loaded level.dat (seed: %d, spawn: %d,%d)", seed, spawnX, spawnZ);
- dimensionCache.setWorldData(seed, spawnX, spawnZ);
- }
-
- private static void populateBoundingBoxCache(File localStructuresFolder, DimensionCache dimensionCache) {
- dimensionCache.put(DimensionType.OVERWORLD, loadOverworldStructures(localStructuresFolder));
- dimensionCache.put(DimensionType.NETHER, loadNetherStructures(localStructuresFolder));
- dimensionCache.put(DimensionType.THE_END, loadEndStructures(localStructuresFolder));
- }
-
- private static BoundingBoxCache loadOverworldStructures(File localStructuresFolder) {
- BoundingBoxCache cache = new BoundingBoxCache();
- if (ConfigManager.drawDesertTemples.getBoolean()) {
- loadStructure(localStructuresFolder, cache, "Temple.dat", StructureType.DesertTemple.getColor(), "TeDP");
- }
- if (ConfigManager.drawJungleTemples.getBoolean()) {
- loadStructure(localStructuresFolder, cache, "Temple.dat", StructureType.JungleTemple.getColor(), "TeJP");
- }
- if (ConfigManager.drawWitchHuts.getBoolean()) {
- loadStructure(localStructuresFolder, cache, "Temple.dat", StructureType.WitchHut.getColor(), "TeSH");
- }
- if (ConfigManager.drawOceanMonuments.getBoolean()) {
- loadStructure(localStructuresFolder, cache, "Monument.dat", StructureType.OceanMonument.getColor(), "*");
- }
- if (ConfigManager.drawStrongholds.getBoolean()) {
- loadStructure(localStructuresFolder, cache, "Stronghold.dat", StructureType.Stronghold.getColor(), "*");
- }
- if (ConfigManager.drawMansions.getBoolean()) {
- loadStructure(localStructuresFolder, cache, "Mansion.dat", StructureType.Mansion.getColor(), "*");
- }
- if (ConfigManager.drawMineShafts.getBoolean()) {
- loadStructure(localStructuresFolder, cache, "Mineshaft.dat", StructureType.MineShaft.getColor(), "*");
- }
- if (ConfigManager.drawVillages.getBoolean()) {
- loadVillages(localStructuresFolder, cache, "Villages.dat");
- }
- return cache;
- }
-
- private static BoundingBoxCache loadNetherStructures(File localStructuresFolder) {
- BoundingBoxCache cache = new BoundingBoxCache();
- if (ConfigManager.drawNetherFortresses.getBoolean())
- loadStructure(localStructuresFolder, cache, "Fortress.dat", StructureType.NetherFortress.getColor(), "*");
- if (ConfigManager.drawVillages.getBoolean()) {
- loadVillages(localStructuresFolder, cache, "villages_nether.dat");
- }
- return cache;
- }
-
- private static BoundingBoxCache loadEndStructures(File localStructuresFolder) {
- BoundingBoxCache cache = new BoundingBoxCache();
- if (ConfigManager.drawVillages.getBoolean()) {
- loadVillages(localStructuresFolder, cache, "Villages_end.dat");
- }
- if (ConfigManager.drawEndCities.getBoolean()) {
- loadStructure(localStructuresFolder, cache, "EndCity.dat", StructureType.EndCity.getColor(), "*");
- }
- return cache;
- }
-
- private static void loadStructure(File localStructuresFolder, BoundingBoxCache cache, String fileName, Color color, String id) {
- File file = new File(localStructuresFolder, fileName);
- NBTTagCompound nbt = loadNbtFile(file);
- if (nbt == null)
- return;
-
- NBTTagCompound features = nbt.getCompound("data")
- .getCompound("Features");
- int loadedStructureCount = 0;
- for (Object key : features.keySet()) {
- NBTTagCompound feature = features.getCompound((String) key);
- BoundingBox structure = BoundingBoxStructure.from(feature.getIntArray("BB"), color);
- Set<BoundingBox> boundingBoxes = new HashSet<>();
- NBTTagCompound[] children = getChildCompoundTags(feature, "Children");
- for (NBTTagCompound child : children) {
- if (id.equals(child.getString("id")) || id.equals("*"))
- boundingBoxes.add(BoundingBoxStructure.from(child.getIntArray("BB"), color));
- }
- if (boundingBoxes.size() > 0)
- ++loadedStructureCount;
- cache.addBoundingBoxes(structure, boundingBoxes);
- }
-
- Logger.info("Loaded %s (%d structures with type %s)", fileName, loadedStructureCount, id);
- }
-
- private static void loadVillages(File localStructuresFolder, BoundingBoxCache cache, String fileName) {
- File file = new File(localStructuresFolder, fileName);
- NBTTagCompound nbt = loadNbtFile(file);
- if (nbt == null)
- return;
-
- NBTTagCompound[] villages = getChildCompoundTags(nbt.getCompound("data"), "Villages");
- for (NBTTagCompound village : villages) {
- BlockPos center = new BlockPos(village.getInt("CX"), village.getInt("CY"), village.getInt("CZ"));
- int radius = village.getInt("Radius");
- int population = village.getInt("PopSize");
- Set<BlockPos> doors = getDoors(village);
- BoundingBox boundingBox = BoundingBoxVillage.from(center, radius, village.hashCode(), population, doors);
- cache.addBoundingBox(boundingBox);
- }
-
- Logger.info("Loaded %s (%d villages)", fileName, villages.length);
- }
-
- private static Set<BlockPos> getDoors(NBTTagCompound village) {
- Set<BlockPos> doors = new HashSet<>();
- for (NBTTagCompound door : getChildCompoundTags(village, "Doors")) {
- doors.add(new BlockPos(door.getInt("X"), door.getInt("Y"), door.getInt("Z")));
- }
- return doors;
- }
-
- private static NBTTagCompound loadNbtFile(File file) {
- if (!file.exists())
- return null;
- try {
- return CompressedStreamTools.readCompressed(new FileInputStream(file));
- } catch (IOException e) {
- return null;
- }
- }
-
- private static NBTTagCompound[] getChildCompoundTags(NBTTagCompound parent, String key) {
- NBTTagList tagList = parent.getList(key, 10);
- NBTTagCompound[] result = new NBTTagCompound[tagList.size()];
- for (int index = 0; index < tagList.size(); index++) {
- result[index] = tagList.getCompound(index);
- }
- return result;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client;
-
-import net.minecraft.entity.player.EntityPlayer;
-
-public class PlayerData {
- private static double x;
- private static double y;
- private static double z;
- private static double activeY;
-
- static void setPlayerPosition(double partialTicks, EntityPlayer entityPlayer) {
- x = entityPlayer.lastTickPosX + (entityPlayer.posX - entityPlayer.lastTickPosX) * partialTicks;
- y = entityPlayer.lastTickPosY + (entityPlayer.posY - entityPlayer.lastTickPosY) * partialTicks;
- z = entityPlayer.lastTickPosZ + (entityPlayer.posZ - entityPlayer.lastTickPosZ) * partialTicks;
- }
-
- static void setActiveY() {
- activeY = y;
- }
-
- public static double getX() {
- return x;
- }
-
- public static double getY() {
- return y;
- }
-
- public static double getZ() {
- return z;
- }
-
- public static double getMaxY(double configMaxY) {
- if (configMaxY == -1) {
- return activeY;
- } else if ((configMaxY == 0) || (y < configMaxY)) {
- return y;
- }
- return configMaxY;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client.renderers;
-
-import com.irtimaled.bbor.client.PlayerData;
-import com.irtimaled.bbor.common.models.BoundingBox;
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.client.renderer.BufferBuilder;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
-import net.minecraft.util.math.AxisAlignedBB;
-import org.lwjgl.opengl.GL11;
-
-import java.awt.*;
-
-public abstract class Renderer<T extends BoundingBox> {
- public abstract void render(T boundingBox);
-
- void renderBoundingBox(T boundingBox) {
- renderCuboid(boundingBox.toAxisAlignedBB(), boundingBox.getColor(), fill());
- }
-
- boolean fill() {
- return ConfigManager.fill.getBoolean();
- }
-
- void renderRectangle(AxisAlignedBB aaBB, double minY, double maxY, Color color, Boolean fill) {
- aaBB = new AxisAlignedBB(aaBB.minX, minY, aaBB.minZ, aaBB.maxX, maxY, aaBB.maxZ);
- renderCuboid(aaBB, color, fill);
- }
-
- void renderCuboid(AxisAlignedBB aaBB, Color color, boolean fill) {
- aaBB = offsetAxisAlignedBB(aaBB);
- if (fill) {
- renderFilledCuboid(aaBB, color);
- }
- renderUnfilledCuboid(aaBB, color);
- }
-
- private AxisAlignedBB offsetAxisAlignedBB(AxisAlignedBB axisAlignedBB) {
- double growXZ = 0.001F;
- double growY = 0;
- if (axisAlignedBB.minY != axisAlignedBB.maxY) {
- growY = growXZ;
- }
- return axisAlignedBB
- .grow(growXZ, growY, growXZ)
- .offset(-PlayerData.getX(), -PlayerData.getY(), -PlayerData.getZ());
- }
-
- private void renderFilledCuboid(AxisAlignedBB aaBB, Color color) {
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
- GL11.glEnable(GL11.GL_BLEND);
- renderCuboid(aaBB, 30, color);
- GL11.glDisable(GL11.GL_BLEND);
- GL11.glEnable(GL11.GL_POLYGON_OFFSET_LINE);
- GL11.glPolygonOffset(-1.f, -1.f);
- }
-
- private void renderUnfilledCuboid(AxisAlignedBB aaBB, Color color) {
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
- renderCuboid(aaBB, 255, color);
- }
-
- private void renderCuboid(AxisAlignedBB bb, int alphaChannel, Color color) {
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder worldRenderer = tessellator.getBuffer();
-
- int colorR = color.getRed();
- int colorG = color.getGreen();
- int colorB = color.getBlue();
-
- worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
- worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- if (bb.minY != bb.maxY) {
-
- worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
-
- worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
- .color(colorR, colorG, colorB, alphaChannel)
- .endVertex();
- }
- tessellator.draw();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client.renderers;
-
-import com.irtimaled.bbor.client.PlayerData;
-import com.irtimaled.bbor.common.models.BoundingBoxSlimeChunk;
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.util.math.AxisAlignedBB;
-
-import java.awt.*;
-
-public class SlimeChunkRenderer extends Renderer<BoundingBoxSlimeChunk> {
- @Override
- public void render(BoundingBoxSlimeChunk boundingBox) {
- AxisAlignedBB aaBB = boundingBox.toAxisAlignedBB();
- Color color = boundingBox.getColor();
- renderCuboid(aaBB, color, fill());
-
- double maxY = PlayerData.getMaxY(ConfigManager.slimeChunkMaxY.getInt());
- if (maxY > 39) {
- renderRectangle(aaBB, 39, maxY, color, fill());
- }
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client.renderers;
-
-import com.irtimaled.bbor.common.models.BoundingBoxStructure;
-
-public class StructureRenderer extends Renderer<BoundingBoxStructure> {
- @Override
- public void render(BoundingBoxStructure boundingBox) {
- renderBoundingBox(boundingBox);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client.renderers;
-
-import com.irtimaled.bbor.client.PlayerData;
-import com.irtimaled.bbor.common.models.BoundingBoxVillage;
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.client.renderer.BufferBuilder;
-import net.minecraft.client.renderer.Tessellator;
-import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
-import net.minecraft.util.math.AxisAlignedBB;
-import net.minecraft.util.math.BlockPos;
-import org.lwjgl.opengl.GL11;
-
-import java.awt.*;
-import java.util.HashSet;
-import java.util.Set;
-
-public class VillageRenderer extends Renderer<BoundingBoxVillage> {
- @Override
- public void render(BoundingBoxVillage boundingBox) {
- if (ConfigManager.renderVillageAsSphere.getBoolean()) {
- renderBoundingBoxVillageAsSphere(boundingBox);
- } else {
- renderBoundingBox(boundingBox);
- }
- if (ConfigManager.drawIronGolemSpawnArea.getBoolean() &&
- boundingBox.getSpawnsIronGolems()) {
- renderIronGolemSpawnArea(boundingBox);
- }
- if (ConfigManager.drawVillageDoors.getBoolean()) {
- renderVillageDoors(boundingBox);
- }
- }
-
- private void renderIronGolemSpawnArea(BoundingBoxVillage boundingBox) {
- BlockPos center = boundingBox.getCenter();
- AxisAlignedBB abb = new AxisAlignedBB(new BlockPos(center.getX() - 8,
- center.getY() - 3,
- center.getZ() - 8),
- new BlockPos(center.getX() + 8,
- center.getY() + 3,
- center.getZ() + 8))
- .offset(boundingBox.getCenterOffsetX(), 0.0, boundingBox.getCenterOffsetZ());
-
- renderCuboid(abb, boundingBox.getColor(), false);
- }
-
- private void renderVillageDoors(BoundingBoxVillage boundingBox) {
- OffsetPoint center = new OffsetPoint(boundingBox.getCenter())
- .add(boundingBox.getCenterOffsetX(), 0.0, boundingBox.getCenterOffsetZ());
- Color color = boundingBox.getColor();
- GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder worldRenderer = tessellator.getBuffer();
-
- int colorR = color.getRed();
- int colorG = color.getGreen();
- int colorB = color.getBlue();
-
- worldRenderer.begin(GL11.GL_LINES, worldRenderer.getVertexFormat());
- for (BlockPos door : boundingBox.getDoors()) {
- OffsetPoint point = new OffsetPoint(door).add(0.5, 0, 0.5);
-
- worldRenderer.pos(point.getX(), point.getY(), point.getZ()).color(colorR, colorG, colorB, 255).endVertex();
- worldRenderer.pos(center.getX(), center.getY(), center.getZ()).color(colorR, colorG, colorB, 255).endVertex();
- }
- tessellator.draw();
- }
-
- private void renderBoundingBoxVillageAsSphere(BoundingBoxVillage boundingBox) {
- OffsetPoint center = new OffsetPoint(boundingBox.getCenter())
- .add(boundingBox.getCenterOffsetX(), 0.0, boundingBox.getCenterOffsetZ());
- int radius = boundingBox.getRadius();
- Color color = boundingBox.getColor();
- renderSphere(center, radius, color);
- }
-
- private void renderSphere(OffsetPoint center, double radius, Color color) {
- GL11.glEnable(GL11.GL_POINT_SMOOTH);
- GL11.glPointSize(2f);
-
- Tessellator tessellator = Tessellator.getInstance();
- BufferBuilder worldRenderer = tessellator.getBuffer();
- worldRenderer.begin(GL11.GL_POINTS, DefaultVertexFormats.POSITION_COLOR);
- for (OffsetPoint point : buildPoints(center, radius)) {
- worldRenderer.pos(point.getX(), point.getY(), point.getZ())
- .color(color.getRed(), color.getGreen(), color.getBlue(), 255)
- .endVertex();
- }
- tessellator.draw();
- }
-
- private class OffsetPoint {
- private final double x;
- private final double y;
- private final double z;
-
- OffsetPoint(double x, double y, double z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- OffsetPoint(BlockPos blockPos) {
- this.x = blockPos.getX();
- this.y = blockPos.getY();
- this.z = blockPos.getZ();
- }
-
- double getX() {
- return x - PlayerData.getX();
- }
-
- double getY() {
- return y - PlayerData.getY();
- }
-
- double getZ() {
- return z - PlayerData.getZ();
- }
-
- public OffsetPoint add(double x, double y, double z) {
- return new OffsetPoint(this.x + x, this.y + y, this.z + z);
- }
- }
-
- private Set<OffsetPoint> buildPoints(OffsetPoint center, double radius) {
- Set<OffsetPoint> points = new HashSet<>(1200);
-
- double tau = 6.283185307179586D;
- double pi = tau / 2D;
- double segment = tau / 48D;
-
- for (double t = 0.0D; t < tau; t += segment)
- for (double theta = 0.0D; theta < pi; theta += segment) {
- double dx = radius * Math.sin(t) * Math.cos(theta);
- double dz = radius * Math.sin(t) * Math.sin(theta);
- double dy = radius * Math.cos(t);
-
- points.add(center.add(dx, dy, dz));
- }
- return points;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.client.renderers;
-
-import com.irtimaled.bbor.client.PlayerData;
-import com.irtimaled.bbor.common.models.BoundingBoxWorldSpawn;
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.util.math.AxisAlignedBB;
-
-import java.awt.*;
-
-public class WorldSpawnRenderer extends Renderer<BoundingBoxWorldSpawn> {
- @Override
- public void render(BoundingBoxWorldSpawn boundingBox) {
- AxisAlignedBB aaBB = boundingBox.toAxisAlignedBB(false);
- Color color = boundingBox.getColor();
- double y = PlayerData.getMaxY(ConfigManager.worldSpawnMaxY.getInt()) + 0.001F;
- renderRectangle(aaBB, y, y, color, false);
- }
-}
\ No newline at end of file
+++ /dev/null
-package com.irtimaled.bbor.common;
-
-import com.irtimaled.bbor.common.models.BoundingBox;
-
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class BoundingBoxCache {
- private Map<BoundingBox, Set<BoundingBox>> cache = new ConcurrentHashMap<>();
-
- public Map<BoundingBox, Set<BoundingBox>> getBoundingBoxes() {
- return cache;
- }
-
- public synchronized void refresh() {
- }
-
- public void close() {
- cache.clear();
- }
-
- boolean isCached(BoundingBox key) {
- return cache.containsKey(key);
- }
-
- public void addBoundingBoxes(BoundingBox key, Set<BoundingBox> boundingBoxes) {
- cache.put(key, boundingBoxes);
- }
-
- public void addBoundingBox(BoundingBox key) {
- Set<BoundingBox> boundingBoxes = new HashSet<>();
- boundingBoxes.add(key);
- addBoundingBoxes(key, boundingBoxes);
- }
-
- public void removeBoundingBox(BoundingBox key) {
- if (cache.containsKey(key)) {
- cache.remove(key);
- }
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common;
-
-
-import com.irtimaled.bbor.Logger;
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraft.world.World;
-import net.minecraft.world.chunk.Chunk;
-import net.minecraft.world.chunk.IChunkProvider;
-import net.minecraft.world.dimension.DimensionType;
-import net.minecraft.world.gen.ChunkProviderServer;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class CommonProxy {
- protected DimensionCache dimensionCache;
- protected Set<VillageProcessor> villageProcessors = new HashSet<>();
-
- private IVillageEventHandler eventHandler = null;
-
- public void worldLoaded(World world) {
- IChunkProvider chunkProvider = world.getChunkProvider();
- if (chunkProvider instanceof ChunkProviderServer) {
- dimensionCache.setWorldData(world.getSeed(), world.getWorldInfo().getSpawnX(), world.getWorldInfo().getSpawnZ());
- DimensionType dimensionType = world.dimension.getType();
- Logger.info("create world dimension: %s, %s (seed: %d)", dimensionType, world.getClass().toString(), world.getSeed());
- DimensionProcessor boundingBoxCache = new DimensionProcessor(dimensionType, (ChunkProviderServer)chunkProvider);
- dimensionCache.put(dimensionType, boundingBoxCache);
- if (ConfigManager.drawVillages.getBoolean()) {
- villageProcessors.add(new VillageProcessor(world, dimensionType, eventHandler, boundingBoxCache));
- }
- }
- }
-
- public void chunkLoaded(Chunk chunk) {
- DimensionType dimensionType = chunk.getWorld().dimension.getType();
- dimensionCache.refresh(dimensionType);
- }
-
- public void tick() {
- villageProcessors.forEach(VillageProcessor::process);
- }
-
- public void init() {
- dimensionCache = new DimensionCache();
- }
-
- public void setEventHandler(IVillageEventHandler eventHandler) {
- this.eventHandler = eventHandler;
- }
-
- public DimensionCache getDimensionCache() {
- return dimensionCache;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common;
-
-import com.irtimaled.bbor.common.models.WorldData;
-import net.minecraft.world.dimension.DimensionType;
-
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class DimensionCache {
- private final Map<DimensionType, BoundingBoxCache> map = new ConcurrentHashMap<>();
- private WorldData worldData;
-
- void refresh(DimensionType dimensionType) {
- if (map.containsKey(dimensionType)) {
- map.get(dimensionType).refresh();
- }
- }
-
- public void put(DimensionType dimensionType, BoundingBoxCache boundingBoxCache) {
- map.put(dimensionType, boundingBoxCache);
- }
-
- public BoundingBoxCache getBoundingBoxes(DimensionType dimensionType) {
- return map.get(dimensionType);
- }
-
- public void clear() {
- worldData = null;
- for (BoundingBoxCache cache : map.values()) {
- cache.close();
- }
- map.clear();
- }
-
- public void setWorldData(long seed, int spawnX, int spawnZ) {
- this.worldData = new WorldData(seed, spawnX, spawnZ);
- }
-
- public WorldData getWorldData() {
- return worldData;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common;
-
-import com.irtimaled.bbor.Logger;
-import com.irtimaled.bbor.common.models.BoundingBox;
-import com.irtimaled.bbor.common.models.BoundingBoxStructure;
-import com.irtimaled.bbor.config.ConfigManager;
-import com.irtimaled.bbor.config.Setting;
-import net.minecraft.world.chunk.Chunk;
-import net.minecraft.world.dimension.DimensionType;
-import net.minecraft.world.gen.ChunkProviderServer;
-import net.minecraft.world.gen.feature.structure.StructurePiece;
-import net.minecraft.world.gen.feature.structure.StructureStart;
-
-import java.awt.*;
-import java.util.*;
-
-public class DimensionProcessor extends BoundingBoxCache {
- DimensionProcessor(DimensionType dimensionType, ChunkProviderServer chunkProvider) {
- this.dimensionType = dimensionType;
- this.chunkProvider = chunkProvider;
- }
-
- private DimensionType dimensionType;
- private ChunkProviderServer chunkProvider;
-
- private boolean closed = false;
-
- @Override
- public void close() {
- closed = true;
- super.close();
- }
-
- private void addStructures(Setting drawStructure, StructureType structureType, Map<String, Collection<StructureStart>> structureMap) {
- if (!drawStructure.getBoolean()) return;
-
- Collection<StructureStart> structureStarts = structureMap.get(structureType.getName());
- if (structureStarts == null || structureStarts.size() == 0) return;
- Color color = structureType.getColor();
- for (StructureStart structureStart : structureStarts) {
- BoundingBox boundingBox = BoundingBoxStructure.from(structureStart.getBoundingBox(), color);
- if (isCached(boundingBox)) continue;
-
- Set<BoundingBox> structureBoundingBoxes = new HashSet<>();
- for (StructurePiece structureComponent : structureStart.getComponents()) {
- structureBoundingBoxes.add(BoundingBoxStructure.from(structureComponent.getBoundingBox(), color));
- }
- addBoundingBoxes(boundingBox, structureBoundingBoxes);
- Logger.info("[%s] new dimensionCache entries: %d", dimensionType, structureBoundingBoxes.size());
- }
- }
-
- private Map<String, Collection<StructureStart>> getStructureMap(ChunkProviderServer chunkProvider) {
- Map<String, Collection<StructureStart>> map = new HashMap<>();
- for (Chunk chunk : chunkProvider.getLoadedChunks()) {
- Map<String, StructureStart> structureStarts = chunk.getStructureStarts();
- for (String key : structureStarts.keySet()) {
- map.computeIfAbsent(key, s -> new HashSet<>())
- .add(structureStarts.get(key));
- }
- }
- return map;
- }
-
- @Override
- public synchronized void refresh() {
- if (closed) return;
-
- Map<String, Collection<StructureStart>> structureMap = getStructureMap(chunkProvider);
- if (structureMap.size() > 0) {
- addStructures(ConfigManager.drawDesertTemples, StructureType.DesertTemple, structureMap);
- addStructures(ConfigManager.drawJungleTemples, StructureType.JungleTemple, structureMap);
- addStructures(ConfigManager.drawWitchHuts, StructureType.WitchHut, structureMap);
- addStructures(ConfigManager.drawOceanMonuments, StructureType.OceanMonument, structureMap);
- addStructures(ConfigManager.drawStrongholds, StructureType.Stronghold, structureMap);
- addStructures(ConfigManager.drawMansions, StructureType.Mansion, structureMap);
- addStructures(ConfigManager.drawMineShafts, StructureType.MineShaft, structureMap);
- addStructures(ConfigManager.drawShipwrecks, StructureType.Shipwreck, structureMap);
- addStructures(ConfigManager.drawOceanRuins, StructureType.OceanRuin, structureMap);
- addStructures(ConfigManager.drawBuriedTreasure, StructureType.BuriedTreasure, structureMap);
- addStructures(ConfigManager.drawIgloos, StructureType.Igloo, structureMap);
- addStructures(ConfigManager.drawNetherFortresses, StructureType.NetherFortress, structureMap);
- addStructures(ConfigManager.drawEndCities, StructureType.EndCity, structureMap);
- }
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common;
-
-import com.irtimaled.bbor.common.models.BoundingBox;
-import net.minecraft.world.dimension.DimensionType;
-
-public interface IVillageEventHandler {
- void villageRemoved(DimensionType dimensionType, BoundingBox bb);
-}
+++ /dev/null
-package com.irtimaled.bbor.common;
-import java.awt.*;
-
-public class StructureType {
- public final static StructureType JungleTemple = new StructureType(Color.GREEN, "Jungle_Pyramid");
- public final static StructureType DesertTemple = new StructureType(Color.ORANGE, "Desert_Pyramid");
- public final static StructureType WitchHut = new StructureType(Color.BLUE, "Swamp_Hut");
- public final static StructureType OceanMonument = new StructureType(Color.CYAN, "Monument");
- public final static StructureType Shipwreck = new StructureType(Color.CYAN, "Shipwreck");
- public final static StructureType OceanRuin = new StructureType(Color.CYAN, "Ocean_Ruin");
- public final static StructureType BuriedTreasure = new StructureType(Color.CYAN, "Buried_Treasure");
- public final static StructureType Stronghold = new StructureType(Color.YELLOW, "Stronghold");
- public final static StructureType MineShaft = new StructureType(Color.LIGHT_GRAY, "Mineshaft");
- public final static StructureType NetherFortress = new StructureType(Color.RED, "Fortress");
- public final static StructureType EndCity = new StructureType(Color.MAGENTA, "EndCity");
- public final static StructureType Mansion = new StructureType(new Color(139, 69, 19), "Mansion");
- public final static StructureType Igloo = new StructureType(Color.WHITE, "Igloo");
-
- private final Color color;
- private String name;
-
- private StructureType(Color color, String name) {
- this.color = color;
- this.name = name;
- }
-
- public Color getColor() {
- return color;
- }
-
- public String getName() {
- return name;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common;
-
-import java.awt.*;
-import java.util.HashMap;
-import java.util.Map;
-
-public class VillageColorCache {
- private static int colorIndex = -1;
-
- public static void clear() {
- colorIndex = -1;
- villageColorCache.clear();
- }
-
- private static Color getNextColor() {
- switch (++colorIndex % 6) {
- case 0:
- return Color.RED;
- case 1:
- return Color.GREEN;
- case 2:
- return Color.BLUE;
- case 3:
- return Color.MAGENTA;
- case 4:
- return Color.YELLOW;
- case 5:
- return Color.CYAN;
- }
- return Color.WHITE;
- }
-
- private static Map<Integer, Color> villageColorCache = new HashMap<>();
-
- public static Color getColor(int villageId) {
- return villageColorCache.computeIfAbsent(villageId, k -> getNextColor());
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common;
-
-import com.irtimaled.bbor.common.models.BoundingBoxVillage;
-import net.minecraft.village.Village;
-import net.minecraft.village.VillageCollection;
-import net.minecraft.world.World;
-import net.minecraft.world.dimension.DimensionType;
-
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class VillageProcessor {
- private World world;
- private DimensionType dimensionType;
- private IVillageEventHandler eventHandler;
- private BoundingBoxCache boundingBoxCache;
- private Map<Integer, BoundingBoxVillage> villageCache = new HashMap<>();
- private boolean closed = false;
-
- VillageProcessor(World world, DimensionType dimensionType, IVillageEventHandler eventHandler, BoundingBoxCache boundingBoxCache) {
- this.world = world;
- this.dimensionType = dimensionType;
- this.eventHandler = eventHandler;
- this.boundingBoxCache = boundingBoxCache;
- }
-
- synchronized void process() {
- if (closed) return;
-
- Map<Integer, BoundingBoxVillage> oldVillages = new HashMap<>(villageCache);
- Map<Integer, BoundingBoxVillage> newVillages = new HashMap<>();
- VillageCollection villageCollection = world.getVillageCollection();
- if (villageCollection != null) {
- List<Village> villages = villageCollection.getVillageList();
- for(int i = 0; i < villages.size(); i++) {
- Village village = villages.get(i);
- int villageId = village.hashCode();
- BoundingBoxVillage newVillage = oldVillages.get(villageId);
- if (newVillage != null && newVillage.matches(village)) {
- oldVillages.remove(villageId);
- } else {
- newVillage = BoundingBoxVillage.from(village);
- }
- newVillages.put(villageId, newVillage);
- }
-
- }
- for (BoundingBoxVillage village : oldVillages.values()) {
- boundingBoxCache.removeBoundingBox(village);
- if (eventHandler != null) {
- eventHandler.villageRemoved(dimensionType, village);
- }
- }
- for (BoundingBoxVillage village : newVillages.values()) {
- boundingBoxCache.addBoundingBox(village);
- }
- villageCache = newVillages;
- }
-
- public void close() {
- closed = true;
- world = null;
- eventHandler = null;
- boundingBoxCache = null;
- villageCache.clear();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common.models;
-
-import net.minecraft.util.math.AxisAlignedBB;
-import net.minecraft.util.math.BlockPos;
-
-import java.awt.*;
-
-public abstract class BoundingBox {
- private final Color color;
- private final BlockPos minBlockPos;
- private final BlockPos maxBlockPos;
-
- protected BoundingBox(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- this.minBlockPos = minBlockPos;
- this.maxBlockPos = maxBlockPos;
- this.color = color;
- }
-
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + minBlockPos.hashCode();
- result = prime * result + maxBlockPos.hashCode();
- return result;
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- BoundingBox other = (BoundingBox) obj;
- return minBlockPos.equals(other.minBlockPos) && maxBlockPos.equals(other.maxBlockPos);
- }
-
- @Override
- public String toString() {
- return "(" + minBlockPos.toString() + "; " + maxBlockPos.toString() + ")";
- }
-
- public AxisAlignedBB toAxisAlignedBB() {
- return toAxisAlignedBB(true);
- }
-
- public AxisAlignedBB toAxisAlignedBB(boolean extendMaxByOne) {
- AxisAlignedBB axisAlignedBB = new AxisAlignedBB(minBlockPos, maxBlockPos);
- if (extendMaxByOne)
- return axisAlignedBB.expand(1, 1, 1);
- return axisAlignedBB;
- }
-
- public BlockPos getMinBlockPos() {
- return minBlockPos;
- }
-
- public BlockPos getMaxBlockPos() {
- return maxBlockPos;
- }
-
- public Color getColor() {
- return color;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common.models;
-
-import net.minecraft.util.math.BlockPos;
-
-import java.awt.*;
-
-public class BoundingBoxSlimeChunk extends BoundingBox {
- private BoundingBoxSlimeChunk(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- super(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxSlimeChunk from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- return new BoundingBoxSlimeChunk(minBlockPos, maxBlockPos, color);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common.models;
-
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.util.math.MutableBoundingBox;
-
-import java.awt.*;
-
-public class BoundingBoxStructure extends BoundingBox {
- private BoundingBoxStructure(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- super(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxStructure from(MutableBoundingBox bb, Color color) {
- BlockPos minBlockPos = new BlockPos(bb.minX, bb.minY, bb.minZ);
- BlockPos maxBlockPos = new BlockPos(bb.maxX, bb.maxY, bb.maxZ);
- return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxStructure from(int[] bb, Color color) {
- BlockPos minBlockPos = new BlockPos(bb[0], bb[1], bb[2]);
- BlockPos maxBlockPos = new BlockPos(bb[3], bb[4], bb[5]);
- return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxStructure from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common.models;
-
-import com.irtimaled.bbor.common.VillageColorCache;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.village.Village;
-import net.minecraft.village.VillageDoorInfo;
-
-import java.awt.*;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Set;
-
-public class BoundingBoxVillage extends BoundingBox {
- private final BlockPos center;
- private final Integer radius;
- private final boolean spawnsIronGolems;
- private Set<BlockPos> doors;
- private Double centerOffsetX;
- private Double centerOffsetZ;
- private int villageHash;
-
- private BoundingBoxVillage(BlockPos center, Integer radius, Color color, boolean spawnsIronGolems, Set<BlockPos> doors, BlockPos minBlockPos, BlockPos maxBlockPos) {
- super(minBlockPos, maxBlockPos, color);
- this.center = center;
- this.radius = radius;
- this.spawnsIronGolems = spawnsIronGolems;
- this.doors = doors;
- this.villageHash = computeHash(center, radius, spawnsIronGolems, doors);
- calculateCenterOffsets(doors);
- }
-
- public static BoundingBoxVillage from(BlockPos center, Integer radius, Color color, boolean spawnsIronGolems, Set<BlockPos> doors) {
- BlockPos minBlockPos = new BlockPos(center.getX() - radius,
- center.getY() - 4,
- center.getZ() - radius);
- BlockPos maxBlockPos = new BlockPos(center.getX() + radius,
- center.getY() + 4,
- center.getZ() + radius);
- return new BoundingBoxVillage(center, radius, color, spawnsIronGolems, doors, minBlockPos, maxBlockPos);
- }
-
- public static BoundingBoxVillage from(BlockPos center, Integer radius, int villageId, int population, Set<BlockPos> doors) {
- Boolean spawnsIronGolems = shouldSpawnIronGolems(population, doors.size());
- Color color = VillageColorCache.getColor(villageId);
- return from(center, radius, color, spawnsIronGolems, doors);
- }
-
- private static boolean shouldSpawnIronGolems(int population, int doorCount) {
- return population >= 10 && doorCount >= 21;
- }
-
- public static BoundingBoxVillage from(Village village) {
- BlockPos center = village.getCenter();
- int radius = village.getVillageRadius();
- Set<BlockPos> doors = getDoorsFromVillage(village);
- return from(center, radius, village.hashCode(), village.getNumVillagers(), doors);
- }
-
- private static Set<BlockPos> getDoorsFromVillage(Village village) {
- Set<BlockPos> doors = new HashSet<>();
- List<VillageDoorInfo> doorInfoList = village.getVillageDoorInfoList();
- for (int i = 0; i < doorInfoList.size(); i++) {
- VillageDoorInfo doorInfo = doorInfoList.get(i);
- doors.add(doorInfo.getDoorBlockPos());
- }
- return doors;
- }
-
- private void calculateCenterOffsets(Set<BlockPos> doors) {
- boolean processedFirstDoor = false;
- int minX = 0;
- int maxX = 0;
- int minZ = 0;
- int maxZ = 0;
- for (BlockPos door : doors) {
- if (!processedFirstDoor ||
- (minX > door.getX()))
- minX = door.getX();
- if (!processedFirstDoor ||
- maxX < door.getX())
- maxX = door.getX();
- if (!processedFirstDoor ||
- minZ > door.getZ())
- minZ = door.getZ();
- if (!processedFirstDoor ||
- maxZ < door.getZ())
- maxZ = door.getZ();
-
- processedFirstDoor = true;
- }
- centerOffsetX = Math.abs(maxX - minX) % 2 == 0 ? 0.5 : (minX < 0 ? 0 : 1);
- centerOffsetZ = Math.abs(maxZ - minZ) % 2 == 0 ? 0.5 : (minZ < 0 ? 0 : 1);
- }
-
- @Override
- public String toString() {
- return "(" + center.toString() + "; " + radius.toString() + ")";
- }
-
- public Integer getRadius() {
- return radius;
- }
-
- public BlockPos getCenter() {
- return center;
- }
-
- public Double getCenterOffsetX() {
- return centerOffsetX;
- }
-
- public Double getCenterOffsetZ() {
- return centerOffsetZ;
- }
-
- private static int computeHash(BlockPos center, Integer radius, boolean spawnsIronGolems, Set<BlockPos> doors) {
- int result = (center.hashCode() * 31) + radius;
- for (BlockPos door : doors) {
- result = (31 * result) + door.hashCode();
- }
- if (spawnsIronGolems) {
- result = 31 * result;
- }
- return result;
- }
-
- public boolean matches(Village village) {
- return this.villageHash == computeHash(village.getCenter(),
- village.getVillageRadius(),
- shouldSpawnIronGolems(village.getNumVillagers(), village.getNumVillageDoors()),
- getDoorsFromVillage(village));
- }
-
- @Override
- public int hashCode() {
- return (super.hashCode() * 31) + villageHash;
- }
-
- public boolean getSpawnsIronGolems() {
- return spawnsIronGolems;
- }
-
- public Set<BlockPos> getDoors() {
- return doors;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common.models;
-
-import net.minecraft.util.math.BlockPos;
-
-import java.awt.*;
-
-public class BoundingBoxWorldSpawn extends BoundingBox {
- private BoundingBoxWorldSpawn(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- super(minBlockPos, maxBlockPos, color);
- }
-
- public static BoundingBoxWorldSpawn from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
- return new BoundingBoxWorldSpawn(minBlockPos, maxBlockPos, color);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.common.models;
-
-public class WorldData {
- private long seed;
- private int spawnX;
- private int spawnZ;
-
- public WorldData(long seed, int spawnX, int spawnZ) {
- this.seed = seed;
- this.spawnX = spawnX;
- this.spawnZ = spawnZ;
- }
-
- public long getSeed() {
- return seed;
- }
-
- public int getSpawnX() {
- return spawnX;
- }
-
- public int getSpawnZ() {
- return spawnZ;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.config;
-
-import java.io.File;
-
-public class ConfigManager {
- public static File configDir;
-
- public static Setting fill;
- public static Setting drawVillages;
- public static Setting drawDesertTemples;
- public static Setting drawJungleTemples;
- public static Setting drawWitchHuts;
- public static Setting drawStrongholds;
- public static Setting drawMineShafts;
- public static Setting drawNetherFortresses;
- public static Setting drawOceanMonuments;
- public static Setting alwaysVisible;
- public static Setting renderVillageAsSphere;
- public static Setting drawIronGolemSpawnArea;
- public static Setting drawVillageDoors;
- public static Setting drawSlimeChunks;
- public static Setting slimeChunkMaxY;
- public static Setting keepCacheBetweenSessions;
- public static Setting drawWorldSpawn;
- public static Setting worldSpawnMaxY;
- public static Setting drawLazySpawnChunks;
- public static Setting drawEndCities;
- public static Setting drawMansions;
- public static Setting drawShipwrecks;
- public static Setting drawOceanRuins;
- public static Setting drawBuriedTreasure;
- public static Setting drawIgloos;
-
- public static void loadConfig(File mcConfigDir) {
- configDir = mcConfigDir;
- Configuration config = new Configuration(new File(configDir, "BBOutlineReloaded.cfg"));
- config.load();
-
- fill = SetupBooleanProperty(config, "general", "fill", true, "If set to true the bounding boxes are filled. (default: true)");
- alwaysVisible = SetupBooleanProperty(config, "general", "alwaysVisible", false, "If set to true boxes will be visible even through other blocks. (default: false)");
- keepCacheBetweenSessions = SetupBooleanProperty(config, "general", "keepCacheBetweenSessions", false, "If set to true bounding box caches will be kept between sessions. (default: false)");
- drawVillages = SetupBooleanProperty(config, "features", "drawVillages", true, "If set to true village bounding boxes are drawn. (default: true)");
- renderVillageAsSphere = SetupBooleanProperty(config, "features", "renderVillageAsSphere", true, "If set to true villages will be drawn as a sphere. (default:true)");
- drawIronGolemSpawnArea = SetupBooleanProperty(config, "features", "drawIronGolemSpawnArea", true, "If set to true the iron golem spawn area of the village will be drawn. (default:true)");
- drawVillageDoors = SetupBooleanProperty(config, "features", "drawVillageDoors", false, "If set to true lines between the village centre and doors will be drawn. (default:false)");
- drawDesertTemples = SetupBooleanProperty(config, "features", "drawDesertTemples", true, "If set to true desert temple bounding boxes are drawn. (default: true)");
- drawJungleTemples = SetupBooleanProperty(config, "features", "drawJungleTemples", true, "If set to true jungle temple bounding boxes are drawn. (default: true)");
- drawWitchHuts = SetupBooleanProperty(config, "features", "drawWitchHuts", true, "If set to true witch hut bounding boxes are drawn. (default: true)");
- drawStrongholds = SetupBooleanProperty(config, "features", "drawStrongholds", false, "If set to true stronghold bounding boxes are drawn. (default: false)");
- drawMineShafts = SetupBooleanProperty(config, "features", "drawMineShafts", false, "If set to true mineshaft bounding boxes are drawn. (default: false)");
- drawNetherFortresses = SetupBooleanProperty(config, "features", "drawNetherFortresses", true, "If set to true nether fortress bounding boxes are drawn. (default: true)");
- drawOceanMonuments = SetupBooleanProperty(config, "features", "drawOceanMonuments", true, "If set to true ocean monument bounding boxes are drawn. (default: true)");
- drawSlimeChunks = SetupBooleanProperty(config, "features", "drawSlimeChunks", true, "If set to true slime chunks bounding boxes are drawn. (default: true)");
- slimeChunkMaxY = SetupIntegerProperty(config, "features", "slimeChunkMaxY", -1, "The maximum top of the slime chunk bounding box. If set to -1 it will use the value when activated, if set to 0 it will always track the player's feet. (default: -1)");
- drawWorldSpawn = SetupBooleanProperty(config, "features", "drawWorldSpawn", true, "If set to true world spawn and spawn chunks bounding boxes are drawn. (default: true)");
- worldSpawnMaxY = SetupIntegerProperty(config, "features", "worldSpawnMaxY", -1, "The maximum top of the world spawn bounding boxes. If set to -1 it will use the value when activated, if set to 0 it will always track the players feet. (default: -1)");
- drawLazySpawnChunks = SetupBooleanProperty(config, "features", "drawLazySpawnChunks", false, "If set to true the lazy spawn chunks bounding boxes will be drawn. (default: false)");
- drawEndCities = SetupBooleanProperty(config, "features", "drawEndCities", true, "If set to true end city bounding boxes will be drawn. (default: true)");
- drawMansions = SetupBooleanProperty(config, "features", "drawMansions", true, "If set to true woodland mansions will be drawn. (default: true)");
- drawShipwrecks = SetupBooleanProperty(config, "features", "drawShipwrecks", false, "If set to true shipwrecks will be drawn. (default: false)");
- drawOceanRuins = SetupBooleanProperty(config, "features", "drawOceanRuins", false, "If set to true ocean ruins will be drawn. (default: false)");
- drawBuriedTreasure = SetupBooleanProperty(config, "features", "drawBuriedTreasures", false, "If set to true buried treasure will be drawn. (default: false)");
- drawIgloos = SetupBooleanProperty(config, "features", "drawIgloos", false, "If set to true igloos will be drawn. (default: false)");
- config.save();
- }
-
- private static Setting SetupBooleanProperty(Configuration config, String category, String settingName, Boolean defaultValue, String comment) {
- Setting property = config.get(category, settingName, defaultValue);
- property.comment = comment;
- property.set(property.getBoolean(defaultValue));
- return property;
- }
-
- private static Setting SetupIntegerProperty(Configuration config, String category, String settingName, int defaultValue, String comment) {
- Setting property = config.get(category, settingName, defaultValue);
- property.comment = comment;
- property.set(property.getInt(defaultValue));
- return property;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.config;
-
-import com.google.common.io.Files;
-
-import java.io.*;
-import java.nio.charset.Charset;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class Configuration {
- private final File file;
-
- Configuration(File file) {
- this.file = file;
- }
-
- void save() {
- Writer writer = null;
- try {
- writer = new BufferedWriter(new OutputStreamWriter(
- new FileOutputStream(file), "utf-8"));
- writer.write("# Configuration file\n");
- for (String category : settingsGroup.keySet()) {
- writer.write("\n");
- writer.write(String.format("%s {\n", category));
- Map<String, Setting> settings = settingsGroup.get(category);
- Boolean first = true;
- for (String settingName : settings.keySet()) {
- if (!first)
- writer.write("\n");
- first = false;
- Setting setting = settings.get(settingName);
- writer.write(String.format(" # %s\n", setting.comment));
- writer.write(String.format(" %s:%s=%s\n", setting.getType(), settingName, setting.getValue()));
- }
- writer.write("}\n");
- }
- } catch (IOException ignored) {
- } finally {
- try {
- if (writer != null) {
- writer.close();
- }
- } catch (Exception ignored) {
- }
- }
- }
-
- private Map<String, Map<String, Setting>> settingsGroup = new HashMap<>();
-
- void load() {
- try {
- List<String> lines = Files.readLines(file, Charset.forName("utf-8"));
- String category = null;
- String lastCommentLine = null;
- for (String line : lines) {
- String trimmedLine = line.trim();
- if (trimmedLine.isEmpty()) {
- continue;
- }
- if (trimmedLine.startsWith("#")) {
- lastCommentLine = trimmedLine.substring(1).trim();
- continue;
- }
- if (trimmedLine.equals("}")) {
- category = null;
- continue;
- }
- if (category == null && trimmedLine.endsWith("{")) {
- category = trimmedLine.substring(0, trimmedLine.length() - 1).trim();
- settingsGroup.put(category, new HashMap<>());
- continue;
- }
- if (category != null) {
- String[] items = trimmedLine.split("[:=]");
- char type = items[0].charAt(0);
- String name = items[1];
- String stringValue = items[2];
- Object value = getTypedValue(type, stringValue);
- Setting setting = new Setting(value);
- setting.comment = lastCommentLine;
- settingsGroup.get(category).put(name, setting);
- }
- }
- } catch (IOException ignored) {
- }
- }
-
- private Object getTypedValue(char type, String stringValue) {
- switch (type) {
- case 'I':
- return Integer.parseInt(stringValue);
- case 'B':
- return stringValue.equals("1") || stringValue.toLowerCase().equals("true");
- }
- return stringValue;
- }
-
- public Setting get(String category, String settingName, Object defaultValue) {
- if (!settingsGroup.containsKey(category)) {
- settingsGroup.put(category, new HashMap<>());
- }
- Map<String, Setting> settings = settingsGroup.get(category);
- if (!settings.containsKey(settingName)) {
- settings.put(settingName, new Setting(defaultValue));
- }
- return settings.get(settingName);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.config;
-
-public class Setting {
- private Object value;
- String comment;
-
- Setting(Object value) {
- this.value = value;
- }
-
- public Boolean getBoolean(Boolean defaultValue) {
- if (value instanceof Boolean)
- return (Boolean) value;
-
- return defaultValue;
- }
-
- int getInt(int defaultValue) {
- if (value instanceof Integer)
- return (Integer) value;
-
- return defaultValue;
- }
-
- public void set(Object value) {
- this.value = value;
- }
-
- public boolean getBoolean() {
- return getBoolean(false);
- }
-
- public int getInt() {
- return getInt(0);
- }
-
- String getType() {
- if (value instanceof Integer)
- return "I";
- if (value instanceof Boolean)
- return "B";
- return "S";
- }
-
- Object getValue() {
- return value;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge;
-
-import com.irtimaled.bbor.client.ClientProxy;
-import net.minecraft.client.Minecraft;
-import net.minecraft.entity.player.EntityPlayer;
-import net.minecraftforge.client.event.RenderWorldLastEvent;
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
-import net.minecraftforge.fml.common.gameevent.InputEvent;
-import net.minecraftforge.fml.common.network.FMLNetworkEvent;
-
-public class ForgeClientProxy extends ForgeCommonProxy {
- private ClientProxy proxy;
-
- @Override
- public ClientProxy getProxy() {
- if (proxy == null) {
- proxy = new ClientProxy();
- }
- return proxy;
- }
-
- @SubscribeEvent
- public void onKeyInputEvent(InputEvent.KeyInputEvent evt) {
- getProxy().keyPressed();
- }
-
- @Override
- protected void onRegisteredPlayerCountChanged(int registeredPlayerCount) {
- getProxy().setRemoteUserCount(registeredPlayerCount-1);
- }
-
- @Override
- protected boolean isRemotePlayer(EntityPlayer player) {
- if (Minecraft.getMinecraft().isSingleplayer()) {
- EntityPlayer singlePlayer = Minecraft.getMinecraft().player;
- return singlePlayer != null && player.getGameProfile() != singlePlayer.getGameProfile();
- }
- return true;
- }
-
- @SubscribeEvent
- public void renderWorldLastEvent(RenderWorldLastEvent event) {
- getProxy().render(event.getPartialTicks());
- }
-
- @SubscribeEvent
- public void clientConnectionToServerEvent(FMLNetworkEvent.ClientConnectedToServerEvent evt) {
- if (!evt.isLocal()) {
- getProxy().playerConnectedToServer(evt.getManager());
- }
- }
-
- @SubscribeEvent
- public void clientDisconnectionFromServerEvent(FMLNetworkEvent.ClientDisconnectionFromServerEvent evt) {
- getProxy().playerDisconnectedFromServer();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge;
-
-import com.irtimaled.bbor.Logger;
-import com.irtimaled.bbor.common.BoundingBoxCache;
-import com.irtimaled.bbor.common.CommonProxy;
-import com.irtimaled.bbor.common.DimensionCache;
-import com.irtimaled.bbor.common.IVillageEventHandler;
-import com.irtimaled.bbor.common.models.BoundingBox;
-import com.irtimaled.bbor.forge.messages.*;
-import net.minecraft.entity.player.EntityPlayer;
-import net.minecraft.entity.player.EntityPlayerMP;
-import net.minecraft.network.NetHandlerPlayServer;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.world.DimensionType;
-import net.minecraft.world.World;
-import net.minecraftforge.event.world.ChunkEvent;
-import net.minecraftforge.event.world.WorldEvent;
-import net.minecraftforge.fml.common.FMLCommonHandler;
-import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
-import net.minecraftforge.fml.common.gameevent.PlayerEvent;
-import net.minecraftforge.fml.common.gameevent.TickEvent;
-import net.minecraftforge.fml.common.network.FMLNetworkEvent;
-import net.minecraftforge.fml.common.network.NetworkRegistry;
-import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
-import net.minecraftforge.fml.relauncher.Side;
-
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-
-public class ForgeCommonProxy implements IVillageEventHandler {
- private Map<EntityPlayerMP, DimensionType> playerDimensions = new ConcurrentHashMap<>();
- private Map<EntityPlayerMP, Set<BoundingBox>> playerBoundingBoxesCache = new HashMap<>();
- private HashSet<EntityPlayerMP> registeredPlayers = new HashSet<>();
-
- protected CommonProxy getProxy() {
- if (commonProxy == null)
- commonProxy = new CommonProxy();
- return commonProxy;
- }
-
- @SubscribeEvent
- public void packetRegistrationEvent(FMLNetworkEvent.CustomPacketRegistrationEvent event) {
- if (event.getOperation().equals("REGISTER") &&
- event.getRegistrations().contains("bbor") &&
- event.getHandler() instanceof NetHandlerPlayServer) {
- registeredPlayers.add(((NetHandlerPlayServer) event.getHandler()).player);
- onRegisteredPlayerCountChanged(registeredPlayers.size());
- }
- }
-
- protected SimpleNetworkWrapper network;
- private CommonProxy commonProxy;
-
- void init() {
- CommonProxy proxy = getProxy();
- proxy.setEventHandler(this);
- proxy.init();
- network = NetworkRegistry.INSTANCE.newSimpleChannel("bbor");
- network.registerMessage(AddBoundingBoxMessageHandler.class, AddBoundingBoxMessage.class, 0, Side.CLIENT);
- network.registerMessage(RemoveBoundingBoxMessageHandler.class, RemoveBoundingBoxMessage.class, 1, Side.CLIENT);
- network.registerMessage(InitializeClientMessageHandler.class, InitializeClientMessage.class, 2, Side.CLIENT);
- }
-
- @SubscribeEvent
- public void worldEvent(WorldEvent.Load event) {
- World world = event.getWorld();
- getProxy().worldLoaded(world);
- }
-
- @SubscribeEvent
- public void chunkEvent(ChunkEvent.Load event) {
- getProxy().chunkLoaded(event.getChunk());
- }
-
- @SubscribeEvent
- public void playerChangedDimensionEvent(PlayerEvent.PlayerChangedDimensionEvent evt) {
- if (playerDimensions.containsKey(evt.player)) {
- EntityPlayerMP player = (EntityPlayerMP) evt.player;
- sendBoundingBoxes(player);
- }
- }
-
- @SubscribeEvent
- public void playerLoggedInEvent(PlayerEvent.PlayerLoggedInEvent evt) {
- if (evt.player instanceof EntityPlayerMP &&
- isRemotePlayer(evt.player)) {
- EntityPlayerMP player = (EntityPlayerMP) evt.player;
- initializeClient(player);
- sendBoundingBoxes(player);
- }
- }
-
- private void sendBoundingBoxes(EntityPlayerMP player) {
- DimensionType dimensionType = DimensionType.getById(player.dimension);
- playerDimensions.put(player, dimensionType);
- sendToPlayer(player, getDimensionCache().getBoundingBoxes(dimensionType));
- }
-
- protected boolean isRemotePlayer(EntityPlayer player) {
- return registeredPlayers.contains(player);
- }
-
- private void initializeClient(EntityPlayerMP player) {
- network.sendTo(InitializeClientMessage.from(getDimensionCache().getWorldData()), player);
- }
-
- @SubscribeEvent
- public void playerLoggedOutEvent(PlayerEvent.PlayerLoggedOutEvent evt) {
- if (isRemotePlayer(evt.player)) {
- playerDimensions.remove(evt.player);
- playerBoundingBoxesCache.remove(evt.player);
- registeredPlayers.remove(evt.player);
- onRegisteredPlayerCountChanged(registeredPlayers.size());
- }
- }
-
- protected void onRegisteredPlayerCountChanged(int registeredPlayerCount) {
- }
-
- @SubscribeEvent
- public void tickEvent(TickEvent event) {
- for (EntityPlayerMP player : playerDimensions.keySet()) {
- MinecraftServer mc = FMLCommonHandler.instance().getMinecraftServerInstance();
- if (!mc.getPlayerList().getPlayers().contains(player)) {
- playerDimensions.remove(player);
- } else {
- DimensionType dimensionType = playerDimensions.get(player);
- sendToPlayer(player, getDimensionCache().getBoundingBoxes(dimensionType));
- }
- }
- getProxy().tick();
- }
-
- private void sendToPlayer(EntityPlayerMP player, BoundingBoxCache boundingBoxCache) {
- if (boundingBoxCache == null)
- return;
- Map<BoundingBox, Set<BoundingBox>> cacheSubset = getBoundingBoxMap(player, boundingBoxCache.getBoundingBoxes());
-
- DimensionType dimensionType = DimensionType.getById(player.dimension);
- if (cacheSubset.keySet().size() > 0) {
- Logger.info("send %d entries to %s (%s)", cacheSubset.keySet().size(), player.getDisplayNameString(), dimensionType);
- }
-
- for (BoundingBox key : cacheSubset.keySet()) {
- Set<BoundingBox> boundingBoxes = cacheSubset.get(key);
- network.sendTo(AddBoundingBoxMessage.from(dimensionType, key, boundingBoxes), player);
-
- if (!playerBoundingBoxesCache.containsKey(player)) {
- playerBoundingBoxesCache.put(player, new HashSet<>());
- }
- playerBoundingBoxesCache.get(player).add(key);
- }
- }
-
- private Map<BoundingBox, Set<BoundingBox>> getBoundingBoxMap(EntityPlayerMP player, Map<BoundingBox, Set<BoundingBox>> boundingBoxMap) {
- Map<BoundingBox, Set<BoundingBox>> cacheSubset = new HashMap<>();
- for (BoundingBox key : boundingBoxMap.keySet()) {
- if (!playerBoundingBoxesCache.containsKey(player) || !playerBoundingBoxesCache.get(player).contains(key)) {
- cacheSubset.put(key, boundingBoxMap.get(key));
- }
- }
- return cacheSubset;
- }
-
- public void villageRemoved(DimensionType dimensionType, BoundingBox bb) {
- RemoveBoundingBoxMessage message = RemoveBoundingBoxMessage.from(dimensionType, bb);
- for (EntityPlayerMP player : playerDimensions.keySet()) {
- if (DimensionType.getById(player.dimension) == dimensionType) {
- Logger.info("remove 1 entry from %s (%s)", player.getDisplayNameString(), dimensionType);
- network.sendTo(message, player);
-
- if (playerBoundingBoxesCache.containsKey(player) &&
- playerBoundingBoxesCache.get(player).contains(bb)) {
- playerBoundingBoxesCache.get(player).remove(bb);
- }
- }
- }
- }
-
- public void setWorldData(long seed, int spawnX, int spawnZ) {
- getDimensionCache().setWorldData(seed, spawnX, spawnZ);
- }
-
- public void addBoundingBox(DimensionType dimensionType, BoundingBox key, Set<BoundingBox> boundingBoxes) {
- DimensionCache dimensionCache = getDimensionCache();
- BoundingBoxCache cache = dimensionCache.getBoundingBoxes(dimensionType);
- if (cache == null) {
- dimensionCache.put(dimensionType, cache = new BoundingBoxCache());
- }
- cache.addBoundingBoxes(key, boundingBoxes);
- }
-
- public void removeBoundingBox(DimensionType dimensionType, BoundingBox key) {
- BoundingBoxCache cache = getDimensionCache().getBoundingBoxes(dimensionType);
- if (cache != null) {
- cache.removeBoundingBox(key);
- }
- }
-
- private DimensionCache getDimensionCache() {
- return getProxy().getDimensionCache();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge;
-
-import com.irtimaled.bbor.config.ConfigManager;
-import net.minecraftforge.common.MinecraftForge;
-import net.minecraftforge.fml.common.Mod;
-import net.minecraftforge.fml.common.SidedProxy;
-import net.minecraftforge.fml.common.event.FMLInitializationEvent;
-import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
-import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
-
-@Mod(modid = ForgeMod.MODID, name = ForgeMod.NAME, version = ForgeMod.VERSION, acceptedMinecraftVersions = ForgeMod.MCVERSION, acceptableRemoteVersions = "*")
-public class ForgeMod {
- static final String MODID = "bbor";
- static final String NAME = "BoundingBoxOutlineReloaded";
- static final String VERSION = "1.0.3";
- static final String MCVERSION = "1.12.2";
-
- public SimpleNetworkWrapper network;
-
- @Mod.Instance()
- public static ForgeMod instance;
-
- @SidedProxy(clientSide = "com.irtimaled.bbor.forge.ForgeClientProxy", serverSide = "com.irtimaled.bbor.forge.ForgeCommonProxy")
- public static ForgeCommonProxy proxy;
-
- @Mod.EventHandler
- public void preInit(FMLPreInitializationEvent evt) {
- ConfigManager.loadConfig(evt.getModConfigurationDirectory());
- }
-
- @Mod.EventHandler
- public void load(FMLInitializationEvent evt) {
- MinecraftForge.EVENT_BUS.register(proxy);
- proxy.init();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge.messages;
-
-import com.irtimaled.bbor.common.models.BoundingBox;
-import io.netty.buffer.ByteBuf;
-import net.minecraft.world.DimensionType;
-import net.minecraftforge.fml.common.network.ByteBufUtils;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
-
-import java.util.HashSet;
-import java.util.Set;
-
-public class AddBoundingBoxMessage implements IMessage {
- private DimensionType dimensionType;
- private BoundingBox key;
- private Set<BoundingBox> boundingBoxes;
-
- public static AddBoundingBoxMessage from(DimensionType dimensionType, BoundingBox key, Set<BoundingBox> boundingBoxes) {
- AddBoundingBoxMessage message = new AddBoundingBoxMessage();
- message.dimensionType = dimensionType;
- message.key = key;
- message.boundingBoxes = boundingBoxes;
- return message;
- }
-
- @Override
- public void fromBytes(ByteBuf buf) {
- dimensionType = DimensionType.getById(ByteBufUtils.readVarInt(buf, 5));
- key = BoundingBoxDeserializer.deserialize(buf);
- boundingBoxes = new HashSet<>();
- while (buf.isReadable()) {
- BoundingBox boundingBox = BoundingBoxDeserializer.deserialize(buf);
- boundingBoxes.add(boundingBox);
- }
- if (boundingBoxes.size() == 0)
- boundingBoxes.add(key);
- }
-
- @Override
- public void toBytes(ByteBuf buf) {
- ByteBufUtils.writeVarInt(buf, dimensionType.getId(), 5);
- BoundingBoxSerializer.serialize(key, buf);
- if (boundingBoxes != null &&
- boundingBoxes.size() > 1) {
- for (BoundingBox boundingBox : boundingBoxes) {
- BoundingBoxSerializer.serialize(boundingBox, buf);
- }
- }
- }
-
- public DimensionType getDimensionType() {
- return dimensionType;
- }
-
- BoundingBox getKey() {
- return key;
- }
-
- Set<BoundingBox> getBoundingBoxes() {
- return boundingBoxes;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge.messages;
-
-import com.irtimaled.bbor.forge.ForgeMod;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
-import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
-
-public class AddBoundingBoxMessageHandler implements IMessageHandler<AddBoundingBoxMessage, IMessage> {
- @Override
- public IMessage onMessage(AddBoundingBoxMessage message, MessageContext ctx) {
- ForgeMod.proxy.addBoundingBox(message.getDimensionType(), message.getKey(), message.getBoundingBoxes());
- return null;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge.messages;
-
-import com.irtimaled.bbor.common.models.BoundingBox;
-import com.irtimaled.bbor.common.models.BoundingBoxStructure;
-import com.irtimaled.bbor.common.models.BoundingBoxVillage;
-import io.netty.buffer.ByteBuf;
-import net.minecraft.util.math.BlockPos;
-import net.minecraftforge.fml.common.network.ByteBufUtils;
-
-import java.awt.*;
-import java.util.HashSet;
-import java.util.Set;
-
-class BoundingBoxDeserializer {
- static BoundingBox deserialize(ByteBuf buf) {
- char type = (char) ByteBufUtils.readVarShort(buf);
- switch (type) {
- case 'V':
- return deserializeVillage(buf);
- case 'S':
- return deserializeStructure(buf);
- }
- return null;
- }
-
- private static BoundingBox deserializeStructure(ByteBuf buf) {
- BlockPos minBlockPos = deserializeBlockPos(buf);
- BlockPos maxBlockPos = deserializeBlockPos(buf);
- Color color = new Color(ByteBufUtils.readVarInt(buf, 5));
- return BoundingBoxStructure.from(minBlockPos, maxBlockPos, color);
- }
-
- private static BoundingBox deserializeVillage(ByteBuf buf) {
- BlockPos center = deserializeBlockPos(buf);
- int radius = ByteBufUtils.readVarInt(buf, 5);
- boolean spawnsIronGolems = ByteBufUtils.readVarShort(buf) == 1;
- Color color = new Color(ByteBufUtils.readVarInt(buf, 5));
- Set<BlockPos> doors = new HashSet<>();
- while (buf.isReadable()) {
- BlockPos door = deserializeBlockPos(buf);
- doors.add(door);
- }
- return BoundingBoxVillage.from(center, radius, color, spawnsIronGolems, doors);
- }
-
- private static BlockPos deserializeBlockPos(ByteBuf buf) {
- int x = ByteBufUtils.readVarInt(buf, 5);
- int y = ByteBufUtils.readVarInt(buf, 5);
- int z = ByteBufUtils.readVarInt(buf, 5);
- return new BlockPos(x, y, z);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge.messages;
-
-import com.irtimaled.bbor.common.models.BoundingBox;
-import com.irtimaled.bbor.common.models.BoundingBoxStructure;
-import com.irtimaled.bbor.common.models.BoundingBoxVillage;
-import io.netty.buffer.ByteBuf;
-import net.minecraft.util.math.BlockPos;
-import net.minecraftforge.fml.common.network.ByteBufUtils;
-
-import java.awt.*;
-
-class BoundingBoxSerializer {
- static void serialize(BoundingBox boundingBox, ByteBuf buf) {
- if (boundingBox instanceof BoundingBoxVillage) {
- serializeVillage((BoundingBoxVillage) boundingBox, buf);
- }
- if (boundingBox instanceof BoundingBoxStructure) {
- serializeStructure((BoundingBoxStructure) boundingBox, buf);
- }
- }
-
- private static void serializeVillage(BoundingBoxVillage boundingBox, ByteBuf buf) {
- ByteBufUtils.writeVarShort(buf, 'V');
- serializeBlockPos(boundingBox.getCenter(), buf);
- ByteBufUtils.writeVarInt(buf, boundingBox.getRadius(), 5);
- ByteBufUtils.writeVarShort(buf, boundingBox.getSpawnsIronGolems() ? 1 : 0);
- serializeColor(boundingBox.getColor(), buf);
- for (BlockPos door : boundingBox.getDoors()) {
- serializeBlockPos(door, buf);
- }
- }
-
- private static void serializeStructure(BoundingBoxStructure boundingBox, ByteBuf buf) {
- ByteBufUtils.writeVarShort(buf, 'S');
- serializeCuboid(boundingBox, buf);
- serializeColor(boundingBox.getColor(), buf);
- }
-
- private static void serializeColor(Color color, ByteBuf buf) {
- ByteBufUtils.writeVarInt(buf, color.getRGB(), 5);
- }
-
- private static void serializeCuboid(BoundingBox boundingBox, ByteBuf buf) {
- serializeBlockPos(boundingBox.getMinBlockPos(), buf);
- serializeBlockPos(boundingBox.getMaxBlockPos(), buf);
- }
-
- private static void serializeBlockPos(BlockPos blockPos, ByteBuf buf) {
- ByteBufUtils.writeVarInt(buf, blockPos.getX(), 5);
- ByteBufUtils.writeVarInt(buf, blockPos.getY(), 5);
- ByteBufUtils.writeVarInt(buf, blockPos.getZ(), 5);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge.messages;
-
-import com.irtimaled.bbor.common.models.WorldData;
-import io.netty.buffer.ByteBuf;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
-
-public class InitializeClientMessage implements IMessage {
- private WorldData worldData;
-
- public static InitializeClientMessage from(WorldData worldData) {
- InitializeClientMessage message = new InitializeClientMessage();
- message.worldData = new WorldData(worldData.getSeed(), worldData.getSpawnX(), worldData.getSpawnZ());
- return message;
- }
-
- @Override
- public void fromBytes(ByteBuf buf) {
- long seed = buf.readLong();
- int spawnX = buf.readInt();
- int spawnZ = buf.readInt();
- worldData = new WorldData(seed, spawnX, spawnZ);
- }
-
- @Override
- public void toBytes(ByteBuf buf) {
- buf.writeLong(worldData.getSeed());
- buf.writeInt(worldData.getSpawnX());
- buf.writeInt(worldData.getSpawnZ());
- }
-
- WorldData getWorldData() {
- return worldData;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge.messages;
-
-import com.irtimaled.bbor.common.models.WorldData;
-import com.irtimaled.bbor.forge.ForgeMod;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
-import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
-
-public class InitializeClientMessageHandler implements IMessageHandler<InitializeClientMessage, IMessage> {
- @Override
- public IMessage onMessage(InitializeClientMessage message, MessageContext ctx) {
- WorldData worldData = message.getWorldData();
- ForgeMod.proxy.setWorldData(worldData.getSeed(), worldData.getSpawnX(), worldData.getSpawnZ());
- return null;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge.messages;
-
-import com.irtimaled.bbor.common.models.BoundingBox;
-import io.netty.buffer.ByteBuf;
-import net.minecraft.world.DimensionType;
-import net.minecraftforge.fml.common.network.ByteBufUtils;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
-
-public class RemoveBoundingBoxMessage implements IMessage {
- private DimensionType dimensionType;
- private BoundingBox key;
-
- public static RemoveBoundingBoxMessage from(DimensionType dimensionType, BoundingBox key) {
- RemoveBoundingBoxMessage message = new RemoveBoundingBoxMessage();
- message.dimensionType = dimensionType;
- message.key = key;
- return message;
- }
-
- @Override
- public void fromBytes(ByteBuf buf) {
- dimensionType = DimensionType.getById(ByteBufUtils.readVarInt(buf, 5));
- key = BoundingBoxDeserializer.deserialize(buf);
- }
-
- @Override
- public void toBytes(ByteBuf buf) {
- ByteBufUtils.writeVarInt(buf, dimensionType.getId(), 5);
- BoundingBoxSerializer.serialize(key, buf);
- }
-
- public DimensionType getDimensionType() {
- return dimensionType;
- }
-
- BoundingBox getKey() {
- return key;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.forge.messages;
-
-import com.irtimaled.bbor.forge.ForgeMod;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
-import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
-import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
-
-public class RemoveBoundingBoxMessageHandler implements IMessageHandler<RemoveBoundingBoxMessage, IMessage> {
- @Override
- public IMessage onMessage(RemoveBoundingBoxMessage message, MessageContext ctx) {
- ForgeMod.proxy.removeBoundingBox(message.getDimensionType(), message.getKey());
- return null;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.litemod;
-
-import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
-import com.mumfrey.liteloader.Tickable;
-import net.minecraft.client.Minecraft;
-
-import java.io.File;
-
-public class LiteMod implements Tickable {
- public LiteMod() {
- }
-
- @Override
- public String getName() {
- return "BoundingBoxOutlineReloaded";
- }
-
- @Override
- public String getVersion() {
- return "1.0.1";
- }
-
- @Override
- public void init(File configPath) {
- BoundingBoxOutlineReloaded.init();
- }
-
- @Override
- public void upgradeSettings(String version, File configPath, File oldConfigPath) {
- }
-
- @Override
- public void onTick(Minecraft minecraft, float partialTicks, boolean inGame, boolean clock) {
- BoundingBoxOutlineReloaded.keyPressed();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.litemod.mixins;
-
-import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
-import net.minecraft.world.chunk.Chunk;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(Chunk.class)
-public abstract class MixinChunk {
- @Inject(method = "onLoad",
- at = @At("RETURN"))
- private void onLoaded(CallbackInfo ci) {
- BoundingBoxOutlineReloaded.chunkLoaded((Chunk)(Object)this);
- }
-}
\ No newline at end of file
+++ /dev/null
-package com.irtimaled.bbor.litemod.mixins;
-
-import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
-import com.mumfrey.liteloader.client.overlays.IEntityRenderer;
-import net.minecraft.client.renderer.EntityRenderer;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(EntityRenderer.class)
-public abstract class MixinEntityRenderer implements IEntityRenderer {
- @Inject(method = "renderWorldPass",
- at = @At(shift = At.Shift.BEFORE,
- value = "INVOKE_STRING",
- target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
- args = "ldc=hand"))
- private void onRenderHand(int pass, float partialTicks, long timeSlice, CallbackInfo ci) {
- BoundingBoxOutlineReloaded.render(partialTicks);
- }
-}
\ No newline at end of file
+++ /dev/null
-package com.irtimaled.bbor.litemod.mixins;
-
-import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.server.integrated.IntegratedServer;
-import net.minecraft.world.World;
-import net.minecraft.world.WorldType;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(IntegratedServer.class)
-public abstract class MixinIntegratedServer extends MinecraftServer {
- public MixinIntegratedServer() {
- super(null, null, null, null, null, null, null);
- }
-
- @Inject(method = "loadAllWorlds",
- at = @At("RETURN"),
- remap = false)
- private void onLoadAllWorlds(String saveName, String worldNameIn, long seed, WorldType type, String generatorOptions, CallbackInfo ci) {
- for (World world : this.worlds) {
- BoundingBoxOutlineReloaded.worldLoaded(world);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-package com.irtimaled.bbor.litemod.mixins;
-
-import net.minecraft.client.resources.I18n;
-import net.minecraft.client.settings.KeyBinding;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Overwrite;
-import org.spongepowered.asm.mixin.Shadow;
-
-import java.util.Map;
-
-@Mixin(KeyBinding.class)
-public abstract class MixinKeyBinding implements Comparable<KeyBinding> {
- @Shadow
- private static Map<String, Integer> CATEGORY_ORDER;
-
- @Shadow
- private String keyDescription;
-
- @Shadow
- private String keyCategory;
-
- @Overwrite()
- public int compareTo(KeyBinding p_compareTo_1_) {
- return this.keyCategory.equals(p_compareTo_1_.getKeyCategory()) ? I18n.format(this.keyDescription).compareTo(I18n.format(p_compareTo_1_.getKeyDescription())) : ((Integer) CATEGORY_ORDER.getOrDefault(this.keyCategory, 0)).compareTo(CATEGORY_ORDER.getOrDefault(p_compareTo_1_.getKeyCategory(), 0));
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.litemod.mixins;
-
-import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
-import net.minecraft.network.NetworkManager;
-import net.minecraft.network.Packet;
-import net.minecraft.network.login.client.CPacketLoginStart;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(NetworkManager.class)
-public abstract class MixinNetworkManager {
- @Inject(method = "sendPacket(Lnet/minecraft/network/Packet;)V",
- at = @At("RETURN"))
- private void onLoaded(Packet<?> packetIn, CallbackInfo ci) {
- if (packetIn instanceof CPacketLoginStart) {
- BoundingBoxOutlineReloaded.playerConnectedToServer((NetworkManager)(Object)this);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-package com.irtimaled.bbor.litemod.mixins;
-
-import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
-import net.minecraft.client.multiplayer.WorldClient;
-import net.minecraft.world.World;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.injection.At;
-import org.spongepowered.asm.mixin.injection.Inject;
-import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-
-@Mixin(WorldClient.class)
-public abstract class MixinWorldClient extends World {
- public MixinWorldClient() {
- super(null, null, null, null, true);
- }
-
- @Inject(method = "sendQuittingDisconnectingPacket",
- at = @At("RETURN"))
- private void onDisconnecting(CallbackInfo ci) {
- BoundingBoxOutlineReloaded.playerDisconnectedFromServer();
- }
-}
+++ /dev/null
-diff -r -u a/net/minecraft/client/Minecraft.java b/net/minecraft/client/Minecraft.java
---- a/net/minecraft/client/Minecraft.java 2017-09-27 12:01:40.000000000 -0700
-+++ b/net/minecraft/client/Minecraft.java 2017-09-27 11:30:01.000000000 -0700
-@@ -643,6 +643,8 @@
- }
-
- this.renderGlobal.makeEntityOutlineShader();
-+
-+ com.irtimaled.bbor.BoundingBoxOutlineReloaded.init();
- }
-
- /**
-@@ -2276,6 +2278,8 @@
- this.gameSettings.smoothCamera = !this.gameSettings.smoothCamera;
- }
-
-+ com.irtimaled.bbor.BoundingBoxOutlineReloaded.keyPressed();
-+
- for (int i = 0; i < 9; ++i)
- {
- boolean flag = this.gameSettings.keyBindSaveToolbar.isKeyDown();
+++ /dev/null
-diff -r -u a/net/minecraft/client/multiplayer/WorldClient.java b/net/minecraft/client/multiplayer/WorldClient.java
---- a/net/minecraft/client/multiplayer/WorldClient.java 2017-09-27 12:01:40.000000000 -0700
-+++ b/net/minecraft/client/multiplayer/WorldClient.java 2017-09-27 11:53:37.000000000 -0700
-@@ -320,6 +320,7 @@
- public void sendQuittingDisconnectingPacket()
- {
- this.connection.getNetworkManager().closeChannel(new TextComponentString("Quitting"));
-+ com.irtimaled.bbor.BoundingBoxOutlineReloaded.playerDisconnectedFromServer();
- }
-
- /**
+++ /dev/null
-diff -r -u a/net/minecraft/client/renderer/EntityRenderer.java b/net/minecraft/client/renderer/EntityRenderer.java
---- a/net/minecraft/client/renderer/EntityRenderer.java 2017-09-27 12:01:40.000000000 -0700
-+++ b/net/minecraft/client/renderer/EntityRenderer.java 2017-09-27 11:53:37.000000000 -0700
-@@ -1483,6 +1483,8 @@
- this.renderCloudsCheck(renderglobal, partialTicks, pass, d0, d1, d2);
- }
-
-+ com.irtimaled.bbor.BoundingBoxOutlineReloaded.render(partialTicks);
-+
- this.mc.mcProfiler.endStartSection("hand");
-
- if (this.renderHand)
+++ /dev/null
-diff -r -u a/net/minecraft/client/settings/KeyBinding.java b/net/minecraft/client/settings/KeyBinding.java
---- a/net/minecraft/client/settings/KeyBinding.java 2017-09-27 12:01:40.000000000 -0700
-+++ b/net/minecraft/client/settings/KeyBinding.java 2017-09-27 11:52:47.000000000 -0700
-@@ -184,5 +184,6 @@
- CATEGORY_ORDER.put("key.categories.multiplayer", Integer.valueOf(5));
- CATEGORY_ORDER.put("key.categories.ui", Integer.valueOf(6));
- CATEGORY_ORDER.put("key.categories.misc", Integer.valueOf(7));
-+ CATEGORY_ORDER.put("Bounding Box Outline Reloaded", Integer.valueOf(0));
- }
- }
+++ /dev/null
-diff -r -u a/net/minecraft/network/NetworkManager.java b/net/minecraft/network/NetworkManager.java
---- a/net/minecraft/network/NetworkManager.java 2017-09-27 12:01:41.000000000 -0700
-+++ b/net/minecraft/network/NetworkManager.java 2017-09-27 11:53:38.000000000 -0700
-@@ -32,6 +32,7 @@
- import java.util.concurrent.locks.ReentrantReadWriteLock;
- import javax.annotation.Nullable;
- import javax.crypto.SecretKey;
-+import net.minecraft.network.login.client.CPacketLoginStart;
- import net.minecraft.util.CryptManager;
- import net.minecraft.util.ITickable;
- import net.minecraft.util.LazyLoadBase;
-@@ -188,6 +189,10 @@
- this.readWriteLock.writeLock().unlock();
- }
- }
-+
-+ if (packetIn instanceof CPacketLoginStart) {
-+ com.irtimaled.bbor.BoundingBoxOutlineReloaded.playerConnectedToServer(this);
-+ }
- }
-
- public void sendPacket(Packet<?> packetIn, GenericFutureListener <? extends Future <? super Void >> listener, GenericFutureListener <? extends Future <? super Void >> ... listeners)
+++ /dev/null
-diff -r -u a/net/minecraft/server/integrated/IntegratedServer.java b/net/minecraft/server/integrated/IntegratedServer.java
---- a/net/minecraft/server/integrated/IntegratedServer.java 2017-09-27 12:01:41.000000000 -0700
-+++ b/net/minecraft/server/integrated/IntegratedServer.java 2017-09-27 11:37:50.000000000 -0700
-@@ -114,6 +114,8 @@
- this.worlds[i] = (WorldServer)(new WorldServerMulti(this, isavehandler, j, this.worlds[0], this.profiler)).init();
- }
-
-+ com.irtimaled.bbor.BoundingBoxOutlineReloaded.worldLoaded(this.worlds[i]);
-+
- this.worlds[i].addEventListener(new ServerWorldEventHandler(this, this.worlds[i]));
- }
-
+++ /dev/null
-diff -r -u a/net/minecraft/world/chunk/Chunk.java b/net/minecraft/world/chunk/Chunk.java
---- a/net/minecraft/world/chunk/Chunk.java 2017-09-27 12:01:41.000000000 -0700
-+++ b/net/minecraft/world/chunk/Chunk.java 2017-09-27 11:34:42.000000000 -0700
-@@ -935,6 +935,7 @@
- {
- this.world.loadEntities(classinheritancemultimap);
- }
-+ com.irtimaled.bbor.BoundingBoxOutlineReloaded.chunkLoaded(this);
- }
-
- /**
+++ /dev/null
-{
- "name": "bbor",
- "displayName": "BoundingBoxOutlineReloaded",
- "description": "Shows the bounding boxes of structures and features.",
- "version": "1.0.1",
- "author": "irtimaled",
- "mcversion": "1.12.1",
- "mixinConfigs": [
- "mixins.bbor.json"
- ]
-}
+++ /dev/null
-[
-{
- "modid": "bbor",
- "name": "Bounding Box Outline Reloaded",
- "description": "Shows the bounding boxes of structures and features.",
- "version": "${version}",
- "mcversion": "${mcversion}",
- "url": "http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2345401",
- "updateUrl": "",
- "authorList": ["irtimaled"],
- "credits": "Thanks to 4poc & KaboPC.",
- "logoFile": "",
- "screenshots": [],
- "dependencies": []
-}
-]
-
+++ /dev/null
-{
- "required": true,
- "minVersion": "0.7.3",
- "compatibilityLevel": "JAVA_8",
- "target": "@env(DEFAULT)",
- "package": "com.irtimaled.bbor.litemod.mixins",
- "refmap": "mixins.bbor.refmap.json",
- "mixins": [
- "MixinIntegratedServer",
- "MixinEntityRenderer",
- "MixinChunk",
- "MixinNetworkManager",
- "MixinWorldClient",
- "MixinKeyBinding"
- ],
- "injectors": {
- "defaultRequire": 1
- }
-}
+++ /dev/null
-{
- "mappings": {
- "com/irtimaled/bbor/litemod/mixins/MixinIntegratedServer": {
- "loadAllWorlds": "Lchd;a(Ljava/lang/String;Ljava/lang/String;JLamz;Ljava/lang/String;)V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinNetworkManager": {
- "sendPacket(Lnet/minecraft/network/Packet;)V": "Lgw;a(Lht;)V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinEntityRenderer": {
- "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V": "Lrl;c(Ljava/lang/String;)V",
- "renderWorldPass": "Lbuq;a(IFJ)V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinWorldClient": {
- "sendQuittingDisconnectingPacket": "Lbsb;O()V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinChunk": {
- "onLoad": "Laxw;c()V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinKeyBinding": {
- "compareTo": "Lbhy;a(Lbhy;)I"
- }
- },
- "data": {
- "notch": {
- "com/irtimaled/bbor/litemod/mixins/MixinIntegratedServer": {
- "loadAllWorlds": "Lchd;a(Ljava/lang/String;Ljava/lang/String;JLamz;Ljava/lang/String;)V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinNetworkManager": {
- "sendPacket(Lnet/minecraft/network/Packet;)V": "Lgw;a(Lht;)V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinEntityRenderer": {
- "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V": "Lrl;c(Ljava/lang/String;)V",
- "renderWorldPass": "Lbuq;a(IFJ)V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinWorldClient": {
- "sendQuittingDisconnectingPacket": "Lbsb;O()V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinChunk": {
- "onLoad": "Laxw;c()V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinKeyBinding": {
- "compareTo": "Lbhy;a(Lbhy;)I"
- }
- },
- "searge": {
- "com/irtimaled/bbor/litemod/mixins/MixinIntegratedServer": {
- "loadAllWorlds": "Lnet/minecraft/server/integrated/IntegratedServer;func_71247_a(Ljava/lang/String;Ljava/lang/String;JLnet/minecraft/world/WorldType;Ljava/lang/String;)V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinNetworkManager": {
- "sendPacket(Lnet/minecraft/network/Packet;)V": "Lnet/minecraft/network/NetworkManager;func_179290_a(Lnet/minecraft/network/Packet;)V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinEntityRenderer": {
- "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V": "Lnet/minecraft/profiler/Profiler;func_76318_c(Ljava/lang/String;)V",
- "renderWorldPass": "Lnet/minecraft/client/renderer/EntityRenderer;func_175068_a(IFJ)V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinWorldClient": {
- "sendQuittingDisconnectingPacket": "Lnet/minecraft/client/multiplayer/WorldClient;func_72882_A()V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinChunk": {
- "onLoad": "Lnet/minecraft/world/chunk/Chunk;func_76631_c()V"
- },
- "com/irtimaled/bbor/litemod/mixins/MixinKeyBinding": {
- "compareTo": "Lnet/minecraft/client/settings/KeyBinding;compareTo(Lnet/minecraft/client/settings/KeyBinding;)I"
- }
- }
- }
-}
+++ /dev/null
-{
- "pack": {
- "description": "bbor resources",
- "pack_format": 3,
- "_comment": "A pack_format of 3 should be used starting with Minecraft 1.11. All resources, including language files, should be lowercase (eg: en_us.lang). A pack_format of 2 will load your mod resources with LegacyV2Adapter, which requires language files to have uppercase letters (eg: en_US.lang)."
- }
-}
--- /dev/null
+package com.irtimaled.bbor;
+
+import org.apache.logging.log4j.LogManager;
+
+public class Logger {
+ private static final org.apache.logging.log4j.Logger logger = LogManager.getLogger();
+
+ public static void info(String s, Object... objects) {
+ if (objects.length == 0) {
+ logger.info(s);
+ } else {
+ logger.info(String.format(s, objects));
+ }
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client;
+
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.settings.KeyBinding;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.Chunk;
+
+import java.io.File;
+
+public class BoundingBoxOutlineReloaded {
+ private static ClientProxy proxy;
+
+ public static void init() {
+ ConfigManager.loadConfig(new File(Minecraft.getInstance().gameDir, "config"));
+ proxy = new ClientProxy();
+ proxy.init();
+ }
+
+ public static void chunkLoaded(Chunk chunk) {
+ proxy.chunkLoaded(chunk);
+ }
+
+ public static void worldLoaded(World world) {
+ proxy.worldLoaded(world);
+ }
+
+ public static void keyPressed() {
+ if (ActiveHotKey.isPressed()) {
+ proxy.toggleActive();
+ } else if (OuterBoxOnlyHotKey.isPressed()) {
+ proxy.toggleOuterBoxOnly();
+ }
+ }
+
+ public static final String KeyCategory = "Bounding Box Outline Reloaded";
+ public static KeyBinding ActiveHotKey = new KeyBinding("Toggle On/Off", 0x42, KeyCategory);
+ public static KeyBinding OuterBoxOnlyHotKey= new KeyBinding("Toggle Display Outer Box Only", 0x4f, KeyCategory);
+
+ public static void render(float partialTicks) {
+ proxy.tick();
+ proxy.render(partialTicks);
+ }
+
+ public static void playerConnectedToServer(NetworkManager networkManager) {
+ proxy.playerConnectedToServer(networkManager);
+ }
+
+ public static void playerDisconnectedFromServer() {
+ proxy.playerDisconnectedFromServer();
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client;
+
+import com.irtimaled.bbor.common.BoundingBoxCache;
+import com.irtimaled.bbor.common.models.BoundingBox;
+import com.irtimaled.bbor.common.models.BoundingBoxSlimeChunk;
+import com.irtimaled.bbor.common.models.BoundingBoxWorldSpawn;
+import com.irtimaled.bbor.common.models.WorldData;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.multiplayer.WorldClient;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.ChunkPos;
+import net.minecraft.util.math.MathHelper;
+import net.minecraft.world.dimension.DimensionType;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.Random;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+class ClientBoundingBoxProvider {
+ private final ClientDimensionCache dimensionCache;
+
+ ClientBoundingBoxProvider(ClientDimensionCache dimensionCache) {
+ this.dimensionCache = dimensionCache;
+ }
+
+ Set<BoundingBox> getBoundingBoxes(DimensionType dimensionType, Boolean outerBoxOnly, WorldClient world) {
+ Set<BoundingBox> boundingBoxes = getClientBoundingBoxes(dimensionType);
+ BoundingBoxCache boundingBoxCache = dimensionCache.getBoundingBoxes(dimensionType);
+ if (boundingBoxCache != null) {
+ if (outerBoxOnly) {
+ boundingBoxes.addAll(boundingBoxCache.getBoundingBoxes().keySet());
+ } else {
+ boundingBoxCache.getBoundingBoxes()
+ .values()
+ .forEach(boundingBoxes::addAll);
+ }
+ }
+
+ return boundingBoxes.stream()
+ .filter(bb -> world.isAreaLoaded(bb.getMinBlockPos(), bb.getMaxBlockPos()))
+ .collect(Collectors.toSet());
+ }
+
+ private Set<BoundingBox> getClientBoundingBoxes(DimensionType dimensionType) {
+ WorldData worldData = dimensionCache.getWorldData();
+
+ Set<BoundingBox> boundingBoxes = new HashSet<>();
+ if (worldData != null && dimensionType == DimensionType.OVERWORLD) {
+ if (ConfigManager.drawWorldSpawn.getBoolean()) {
+ boundingBoxes.add(getWorldSpawnBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
+ boundingBoxes.add(buildSpawnChunksBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
+ }
+ if (ConfigManager.drawLazySpawnChunks.getBoolean()) {
+ boundingBoxes.add(getLazySpawnChunksBoundingBox(worldData.getSpawnX(), worldData.getSpawnZ()));
+ }
+ if (ConfigManager.drawSlimeChunks.getBoolean()) {
+ boundingBoxes.addAll(this.getSlimeChunks());
+ }
+ }
+ return boundingBoxes;
+ }
+
+ private Set<BoundingBoxSlimeChunk> getSlimeChunks() {
+ Minecraft minecraft = Minecraft.getInstance();
+ int renderDistanceChunks = minecraft.gameSettings.renderDistanceChunks;
+ int playerChunkX = MathHelper.floor(minecraft.player.posX / 16.0D);
+ int playerChunkZ = MathHelper.floor(minecraft.player.posZ / 16.0D);
+ Set<BoundingBoxSlimeChunk> slimeChunks = new HashSet<>();
+ for (int chunkX = playerChunkX - renderDistanceChunks; chunkX <= playerChunkX + renderDistanceChunks; ++chunkX) {
+ for (int chunkZ = playerChunkZ - renderDistanceChunks; chunkZ <= playerChunkZ + renderDistanceChunks; ++chunkZ) {
+ if (isSlimeChunk(chunkX, chunkZ)) {
+ ChunkPos chunk = new ChunkPos(chunkX, chunkZ);
+ BlockPos minBlockPos = new BlockPos(chunk.getXStart(), 1, chunk.getZStart());
+ BlockPos maxBlockPos = new BlockPos(chunk.getXEnd(), 38, chunk.getZEnd());
+ if (minecraft.world.isAreaLoaded(minBlockPos, maxBlockPos)) {
+ slimeChunks.add(BoundingBoxSlimeChunk.from(minBlockPos, maxBlockPos, Color.GREEN));
+ }
+ }
+ }
+ }
+ return slimeChunks;
+ }
+
+ private boolean isSlimeChunk(int chunkX, int chunkZ) {
+ WorldData worldData = dimensionCache.getWorldData();
+ Random r = new Random(worldData.getSeed() +
+ (long) (chunkX * chunkX * 4987142) +
+ (long) (chunkX * 5947611) +
+ (long) (chunkZ * chunkZ) * 4392871L +
+ (long) (chunkZ * 389711) ^ 987234911L);
+ return r.nextInt(10) == 0;
+ }
+
+ private BoundingBox buildSpawnChunksBoundingBox(int spawnX, int spawnZ) {
+ return dimensionCache.getOrSetSpawnChunks(() -> buildSpawnChunksBoundingBox(spawnX, spawnZ, 12));
+ }
+
+ private BoundingBox getLazySpawnChunksBoundingBox(int spawnX, int spawnZ) {
+ return dimensionCache.getOrSetLazySpawnChunks(() -> buildSpawnChunksBoundingBox(spawnX, spawnZ, 16));
+ }
+
+ private BoundingBox buildSpawnChunksBoundingBox(int spawnX, int spawnZ, int size) {
+ double chunkSize = 16;
+ double midOffset = chunkSize * (size / 2);
+ double midX = Math.round((float) (spawnX / chunkSize)) * chunkSize;
+ double midZ = Math.round((float) (spawnZ / chunkSize)) * chunkSize;
+ BlockPos minBlockPos = new BlockPos(midX - midOffset, 0, midZ - midOffset);
+ if (spawnX / chunkSize % 0.5D == 0.0D && spawnZ / chunkSize % 0.5D == 0.0D) {
+ midX += chunkSize;
+ midZ += chunkSize;
+ }
+ BlockPos maxBlockPos = new BlockPos(midX + midOffset, 0, midZ + midOffset);
+ return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, Color.RED);
+ }
+
+ private BoundingBox getWorldSpawnBoundingBox(int spawnX, int spawnZ) {
+ return dimensionCache.getOrSetWorldSpawn(() -> buildWorldSpawnBoundingBox(spawnX, spawnZ));
+ }
+
+ private BoundingBox buildWorldSpawnBoundingBox(int spawnX, int spawnZ) {
+ BlockPos minBlockPos = new BlockPos(spawnX - 10, 0, spawnZ - 10);
+ BlockPos maxBlockPos = new BlockPos(spawnX + 10, 0, spawnZ + 10);
+
+ return BoundingBoxWorldSpawn.from(minBlockPos, maxBlockPos, Color.RED);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client;
+
+import com.irtimaled.bbor.common.DimensionCache;
+import com.irtimaled.bbor.common.models.BoundingBox;
+
+import java.util.function.Supplier;
+
+public class ClientDimensionCache extends DimensionCache {
+ private BoundingBox worldSpawnBoundingBox;
+ private BoundingBox spawnChunksBoundingBox;
+ private BoundingBox lazySpawnChunksBoundingBox;
+
+ @Override
+ public void setWorldData(long seed, int spawnX, int spawnZ) {
+ clearClientCache();
+ super.setWorldData(seed, spawnX, spawnZ);
+ }
+
+ @Override
+ public void clear() {
+ clearClientCache();
+ super.clear();
+ }
+
+ private void clearClientCache() {
+ worldSpawnBoundingBox = null;
+ spawnChunksBoundingBox = null;
+ lazySpawnChunksBoundingBox = null;
+ }
+
+ BoundingBox getOrSetSpawnChunks(Supplier<BoundingBox> defaultSupplier) {
+ if(spawnChunksBoundingBox == null) {
+ spawnChunksBoundingBox = defaultSupplier.get();
+ }
+ return spawnChunksBoundingBox;
+ }
+
+ BoundingBox getOrSetLazySpawnChunks(Supplier<BoundingBox> defaultSupplier) {
+ if(lazySpawnChunksBoundingBox == null) {
+ lazySpawnChunksBoundingBox = defaultSupplier.get();
+ }
+ return lazySpawnChunksBoundingBox;
+ }
+
+ BoundingBox getOrSetWorldSpawn(Supplier<BoundingBox> defaultSupplier) {
+ if(worldSpawnBoundingBox == null) {
+ worldSpawnBoundingBox = defaultSupplier.get();
+ }
+ return worldSpawnBoundingBox;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client;
+
+import com.irtimaled.bbor.common.CommonProxy;
+import com.irtimaled.bbor.common.VillageColorCache;
+import com.irtimaled.bbor.common.VillageProcessor;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.Minecraft;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.world.dimension.DimensionType;
+
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+
+public class ClientProxy extends CommonProxy {
+ private boolean active;
+ private boolean outerBoxOnly;
+ private ClientRenderer renderer;
+ private int remoteUserCount = 0;
+
+ public void toggleActive() {
+ active = !active;
+ if (active)
+ PlayerData.setActiveY();
+ }
+
+ public void toggleOuterBoxOnly() {
+ outerBoxOnly = !outerBoxOnly;
+ }
+
+ @Override
+ public void init() {
+ ClientDimensionCache clientDimensionCache = new ClientDimensionCache();
+ renderer = new ClientRenderer(clientDimensionCache);
+ dimensionCache = clientDimensionCache;
+ }
+
+ public void render(float partialTicks) {
+ EntityPlayer entityPlayer = Minecraft.getInstance().player;
+ PlayerData.setPlayerPosition(partialTicks, entityPlayer);
+
+ if (this.active) {
+ renderer.render(DimensionType.getById(entityPlayer.dimension), outerBoxOnly);
+ }
+ }
+
+ public void setRemoteUserCount(int remoteUserCount) {
+ this.remoteUserCount = remoteUserCount;
+ }
+
+ protected boolean hasRemoteUsers() {
+ return remoteUserCount > 0;
+ }
+
+ @Override
+ public void tick() {
+ if (this.active || this.hasRemoteUsers()) {
+ super.tick();
+ }
+ }
+
+ public void playerConnectedToServer(NetworkManager networkManager) {
+ SocketAddress remoteAddress = networkManager.getRemoteAddress();
+ if (remoteAddress instanceof InetSocketAddress) {
+ InetSocketAddress socketAddress = (InetSocketAddress) remoteAddress;
+ NBTFileParser.loadLocalDatFiles(socketAddress.getHostName(), socketAddress.getPort(), dimensionCache);
+ }
+ }
+
+ public void playerDisconnectedFromServer() {
+ active = false;
+ villageProcessors.forEach(VillageProcessor::close);
+ villageProcessors.clear();
+
+ if (ConfigManager.keepCacheBetweenSessions.getBoolean()) return;
+ VillageColorCache.clear();
+ dimensionCache.clear();
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client;
+
+import com.irtimaled.bbor.client.renderers.*;
+import com.irtimaled.bbor.common.models.*;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.Minecraft;
+import net.minecraft.world.dimension.DimensionType;
+import org.lwjgl.opengl.GL11;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class ClientRenderer {
+ private final ClientBoundingBoxProvider clientBoundingBoxProvider;
+ private static final Map<Class<? extends BoundingBox>, Renderer> boundingBoxRendererMap = new HashMap<>();
+
+ ClientRenderer(ClientDimensionCache dimensionCache) {
+ this.clientBoundingBoxProvider = new ClientBoundingBoxProvider(dimensionCache);
+ boundingBoxRendererMap.put(BoundingBoxVillage.class, new VillageRenderer());
+ boundingBoxRendererMap.put(BoundingBoxSlimeChunk.class, new SlimeChunkRenderer());
+ boundingBoxRendererMap.put(BoundingBoxWorldSpawn.class, new WorldSpawnRenderer());
+ boundingBoxRendererMap.put(BoundingBoxStructure.class, new StructureRenderer());
+ }
+
+ public void render(DimensionType dimensionType, Boolean outerBoxesOnly) {
+ Set<BoundingBox> boundingBoxes = clientBoundingBoxProvider.getBoundingBoxes(dimensionType, outerBoxesOnly, Minecraft.getInstance().world);
+ if (boundingBoxes == null || boundingBoxes.size() == 0)
+ return;
+
+ GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+ GL11.glLineWidth(2.0f);
+ GL11.glDisable(GL11.GL_TEXTURE_2D);
+ GL11.glDisable(GL11.GL_CULL_FACE);
+
+ if (ConfigManager.alwaysVisible.getBoolean()) {
+ GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT);
+ }
+ for (BoundingBox bb : boundingBoxes) {
+ Renderer renderer = boundingBoxRendererMap.get(bb.getClass());
+ if (renderer != null) {
+ renderer.render(bb);
+ }
+ }
+
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
+ GL11.glEnable(GL11.GL_CULL_FACE);
+ GL11.glEnable(GL11.GL_TEXTURE_2D);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client;
+
+import com.irtimaled.bbor.Logger;
+import com.irtimaled.bbor.common.BoundingBoxCache;
+import com.irtimaled.bbor.common.DimensionCache;
+import com.irtimaled.bbor.common.StructureType;
+import com.irtimaled.bbor.common.models.BoundingBox;
+import com.irtimaled.bbor.common.models.BoundingBoxStructure;
+import com.irtimaled.bbor.common.models.BoundingBoxVillage;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.nbt.CompressedStreamTools;
+import net.minecraft.nbt.NBTTagCompound;
+import net.minecraft.nbt.NBTTagList;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.world.dimension.DimensionType;
+
+import java.awt.*;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+class NBTFileParser {
+ static void loadLocalDatFiles(String host, int port, DimensionCache dimensionCache) {
+ Logger.info("Looking for local structures (host:port=%s:%d)", host, port);
+ String path = String.format("BBOutlineReloaded%s%s%s%d", File.separator, host, File.separator, port);
+ File localStructuresFolder = new File(ConfigManager.configDir, path);
+ Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
+ if (!localStructuresFolder.exists()) {
+ path = String.format("BBOutlineReloaded%s%s", File.separator, host);
+ localStructuresFolder = new File(ConfigManager.configDir, path);
+ Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
+ }
+ if (!localStructuresFolder.exists()) {
+ path = String.format("BBOutlineReloaded%s%s,%d", File.separator, host, port);
+ localStructuresFolder = new File(ConfigManager.configDir, path);
+ Logger.info("Looking for local structures (folder=%s)", localStructuresFolder.getAbsolutePath());
+ }
+ if (!localStructuresFolder.exists()) {
+ Logger.info("No local structures folders found");
+ return;
+ }
+ loadWorldData(localStructuresFolder, dimensionCache);
+ populateBoundingBoxCache(localStructuresFolder, dimensionCache);
+ }
+
+ private static void loadWorldData(File localStructuresFolder, DimensionCache dimensionCache) {
+ File file = new File(localStructuresFolder, "level.dat");
+ NBTTagCompound nbt = loadNbtFile(file);
+ if (nbt == null)
+ return;
+
+ NBTTagCompound data = nbt.getCompoundTag("Data");
+ long seed = data.getLong("RandomSeed");
+ int spawnX = data.getInteger("SpawnX");
+ int spawnZ = data.getInteger("SpawnZ");
+ Logger.info("Loaded level.dat (seed: %d, spawn: %d,%d)", seed, spawnX, spawnZ);
+ dimensionCache.setWorldData(seed, spawnX, spawnZ);
+ }
+
+ private static void populateBoundingBoxCache(File localStructuresFolder, DimensionCache dimensionCache) {
+ dimensionCache.put(DimensionType.OVERWORLD, loadOverworldStructures(localStructuresFolder));
+ dimensionCache.put(DimensionType.NETHER, loadNetherStructures(localStructuresFolder));
+ dimensionCache.put(DimensionType.THE_END, loadEndStructures(localStructuresFolder));
+ }
+
+ private static BoundingBoxCache loadOverworldStructures(File localStructuresFolder) {
+ BoundingBoxCache cache = new BoundingBoxCache();
+ if (ConfigManager.drawDesertTemples.getBoolean()) {
+ loadStructure(localStructuresFolder, cache, "Temple.dat", StructureType.DesertTemple.getColor(), "TeDP");
+ }
+ if (ConfigManager.drawJungleTemples.getBoolean()) {
+ loadStructure(localStructuresFolder, cache, "Temple.dat", StructureType.JungleTemple.getColor(), "TeJP");
+ }
+ if (ConfigManager.drawWitchHuts.getBoolean()) {
+ loadStructure(localStructuresFolder, cache, "Temple.dat", StructureType.WitchHut.getColor(), "TeSH");
+ }
+ if (ConfigManager.drawOceanMonuments.getBoolean()) {
+ loadStructure(localStructuresFolder, cache, "Monument.dat", StructureType.OceanMonument.getColor(), "*");
+ }
+ if (ConfigManager.drawStrongholds.getBoolean()) {
+ loadStructure(localStructuresFolder, cache, "Stronghold.dat", StructureType.Stronghold.getColor(), "*");
+ }
+ if (ConfigManager.drawMansions.getBoolean()) {
+ loadStructure(localStructuresFolder, cache, "Mansion.dat", StructureType.Mansion.getColor(), "*");
+ }
+ if (ConfigManager.drawMineShafts.getBoolean()) {
+ loadStructure(localStructuresFolder, cache, "Mineshaft.dat", StructureType.MineShaft.getColor(), "*");
+ }
+ if (ConfigManager.drawVillages.getBoolean()) {
+ loadVillages(localStructuresFolder, cache, "Villages.dat");
+ }
+ return cache;
+ }
+
+ private static BoundingBoxCache loadNetherStructures(File localStructuresFolder) {
+ BoundingBoxCache cache = new BoundingBoxCache();
+ if (ConfigManager.drawNetherFortresses.getBoolean())
+ loadStructure(localStructuresFolder, cache, "Fortress.dat", StructureType.NetherFortress.getColor(), "*");
+ if (ConfigManager.drawVillages.getBoolean()) {
+ loadVillages(localStructuresFolder, cache, "villages_nether.dat");
+ }
+ return cache;
+ }
+
+ private static BoundingBoxCache loadEndStructures(File localStructuresFolder) {
+ BoundingBoxCache cache = new BoundingBoxCache();
+ if (ConfigManager.drawVillages.getBoolean()) {
+ loadVillages(localStructuresFolder, cache, "Villages_end.dat");
+ }
+ if (ConfigManager.drawEndCities.getBoolean()) {
+ loadStructure(localStructuresFolder, cache, "EndCity.dat", StructureType.EndCity.getColor(), "*");
+ }
+ return cache;
+ }
+
+ private static void loadStructure(File localStructuresFolder, BoundingBoxCache cache, String fileName, Color color, String id) {
+ File file = new File(localStructuresFolder, fileName);
+ NBTTagCompound nbt = loadNbtFile(file);
+ if (nbt == null)
+ return;
+
+ NBTTagCompound features = nbt.getCompoundTag("data")
+ .getCompoundTag("Features");
+ int loadedStructureCount = 0;
+ for (Object key : features.getKeySet()) {
+ NBTTagCompound feature = features.getCompoundTag((String) key);
+ BoundingBox structure = BoundingBoxStructure.from(feature.getIntArray("BB"), color);
+ Set<BoundingBox> boundingBoxes = new HashSet<>();
+ NBTTagCompound[] children = getChildCompoundTags(feature, "Children");
+ for (NBTTagCompound child : children) {
+ if (id.equals(child.getString("id")) || id.equals("*"))
+ boundingBoxes.add(BoundingBoxStructure.from(child.getIntArray("BB"), color));
+ }
+ if (boundingBoxes.size() > 0)
+ ++loadedStructureCount;
+ cache.addBoundingBoxes(structure, boundingBoxes);
+ }
+
+ Logger.info("Loaded %s (%d structures with type %s)", fileName, loadedStructureCount, id);
+ }
+
+ private static void loadVillages(File localStructuresFolder, BoundingBoxCache cache, String fileName) {
+ File file = new File(localStructuresFolder, fileName);
+ NBTTagCompound nbt = loadNbtFile(file);
+ if (nbt == null)
+ return;
+
+ NBTTagCompound[] villages = getChildCompoundTags(nbt.getCompoundTag("data"), "Villages");
+ for (NBTTagCompound village : villages) {
+ BlockPos center = new BlockPos(village.getInteger("CX"), village.getInteger("CY"), village.getInteger("CZ"));
+ int radius = village.getInteger("Radius");
+ int population = village.getInteger("PopSize");
+ Set<BlockPos> doors = getDoors(village);
+ BoundingBox boundingBox = BoundingBoxVillage.from(center, radius, village.hashCode(), population, doors);
+ cache.addBoundingBox(boundingBox);
+ }
+
+ Logger.info("Loaded %s (%d villages)", fileName, villages.length);
+ }
+
+ private static Set<BlockPos> getDoors(NBTTagCompound village) {
+ Set<BlockPos> doors = new HashSet<>();
+ for (NBTTagCompound door : getChildCompoundTags(village, "Doors")) {
+ doors.add(new BlockPos(door.getInteger("X"), door.getInteger("Y"), door.getInteger("Z")));
+ }
+ return doors;
+ }
+
+ private static NBTTagCompound loadNbtFile(File file) {
+ if (!file.exists())
+ return null;
+ try {
+ return CompressedStreamTools.readCompressed(new FileInputStream(file));
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ private static NBTTagCompound[] getChildCompoundTags(NBTTagCompound parent, String key) {
+ NBTTagList tagList = parent.getTagList(key, 10);
+ NBTTagCompound[] result = new NBTTagCompound[tagList.size()];
+ for (int index = 0; index < tagList.size(); index++) {
+ result[index] = tagList.getCompoundTagAt(index);
+ }
+ return result;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client;
+
+import net.minecraft.entity.player.EntityPlayer;
+
+public class PlayerData {
+ private static double x;
+ private static double y;
+ private static double z;
+ private static double activeY;
+
+ static void setPlayerPosition(double partialTicks, EntityPlayer entityPlayer) {
+ x = entityPlayer.lastTickPosX + (entityPlayer.posX - entityPlayer.lastTickPosX) * partialTicks;
+ y = entityPlayer.lastTickPosY + (entityPlayer.posY - entityPlayer.lastTickPosY) * partialTicks;
+ z = entityPlayer.lastTickPosZ + (entityPlayer.posZ - entityPlayer.lastTickPosZ) * partialTicks;
+ }
+
+ static void setActiveY() {
+ activeY = y;
+ }
+
+ public static double getX() {
+ return x;
+ }
+
+ public static double getY() {
+ return y;
+ }
+
+ public static double getZ() {
+ return z;
+ }
+
+ public static double getMaxY(double configMaxY) {
+ if (configMaxY == -1) {
+ return activeY;
+ } else if ((configMaxY == 0) || (y < configMaxY)) {
+ return y;
+ }
+ return configMaxY;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.client.PlayerData;
+import com.irtimaled.bbor.common.models.BoundingBox;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.util.math.AxisAlignedBB;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.*;
+
+public abstract class Renderer<T extends BoundingBox> {
+ public abstract void render(T boundingBox);
+
+ void renderBoundingBox(T boundingBox) {
+ renderCuboid(boundingBox.toAxisAlignedBB(), boundingBox.getColor(), fill());
+ }
+
+ boolean fill() {
+ return ConfigManager.fill.getBoolean();
+ }
+
+ void renderRectangle(AxisAlignedBB aaBB, double minY, double maxY, Color color, Boolean fill) {
+ aaBB = new AxisAlignedBB(aaBB.minX, minY, aaBB.minZ, aaBB.maxX, maxY, aaBB.maxZ);
+ renderCuboid(aaBB, color, fill);
+ }
+
+ void renderCuboid(AxisAlignedBB aaBB, Color color, boolean fill) {
+ aaBB = offsetAxisAlignedBB(aaBB);
+ if (fill) {
+ renderFilledCuboid(aaBB, color);
+ }
+ renderUnfilledCuboid(aaBB, color);
+ }
+
+ private AxisAlignedBB offsetAxisAlignedBB(AxisAlignedBB axisAlignedBB) {
+ double growXZ = 0.001F;
+ double growY = 0;
+ if (axisAlignedBB.minY != axisAlignedBB.maxY) {
+ growY = growXZ;
+ }
+ return axisAlignedBB
+ .grow(growXZ, growY, growXZ)
+ .offset(-PlayerData.getX(), -PlayerData.getY(), -PlayerData.getZ());
+ }
+
+ private void renderFilledCuboid(AxisAlignedBB aaBB, Color color) {
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_FILL);
+ GL11.glEnable(GL11.GL_BLEND);
+ renderCuboid(aaBB, 30, color);
+ GL11.glDisable(GL11.GL_BLEND);
+ GL11.glEnable(GL11.GL_POLYGON_OFFSET_LINE);
+ GL11.glPolygonOffset(-1.f, -1.f);
+ }
+
+ private void renderUnfilledCuboid(AxisAlignedBB aaBB, Color color) {
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
+ renderCuboid(aaBB, 255, color);
+ }
+
+ private void renderCuboid(AxisAlignedBB bb, int alphaChannel, Color color) {
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder worldRenderer = tessellator.getBuffer();
+
+ int colorR = color.getRed();
+ int colorG = color.getGreen();
+ int colorB = color.getBlue();
+
+ worldRenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_COLOR);
+ worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ if (bb.minY != bb.maxY) {
+
+ worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.minX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.minX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+
+ worldRenderer.pos(bb.maxX, bb.minY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.minY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.maxZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ worldRenderer.pos(bb.maxX, bb.maxY, bb.minZ)
+ .color(colorR, colorG, colorB, alphaChannel)
+ .endVertex();
+ }
+ tessellator.draw();
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.client.PlayerData;
+import com.irtimaled.bbor.common.models.BoundingBoxSlimeChunk;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.util.math.AxisAlignedBB;
+
+import java.awt.*;
+
+public class SlimeChunkRenderer extends Renderer<BoundingBoxSlimeChunk> {
+ @Override
+ public void render(BoundingBoxSlimeChunk boundingBox) {
+ AxisAlignedBB aaBB = boundingBox.toAxisAlignedBB();
+ Color color = boundingBox.getColor();
+ renderCuboid(aaBB, color, fill());
+
+ double maxY = PlayerData.getMaxY(ConfigManager.slimeChunkMaxY.getInt());
+ if (maxY > 39) {
+ renderRectangle(aaBB, 39, maxY, color, fill());
+ }
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.common.models.BoundingBoxStructure;
+
+public class StructureRenderer extends Renderer<BoundingBoxStructure> {
+ @Override
+ public void render(BoundingBoxStructure boundingBox) {
+ renderBoundingBox(boundingBox);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.client.PlayerData;
+import com.irtimaled.bbor.common.models.BoundingBoxVillage;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.client.renderer.BufferBuilder;
+import net.minecraft.client.renderer.Tessellator;
+import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+import org.lwjgl.opengl.GL11;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.Set;
+
+public class VillageRenderer extends Renderer<BoundingBoxVillage> {
+ @Override
+ public void render(BoundingBoxVillage boundingBox) {
+ if (ConfigManager.renderVillageAsSphere.getBoolean()) {
+ renderBoundingBoxVillageAsSphere(boundingBox);
+ } else {
+ renderBoundingBox(boundingBox);
+ }
+ if (ConfigManager.drawIronGolemSpawnArea.getBoolean() &&
+ boundingBox.getSpawnsIronGolems()) {
+ renderIronGolemSpawnArea(boundingBox);
+ }
+ if (ConfigManager.drawVillageDoors.getBoolean()) {
+ renderVillageDoors(boundingBox);
+ }
+ }
+
+ private void renderIronGolemSpawnArea(BoundingBoxVillage boundingBox) {
+ BlockPos center = boundingBox.getCenter();
+ AxisAlignedBB abb = new AxisAlignedBB(new BlockPos(center.getX() - 8,
+ center.getY() - 3,
+ center.getZ() - 8),
+ new BlockPos(center.getX() + 8,
+ center.getY() + 3,
+ center.getZ() + 8))
+ .offset(boundingBox.getCenterOffsetX(), 0.0, boundingBox.getCenterOffsetZ());
+
+ renderCuboid(abb, boundingBox.getColor(), false);
+ }
+
+ private void renderVillageDoors(BoundingBoxVillage boundingBox) {
+ OffsetPoint center = new OffsetPoint(boundingBox.getCenter())
+ .add(boundingBox.getCenterOffsetX(), 0.0, boundingBox.getCenterOffsetZ());
+ Color color = boundingBox.getColor();
+ GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, GL11.GL_LINE);
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder worldRenderer = tessellator.getBuffer();
+
+ int colorR = color.getRed();
+ int colorG = color.getGreen();
+ int colorB = color.getBlue();
+
+ worldRenderer.begin(GL11.GL_LINES, worldRenderer.getVertexFormat());
+ for (BlockPos door : boundingBox.getDoors()) {
+ OffsetPoint point = new OffsetPoint(door).add(0.5, 0, 0.5);
+
+ worldRenderer.pos(point.getX(), point.getY(), point.getZ()).color(colorR, colorG, colorB, 255).endVertex();
+ worldRenderer.pos(center.getX(), center.getY(), center.getZ()).color(colorR, colorG, colorB, 255).endVertex();
+ }
+ tessellator.draw();
+ }
+
+ private void renderBoundingBoxVillageAsSphere(BoundingBoxVillage boundingBox) {
+ OffsetPoint center = new OffsetPoint(boundingBox.getCenter())
+ .add(boundingBox.getCenterOffsetX(), 0.0, boundingBox.getCenterOffsetZ());
+ int radius = boundingBox.getRadius();
+ Color color = boundingBox.getColor();
+ renderSphere(center, radius, color);
+ }
+
+ private void renderSphere(OffsetPoint center, double radius, Color color) {
+ GL11.glEnable(GL11.GL_POINT_SMOOTH);
+ GL11.glPointSize(2f);
+
+ Tessellator tessellator = Tessellator.getInstance();
+ BufferBuilder worldRenderer = tessellator.getBuffer();
+ worldRenderer.begin(GL11.GL_POINTS, DefaultVertexFormats.POSITION_COLOR);
+ for (OffsetPoint point : buildPoints(center, radius)) {
+ worldRenderer.pos(point.getX(), point.getY(), point.getZ())
+ .color(color.getRed(), color.getGreen(), color.getBlue(), 255)
+ .endVertex();
+ }
+ tessellator.draw();
+ }
+
+ private class OffsetPoint {
+ private final double x;
+ private final double y;
+ private final double z;
+
+ OffsetPoint(double x, double y, double z) {
+ this.x = x;
+ this.y = y;
+ this.z = z;
+ }
+
+ OffsetPoint(BlockPos blockPos) {
+ this.x = blockPos.getX();
+ this.y = blockPos.getY();
+ this.z = blockPos.getZ();
+ }
+
+ double getX() {
+ return x - PlayerData.getX();
+ }
+
+ double getY() {
+ return y - PlayerData.getY();
+ }
+
+ double getZ() {
+ return z - PlayerData.getZ();
+ }
+
+ public OffsetPoint add(double x, double y, double z) {
+ return new OffsetPoint(this.x + x, this.y + y, this.z + z);
+ }
+ }
+
+ private Set<OffsetPoint> buildPoints(OffsetPoint center, double radius) {
+ Set<OffsetPoint> points = new HashSet<>(1200);
+
+ double tau = 6.283185307179586D;
+ double pi = tau / 2D;
+ double segment = tau / 48D;
+
+ for (double t = 0.0D; t < tau; t += segment)
+ for (double theta = 0.0D; theta < pi; theta += segment) {
+ double dx = radius * Math.sin(t) * Math.cos(theta);
+ double dz = radius * Math.sin(t) * Math.sin(theta);
+ double dy = radius * Math.cos(t);
+
+ points.add(center.add(dx, dy, dz));
+ }
+ return points;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import com.irtimaled.bbor.client.PlayerData;
+import com.irtimaled.bbor.common.models.BoundingBoxWorldSpawn;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.util.math.AxisAlignedBB;
+
+import java.awt.*;
+
+public class WorldSpawnRenderer extends Renderer<BoundingBoxWorldSpawn> {
+ @Override
+ public void render(BoundingBoxWorldSpawn boundingBox) {
+ AxisAlignedBB aaBB = boundingBox.toAxisAlignedBB(false);
+ Color color = boundingBox.getColor();
+ double y = PlayerData.getMaxY(ConfigManager.worldSpawnMaxY.getInt()) + 0.001F;
+ renderRectangle(aaBB, y, y, color, false);
+ }
+}
\ No newline at end of file
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.common.models.BoundingBox;
+
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class BoundingBoxCache {
+ private Map<BoundingBox, Set<BoundingBox>> cache = new ConcurrentHashMap<>();
+
+ public Map<BoundingBox, Set<BoundingBox>> getBoundingBoxes() {
+ return cache;
+ }
+
+ public void close() {
+ cache.clear();
+ }
+
+ boolean isCached(BoundingBox key) {
+ return cache.containsKey(key);
+ }
+
+ public void addBoundingBoxes(BoundingBox key, Set<BoundingBox> boundingBoxes) {
+ cache.put(key, boundingBoxes);
+ }
+
+ public void addBoundingBox(BoundingBox key) {
+ Set<BoundingBox> boundingBoxes = new HashSet<>();
+ boundingBoxes.add(key);
+ addBoundingBoxes(key, boundingBoxes);
+ }
+
+ public void removeBoundingBox(BoundingBox key) {
+ if (cache.containsKey(key)) {
+ cache.remove(key);
+ }
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.Logger;
+import com.irtimaled.bbor.config.ConfigManager;
+import net.minecraft.world.World;
+import net.minecraft.world.chunk.Chunk;
+import net.minecraft.world.chunk.IChunkProvider;
+import net.minecraft.world.dimension.DimensionType;
+import net.minecraft.world.gen.ChunkProviderServer;
+
+import java.util.HashSet;
+import java.util.Set;
+
+public class CommonProxy {
+ protected DimensionCache dimensionCache;
+ protected Set<VillageProcessor> villageProcessors = new HashSet<>();
+
+ private IVillageEventHandler eventHandler = null;
+
+ public void worldLoaded(World world) {
+ IChunkProvider chunkProvider = world.getChunkProvider();
+ if (chunkProvider instanceof ChunkProviderServer) {
+ dimensionCache.setWorldData(world.getSeed(), world.getWorldInfo().getSpawnX(), world.getWorldInfo().getSpawnZ());
+ DimensionType dimensionType = world.dimension.getType();
+ Logger.info("create world dimension: %s, %s (seed: %d)", dimensionType, world.getClass().toString(), world.getSeed());
+ DimensionProcessor boundingBoxCache = new DimensionProcessor(dimensionType);
+ dimensionCache.put(dimensionType, boundingBoxCache);
+ if (ConfigManager.drawVillages.getBoolean()) {
+ villageProcessors.add(new VillageProcessor(world, dimensionType, eventHandler, boundingBoxCache));
+ }
+ }
+ }
+
+ public void chunkLoaded(Chunk chunk) {
+ DimensionType dimensionType = chunk.getWorld().dimension.getType();
+ BoundingBoxCache cache = dimensionCache.get(dimensionType);
+ if(cache instanceof DimensionProcessor) {
+ ((DimensionProcessor)cache).processChunk(chunk);
+ }
+ }
+
+ public void tick() {
+ villageProcessors.forEach(VillageProcessor::process);
+ }
+
+ public void init() {
+ dimensionCache = new DimensionCache();
+ }
+
+ public void setEventHandler(IVillageEventHandler eventHandler) {
+ this.eventHandler = eventHandler;
+ }
+
+ public DimensionCache getDimensionCache() {
+ return dimensionCache;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.common.models.WorldData;
+import net.minecraft.world.dimension.DimensionType;
+
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class DimensionCache {
+ private final Map<DimensionType, BoundingBoxCache> map = new ConcurrentHashMap<>();
+ private WorldData worldData;
+
+ public BoundingBoxCache get(DimensionType dimensionType) {
+ return map.get(dimensionType);
+ }
+
+ public void put(DimensionType dimensionType, BoundingBoxCache boundingBoxCache) {
+ map.put(dimensionType, boundingBoxCache);
+ }
+
+ public BoundingBoxCache getBoundingBoxes(DimensionType dimensionType) {
+ return map.get(dimensionType);
+ }
+
+ public void clear() {
+ worldData = null;
+ for (BoundingBoxCache cache : map.values()) {
+ cache.close();
+ }
+ map.clear();
+ }
+
+ public void setWorldData(long seed, int spawnX, int spawnZ) {
+ this.worldData = new WorldData(seed, spawnX, spawnZ);
+ }
+
+ public WorldData getWorldData() {
+ return worldData;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.Logger;
+import com.irtimaled.bbor.common.models.BoundingBox;
+import com.irtimaled.bbor.common.models.BoundingBoxStructure;
+import com.irtimaled.bbor.config.ConfigManager;
+import com.irtimaled.bbor.config.Setting;
+import net.minecraft.util.math.MutableBoundingBox;
+import net.minecraft.world.chunk.Chunk;
+import net.minecraft.world.dimension.DimensionType;
+import net.minecraft.world.gen.feature.structure.StructurePiece;
+import net.minecraft.world.gen.feature.structure.StructureStart;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class DimensionProcessor extends BoundingBoxCache {
+ DimensionProcessor(DimensionType dimensionType) {
+ this.dimensionType = dimensionType;
+ }
+
+ private DimensionType dimensionType;
+
+ private boolean closed = false;
+
+ @Override
+ public void close() {
+ closed = true;
+ super.close();
+ }
+
+ private void addStructures(Setting drawStructure, StructureType structureType, Map<String, StructureStart> structureMap) {
+ if (!drawStructure.getBoolean()) return;
+
+ StructureStart structureStart = structureMap.get(structureType.getName());
+ if (structureStart == null) return;
+ Color color = structureType.getColor();
+ MutableBoundingBox bb = structureStart.getBoundingBox();
+ if (bb == null)
+ return;
+
+ BoundingBox boundingBox = BoundingBoxStructure.from(bb, color);
+ if (isCached(boundingBox)) return;
+
+ Set<BoundingBox> structureBoundingBoxes = new HashSet<>();
+ for (StructurePiece structureComponent : structureStart.getComponents()) {
+ structureBoundingBoxes.add(BoundingBoxStructure.from(structureComponent.getBoundingBox(), color));
+ }
+ addBoundingBoxes(boundingBox, structureBoundingBoxes);
+ Logger.info("[%s] new dimensionCache entries: %d", dimensionType, structureBoundingBoxes.size());
+ }
+
+ public synchronized void processChunk(Chunk chunk) {
+ if (closed) return;
+
+ Map<String, StructureStart> structureMap = chunk.getStructureStarts();
+ if (structureMap.size() > 0) {
+ addStructures(ConfigManager.drawDesertTemples, StructureType.DesertTemple, structureMap);
+ addStructures(ConfigManager.drawJungleTemples, StructureType.JungleTemple, structureMap);
+ addStructures(ConfigManager.drawWitchHuts, StructureType.WitchHut, structureMap);
+ addStructures(ConfigManager.drawOceanMonuments, StructureType.OceanMonument, structureMap);
+ addStructures(ConfigManager.drawStrongholds, StructureType.Stronghold, structureMap);
+ addStructures(ConfigManager.drawMansions, StructureType.Mansion, structureMap);
+ addStructures(ConfigManager.drawMineShafts, StructureType.MineShaft, structureMap);
+ addStructures(ConfigManager.drawShipwrecks, StructureType.Shipwreck, structureMap);
+ addStructures(ConfigManager.drawOceanRuins, StructureType.OceanRuin, structureMap);
+ addStructures(ConfigManager.drawBuriedTreasure, StructureType.BuriedTreasure, structureMap);
+ addStructures(ConfigManager.drawIgloos, StructureType.Igloo, structureMap);
+ addStructures(ConfigManager.drawNetherFortresses, StructureType.NetherFortress, structureMap);
+ addStructures(ConfigManager.drawEndCities, StructureType.EndCity, structureMap);
+ }
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.common.models.BoundingBox;
+import net.minecraft.world.dimension.DimensionType;
+
+public interface IVillageEventHandler {
+ void villageRemoved(DimensionType dimensionType, BoundingBox bb);
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import java.awt.*;
+
+public class StructureType {
+ public final static StructureType JungleTemple = new StructureType(Color.GREEN, "Jungle_Pyramid");
+ public final static StructureType DesertTemple = new StructureType(Color.ORANGE, "Desert_Pyramid");
+ public final static StructureType WitchHut = new StructureType(Color.BLUE, "Swamp_Hut");
+ public final static StructureType OceanMonument = new StructureType(Color.CYAN, "Monument");
+ public final static StructureType Shipwreck = new StructureType(Color.CYAN, "Shipwreck");
+ public final static StructureType OceanRuin = new StructureType(Color.CYAN, "Ocean_Ruin");
+ public final static StructureType BuriedTreasure = new StructureType(Color.CYAN, "Buried_Treasure");
+ public final static StructureType Stronghold = new StructureType(Color.YELLOW, "Stronghold");
+ public final static StructureType MineShaft = new StructureType(Color.LIGHT_GRAY, "Mineshaft");
+ public final static StructureType NetherFortress = new StructureType(Color.RED, "Fortress");
+ public final static StructureType EndCity = new StructureType(Color.MAGENTA, "EndCity");
+ public final static StructureType Mansion = new StructureType(new Color(139, 69, 19), "Mansion");
+ public final static StructureType Igloo = new StructureType(Color.WHITE, "Igloo");
+
+ private final Color color;
+ private String name;
+
+ private StructureType(Color color, String name) {
+ this.color = color;
+ this.name = name;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+
+ public String getName() {
+ return name;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import java.awt.*;
+import java.util.HashMap;
+import java.util.Map;
+
+public class VillageColorCache {
+ private static int colorIndex = -1;
+
+ public static void clear() {
+ colorIndex = -1;
+ villageColorCache.clear();
+ }
+
+ private static Color getNextColor() {
+ switch (++colorIndex % 6) {
+ case 0:
+ return Color.RED;
+ case 1:
+ return Color.GREEN;
+ case 2:
+ return Color.BLUE;
+ case 3:
+ return Color.MAGENTA;
+ case 4:
+ return Color.YELLOW;
+ case 5:
+ return Color.CYAN;
+ }
+ return Color.WHITE;
+ }
+
+ private static Map<Integer, Color> villageColorCache = new HashMap<>();
+
+ public static Color getColor(int villageId) {
+ return villageColorCache.computeIfAbsent(villageId, k -> getNextColor());
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common;
+
+import com.irtimaled.bbor.common.models.BoundingBoxVillage;
+import net.minecraft.village.Village;
+import net.minecraft.village.VillageCollection;
+import net.minecraft.world.World;
+import net.minecraft.world.dimension.DimensionType;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class VillageProcessor {
+ private World world;
+ private DimensionType dimensionType;
+ private IVillageEventHandler eventHandler;
+ private BoundingBoxCache boundingBoxCache;
+ private Map<Integer, BoundingBoxVillage> villageCache = new HashMap<>();
+ private boolean closed = false;
+
+ VillageProcessor(World world, DimensionType dimensionType, IVillageEventHandler eventHandler, BoundingBoxCache boundingBoxCache) {
+ this.world = world;
+ this.dimensionType = dimensionType;
+ this.eventHandler = eventHandler;
+ this.boundingBoxCache = boundingBoxCache;
+ }
+
+ synchronized void process() {
+ if (closed) return;
+
+ Map<Integer, BoundingBoxVillage> oldVillages = new HashMap<>(villageCache);
+ Map<Integer, BoundingBoxVillage> newVillages = new HashMap<>();
+ VillageCollection villageCollection = world.getVillageCollection();
+ if (villageCollection != null) {
+ List<Village> villages = villageCollection.getVillageList();
+ for(int i = 0; i < villages.size(); i++) {
+ Village village = villages.get(i);
+ int villageId = village.hashCode();
+ BoundingBoxVillage newVillage = oldVillages.get(villageId);
+ if (newVillage != null && newVillage.matches(village)) {
+ oldVillages.remove(villageId);
+ } else {
+ newVillage = BoundingBoxVillage.from(village);
+ }
+ newVillages.put(villageId, newVillage);
+ }
+
+ }
+ for (BoundingBoxVillage village : oldVillages.values()) {
+ boundingBoxCache.removeBoundingBox(village);
+ if (eventHandler != null) {
+ eventHandler.villageRemoved(dimensionType, village);
+ }
+ }
+ for (BoundingBoxVillage village : newVillages.values()) {
+ boundingBoxCache.addBoundingBox(village);
+ }
+ villageCache = newVillages;
+ }
+
+ public void close() {
+ closed = true;
+ world = null;
+ eventHandler = null;
+ boundingBoxCache = null;
+ villageCache.clear();
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+import net.minecraft.util.math.AxisAlignedBB;
+import net.minecraft.util.math.BlockPos;
+
+import java.awt.*;
+
+public abstract class BoundingBox {
+ private final Color color;
+ private final BlockPos minBlockPos;
+ private final BlockPos maxBlockPos;
+
+ protected BoundingBox(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ this.minBlockPos = minBlockPos;
+ this.maxBlockPos = maxBlockPos;
+ this.color = color;
+ }
+
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + minBlockPos.hashCode();
+ result = prime * result + maxBlockPos.hashCode();
+ return result;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ BoundingBox other = (BoundingBox) obj;
+ return minBlockPos.equals(other.minBlockPos) && maxBlockPos.equals(other.maxBlockPos);
+ }
+
+ @Override
+ public String toString() {
+ return "(" + minBlockPos.toString() + "; " + maxBlockPos.toString() + ")";
+ }
+
+ public AxisAlignedBB toAxisAlignedBB() {
+ return toAxisAlignedBB(true);
+ }
+
+ public AxisAlignedBB toAxisAlignedBB(boolean extendMaxByOne) {
+ AxisAlignedBB axisAlignedBB = new AxisAlignedBB(minBlockPos, maxBlockPos);
+ if (extendMaxByOne)
+ return axisAlignedBB.expand(1, 1, 1);
+ return axisAlignedBB;
+ }
+
+ public BlockPos getMinBlockPos() {
+ return minBlockPos;
+ }
+
+ public BlockPos getMaxBlockPos() {
+ return maxBlockPos;
+ }
+
+ public Color getColor() {
+ return color;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+import net.minecraft.util.math.BlockPos;
+
+import java.awt.*;
+
+public class BoundingBoxSlimeChunk extends BoundingBox {
+ private BoundingBoxSlimeChunk(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ super(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxSlimeChunk from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ return new BoundingBoxSlimeChunk(minBlockPos, maxBlockPos, color);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.util.math.MutableBoundingBox;
+
+import java.awt.*;
+
+public class BoundingBoxStructure extends BoundingBox {
+ private BoundingBoxStructure(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ super(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxStructure from(MutableBoundingBox bb, Color color) {
+ BlockPos minBlockPos = new BlockPos(bb.minX, bb.minY, bb.minZ);
+ BlockPos maxBlockPos = new BlockPos(bb.maxX, bb.maxY, bb.maxZ);
+ return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxStructure from(int[] bb, Color color) {
+ BlockPos minBlockPos = new BlockPos(bb[0], bb[1], bb[2]);
+ BlockPos maxBlockPos = new BlockPos(bb[3], bb[4], bb[5]);
+ return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxStructure from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ return new BoundingBoxStructure(minBlockPos, maxBlockPos, color);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+import com.irtimaled.bbor.common.VillageColorCache;
+import net.minecraft.util.math.BlockPos;
+import net.minecraft.village.Village;
+import net.minecraft.village.VillageDoorInfo;
+
+import java.awt.*;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+public class BoundingBoxVillage extends BoundingBox {
+ private final BlockPos center;
+ private final Integer radius;
+ private final boolean spawnsIronGolems;
+ private Set<BlockPos> doors;
+ private Double centerOffsetX;
+ private Double centerOffsetZ;
+ private int villageHash;
+
+ private BoundingBoxVillage(BlockPos center, Integer radius, Color color, boolean spawnsIronGolems, Set<BlockPos> doors, BlockPos minBlockPos, BlockPos maxBlockPos) {
+ super(minBlockPos, maxBlockPos, color);
+ this.center = center;
+ this.radius = radius;
+ this.spawnsIronGolems = spawnsIronGolems;
+ this.doors = doors;
+ this.villageHash = computeHash(center, radius, spawnsIronGolems, doors);
+ calculateCenterOffsets(doors);
+ }
+
+ public static BoundingBoxVillage from(BlockPos center, Integer radius, Color color, boolean spawnsIronGolems, Set<BlockPos> doors) {
+ BlockPos minBlockPos = new BlockPos(center.getX() - radius,
+ center.getY() - 4,
+ center.getZ() - radius);
+ BlockPos maxBlockPos = new BlockPos(center.getX() + radius,
+ center.getY() + 4,
+ center.getZ() + radius);
+ return new BoundingBoxVillage(center, radius, color, spawnsIronGolems, doors, minBlockPos, maxBlockPos);
+ }
+
+ public static BoundingBoxVillage from(BlockPos center, Integer radius, int villageId, int population, Set<BlockPos> doors) {
+ Boolean spawnsIronGolems = shouldSpawnIronGolems(population, doors.size());
+ Color color = VillageColorCache.getColor(villageId);
+ return from(center, radius, color, spawnsIronGolems, doors);
+ }
+
+ private static boolean shouldSpawnIronGolems(int population, int doorCount) {
+ return population >= 10 && doorCount >= 21;
+ }
+
+ public static BoundingBoxVillage from(Village village) {
+ BlockPos center = village.getCenter();
+ int radius = village.getVillageRadius();
+ Set<BlockPos> doors = getDoorsFromVillage(village);
+ return from(center, radius, village.hashCode(), village.getNumVillagers(), doors);
+ }
+
+ private static Set<BlockPos> getDoorsFromVillage(Village village) {
+ Set<BlockPos> doors = new HashSet<>();
+ List<VillageDoorInfo> doorInfoList = village.getVillageDoorInfoList();
+ for (int i = 0; i < doorInfoList.size(); i++) {
+ VillageDoorInfo doorInfo = doorInfoList.get(i);
+ doors.add(doorInfo.getDoorBlockPos());
+ }
+ return doors;
+ }
+
+ private void calculateCenterOffsets(Set<BlockPos> doors) {
+ boolean processedFirstDoor = false;
+ int minX = 0;
+ int maxX = 0;
+ int minZ = 0;
+ int maxZ = 0;
+ for (BlockPos door : doors) {
+ if (!processedFirstDoor ||
+ (minX > door.getX()))
+ minX = door.getX();
+ if (!processedFirstDoor ||
+ maxX < door.getX())
+ maxX = door.getX();
+ if (!processedFirstDoor ||
+ minZ > door.getZ())
+ minZ = door.getZ();
+ if (!processedFirstDoor ||
+ maxZ < door.getZ())
+ maxZ = door.getZ();
+
+ processedFirstDoor = true;
+ }
+ centerOffsetX = Math.abs(maxX - minX) % 2 == 0 ? 0.5 : (minX < 0 ? 0 : 1);
+ centerOffsetZ = Math.abs(maxZ - minZ) % 2 == 0 ? 0.5 : (minZ < 0 ? 0 : 1);
+ }
+
+ @Override
+ public String toString() {
+ return "(" + center.toString() + "; " + radius.toString() + ")";
+ }
+
+ public Integer getRadius() {
+ return radius;
+ }
+
+ public BlockPos getCenter() {
+ return center;
+ }
+
+ public Double getCenterOffsetX() {
+ return centerOffsetX;
+ }
+
+ public Double getCenterOffsetZ() {
+ return centerOffsetZ;
+ }
+
+ private static int computeHash(BlockPos center, Integer radius, boolean spawnsIronGolems, Set<BlockPos> doors) {
+ int result = (center.hashCode() * 31) + radius;
+ for (BlockPos door : doors) {
+ result = (31 * result) + door.hashCode();
+ }
+ if (spawnsIronGolems) {
+ result = 31 * result;
+ }
+ return result;
+ }
+
+ public boolean matches(Village village) {
+ return this.villageHash == computeHash(village.getCenter(),
+ village.getVillageRadius(),
+ shouldSpawnIronGolems(village.getNumVillagers(), village.getNumVillageDoors()),
+ getDoorsFromVillage(village));
+ }
+
+ @Override
+ public int hashCode() {
+ return (super.hashCode() * 31) + villageHash;
+ }
+
+ public boolean getSpawnsIronGolems() {
+ return spawnsIronGolems;
+ }
+
+ public Set<BlockPos> getDoors() {
+ return doors;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+import net.minecraft.util.math.BlockPos;
+
+import java.awt.*;
+
+public class BoundingBoxWorldSpawn extends BoundingBox {
+ private BoundingBoxWorldSpawn(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ super(minBlockPos, maxBlockPos, color);
+ }
+
+ public static BoundingBoxWorldSpawn from(BlockPos minBlockPos, BlockPos maxBlockPos, Color color) {
+ return new BoundingBoxWorldSpawn(minBlockPos, maxBlockPos, color);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.common.models;
+
+public class WorldData {
+ private long seed;
+ private int spawnX;
+ private int spawnZ;
+
+ public WorldData(long seed, int spawnX, int spawnZ) {
+ this.seed = seed;
+ this.spawnX = spawnX;
+ this.spawnZ = spawnZ;
+ }
+
+ public long getSeed() {
+ return seed;
+ }
+
+ public int getSpawnX() {
+ return spawnX;
+ }
+
+ public int getSpawnZ() {
+ return spawnZ;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.config;
+
+import java.io.File;
+
+public class ConfigManager {
+ public static File configDir;
+
+ public static Setting fill;
+ public static Setting drawVillages;
+ public static Setting drawDesertTemples;
+ public static Setting drawJungleTemples;
+ public static Setting drawWitchHuts;
+ public static Setting drawStrongholds;
+ public static Setting drawMineShafts;
+ public static Setting drawNetherFortresses;
+ public static Setting drawOceanMonuments;
+ public static Setting alwaysVisible;
+ public static Setting renderVillageAsSphere;
+ public static Setting drawIronGolemSpawnArea;
+ public static Setting drawVillageDoors;
+ public static Setting drawSlimeChunks;
+ public static Setting slimeChunkMaxY;
+ public static Setting keepCacheBetweenSessions;
+ public static Setting drawWorldSpawn;
+ public static Setting worldSpawnMaxY;
+ public static Setting drawLazySpawnChunks;
+ public static Setting drawEndCities;
+ public static Setting drawMansions;
+ public static Setting drawShipwrecks;
+ public static Setting drawOceanRuins;
+ public static Setting drawBuriedTreasure;
+ public static Setting drawIgloos;
+
+ public static void loadConfig(File mcConfigDir) {
+ configDir = mcConfigDir;
+ configDir.mkdirs();
+ Configuration config = new Configuration(new File(configDir, "BBOutlineReloaded.cfg"));
+ config.load();
+
+ fill = SetupBooleanProperty(config, "general", "fill", true, "If set to true the bounding boxes are filled. (default: true)");
+ alwaysVisible = SetupBooleanProperty(config, "general", "alwaysVisible", false, "If set to true boxes will be visible even through other blocks. (default: false)");
+ keepCacheBetweenSessions = SetupBooleanProperty(config, "general", "keepCacheBetweenSessions", false, "If set to true bounding box caches will be kept between sessions. (default: false)");
+ drawVillages = SetupBooleanProperty(config, "features", "drawVillages", true, "If set to true village bounding boxes are drawn. (default: true)");
+ renderVillageAsSphere = SetupBooleanProperty(config, "features", "renderVillageAsSphere", true, "If set to true villages will be drawn as a sphere. (default:true)");
+ drawIronGolemSpawnArea = SetupBooleanProperty(config, "features", "drawIronGolemSpawnArea", true, "If set to true the iron golem spawn area of the village will be drawn. (default:true)");
+ drawVillageDoors = SetupBooleanProperty(config, "features", "drawVillageDoors", false, "If set to true lines between the village centre and doors will be drawn. (default:false)");
+ drawDesertTemples = SetupBooleanProperty(config, "features", "drawDesertTemples", true, "If set to true desert temple bounding boxes are drawn. (default: true)");
+ drawJungleTemples = SetupBooleanProperty(config, "features", "drawJungleTemples", true, "If set to true jungle temple bounding boxes are drawn. (default: true)");
+ drawWitchHuts = SetupBooleanProperty(config, "features", "drawWitchHuts", true, "If set to true witch hut bounding boxes are drawn. (default: true)");
+ drawStrongholds = SetupBooleanProperty(config, "features", "drawStrongholds", false, "If set to true stronghold bounding boxes are drawn. (default: false)");
+ drawMineShafts = SetupBooleanProperty(config, "features", "drawMineShafts", false, "If set to true mineshaft bounding boxes are drawn. (default: false)");
+ drawNetherFortresses = SetupBooleanProperty(config, "features", "drawNetherFortresses", true, "If set to true nether fortress bounding boxes are drawn. (default: true)");
+ drawOceanMonuments = SetupBooleanProperty(config, "features", "drawOceanMonuments", true, "If set to true ocean monument bounding boxes are drawn. (default: true)");
+ drawSlimeChunks = SetupBooleanProperty(config, "features", "drawSlimeChunks", true, "If set to true slime chunks bounding boxes are drawn. (default: true)");
+ slimeChunkMaxY = SetupIntegerProperty(config, "features", "slimeChunkMaxY", -1, "The maximum top of the slime chunk bounding box. If set to -1 it will use the value when activated, if set to 0 it will always track the player's feet. (default: -1)");
+ drawWorldSpawn = SetupBooleanProperty(config, "features", "drawWorldSpawn", true, "If set to true world spawn and spawn chunks bounding boxes are drawn. (default: true)");
+ worldSpawnMaxY = SetupIntegerProperty(config, "features", "worldSpawnMaxY", -1, "The maximum top of the world spawn bounding boxes. If set to -1 it will use the value when activated, if set to 0 it will always track the players feet. (default: -1)");
+ drawLazySpawnChunks = SetupBooleanProperty(config, "features", "drawLazySpawnChunks", false, "If set to true the lazy spawn chunks bounding boxes will be drawn. (default: false)");
+ drawEndCities = SetupBooleanProperty(config, "features", "drawEndCities", true, "If set to true end city bounding boxes will be drawn. (default: true)");
+ drawMansions = SetupBooleanProperty(config, "features", "drawMansions", true, "If set to true woodland mansions will be drawn. (default: true)");
+ drawShipwrecks = SetupBooleanProperty(config, "features", "drawShipwrecks", false, "If set to true shipwrecks will be drawn. (default: false)");
+ drawOceanRuins = SetupBooleanProperty(config, "features", "drawOceanRuins", false, "If set to true ocean ruins will be drawn. (default: false)");
+ drawBuriedTreasure = SetupBooleanProperty(config, "features", "drawBuriedTreasures", false, "If set to true buried treasure will be drawn. (default: false)");
+ drawIgloos = SetupBooleanProperty(config, "features", "drawIgloos", false, "If set to true igloos will be drawn. (default: false)");
+ config.save();
+ }
+
+ private static Setting SetupBooleanProperty(Configuration config, String category, String settingName, Boolean defaultValue, String comment) {
+ Setting property = config.get(category, settingName, defaultValue);
+ property.comment = comment;
+ property.set(property.getBoolean(defaultValue));
+ return property;
+ }
+
+ private static Setting SetupIntegerProperty(Configuration config, String category, String settingName, int defaultValue, String comment) {
+ Setting property = config.get(category, settingName, defaultValue);
+ property.comment = comment;
+ property.set(property.getInt(defaultValue));
+ return property;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.config;
+
+import com.google.common.io.Files;
+
+import java.io.*;
+import java.nio.charset.Charset;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class Configuration {
+ private final File file;
+
+ Configuration(File file) {
+ this.file = file;
+ }
+
+ void save() {
+ Writer writer = null;
+ try {
+ writer = new BufferedWriter(new OutputStreamWriter(
+ new FileOutputStream(file), "utf-8"));
+ writer.write("# Configuration file\n");
+ for (String category : settingsGroup.keySet()) {
+ writer.write("\n");
+ writer.write(String.format("%s {\n", category));
+ Map<String, Setting> settings = settingsGroup.get(category);
+ Boolean first = true;
+ for (String settingName : settings.keySet()) {
+ if (!first)
+ writer.write("\n");
+ first = false;
+ Setting setting = settings.get(settingName);
+ writer.write(String.format(" # %s\n", setting.comment));
+ writer.write(String.format(" %s:%s=%s\n", setting.getType(), settingName, setting.getValue()));
+ }
+ writer.write("}\n");
+ }
+ } catch (IOException ignored) {
+ } finally {
+ try {
+ if (writer != null) {
+ writer.close();
+ }
+ } catch (Exception ignored) {
+ }
+ }
+ }
+
+ private Map<String, Map<String, Setting>> settingsGroup = new HashMap<>();
+
+ void load() {
+ try {
+ List<String> lines = Files.readLines(file, Charset.forName("utf-8"));
+ String category = null;
+ String lastCommentLine = null;
+ for (String line : lines) {
+ String trimmedLine = line.trim();
+ if (trimmedLine.isEmpty()) {
+ continue;
+ }
+ if (trimmedLine.startsWith("#")) {
+ lastCommentLine = trimmedLine.substring(1).trim();
+ continue;
+ }
+ if (trimmedLine.equals("}")) {
+ category = null;
+ continue;
+ }
+ if (category == null && trimmedLine.endsWith("{")) {
+ category = trimmedLine.substring(0, trimmedLine.length() - 1).trim();
+ settingsGroup.put(category, new HashMap<>());
+ continue;
+ }
+ if (category != null) {
+ String[] items = trimmedLine.split("[:=]");
+ char type = items[0].charAt(0);
+ String name = items[1];
+ String stringValue = items[2];
+ Object value = getTypedValue(type, stringValue);
+ Setting setting = new Setting(value);
+ setting.comment = lastCommentLine;
+ settingsGroup.get(category).put(name, setting);
+ }
+ }
+ } catch (IOException ignored) {
+ }
+ }
+
+ private Object getTypedValue(char type, String stringValue) {
+ switch (type) {
+ case 'I':
+ return Integer.parseInt(stringValue);
+ case 'B':
+ return stringValue.equals("1") || stringValue.toLowerCase().equals("true");
+ }
+ return stringValue;
+ }
+
+ public Setting get(String category, String settingName, Object defaultValue) {
+ if (!settingsGroup.containsKey(category)) {
+ settingsGroup.put(category, new HashMap<>());
+ }
+ Map<String, Setting> settings = settingsGroup.get(category);
+ if (!settings.containsKey(settingName)) {
+ settings.put(settingName, new Setting(defaultValue));
+ }
+ return settings.get(settingName);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.config;
+
+public class Setting {
+ private Object value;
+ String comment;
+
+ Setting(Object value) {
+ this.value = value;
+ }
+
+ public Boolean getBoolean(Boolean defaultValue) {
+ if (value instanceof Boolean)
+ return (Boolean) value;
+
+ return defaultValue;
+ }
+
+ int getInt(int defaultValue) {
+ if (value instanceof Integer)
+ return (Integer) value;
+
+ return defaultValue;
+ }
+
+ public void set(Object value) {
+ this.value = value;
+ }
+
+ public boolean getBoolean() {
+ return getBoolean(false);
+ }
+
+ public int getInt() {
+ return getInt(0);
+ }
+
+ String getType() {
+ if (value instanceof Integer)
+ return "I";
+ if (value instanceof Boolean)
+ return "B";
+ return "S";
+ }
+
+ Object getValue() {
+ return value;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.install;
+
+import javax.swing.*;
+import java.io.*;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.text.SimpleDateFormat;
+import java.util.*;
+
+public class Main {
+ public static void main(String... args) throws Throwable {
+ try {
+ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+ try {
+ String osName = getOsName();
+ File minecraftFolder = getMinecraftFolder(osName);
+ File versionFolder = new File(minecraftFolder, "versions/BBOR-@VERSION@/");
+ versionFolder.mkdirs();
+
+ File versionJson = new File(versionFolder, "BBOR-@VERSION@.json");
+ Files.copy(Main.class.getResourceAsStream("/profile.json"), versionJson.toPath(), StandardCopyOption.REPLACE_EXISTING);
+
+ try {
+ File profilesJson = new File(minecraftFolder, "launcher_profiles.json");
+ if (profilesJson.exists()) { // TODO: use gson instead
+ String identifier = "\"bbor-@MC_VERSION@\"";
+ String contents = new String(Files.readAllBytes(profilesJson.toPath()));
+ if (contents.contains(identifier)) {
+ contents = contents.replaceAll(",\n *"+identifier+": \\{[^}]*},", ",");
+ contents = contents.replaceAll(",?\n *"+identifier+": \\{[^}]*},?", "");
+ }
+
+ String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
+
+ contents = contents.replace("\n \"profiles\": {", "\n \"profiles\": {\n" +
+ " "+identifier+": {\n" +
+ " \"name\": \"Bounding Box Outline Reloaded\",\n" +
+ " \"type\": \"custom\",\n" +
+ " \"created\": \""+date+"T00:00:00.000Z\",\n" +
+ " \"lastUsed\": \"2100-01-01T00:00:00.000Z\",\n" +
+ " \"lastVersionId\": \"BBOR-@VERSION@\"\n" +
+ " },");
+
+ Files.write(profilesJson.toPath(), contents.getBytes());
+ }
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+ // Copy rift jar to libraries
+ try {
+ String source = Main.class.getProtectionDomain().getCodeSource().getLocation().getPath();
+ if (source.startsWith("/") && osName.contains("win")) {
+ source = source.substring(1);
+ }
+ File riftJar = new File(minecraftFolder, "libraries/com/irtimaled/bbor/@VERSION@/bbor-@VERSION@.jar");
+ riftJar.getParentFile().mkdirs();
+ Files.copy(Paths.get(source), riftJar.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ }
+
+ JOptionPane.showMessageDialog(null,
+ "Bounding Box Outline Reloaded @VERSION@ has been successfully installed!\n" +
+ "\n" +
+ "Re-open the Minecraft Launcher to see it in the dropdown.",
+ "Bounding Box Outline Reloaded Installer", JOptionPane.INFORMATION_MESSAGE);
+ } catch (Throwable t) {
+ StringWriter w = new StringWriter();
+ t.printStackTrace(new PrintWriter(w));
+ JOptionPane.showMessageDialog(null,
+ "An error occured while installing Bounding Box Outline Reloaded, please report this to the issue\n" +
+ "tracker (https://github.com/irtimaled/BoundingBoxOutlineReloaded/issues):\n" +
+ "\n" +
+ w.toString().replace("\t", " "), "Bounding Box Outline Reloaded Installer", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+
+ private static File getMinecraftFolder(String osName) {
+ File minecraftFolder;
+ if (osName.contains("win")) {
+ minecraftFolder = new File(System.getenv("APPDATA") + "/.minecraft");
+ } else if (osName.contains("mac")) {
+ minecraftFolder = new File(System.getProperty("user.home") + "/Library/Application Support/minecraft");
+ } else {
+ minecraftFolder = new File(System.getProperty("user.home") + "/.minecraft");
+ }
+ return minecraftFolder;
+ }
+
+ private static String getOsName() {
+ return System.getProperty("os.name").toLowerCase(Locale.ROOT);
+ }
+
+}
--- /dev/null
+package com.irtimaled.bbor.launch;
+
+import java.io.File;
+import java.util.List;
+
+public class ClientTweaker extends Tweaker {
+ @Override
+ protected void addOptions(List<String> args, File gameDir, File assetsDir, String profile){
+ addArg("--assetsDir", assetsDir.getPath());
+ }
+
+ @Override
+ public String getLaunchTarget() {
+ return "net.minecraft.client.main.Main";
+ }
+
+ @Override
+ protected boolean isClient() {
+ return true;
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.launch;
+
+public class ServerTweaker extends Tweaker {
+ @Override
+ protected boolean isClient() {
+ return false;
+ }
+
+ @Override
+ public String getLaunchTarget() {
+ return "net.minecraft.server.MinecraftServer";
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.launch;
+
+import net.minecraft.launchwrapper.ITweaker;
+import net.minecraft.launchwrapper.LaunchClassLoader;
+import org.spongepowered.asm.launch.MixinBootstrap;
+import org.spongepowered.asm.mixin.MixinEnvironment;
+import org.spongepowered.asm.mixin.Mixins;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class Tweaker implements ITweaker {
+ public List<String> args;
+
+ @Override
+ public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
+ this.args = new ArrayList<>(args);
+ addArg("--version", profile);
+ addOptions(args, gameDir, assetsDir, profile);
+ }
+
+ protected void addArg(String name, String value) {
+ args.add(name);
+ if (value != null) {
+ args.add(value);
+ }
+ }
+
+ protected void addOptions(List<String> args, File gameDir, File assetsDir, String profile) {
+ }
+
+ @Override
+ public void injectIntoClassLoader(LaunchClassLoader classLoader) {
+ // Use the Launch classLoader to load the RiftLoader class. Otherwise identical
+ // classes may not be equal, and 'instanceof' may return false when it should be true.
+ /*try {
+ Class<?> clazz = Launch.classLoader.findClass("org.dimdev.riftloader.RiftLoader");
+ clazz.getMethod("load", boolean.class).invoke(clazz.getField("instance").get(null), isClient());
+ } catch (ReflectiveOperationException e) {
+ throw new RuntimeException(e);
+ }
+*/
+ MixinBootstrap.init();
+ Mixins.addConfiguration("mixins.bbor.json");
+ MixinEnvironment.getDefaultEnvironment().setSide(isClient() ? MixinEnvironment.Side.CLIENT : MixinEnvironment.Side.SERVER);
+
+ }
+
+ protected abstract boolean isClient();
+
+ @Override
+ public String[] getLaunchArguments() {
+ return args.toArray(new String[0]);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.mixin.client;
+
+import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
+import net.minecraft.client.Minecraft;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(Minecraft.class)
+public class MixinMinecraft {
+ @Inject(method = "init", at = @At("RETURN"))
+ private void init(CallbackInfo ci) {
+ BoundingBoxOutlineReloaded.init();
+ }
+
+ @Inject(method = "processKeyBinds", at = @At("HEAD"))
+ public void processKeyBinds(CallbackInfo ci) {
+ BoundingBoxOutlineReloaded.keyPressed();
+ }
+}
\ No newline at end of file
--- /dev/null
+package com.irtimaled.bbor.mixin.client.multiplayer;
+
+import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
+import net.minecraft.client.multiplayer.WorldClient;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(WorldClient.class)
+public class MixinWorldClient {
+ @Inject(method="sendQuittingDisconnectingPacket", at=@At("RETURN"))
+ private void sendQuittingDisconnectingPacket(CallbackInfo ci)
+ {
+ BoundingBoxOutlineReloaded.playerDisconnectedFromServer();
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.mixin.client.renderer;
+
+import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
+import net.minecraft.client.renderer.EntityRenderer;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(EntityRenderer.class)
+public class MixinEntityRenderer {
+ @Inject(method = "updateCameraAndRender(FJ)V", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V", args = "ldc=hand", shift = At.Shift.BEFORE))
+ private void render(float partialTicks, long ignored, CallbackInfo ci) {
+ BoundingBoxOutlineReloaded.render(partialTicks);
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.mixin.client.settings;
+
+import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
+import net.minecraft.client.GameSettings;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.settings.KeyBinding;
+import org.apache.commons.lang3.ArrayUtils;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+import java.io.File;
+
+@Mixin(GameSettings.class)
+public class MixinGameSettings {
+ @Shadow private KeyBinding[] keyBindings;
+
+ @Inject(method = "<init>()V", at = @At("RETURN"))
+ private void init(CallbackInfo ci) {
+ keyBindings = getKeysAll();
+ }
+
+ private KeyBinding[] getKeysAll() {
+ return ArrayUtils.addAll(keyBindings, BoundingBoxOutlineReloaded.ActiveHotKey, BoundingBoxOutlineReloaded.OuterBoxOnlyHotKey);
+ }
+
+ @Inject(method = "<init>(Lnet/minecraft/client/Minecraft;Ljava/io/File;)V", at = @At("RETURN"))
+ private void init(Minecraft minecraft, File file, CallbackInfo ci) {
+ keyBindings = getKeysAll();
+ }
+}
\ No newline at end of file
--- /dev/null
+package com.irtimaled.bbor.mixin.client.settings;
+
+import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
+import net.minecraft.client.settings.KeyBinding;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+
+import java.util.Map;
+
+@Mixin(KeyBinding.class)
+public class MixinKeyBinding {
+ @Shadow private static Map<String, Integer> CATEGORY_ORDER;
+
+ static {
+ CATEGORY_ORDER.put(BoundingBoxOutlineReloaded.KeyCategory, 0);
+ }
+}
\ No newline at end of file
--- /dev/null
+package com.irtimaled.bbor.mixin.network;
+
+import io.netty.util.concurrent.GenericFutureListener;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.network.Packet;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(NetworkManager.class)
+public class MixinNetworkManager {
+ @Inject(method = "sendPacket(Lnet/minecraft/network/Packet;Lio/netty/util/concurrent/GenericFutureListener;)V", at= @At("RETURN"))
+ public void sendPacket(Packet<?> packetIn, GenericFutureListener<?> listener, CallbackInfo ci) {
+ if (packetIn instanceof net.minecraft.network.login.client.CPacketLoginStart) {
+ com.irtimaled.bbor.client.BoundingBoxOutlineReloaded.playerConnectedToServer((NetworkManager) (Object) this);
+ }
+ }
+
+}
--- /dev/null
+package com.irtimaled.bbor.mixin.server;
+
+import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
+import net.minecraft.server.MinecraftServer;
+import net.minecraft.world.World;
+import net.minecraft.world.WorldServer;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.Shadow;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(MinecraftServer.class)
+public class MixinMinecraftServer {
+ @Shadow public WorldServer[] worlds;
+
+ @Inject(method = "initialWorldChunkLoad", at = @At("HEAD"))
+ private void initialWorldChunkLoad(CallbackInfo ci)
+ {
+ for(World world : worlds) {
+ BoundingBoxOutlineReloaded.worldLoaded(world);
+ }
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.mixin.world.chunk;
+
+import com.irtimaled.bbor.client.BoundingBoxOutlineReloaded;
+import net.minecraft.world.chunk.Chunk;
+import org.spongepowered.asm.mixin.Mixin;
+import org.spongepowered.asm.mixin.injection.At;
+import org.spongepowered.asm.mixin.injection.Inject;
+import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
+
+@Mixin(Chunk.class)
+public class MixinChunk {
+ @Inject(method = "onLoad", at = @At("RETURN"))
+ private void onLoad(CallbackInfo ci) {
+ BoundingBoxOutlineReloaded.chunkLoaded((Chunk) (Object) this);
+ }
+}
\ No newline at end of file
--- /dev/null
+{
+ "required": true,
+ "minVersion": "0.7.11",
+ "compatibilityLevel": "JAVA_8",
+ "target": "@env(DEFAULT)",
+ "package": "com.irtimaled.bbor.mixin",
+ "refmap": "mixins.bbor.refmap.json",
+ "mixins": [
+ "world.chunk.MixinChunk",
+ "network.MixinNetworkManager",
+ "server.MixinMinecraftServer"
+ ],
+ "client": [
+ "client.MixinMinecraft",
+ "client.renderer.MixinEntityRenderer",
+ "client.multiplayer.MixinWorldClient",
+ "client.settings.MixinKeyBinding",
+ "client.settings.MixinGameSettings"
+ ]
+}
--- /dev/null
+{
+ "inheritsFrom": "${mcVersion}",
+ "id": "BBOR-${version}",
+ "jar": "${mcVersion}",
+ "time": "${formattedTime}",
+ "type": "release",
+ "arguments": {
+ "game": [
+ "--tweakClass",
+ "${tweakClass}"
+ ]
+ },
+ "mainClass": "net.minecraft.launchwrapper.Launch",
+ "libraries": [
+ {
+ "name": "com.irtimaled:bbor:${version}"
+ },
+ {
+ "name": "org.spongepowered:mixin:0.7.11-SNAPSHOT",
+ "url": "https://github.com/irtimaled/Mixin/releases/download/"
+ },
+ {
+ "name": "org.ow2.asm:asm:6.2",
+ "url": "http://repo1.maven.org/maven2/"
+ },
+ {
+ "name": "org.ow2.asm:asm-commons:6.2",
+ "url": "http://repo1.maven.org/maven2/"
+ },
+ {
+ "name": "net.minecraft:launchwrapper:1.12"
+ }
+ ]
+}
\ No newline at end of file