dependencies {
minecraft 'com.mojang:minecraft:' + project.mcVersion
- mappings 'net.fabricmc:yarn:' + project.mcVersion + '+build.16'
+ mappings 'net.fabricmc:yarn:' + project.mcVersion + '+build.9'
modCompile 'net.fabricmc:fabric-loader:0.8.3+build.196'
}
name=bbor
buildVersion=2.4
# leave a space to reduce merge conflicts on version change
-mcVersion=1.14.4
+mcVersion=1.15.2
import com.irtimaled.bbor.client.interop.FlowerForestHelper;
import com.irtimaled.bbor.client.keyboard.Key;
import com.irtimaled.bbor.client.keyboard.KeyListener;
-import com.irtimaled.bbor.client.providers.*;
+import com.irtimaled.bbor.client.providers.CacheProvider;
+import com.irtimaled.bbor.client.providers.SlimeChunkProvider;
+import com.irtimaled.bbor.client.providers.WorldSpawnProvider;
import com.irtimaled.bbor.common.BoundingBoxCache;
import com.irtimaled.bbor.common.CommonProxy;
import com.irtimaled.bbor.common.EventBus;
RenderHelper.afterRender();
}
+ public static void renderDeferred() {
+ RenderHelper.beforeRender();
+ RenderHelper.polygonModeFill();
+ RenderHelper.enableBlend();
+ RenderQueue.renderDeferred();
+ RenderHelper.disableBlend();
+ RenderHelper.enablePolygonOffsetLine();
+ RenderHelper.polygonOffsetMinusOne();
+ RenderHelper.afterRender();
+ }
+
public static Stream<AbstractBoundingBox> getBoundingBoxes(DimensionId dimensionId) {
Stream.Builder<AbstractBoundingBox> boundingBoxes = Stream.builder();
for (IBoundingBoxProvider<?> provider : providers) {
private static DimensionId dimensionId;
public static void setPosition(double partialTicks, ClientPlayerEntity player) {
- x = player.prevX + (player.x - player.prevX) * partialTicks;
- y = player.prevY + (player.y - player.prevY) * partialTicks;
- z = player.prevZ + (player.z - player.prevZ) * partialTicks;
+ x = player.prevX + (player.getX() - player.prevX) * partialTicks;
+ y = player.prevY + (player.getY() - player.prevY) * partialTicks;
+ z = player.prevZ + (player.getZ() - player.prevZ) * partialTicks;
dimensionId = DimensionId.from(player.dimension);
}
ClientRenderer.render(DimensionId.from(player.dimension));
}
+ public static void renderDeferred() {
+ ClientRenderer.renderDeferred();
+ }
+
public static boolean interceptChatMessage(String message) {
if (message.startsWith("/bbor:")) {
ClientPlayNetworkHandler connection = MinecraftClient.getInstance().getNetworkHandler();
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.biome.Biomes;
import net.minecraft.world.gen.feature.DecoratedFeatureConfig;
+import net.minecraft.world.gen.feature.FeatureConfig;
import net.minecraft.world.gen.feature.FlowerFeature;
import java.util.HashMap;
private static final Map<BlockState, Setting<HexColor>> flowerColorMap = new HashMap<>();
private static final FlowerFeature flowersFeature;
+ private static final FeatureConfig flowersConfig;
static {
flowerColorMap.put(Blocks.DANDELION.getDefaultState(), ConfigManager.colorFlowerForestDandelion);
DecoratedFeatureConfig config = (DecoratedFeatureConfig) Biomes.FLOWER_FOREST.getFlowerFeatures().get(0).config;
flowersFeature = (FlowerFeature) config.feature.feature;
+ flowersConfig = config.feature.config;
}
public static Setting<HexColor> getFlowerColorAtPos(Coords coords) {
int x = coords.getX();
int z = coords.getZ();
- BlockState blockState = flowersFeature.getFlowerToPlace(random, new BlockPos(x, coords.getY(), z));
+ BlockState blockState = flowersFeature.getFlowerToPlace(random, new BlockPos(x, coords.getY(), z), flowersConfig);
return flowerColorMap.get(blockState);
}
package com.irtimaled.bbor.client.interop;
import com.irtimaled.bbor.common.EventBus;
+import com.irtimaled.bbor.common.ReflectionHelper;
import com.irtimaled.bbor.common.events.StructuresLoaded;
import com.irtimaled.bbor.common.models.DimensionId;
import net.minecraft.nbt.CompoundTag;
import java.io.File;
import java.io.IOException;
import java.util.*;
+import java.util.function.Function;
class NBTStructureLoader {
private final DimensionId dimensionId;
super(null,
0,
0,
- null,
new BlockBox(compound.getIntArray("BB")),
0,
0);
}
@Override
- public boolean generate(IWorld iWorld, Random random, BlockBox blockBox, ChunkPos chunkPos) {
+ public boolean generate(IWorld iWorld, ChunkGenerator<?> chunkGenerator, Random random, BlockBox blockBox, ChunkPos chunkPos) {
return false;
}
}
private static class ChunkLoader {
+ private static final Function<File, RegionBasedStorage> creator =
+ ReflectionHelper.getPrivateInstanceBuilder(RegionBasedStorage.class, File.class);
+
private final RegionBasedStorage regionFileCache;
public ChunkLoader(File file) {
- this.regionFileCache = new RegionBasedStorage(file) {
- };
+ this.regionFileCache = creator.apply(file);
}
public CompoundTag readChunk(int chunkX, int chunkZ) throws IOException {
+ if (regionFileCache == null) return null;
return regionFileCache.getTagAt(new ChunkPos(chunkX, chunkZ));
}
public void close() throws IOException {
+ if (regionFileCache == null) return;
regionFileCache.close();
}
}
public static final String Category = "Bounding Box Outline Reloaded";
public static void init() {
- mainWindowHandle = minecraft.window.getHandle();
+ mainWindowHandle = minecraft.getWindow().getHandle();
GLFW.glfwSetKeyCallback(mainWindowHandle, KeyListener::onKeyEvent);
}
import com.irtimaled.bbor.client.Player;
import com.irtimaled.bbor.client.config.BoundingBoxTypeHelper;
-import com.irtimaled.bbor.client.config.ConfigManager;
import com.irtimaled.bbor.client.interop.BedrockCeilingHelper;
import com.irtimaled.bbor.client.interop.ClientInterop;
import com.irtimaled.bbor.client.models.BoundingBoxBedrockCeiling;
void renderFilledFaces(OffsetPoint min, OffsetPoint max, Color color, int alpha) {
if (!ConfigManager.fill.get()) return;
-
- RenderHelper.polygonModeFill();
- RenderHelper.enableBlend();
- renderFaces(min, max, color, alpha, Renderer::startQuads);
- RenderHelper.disableBlend();
- RenderHelper.enablePolygonOffsetLine();
- RenderHelper.polygonOffsetMinusOne();
+ RenderQueue.deferRendering(() -> renderFaces(min, max, color, alpha, Renderer::startQuads));
}
void renderText(OffsetPoint offsetPoint, String... texts) {
.render();
if (!ConfigManager.fill.get()) return;
-
- RenderHelper.polygonModeFill();
- RenderHelper.enableBlend();
- Renderer.startQuads()
+ RenderQueue.deferRendering(() -> Renderer.startQuads()
.setColor(color)
.setAlpha(30)
.addPoints(cornerPoints)
- .render();
- RenderHelper.disableBlend();
- RenderHelper.enablePolygonOffsetLine();
- RenderHelper.polygonOffsetMinusOne();
+ .render());
}
}
--- /dev/null
+package com.irtimaled.bbor.client.renderers;
+
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+
+public class RenderQueue {
+ private static final Queue<RenderAction> queue = new ConcurrentLinkedQueue<>();
+
+ public static void deferRendering(RenderAction action) {
+ queue.add(action);
+ }
+
+ public static void renderDeferred() {
+ while (!queue.isEmpty()) {
+ queue.poll().render();
+ }
+ }
+
+ @FunctionalInterface
+ public interface RenderAction {
+ void render();
+ }
+}
\ No newline at end of file
}
private void tex(double u, double v) {
- bufferBuilder.texture(u, v);
+ bufferBuilder.texture((float) u, (float) v);
}
private void color() {
package com.irtimaled.bbor.common;
+import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
}
return true;
}
+
+ public static <T, R> Function<T, R> getPrivateInstanceBuilder(Class<R> clazz, Class<T> parameter) {
+ Constructor<R> constructor = findConstructor(clazz, parameter);
+ if (constructor == null) return obj -> null;
+
+ constructor.setAccessible(true);
+ return obj -> {
+ try {
+ return (R) constructor.newInstance(obj);
+ } catch (Exception ignored) {
+ return null;
+ }
+ };
+ }
+
+ private static <T> Constructor<T> findConstructor(Class<T> clazz, Class<?>... parameters) {
+ try {
+ return clazz.getDeclaredConstructor(parameters);
+ } catch (NoSuchMethodException ignored) {
+ return null;
+ }
+ }
}
ServerPlayNetworkHandler connection = player.networkHandler;
if (connection == null) return;
- ClientConnection networkManager = connection.connection;
+ ClientConnection networkManager = connection.client;
if (networkManager.isLocal()) return;
EventBus.publish(new PlayerLoggedIn(new ServerPlayer(player)));
import com.irtimaled.bbor.common.models.Coords;
import com.irtimaled.bbor.common.models.DimensionId;
import io.netty.buffer.Unpooled;
+import net.minecraft.client.network.packet.CustomPayloadS2CPacket;
import net.minecraft.network.Packet;
-import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket;
-import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
+import net.minecraft.server.network.packet.CustomPayloadC2SPacket;
import net.minecraft.util.Identifier;
import net.minecraft.util.PacketByteBuf;
@Shadow
@Final
private ResourcePackManager<ClientResourcePackProfile> resourcePackManager;
- private ClientProxy clientProxy;
@Inject(method = "<init>", at = @At("RETURN"))
private void constructor(RunArgs configuration, CallbackInfo ci) {
- clientProxy = new ClientProxy();
- this.resourcePackManager.registerProvider(new ModPackFinder());
+ new ClientProxy().init();
}
- @Inject(method = "init", at = @At("RETURN"))
+ @Inject(method = "startTimerHackThread", at = @At("RETURN"))
private void init(CallbackInfo ci) {
- clientProxy.init();
+ this.resourcePackManager.registerProvider(new ModPackFinder());
}
}
import com.irtimaled.bbor.client.interop.ClientInterop;
import net.minecraft.client.MinecraftClient;
+import net.minecraft.client.render.Camera;
import net.minecraft.client.render.GameRenderer;
+import net.minecraft.client.render.LightmapTextureManager;
+import net.minecraft.client.render.WorldRenderer;
+import net.minecraft.client.util.math.Matrix4f;
+import net.minecraft.client.util.math.MatrixStack;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
-@Mixin(GameRenderer.class)
+@Mixin(WorldRenderer.class)
public class MixinGameRenderer {
@Shadow
@Final
private MinecraftClient client;
- @Inject(method = "renderCenter(FJ)V", at = @At(value = "INVOKE_STRING", target = "Lnet/minecraft/util/profiler/Profiler;swap(Ljava/lang/String;)V", args = "ldc=hand", shift = At.Shift.BEFORE))
- private void render(float partialTicks, long ignored, CallbackInfo ci) {
+ @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/debug/DebugRenderer;render(Lnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumerProvider$Immediate;DDD)V", shift = At.Shift.BEFORE))
+ private void renderFirst(MatrixStack ignored_1, float partialTicks, long ignored_2, boolean ignored_3, Camera ignored_4, GameRenderer ignored_5, LightmapTextureManager ignored_6, Matrix4f ignored_7, CallbackInfo ci) {
ClientInterop.render(partialTicks, this.client.player);
}
+
+ @Inject(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/WorldRenderer;renderChunkDebugInfo(Lnet/minecraft/client/render/Camera;)V", shift = At.Shift.BEFORE))
+ private void render(MatrixStack ignored_1, float partialTicks, long ignored_2, boolean ignored_3, Camera ignored_4, GameRenderer ignored_5, LightmapTextureManager ignored_6, Matrix4f ignored_7, CallbackInfo ci) {
+ ClientInterop.renderDeferred();
+ }
}
import com.irtimaled.bbor.common.interop.CommonInterop;
import com.irtimaled.bbor.common.messages.SubscribeToServer;
import net.minecraft.network.listener.ServerPlayPacketListener;
-import net.minecraft.network.packet.c2s.play.CustomPayloadC2SPacket;
import net.minecraft.server.network.ServerPlayNetworkHandler;
+import net.minecraft.server.network.packet.CustomPayloadC2SPacket;
import net.minecraft.util.Identifier;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Shadow
private Identifier channel;
- @Redirect(method = "apply", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/listener/ServerPlayPacketListener;onCustomPayload(Lnet/minecraft/network/packet/c2s/play/CustomPayloadC2SPacket;)V"))
+ @Redirect(method = "apply", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/listener/ServerPlayPacketListener;onCustomPayload(Lnet/minecraft/server/network/packet/CustomPayloadC2SPacket;)V"))
private void processPacket(ServerPlayPacketListener netHandlerPlayServer, CustomPayloadC2SPacket packet) {
if (this.channel.toString().equals(SubscribeToServer.NAME)) {
CommonInterop.playerSubscribed(((ServerPlayNetworkHandler) netHandlerPlayServer).player);
package com.irtimaled.bbor.mixin.network.play.server;
import com.irtimaled.bbor.client.interop.ClientInterop;
-import net.minecraft.network.packet.s2c.play.ChatMessageS2CPacket;
+import net.minecraft.client.network.packet.ChatMessageS2CPacket;
import net.minecraft.text.Text;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
package com.irtimaled.bbor.mixin.network.play.server;
import com.irtimaled.bbor.client.interop.ClientInterop;
+import net.minecraft.client.network.packet.ChunkDataS2CPacket;
import net.minecraft.network.listener.ClientPlayPacketListener;
-import net.minecraft.network.packet.s2c.play.ChunkDataS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import com.irtimaled.bbor.client.interop.ClientInterop;
import com.irtimaled.bbor.common.TypeHelper;
import net.minecraft.client.network.ClientPlayNetworkHandler;
+import net.minecraft.client.network.packet.CommandTreeS2CPacket;
import net.minecraft.network.listener.ClientPlayPacketListener;
-import net.minecraft.network.packet.s2c.play.CommandTreeS2CPacket;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import com.irtimaled.bbor.common.messages.PayloadReader;
import com.irtimaled.bbor.common.messages.SubscribeToServer;
import net.minecraft.client.network.ClientPlayNetworkHandler;
+import net.minecraft.client.network.packet.CustomPayloadS2CPacket;
import net.minecraft.network.listener.ClientPlayPacketListener;
-import net.minecraft.network.packet.s2c.play.CustomPayloadS2CPacket;
import net.minecraft.util.Identifier;
import net.minecraft.util.PacketByteBuf;
import org.spongepowered.asm.mixin.Mixin;
@Shadow
private Identifier channel;
- @Redirect(method = "apply", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/listener/ClientPlayPacketListener;onCustomPayload(Lnet/minecraft/network/packet/s2c/play/CustomPayloadS2CPacket;)V"))
+ @Redirect(method = "apply", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/listener/ClientPlayPacketListener;onCustomPayload(Lnet/minecraft/client/network/packet/CustomPayloadS2CPacket;)V"))
private void processPacket(ClientPlayPacketListener netHandlerPlayClient, CustomPayloadS2CPacket packet) {
String channelName = channel.toString();
if (channelName.startsWith("bbor:")) {
package com.irtimaled.bbor.mixin.network.play.server;
import com.irtimaled.bbor.client.interop.ClientInterop;
-import net.minecraft.network.packet.s2c.play.PlayerSpawnPositionS2CPacket;
+import net.minecraft.client.network.packet.PlayerSpawnPositionS2CPacket;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;