buildscript {
repositories {
jcenter()
- maven { url 'https://repo.spongepowered.org/maven' }
- maven { url 'https://jitpack.io' }
+ mavenCentral()
maven { url 'https://files.minecraftforge.net/maven' }
}
dependencies {
- classpath 'com.github.Irtimaled:ForgeGradle:' + project.mcVersion + '-SNAPSHOT'
- classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
+ classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
}
}
-apply plugin: 'net.minecraftforge.gradle.tweaker-client'
+apply plugin: 'net.minecraftforge.gradle'
+apply plugin: 'eclipse'
apply plugin: 'java'
-apply plugin: 'org.spongepowered.mixin'
group 'com.irtimaled'
version project.buildVersion + '-' + project.mcVersion
sourceCompatibility = 1.8
targetCompatibility = 1.8
-repositories {
- mavenCentral()
- maven { url 'https://libraries.minecraft.net/' }
- maven { url 'https://repo.spongepowered.org/maven/' }
- maven { url 'https://jitpack.io' }
-}
-
-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 = project.mcVersion
- mappings = 'snapshot_20190227'
- runDir = 'run'
- tweakClass = 'com.irtimaled.bbor.launch.ClientTweaker'
- makeObfSourceJar = false
-
- replace "@VERSION@", project.version
- replaceIn "com/irtimaled/bbor/Main.java"
-
- replace "@MC_VERSION@", project.mcVersion
- replaceIn "com/irtimaled/bbor/Main.java"
-}
-
-mixin {
- defaultObfuscationEnv notch
- add sourceSets.main, 'mixins.bbor.refmap.json'
-}
+ mappings channel: 'snapshot', version: '20190511-1.13.2'
+ runs {
+ client {
+ workingDirectory project.file('run')
+ property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
+ property 'forge.logging.console.level', 'debug'
+ mods {
+ bbor {
+ source sourceSets.main
+ }
+ }
+ }
-sourceSets {
- main
- debug {
- compileClasspath += main.compileClasspath
+ server {
+ workingDirectory project.file('run')
+ property 'forge.logging.markers', 'SCAN,REGISTRIES,REGISTRYDUMP'
+ property 'forge.logging.console.level', 'debug'
+ mods {
+ bbor {
+ source sourceSets.main
+ }
+ }
+ }
}
}
-processResources {
- filesMatching('profile.json') {
- expand([
- 'version' : project.version,
- 'mcVersion' : project.mcVersion,
- 'tweakClass' : project.minecraft.tweakClass,
- 'formattedTime': new Date().format("yyyy-MM-dd'T'HH:mm:ss'-08:00'")
- ])
- }
-
- inputs.property "version", project.version
- inputs.property "mcVersion", project.mcVersion
+dependencies {
+ minecraft 'net.minecraftforge:forge:1.13.2-25.0.198'
}
jar {
- finalizedBy reobfJar
- manifest.attributes(
- 'Main-Class': 'com.irtimaled.bbor.Main'
- )
-
- classifier = 'vanilla'
-}
+ manifest {
+ attributes([
+ "Specification-Title" : "bbor",
+ "Specification-Vendor" : "Irtimaled",
+ "Specification-Version" : "1", // We are version 1 of ourselves
+ "Implementation-Title" : project.name,
+ "Implementation-Version" : "${version}",
+ "Implementation-Vendor" : "Irtimaled",
+ "Implementation-Timestamp": new Date().format("yyyy-MM-dd'T'HH:mm:ssZ")
+ ])
+ }
-artifacts {
- archives jar
+ classifier = 'forge'
}
buildVersion=1.0.14
# leave a space to reduce merge conflicts on version change
mcVersion=1.13.2
+
+# Sets default memory used for gradle commands. Can be overridden by user or command line properties.
+# This is required to provide enough memory for the Minecraft decompilation process.
+org.gradle.jvmargs=-Xmx3G
+org.gradle.daemon=false
\ No newline at end of file
+++ /dev/null
-package com.irtimaled.bbor;
-
-import com.irtimaled.bbor.install.Installer;
-import com.irtimaled.bbor.server.ServerRunner;
-
-import java.io.IOException;
-import java.util.Arrays;
-
-public class Main {
- public static void main(String... args) throws IOException {
- if (args.length > 0 && args[0].equals("--server")) {
- ServerRunner.run("@MC_VERSION@", Arrays.asList(args).subList(1, args.length));
- } else {
- Installer.install("@VERSION@", "@MC_VERSION@");
-
- }
- }
-}
private String title;
private Set<IRenderableControl> controls = new HashSet<>();
- SettingsScreen(GuiScreen lastScreen, int tabIndex) {
+ public SettingsScreen(GuiScreen lastScreen, int tabIndex) {
this.lastScreen = lastScreen;
this.tabIndex = tabIndex;
}
key.updateKeyCode(keyCode);
}
- public Key getKey() {
+ public Key getCustomKey() {
return key;
}
}
\ No newline at end of file
CustomKeyBinding keyBinding = new CustomKeyBinding(description, input.getKeyCode());
keyBindings.add(keyBinding);
- Key key = keyBinding.getKey();
+ Key key = keyBinding.getCustomKey();
keys.add(key);
return key;
}
--- /dev/null
+package com.irtimaled.bbor.forge;
+
+import com.irtimaled.bbor.client.interop.ClientInterop;
+import io.netty.channel.ChannelHandlerContext;
+import io.netty.channel.SimpleChannelInboundHandler;
+import net.minecraft.network.Packet;
+import net.minecraft.network.play.server.SPacketSpawnPosition;
+
+public class ForgeClientChannelHandler extends SimpleChannelInboundHandler<Packet<?>> {
+ @Override
+ protected void channelRead0(ChannelHandlerContext ctx, Packet<?> msg) {
+ if (msg instanceof SPacketSpawnPosition) {
+ handle((SPacketSpawnPosition) msg);
+ }
+ ctx.fireChannelRead(msg);
+ }
+
+ private void handle(SPacketSpawnPosition msg) {
+ ClientInterop.updateWorldSpawnReceived(msg.getSpawnPos());
+ }
+}
+
--- /dev/null
+package com.irtimaled.bbor.forge;
+
+import com.irtimaled.bbor.client.ClientProxy;
+import com.irtimaled.bbor.client.interop.ClientInterop;
+import com.irtimaled.bbor.client.keyboard.KeyListener;
+import com.irtimaled.bbor.common.EventBus;
+import com.irtimaled.bbor.common.messages.*;
+import net.minecraft.client.Minecraft;
+import net.minecraft.client.multiplayer.WorldClient;
+import net.minecraft.network.NetworkManager;
+import net.minecraftforge.client.event.ClientChatEvent;
+import net.minecraftforge.client.event.ClientChatReceivedEvent;
+import net.minecraftforge.client.event.RenderWorldLastEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fml.network.NetworkEvent;
+import org.apache.commons.lang3.ArrayUtils;
+
+public class ForgeClientProxy extends ForgeCommonProxy {
+ @Override
+ void init() {
+ new ClientProxy().init();
+ Minecraft.getInstance().gameSettings.keyBindings = ArrayUtils.addAll(Minecraft.getInstance().gameSettings.keyBindings, KeyListener.keyBindings());
+ ForgeNetworkHelper.addBusEventConsumer(AddBoundingBox.NAME, AddBoundingBox::getEvent);
+ ForgeNetworkHelper.addBusEventConsumer(RemoveBoundingBox.NAME, RemoveBoundingBox::getEvent);
+ ForgeNetworkHelper.addConsumer(InitializeClient.NAME, this::initializeClient);
+ }
+
+ private <T extends NetworkEvent> void initializeClient(final T packet) {
+ EventBus.publish(InitializeClient.getEvent(new PayloadReader(packet.getPayload())));
+
+ NetworkManager networkManager = Minecraft.getInstance().getConnection().getNetworkManager();
+ networkManager.channel().pipeline().addBefore("packet_handler", "bbor", new ForgeClientChannelHandler());
+
+ networkManager.sendPacket(SubscribeToServer.getPayload().build());
+ }
+
+ @SubscribeEvent
+ public void renderWorldLastEvent(RenderWorldLastEvent event) {
+ ClientInterop.render(event.getPartialTicks(), Minecraft.getInstance().player);
+ }
+
+ @SubscribeEvent
+ public void worldUnloadedEvent(WorldEvent.Unload event) {
+ if (event.getWorld() instanceof WorldClient && !Minecraft.getInstance().getConnection().getNetworkManager().isChannelOpen()) {
+ ClientInterop.disconnectedFromRemoteServer();
+ }
+ }
+
+ @SubscribeEvent
+ public void clientChatEvent(ClientChatEvent event) {
+ if (ClientInterop.interceptChatMessage(event.getMessage()))
+ event.setMessage("");
+ }
+
+ @SubscribeEvent
+ public void clientChatReceivedEvent(ClientChatReceivedEvent event) {
+ ClientInterop.handleSeedMessage(event.getMessage());
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.forge;
+
+import com.irtimaled.bbor.common.CommonProxy;
+import com.irtimaled.bbor.common.interop.CommonInterop;
+import com.irtimaled.bbor.common.messages.SubscribeToServer;
+import net.minecraft.block.Block;
+import net.minecraft.entity.player.EntityPlayer;
+import net.minecraft.entity.player.EntityPlayerMP;
+import net.minecraft.world.IWorld;
+import net.minecraft.world.World;
+import net.minecraft.world.WorldServer;
+import net.minecraft.world.chunk.Chunk;
+import net.minecraft.world.chunk.IChunk;
+import net.minecraftforge.event.world.BlockEvent;
+import net.minecraftforge.event.world.ChunkEvent;
+import net.minecraftforge.event.world.WorldEvent;
+import net.minecraftforge.eventbus.api.SubscribeEvent;
+import net.minecraftforge.fml.common.gameevent.PlayerEvent;
+import net.minecraftforge.fml.common.gameevent.TickEvent;
+import net.minecraftforge.fml.network.NetworkEvent;
+
+public class ForgeCommonProxy {
+ void init() {
+ new CommonProxy().init();
+ ForgeNetworkHelper.addConsumer(SubscribeToServer.NAME, this::playerSubscribed);
+ }
+
+ private <T extends NetworkEvent> void playerSubscribed(final T packet) {
+ CommonInterop.playerSubscribed(packet.getSource().get().getSender());
+ }
+
+ @SubscribeEvent
+ public void worldEvent(WorldEvent.Load event) {
+ IWorld world = event.getWorld();
+ if (world instanceof WorldServer) {
+ CommonInterop.loadWorld((WorldServer) world);
+ }
+ }
+
+ @SubscribeEvent
+ public void chunkEvent(ChunkEvent.Load event) {
+ IChunk chunk = event.getChunk();
+ if (chunk instanceof Chunk) {
+ CommonInterop.chunkLoaded((Chunk) chunk);
+ }
+ }
+
+ @SubscribeEvent
+ public void playerLoggedInEvent(PlayerEvent.PlayerLoggedInEvent evt) {
+ EntityPlayer player = evt.getPlayer();
+ if (player instanceof EntityPlayerMP) {
+ CommonInterop.playerLoggedIn((EntityPlayerMP) player);
+ }
+ }
+
+ @SubscribeEvent
+ public void playerLoggedOutEvent(PlayerEvent.PlayerLoggedOutEvent evt) {
+ EntityPlayer player = evt.getPlayer();
+ if (player instanceof EntityPlayerMP) {
+ CommonInterop.playerLoggedOut((EntityPlayerMP) player);
+ }
+ }
+
+ @SubscribeEvent
+ public void worldTickEvent(TickEvent.WorldTickEvent event) {
+ if (event.phase == TickEvent.Phase.END &&
+ event.world instanceof WorldServer) {
+ CommonInterop.worldTick((WorldServer) event.world);
+ }
+ }
+
+ @SubscribeEvent
+ public void serverTickEvent(TickEvent.ServerTickEvent event) {
+ if (event.phase == TickEvent.Phase.END)
+ CommonInterop.tick();
+ }
+
+ @SubscribeEvent
+ public void blockBreakEvent(BlockEvent.BreakEvent event) {
+ Block block = event.getState().getBlock();
+ IWorld world = event.getWorld();
+ if (world instanceof World) {
+ CommonInterop.tryHarvestBlock(block, event.getPos(), (World) world);
+ }
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.forge;
+
+import com.irtimaled.bbor.common.interop.CommonInterop;
+import net.minecraftforge.common.MinecraftForge;
+import net.minecraftforge.fml.DistExecutor;
+import net.minecraftforge.fml.common.Mod;
+import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
+import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
+
+@Mod("bbor")
+public class ForgeMod {
+ public static ForgeMod instance;
+
+ public static ForgeCommonProxy proxy = DistExecutor.runForDist(() -> ForgeClientProxy::new, () -> ForgeCommonProxy::new);
+
+ public ForgeMod() {
+ instance = this;
+ FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
+ }
+
+ private void setup(final FMLCommonSetupEvent event) {
+ CommonInterop.init();
+ MinecraftForge.EVENT_BUS.register(proxy);
+ proxy.init();
+ }
+}
--- /dev/null
+package com.irtimaled.bbor.forge;
+
+import com.irtimaled.bbor.common.EventBus;
+import com.irtimaled.bbor.common.messages.PayloadReader;
+import net.minecraft.util.ResourceLocation;
+import net.minecraftforge.fml.network.NetworkEvent;
+import net.minecraftforge.fml.network.NetworkRegistry;
+
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+class ForgeNetworkHelper {
+ private static final String PROTOCOL_VERSION = Integer.toString(1);
+
+ static <T extends NetworkEvent> void addBusEventConsumer(String name, Function<PayloadReader, ?> getEventSupplier) {
+ addConsumer(name, e -> EventBus.publish(getEventSupplier.apply(new PayloadReader(e.getPayload()))));
+ }
+
+ static <T extends NetworkEvent> void addConsumer(String name, Consumer<T> consumer) {
+ NetworkRegistry.newEventChannel(new ResourceLocation(name), () -> PROTOCOL_VERSION, PROTOCOL_VERSION::equals, PROTOCOL_VERSION::equals)
+ .addListener(consumer);
+ }
+}
+++ /dev/null
-package com.irtimaled.bbor.install;
-
-import javax.swing.*;
-import java.io.File;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.nio.file.Files;
-import java.nio.file.Paths;
-import java.nio.file.StandardCopyOption;
-import java.text.SimpleDateFormat;
-import java.util.Date;
-import java.util.Locale;
-
-public class Installer {
- public static void install(final String version, final String mcVersion) {
- 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(Installer.class.getResourceAsStream("/profile.json"), versionJson.toPath(), StandardCopyOption.REPLACE_EXISTING);
-
- try {
- File profilesJson = new File(minecraftFolder, "launcher_profiles.json");
- if (profilesJson.exists()) {
- String identifier = "\"bbor-" + mcVersion + "\"";
- String contents = new String(Files.readAllBytes(profilesJson.toPath()));
- if (contents.contains(identifier)) {
- contents = contents.replaceAll(",\n?\\s*" + identifier + "\\s*:\\s*\\{[^}]*},", ",");
- contents = contents.replaceAll(",?\n?\\s*" + identifier + "\\s*:\\s*\\{[^}]*},?", "");
- }
-
- String date = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
-
- contents = contents.replaceAll("([}],\n?\\s*\"profiles\"\\s*:\\s*[{]\n?)", "$1" +
- " " + 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" +
- " },\n");
-
- Files.write(profilesJson.toPath(), contents.getBytes());
- }
- } catch (Throwable t) {
- t.printStackTrace();
- }
-
- try {
- String source = Installer.class.getProtectionDomain().getCodeSource().getLocation().getPath();
- if (source.startsWith("/") && osName.contains("win")) {
- source = source.substring(1);
- }
- File mainJar = new File(minecraftFolder, "libraries/com/irtimaled/bbor/" + version + "/bbor-" + version + ".jar");
- mainJar.getParentFile().mkdirs();
- Files.copy(Paths.get(source), mainJar.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) {
- if (!isOptifineLoaded()) {
- super.addOptions(args, gameDir, assetsDir, profile);
- addArg("--gameDir", gameDir != null ? gameDir.getAbsolutePath() : null);
- addArg("--assetsDir", assetsDir != null ? assetsDir.getPath() : null);
- addArg("--version", profile);
- }
- }
-
- private boolean isOptifineLoaded() {
- try {
- Class cls = Class.forName("optifine.OptiFineTweaker");
- return cls != null;
- } catch (Throwable e) {
- return false;
- }
- }
-
- @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 {
- private List<String> args;
-
- @Override
- public void acceptOptions(List<String> args, File gameDir, File assetsDir, String profile) {
- this.args = new ArrayList<>();
- addOptions(args, gameDir, assetsDir, profile);
- }
-
- void addArg(String name, String value) {
- if (value != null) {
- args.add(name);
- args.add(value);
- }
- }
-
- protected void addOptions(List<String> args, File gameDir, File assetsDir, String profile) {
- this.args.addAll(args);
- }
-
- @Override
- public void injectIntoClassLoader(LaunchClassLoader classLoader) {
- 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.ClientProxy;
-import com.irtimaled.bbor.common.interop.CommonInterop;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.main.GameConfiguration;
-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 {
- private ClientProxy clientProxy;
-
- @Inject(method = "<init>", at = @At("RETURN"))
- private void constructor(GameConfiguration configuration, CallbackInfo ci) {
- CommonInterop.init();
- clientProxy = new ClientProxy();
- }
-
- @Inject(method = "init", at = @At("RETURN"))
- private void init(CallbackInfo ci) {
- clientProxy.init();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.client.entity;
-
-import com.irtimaled.bbor.client.interop.ClientInterop;
-import net.minecraft.client.entity.EntityPlayerSP;
-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(EntityPlayerSP.class)
-public abstract class MixinEntityPlayerSP {
- @Inject(method = "sendChatMessage", at = @At("HEAD"), cancellable = true)
- private void sendChatMessage(String message, CallbackInfo ci) {
- if (ClientInterop.interceptChatMessage(message))
- ci.cancel();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.client.gui;
-
-import com.irtimaled.bbor.client.gui.SettingsScreenButton;
-import net.minecraft.client.gui.GuiButton;
-import net.minecraft.client.gui.GuiOptions;
-import net.minecraft.client.gui.GuiScreen;
-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(GuiOptions.class)
-public class MixinGuiOptions extends GuiScreen {
- @Inject(method = "initGui", at = @At("RETURN"))
- private void initGui(CallbackInfo ci) {
- //shuffle middle buttons up by 12 px to make space
- int top = this.height / 6 + 42;
- int bottom = this.height / 6 + 168;
- for (GuiButton button : buttons) {
- if (button.y >= top && button.y < bottom)
- button.y -= 12;
- }
- this.addButton(new SettingsScreenButton(199, this.width / 2 - 155, top + 84, 150, "BBOR", this));
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.client.multiplayer;
-
-import com.irtimaled.bbor.client.interop.ClientInterop;
-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) {
- ClientInterop.disconnectedFromRemoteServer();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.client.network;
-
-import com.irtimaled.bbor.client.interop.ClientInterop;
-import net.minecraft.client.network.NetHandlerLoginClient;
-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(NetHandlerLoginClient.class)
-public abstract class MixinNetHandlerLoginClient {
- @Inject(method = "onDisconnect", at = @At("HEAD"))
- private void onDisconnect(CallbackInfo ci) {
- ClientInterop.disconnectedFromRemoteServer();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.client.network;
-
-import com.irtimaled.bbor.client.interop.ClientInterop;
-import net.minecraft.client.network.NetHandlerPlayClient;
-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(NetHandlerPlayClient.class)
-public class MixinNetHandlerPlayClient {
- @Inject(method = "onDisconnect", at = @At("HEAD"))
- private void onDisconnect(CallbackInfo ci) {
- ClientInterop.disconnectedFromRemoteServer();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.client.renderer;
-
-import com.irtimaled.bbor.client.interop.ClientInterop;
-import net.minecraft.client.Minecraft;
-import net.minecraft.client.renderer.GameRenderer;
-import org.spongepowered.asm.mixin.Final;
-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(GameRenderer.class)
-public class MixinEntityRenderer {
- @Shadow
- @Final
- private Minecraft mc;
-
- @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) {
- ClientInterop.render(partialTicks, this.mc.player);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.client.settings;
-
-import com.irtimaled.bbor.client.keyboard.KeyListener;
-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 abstract class MixinGameSettings {
- @Shadow
- public KeyBinding[] keyBindings;
-
- @Shadow
- public abstract void loadOptions();
-
- @Inject(method = "<init>(Lnet/minecraft/client/Minecraft;Ljava/io/File;)V", at = @At("RETURN"))
- private void init(Minecraft minecraft, File file, CallbackInfo ci) {
- keyBindings = ArrayUtils.addAll(keyBindings, KeyListener.keyBindings());
- this.loadOptions();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.client.settings;
-
-import com.irtimaled.bbor.client.keyboard.KeyListener;
-import net.minecraft.client.settings.KeyBinding;
-import org.spongepowered.asm.mixin.Final;
-import org.spongepowered.asm.mixin.Mixin;
-import org.spongepowered.asm.mixin.Shadow;
-
-import java.util.Map;
-
-@Mixin(KeyBinding.class)
-public class MixinKeyBinding {
- @Final
- @Shadow
- private static Map<String, Integer> CATEGORY_ORDER;
-
- static {
- CATEGORY_ORDER.put(KeyListener.Category, 0);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.network.play.client;
-
-import com.irtimaled.bbor.common.interop.CommonInterop;
-import com.irtimaled.bbor.common.messages.SubscribeToServer;
-import net.minecraft.network.NetHandlerPlayServer;
-import net.minecraft.network.play.INetHandlerPlayServer;
-import net.minecraft.network.play.client.CPacketCustomPayload;
-import net.minecraft.util.ResourceLocation;
-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.Redirect;
-
-@Mixin(CPacketCustomPayload.class)
-public class MixinCPacketCustomPayload {
- @Shadow
- private ResourceLocation channel;
-
- @Redirect(method = "processPacket", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/play/INetHandlerPlayServer;processCustomPayload(Lnet/minecraft/network/play/client/CPacketCustomPayload;)V"))
- private void processPacket(INetHandlerPlayServer netHandlerPlayServer, CPacketCustomPayload packet) {
- if (this.channel.toString().equals(SubscribeToServer.NAME)) {
- CommonInterop.playerSubscribed(((NetHandlerPlayServer) netHandlerPlayServer).player);
- } else {
- netHandlerPlayServer.processCustomPayload(packet);
- }
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.network.play.server;
-
-import com.irtimaled.bbor.client.interop.ClientInterop;
-import net.minecraft.network.play.server.SPacketChat;
-import net.minecraft.util.text.ITextComponent;
-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(SPacketChat.class)
-public class MixinSPacketChat {
- @Shadow private ITextComponent chatComponent;
-
- @Inject(method = "processPacket", at = @At("RETURN"))
- private void processPacket(CallbackInfo ci) {
- ClientInterop.handleSeedMessage(this.chatComponent);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.network.play.server;
-
-import com.irtimaled.bbor.client.interop.ClientInterop;
-import com.irtimaled.bbor.common.TypeHelper;
-import net.minecraft.client.network.NetHandlerPlayClient;
-import net.minecraft.network.play.INetHandlerPlayClient;
-import net.minecraft.network.play.server.SPacketCommandList;
-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(SPacketCommandList.class)
-public class MixinSPacketCommandList {
- @Inject(method = "processPacket", at= @At("RETURN"))
- private void processPacket(INetHandlerPlayClient netHandlerPlayClient, CallbackInfo ci) {
- TypeHelper.doIfType(netHandlerPlayClient, NetHandlerPlayClient.class, handler -> {
- ClientInterop.registerClientCommands(handler.func_195515_i());
- });
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.network.play.server;
-
-import com.irtimaled.bbor.common.EventBus;
-import com.irtimaled.bbor.common.messages.*;
-import net.minecraft.client.network.NetHandlerPlayClient;
-import net.minecraft.network.PacketBuffer;
-import net.minecraft.network.play.INetHandlerPlayClient;
-import net.minecraft.network.play.server.SPacketCustomPayload;
-import net.minecraft.util.ResourceLocation;
-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.Redirect;
-
-@Mixin(SPacketCustomPayload.class)
-public abstract class MixinSPacketCustomPayload {
- @Shadow
- private ResourceLocation channel;
-
- @Redirect(method = "processPacket", at = @At(value = "INVOKE", target = "Lnet/minecraft/network/play/INetHandlerPlayClient;handleCustomPayload(Lnet/minecraft/network/play/server/SPacketCustomPayload;)V"))
- private void processPacket(INetHandlerPlayClient netHandlerPlayClient, SPacketCustomPayload packet) {
- String channelName = channel.toString();
- if (channelName.startsWith("bbor:")) {
- PacketBuffer data = null;
- try {
- data = packet.getBufferData();
- PayloadReader reader = new PayloadReader(data);
- switch (channelName) {
- case InitializeClient.NAME: {
- EventBus.publish(InitializeClient.getEvent(reader));
- ((NetHandlerPlayClient) netHandlerPlayClient).sendPacket(SubscribeToServer.getPayload().build());
- break;
- }
- case AddBoundingBox.NAME: {
- EventBus.publish(AddBoundingBox.getEvent(reader));
- break;
- }
- case RemoveBoundingBox.NAME: {
- EventBus.publish(RemoveBoundingBox.getEvent(reader));
- break;
- }
- }
- } finally {
- if (data != null)
- data.release();
- }
- } else {
- netHandlerPlayClient.handleCustomPayload(packet);
- }
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.network.play.server;
-
-import com.irtimaled.bbor.client.interop.ClientInterop;
-import net.minecraft.network.play.server.SPacketSpawnPosition;
-import net.minecraft.util.math.BlockPos;
-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(SPacketSpawnPosition.class)
-public abstract class MixinSPacketSpawnPosition {
- @Shadow
- private BlockPos spawnBlockPos;
-
- @Inject(method = "processPacket", at = @At("RETURN"))
- private void afterProcessPacket(CallbackInfo ci) {
- ClientInterop.updateWorldSpawnReceived(spawnBlockPos);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.server;
-
-import com.irtimaled.bbor.common.interop.CommonInterop;
-import net.minecraft.server.MinecraftServer;
-import net.minecraft.world.WorldServer;
-import net.minecraft.world.dimension.DimensionType;
-import org.spongepowered.asm.mixin.Final;
-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.util.Map;
-
-@Mixin(MinecraftServer.class)
-public class MixinMinecraftServer {
- @Shadow
- @Final
- private Map<DimensionType, WorldServer> worlds;
-
- @Inject(method = "initialWorldChunkLoad", at = @At("HEAD"))
- private void initialWorldChunkLoad(CallbackInfo ci) {
- CommonInterop.loadWorlds(worlds.values());
- }
-
- @Inject(method = "tick", at = @At("RETURN"))
- private void tick(CallbackInfo ci) {
- CommonInterop.tick();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.server.dedicated;
-
-import com.irtimaled.bbor.common.CommonProxy;
-import com.irtimaled.bbor.common.interop.CommonInterop;
-import net.minecraft.server.dedicated.DedicatedServer;
-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.CallbackInfoReturnable;
-
-@Mixin(DedicatedServer.class)
-public class MixinDedicatedServer {
- @Inject(method = "init", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/dedicated/DedicatedServer;loadAllWorlds(Ljava/lang/String;Ljava/lang/String;JLnet/minecraft/world/WorldType;Lcom/google/gson/JsonElement;)V"))
- private void init(CallbackInfoReturnable<Boolean> cir) {
- CommonInterop.init();
- new CommonProxy().init();
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.server.management;
-
-import com.irtimaled.bbor.common.interop.CommonInterop;
-import net.minecraft.block.Block;
-import net.minecraft.server.management.PlayerInteractionManager;
-import net.minecraft.util.math.BlockPos;
-import net.minecraft.world.World;
-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.CallbackInfoReturnable;
-
-@Mixin(PlayerInteractionManager.class)
-public class MixinPlayerInteractionManager {
- @Shadow
- public World world;
-
- @Inject(method = "tryHarvestBlock", at = @At("HEAD"))
- private void tryHarvestBlock(BlockPos pos, CallbackInfoReturnable<Boolean> cir) {
- Block block = this.world.getBlockState(pos).getBlock();
- CommonInterop.tryHarvestBlock(block, pos, world);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.server.management;
-
-import com.irtimaled.bbor.common.interop.CommonInterop;
-import net.minecraft.entity.player.EntityPlayerMP;
-import net.minecraft.server.management.PlayerList;
-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(PlayerList.class)
-public class MixinPlayerList {
- @Inject(method = "playerLoggedIn", at = @At("RETURN"))
- private void playerLoggedIn(EntityPlayerMP player, CallbackInfo ci) {
- CommonInterop.playerLoggedIn(player);
- }
-
- @Inject(method = "playerLoggedOut", at = @At("HEAD"))
- private void playerLoggedOut(EntityPlayerMP player, CallbackInfo ci) {
- CommonInterop.playerLoggedOut(player);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.world;
-
-import com.irtimaled.bbor.common.interop.CommonInterop;
-import net.minecraft.world.WorldServer;
-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(WorldServer.class)
-public class MixinWorldServer {
- @Inject(method = "tick", at = @At(value = "INVOKE", target = "Lnet/minecraft/village/VillageCollection;tick()V", shift = At.Shift.AFTER))
- private void afterVillageTick(CallbackInfo ci) {
- CommonInterop.worldTick((WorldServer) (Object) this);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.mixin.world.chunk;
-
-import com.irtimaled.bbor.common.interop.CommonInterop;
-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) {
- CommonInterop.chunkLoaded((Chunk) (Object) this);
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.server;
-
-import net.minecraft.launchwrapper.Launch;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.lang.reflect.Method;
-import java.net.MalformedURLException;
-import java.net.URL;
-import java.net.URLClassLoader;
-import java.nio.channels.Channels;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class ServerRunner {
- private static final Map<String, String> VANILLA_SERVER_JARS = new HashMap<>();
-
- private static final String[] LIBRARIES = {
- "https://github.com/irtimaled/Mixin/releases/download/org/spongepowered/mixin/0.7.11-SNAPSHOT/mixin-0.7.11-SNAPSHOT.jar",
- "https://repo1.maven.org/maven2/org/ow2/asm/asm/6.2/asm-6.2.jar",
- "https://repo1.maven.org/maven2/org/ow2/asm/asm-commons/6.2/asm-commons-6.2.jar",
- "https://repo1.maven.org/maven2/org/ow2/asm/asm-tree/6.2/asm-tree-6.2.jar",
- "https://libraries.minecraft.net/net/minecraft/launchwrapper/1.12/launchwrapper-1.12.jar"
- };
-
- private static final ThrowableConsumer<URL> addURL;
-
- static {
- VANILLA_SERVER_JARS.put("1.13.2", "https://launcher.mojang.com/v1/objects/3737db93722a9e39eeada7c27e7aca28b144ffa7/server.jar");
- VANILLA_SERVER_JARS.put("1.13.1", "https://launcher.mojang.com/v1/objects/fe123682e9cb30031eae351764f653500b7396c9/server.jar");
- VANILLA_SERVER_JARS.put("1.13", "https://launcher.mojang.com/v1/objects/d0caafb8438ebd206f99930cfaecfa6c9a13dca0/server.jar");
-
- try {
- Method method = URLClassLoader.class
- .getDeclaredMethod("addURL", URL.class);
- method.setAccessible(true);
- addURL = url -> method.invoke(ClassLoader.getSystemClassLoader(), url);
- } catch (ReflectiveOperationException e) {
- throw new AssertionError(e);
- }
- }
-
- private static void addURLToClasspath(File file) throws MalformedURLException {
- addURL.accept(file.toURI().toURL());
- }
-
- public static void run(String version, List<String> args) throws IOException {
- String serverJarUrl = VANILLA_SERVER_JARS.get(version);
-
- addURLToClasspath(getOrDownload(new File("."), serverJarUrl));
- for (String url : LIBRARIES) {
- addURLToClasspath(getOrDownload(new File("libs"), url));
- }
-
- args = new ArrayList<>(args);
- args.add("--tweakClass");
- args.add("com.irtimaled.bbor.launch.ServerTweaker");
-
- System.out.println("Launching server...");
- Launch.main(args.toArray(new String[0]));
- }
-
- private static File getOrDownload(File directory, String url) throws IOException {
- String fileName = url.substring(url.lastIndexOf('/') + 1);
- File target = new File(directory, fileName);
- if (target.isFile()) {
- return target;
- }
- target.getParentFile().mkdirs();
-
- System.out.println("Downloading library: " + url);
- new FileOutputStream(target).getChannel()
- .transferFrom(Channels.newChannel(new URL(url).openStream()), 0, Long.MAX_VALUE);
-
- return target;
- }
-}
+++ /dev/null
-package com.irtimaled.bbor.server;
-
-import com.irtimaled.bbor.common.TypeHelper;
-
-import java.util.function.Consumer;
-
-public interface ThrowableConsumer<T> extends Consumer<T> {
- @Override
- default void accept(final T elem) {
- try {
- acceptThrows(elem);
- } catch (final Throwable t) {
- throw TypeHelper.as(t, RuntimeException.class, () -> new RuntimeException(t));
- }
- }
-
- void acceptThrows(T elem) throws Throwable;
-}
--- /dev/null
+modLoader="javafml" #mandatory
+loaderVersion="[25,)" #mandatory (24 is current forge version)
+
+[[mods]] #mandatory
+modId="bbor" #mandatory
+version="${file.jarVersion}" #mandatory
+displayName="BoundingBoxOutlineReloaded" #mandatory
+displayURL="http://www.minecraftforum.net/forums/mapping-and-modding/minecraft-mods/2345401" #optional
+credits="Thanks to 4poc & KaboPC." #optional
+authors="irtimaled" #optional
+description="Shows the bounding boxes of structures and features."
+
+[[dependencies.bbor]] #optional
+ modId="forge" #mandatory
+ mandatory=true #mandatory
+ versionRange="[25,)" #mandatory
+ ordering="NONE"
+ side="BOTH"
+
+[[dependencies.bbor]]
+ modId="minecraft"
+ mandatory=true
+ versionRange="[1.13.2]"
+ ordering="NONE"
+ side="BOTH"
\ 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": [
- "network.play.client.MixinCPacketCustomPayload",
- "server.MixinMinecraftServer",
- "server.management.MixinPlayerInteractionManager",
- "server.management.MixinPlayerList",
- "world.MixinWorldServer",
- "world.chunk.MixinChunk"
- ],
- "client": [
- "client.MixinMinecraft",
- "client.entity.MixinEntityPlayerSP",
- "client.gui.MixinGuiOptions",
- "client.multiplayer.MixinWorldClient",
- "client.network.MixinNetHandlerLoginClient",
- "client.network.MixinNetHandlerPlayClient",
- "client.renderer.MixinEntityRenderer",
- "client.settings.MixinGameSettings",
- "client.settings.MixinKeyBinding",
- "network.play.server.MixinSPacketChat",
- "network.play.server.MixinSPacketCommandList",
- "network.play.server.MixinSPacketCustomPayload",
- "network.play.server.MixinSPacketSpawnPosition"
- ],
- "server": [
- "server.dedicated.MixinDedicatedServer"
- ]
-}
--- /dev/null
+{
+ "pack": {
+ "description": "bbor resources",
+ "pack_format": 4,
+ "_comment": "A pack_format of 4 requires json lang files. Note: we require v4 pack meta for all mods."
+ }
+}
\ No newline at end of file
+++ /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}",
- "url": "https://github.com/irtimaled/maven/releases/download/"
- },
- {
- "name": "org.spongepowered:mixin:0.7.11-SNAPSHOT",
- "url": "https://github.com/irtimaled/maven/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